Search for a command to run...

본 문서에서는 BitTorrent v2 프로토콜을 다룹니다. 이는 BEP 52 문서를 기반으로 수정된 버전입니다.
이 아티클은 BitTorrent 창시자 Bram Cohen이 직접 작성한 BitTorrent 논문의 내용을 이해하기 쉽게 다룹니다. 단, v1에 한정된 내용은 다루지 않습니다.
BitTorrent 프로토콜이란 대용량 파일을 효율적으로 배포하기 위해 설계된 P2P(Peer-to-Peer) 파일 전송 시스템입니다. 절대 불법 파일 공유 프로토콜이 아닙니다!!!
HTTP를 사용해 파일을 배포하는 대부분의 경우, 모든 업로드 비용은 서버에 집중됩니다. 반면, BitTorrent에서는 여러 사용자가 동시에 동일한 파일을 다운로드할 때, 서로가 서로에게 파일을 업로드하여 업로드 비용이 분산됩니다. 이를 통해 최초 배포자의 파일 호스팅 비용을 절감할 수 있습니다.
BitTorrent는 파일을 하나의 스트림으로 업로드하지 않습니다. 업로드 시 파일을 조각(piece)으로 분할하며, 조각화된 파일을 전송 단위로 관리합니다. 각 조각은 보통 수백 KB에서 수 MB 정도의 크기며, 각 조각은 순서대로 전송되지 않습니다. 또한, 각 조각은 해싱을 통한 무결성 검사에도 사용합니다.
이러한 조각화는 특정 피어가 전체 콘텐츠를 보유하고 있지 않더라도, 서로 가지고 있는 콘텐츠를 배포하여 완전한 파일 배포가 가능해지고, 특정 업로더에 대한 의존성이 감소합니다.
이외에도 일부 조각의 전송 오류가 발생하더라도 해당 조각만 다시 요청하면 되기에 전송 효율성과 안정성이 향상됩니다. :)
조각의 실제 전송은 블록이라는 아주 작은 단위로 나눠서 전송됩니다. (일반적으로 16KB 크기)
피어는 크게 시더(Seeder), 리처(Leecher) 로 분리됩니다.
트래커란 피어들이 서로를 찾을 수 있도록 도와주는 서비스입니다. BitTorrent는 P2P 서비스이지만, 피어들이 서로를 찾기 위해 트래커라는 중앙화 서비스를 사용합니다. 다운로더는 어떤 파일을 다운로드하고 있는 지, 어떤 포트에서 리스닝 중인지 등의 정보를 트래커에 전송하고, 트래커는 동일한 파일을 다운로드 중인 피어들의 접속 정보 목록을 응답합니다. 다운로더들은 이 정보를 이용해 서로를 연결합니다.
트래커의 역할은 "피어들이 서로를 찾게 도와주는 것"으로 엄격하게 제한되어 있습니다.
.torrent 파일BitTorrent를 통해 파일을 배포하기 위해서는 .torrent 확장자를 가진 파일을 어딘가(웹 서버 등)에 배포합니다. 이 .torrent 파일은 배포하고자 하는 파일의 실제 콘텐츠를 포함하지 않으며, 다음과 같은 정보를 가질 수 있습니다:
announce : 트래커의 URL (필수)announce-list : 다중 트래커 URL 리스트. announce를 사용할 수 없을 때 사용creation date : .torrent 파일이 생성된 시각created by .torrent 파일을 생성한 프로그램의 이름과 버전comment : .torrent 파일 생성자가 남긴 코멘트encoding : 문자열 인코딩 방식 (예: UTF-8)piece layers : 각 파일의 조각의 해시값이 저장된 곳info
meta version : 프로토콜 버전 정수값piece length : 데이터를 전송할 때 나누는 조각 크기name : 최상위 디렉토리명 또는 파일명file tree : 파일 구조와 해시 정보를 담은 계층적 dict이러한 정보가 담긴 .torrent 파일을 통해 다운로더는 BitTorrent 프로토콜에 참여할 수 있습니다.
// 파일 트리 예시
{
"movie.mp4": {
"": {
"length": 145020304,
"pieces root": "<32-byte-binary-hash>"
}
},
"subs": {
"kor.srt": {
"": {
"length": 30204,
"pieces root": "<32-byte-binary-hash>"
}
}
}
}
.torrent 파일을 통해 BitTorrent 프로토콜에 참여하기 위해서는 피어를 검색해야 합니다. 피어 검색은 동일한 콘텐츠를 공유하는 다른 피어들의 네트워크 주소(IP:port)를 획득하는 과정을 의미하며, 검색 방식은 다양하며 다음과 같습니다:
.torrent 파일에 기록된 트래커 서버에 피어 검색 요청하는 방식 (중앙화)
만약 DHT 네트워크의 개념을 보고, 바로 주소록 역할을 하는 노드로부터 발생할 수 있는 중간자 공격에 대한 아이디어가 떠오르셨다면 이후 보안 파트에서 다루니 이동해서 보셔도 좋습니다.
BitTorrent는 전체 파일을 하나의 연속된 스트림으로 전송하지 않고, 조각 단위로 전송합니다. 때문에 다운로드할 때에도 조각 단위로 다운로드하며, 모든 조각을 수신한 후 이를 병합하여 원본 파일을 완성하는 과정을 거칩니다.
조각 단위 다운로드는 여러 피어로 부터 병렬 다운로드를 가능하게 하며, 무결성 검증을 안전하게 만들어줍니다. 조각 무결성 검사에는 .torrent 파일 내의 file tree에 저장된 각 파일의 pieces root와 별도로 제공되는 piece layers 속성을 활용합니다.
조각 요청 및 전송 과정은 다음과 같습니다:
piece layers 해시 목록 확보piece layers 에 기록된 해당 조각의 해시값과 일치하는 지 대조
이때, 어떤 순서로 조각을 다운로드할 지 결정하는 것은 성능에 있어 매우 중요한 부분입니다. BitTorrent는 다음과 같은 조각 선택 전략을 가집니다:
조각은 순차적으로 다운로드 되지 않습니다. 따라서 조각이 도착하는 시점에 정확한 offset 위치에 데이터를 기록해야 합니다. 이는 다운로드 완료 후 단순 바이너리 병합만으로 완전한 파일을 만들 수 있게 해줍니다.
완전한 파일을 가지게 되면, 시더가 됩니다. BitTorrent 생태계를 유지하려면 다운로드가 끝난 후에도 일정 기간 시딩을 유지하는 것이 중요합니다.
BitTorrent 프로토콜은 TCP와 UDP 모두 사용하며, 과거에는 기본적으로 TCP로 동작했으나, 네트워크 대역폭을 다 잡아 먹어버리기에, 현대적인 클라이언트는 보통 UDP를 사용하여 이를 해결합니다.
하지만 UDP를 그대로 사용하는 경우는 없으며, UDP 위에서 신뢰성과 혼잡 제어 기능을 구현한 uTP(μTP)를 사용합니다. 혼잡 제어 기능 덕분에 다른 네트워크 활동이 디바이스에서 감지되면, 토렌트 속도를 조절해줍니다.
uTP(μTP)는 Micro Transport Protocol의 약자로 μTorrent에서 처음 개발했습니다. uTP라고도 불리는 이유는 'μ' 문자의 키보드 입력이 어렵기 때문입니다. (μTorrent는 단순 스파이/애드웨어 회사가 아닙니다!)
단, 파일 공유 시에만 uTP(μTP)를 사용하며, DHT 트래픽 등 다른 트래픽은 일반 UDP를 사용합니다.
BitTorrent는 초킹(Choking) 기법을 사용합니다. 초킹이란 특정 피어에게 데이터 업로드를 일시적으로 중단하는 상태를 말합니다.
BitTorrent 프로토콜은 P2P 통신이기에 피어들의 대역폭 자원이 매우 중요합니다. 따라서 데이터를 빠른 속도로 전송하고 있는 피어들 끼리 우선적으로 통신해야 효율적이며, 반대로 "업로드 기능을 제대로 수행하지 않는 민폐 피어" 는 초크 대상이 됩니다.
BitTorrent 클라이언트는 보통 10초마다 초킹 대상을 재결정합니다. 초킹 대상은 보통 가장 빠른 속도로 나와 상호작용하는 상위 피어(보통 4명)를 선택하여 언초크합니다. 자신이 리처라면 다운로드를 빨리 시켜주는 피어, 시더라면 파일을 빨리 가져가는 피어를 우대합니다.
하지만 이런 실력 주의적 언초킹 전략만 사용하면, 신입 피어는 영원히 데이터를 받을 기회가 없습니다.
때문에 BitTorrent는 낙관적 언초킹 기법을 사용합니다. 이는 30초마다 현재 연결된 피어 중 무작위로 하나를 선택하여 해당 피어의 데이터 전송 속도를 테스트해보는 전략입니다. 만약 빠르게 응답한다면 해당 피어는 언초킹 리스트에 등록됩니다.
스너빙(Snubbing) : 상대방 피어가 데이터를 보내주지 않고, 무시(냉대, 퇴짜)하는 상태. (보통 60초 동안 데이터가 전송되지 않으면 스너빙이라고 판단)
가끔 BitTorrent 프로토콜에는 절대로 업로드를 하지 않는 괴물 같은 민폐 피어가 존재합니다. BitTorrent 프로토콜에서는 이런 피어가 스너빙 중이라고 정의하며, 이런 피어에게 Anti-Snubbing이라고 불리는 보복 전략을 사용합니다. Anti-Snubbing은 "나를 스너빙한 피어에게 초크 상태를 유지하는 것"을 뜻하며, 낙관적 언초킹 외에 이 관계가 복구되는 일은 없습니다.
BitTorrent 프로토콜은 기본적으로 퍼블릭 네트워크에서 동작하기에, 특히 익명성에 대한 명확한 이해 없이 사용하게 될 경우, 개인정보 노출이 발생할 수 있습니다.
많은 ISP는 여러가지 이유로 P2P 트래픽을 감지하고 대역폭을 제한합니다. 이를 우회하기 위해 RC4 스트림 암호화를 사용하는 MSE(Message Stream Encryption) / PE(Protocol Encryption) 을 사용할 수 있습니다. 단, 이는 난독화에 가까우며, IP 주소를 숨겨주지 않아 익명성을 보장하지 못합니다.
BitTorrent의 구조적 특징이자 보안 위협은 "모든 피어의 IP는 공개된다." 입니다. 때문에 진정한 익명성을 위해서는 VPN 또는 프록시를 통해 실제 IP를 은닉해야 합니다. 단, 이 경우 포트포워딩이 제대로 동작하지 않는 경우가 많아 민폐 피어가 될 가능성이 있습니다.
2.4. 조각 다운로드 파트에서 설명하던 DHT 네트워크에서 발생할 수 있는 중간자 공격을 Sybil Attack이라고 합니다. 이는 공격자가 많은 수의 가짜 노드를 생성하여 DHT 네트워크의 특정 구역을 장악하는 공격으로, 특정 구역에 해당되는 파일들에 대한 요청을 가로채 악성코드를 삽입하거나 스누핑하게 만들 수 있습니다.
이를 막기 위한 전략은 여러가지 있지만, 가장 간단하고 강력한 방어책은 노드 ID 생성 제한입니다. 과거에는 랜덤으로 ID를 여러개 만들 수 있었지만, 현재는 노드 ID를 생성할 때 자신의 실제 IP를 사용해야 합니다. 때문에 수천 개의 실제 공인 IP 주소가 필요하므로, 공격자는 비용 문제로 포기할 수 밖에 없습니다.
그럼 그냥 IP 인자에 랜덤한 IP를 넣으면 되는 거 아닌가?
BitTorrent는 기본적으로 IP가 공개되어 있습니다. 때문에 상대방의 실제 IP를 알 수 있으며, 수신자는 이 IP와 노드 ID를 대조하며 진짜 노드인지 아닌지 간단히 판단 가능합니다.
과거에는 BitTorrent 네트워크 접속를 위해 .torrent 확장자를 가진 물리적인 파일이 필수적으로 요구 되었습니다. 현대에는 이를 해결하기 위해 URI 기반의 마그넷 링크(Magnet Link) 가 등장했습니다. 이는 단순히 링크만 공유하면 되며, 이는 굉장히 편리한 방식으로 자주 사용됩니다.
마그넷 링크는 magnet: 프로토콜 헤더를 가지며, 다음과 같은 구조를 가집니다:
xt : 찾고자 하는 파일의 고유한 해시값 (필수)
urn : 리소스명btih : BitTorrent 정보 해시dn : 다운로드 전, 피어에게 보여줄 파일명 (선택)tr : 초기 접속을 위한 트래커의 URL (선택)트래커 URL은 선택이며, 파일 정보가 없다!
마크넷 링크를 사용하면, 트래커 URL은 선택 사항입니다. 따라서 트래커 URL가 없는 링크를 사용하게 되면 DHT 만으로 피어를 검색해야 합니다. 또한, 파일 정보가 없기에, 메타데이터 조차도 다른 피어에게 받아와야 하며, 이는 다운로드 지연으로 이어집니다.
하지만, 탈중앙화된 방식을 사용하기에 특정 트래커에 정보를 전달하지 않아도 됩니다.
대부분의 가정용 PC는 NAT 뒤에 숨어 있기에 포트 포워딩 없이 외부망에서 직접 접근할 수 없습니다. 이때 BitTorrent 클라이언트는 UPnP(Universal Plug and Play) 기능을 사용해 공유기와 통신 후 알아서 포트를 열어주는 기능이 탑재되어, 일반 사용자 입장에서는 복잡한 설정 없이 업로드가 가능합니다.
반대로 보면, 일반 사용자는 본인의 의지와 상관 없이 포트를 외부에 개방하게 됩니다!
로그인 후 댓글을 작성할 수 있습니다.