비트토렌트 동작 방식

2023. 2. 14. 20:39졸논 백업

1. 비트토렌트란?

기존 클라이언트-서버 구조에서 파일을 요청할 때 클라이언트가 서버에 파일을 요청하고, 서버가 요청한 파일을 클라이언트에게 응답하는 것과 달리 비트토렌트는 클라이언트-클라이언트 구조로 파일을 갖고 있는 다수의 다른 클라이언트에게 파일을 요청하고 파일을 받는 분산 파일공유 프로토콜이다.

 

2. 특징

클라이언트-서버 구조의 일대일 파일 공유 방식은 클라이언트의 인터넷 환경과 서버의 성능에 따라 파일 전송 속도가 상이하다. 느린 인터넷을 사용한다면 당연히 파일 전송 속도도 느리고, 서버와 클라이언트 간 거리가 매우 멀어도 속도가 떨어질 수 있다.

반면 비트토렌트의 일대다 파일 공유 방식은 파일을 조각내어 클라이언트들 간에 그 조각을 교환하는 방식이다.(하나의 파일을 수백 개의 작은 비트단위로 나눈 것.. 그래서 비트 토렌트다.)

해당 파일 정보(조각)를 보유하고 있는 클라이언트 수가 많을 수록 다운로드 속도는 향상된다. 

파일을 얻고자 하는 클라이언트 A는 파일 조각을 보유/공유하고 있는 다른 클라이언트들과 여러 개의 세션을 생성하여 조각을 요청한다. 각 클라이언트들은 해당 파일을 공유하고 있는 새로운 클라이언트를 발견하면 자신이 보유하고 있는 조각 정보를 알려주고, 새로운 클라이언트들에게 자신이 필요한 조각을 요청한다.

이런 방식으로 비트토렌트에서 파일을 다운받고자 할 땐 다수의 클라이언트들과 무수히 많은 세션을 생성해야 하며, 세션이 늘어남에 따라 인터넷 환경 최대 대역폭까지 다운로드 속도가 증가한다.

이 '무수히 많은 세션을 생성해야 하는' 특징으로 인해 비트토렌트는 몇몇 문제점을 가지고 있는데, 문제점을 알아보기에 앞서 비트토렌트 프로토콜의 동작 방식에 대해 알아보자.

 

3. 비트트토렌트의 동작방식

비트토렌트 파일의 확장자는 .torrent이며, 이 파일은 다운로드 받고자 하는 파일의 정보를 담고 있다. 이 파일은 공유 할 파일을 갖고 있는 사용자가 자료 공유 목적으로 토렌트 파일을 작성하여 웹에 게시하는 것이 일반적이며,<이거에 대해선 좀 더 알아보자> 해당 파일을 실행하기 위해서는 BitTorrent 프로그램이 필요하다(ex. BitTorrent, uTorrent 등). 클라이언트는 프로그램을 실행하고 다운받을 파일의 정보를 담고 있는 토렌트 파일을 실행하여 파일 정보를 요청한다.

 

[비트토렌트 구성요소]

  • 조각(Piece) : 파일을 비트 단위로 조각 낸 파일. 조각의 크기는 토렌트 생성 시에 설정할 수 있다.
  • 시더(Seeder) : 공유 파일의 모든 조각(파일 완전체)을 갖고 있는 클라이언트
  • 리처(Leecher) : 공유 파일의 일부 조각을 갖고 있는 클라이언트
  • 피어(Peer) : 시더+리처를 총칭
  • 트래커(Tracker) : 파일 공유를 위해 피어 정보를 관리 하는 서버. 누구나 트래커 서버를 운영할 수 있다(비트토렌트는 오픈소스이다). 따라서 파일마다 다른 Tracker를 가질 수 있고, 하나의 파일이 여러개의 Tracker를 가질 수도 있다.
  • 스웜(Swarm) : 각 공유 파일마다 갖고 있는 고유 식별자(hash)와 공유 파일을 갖고있는 피어 리스트 정보. 트래커가 관리한다.

 

1. 토렌트 파일 다운

웹사이트에서 원하는 파일(m_mp4)의 토렌트 파일을 다운 받는다. 토렌트 파일에는 m_mp4의 해시값과 트래커 URL 주소가 포함된다. 해시는 같은 이름을 가진 다른파일과 구분하기 위한 유일한 값이며, 트래커 URL은 어떤 트래커를 사용하여 피어 목록을 받을지를 지정하는 것이다.  즉, 이름이 같은 파일일지라도 파일 해시나 트래커 URL이 다르다면 이는 다른 토렌트 파일이다. 쉬운 예로, m_mp4라는 동일한 이름의 두 파일이 있을 때, 한 파일의 해시는 $abcdE, 트래커 URL은 A이고 다른 파일의 해시는 $fghI,  트래커 URL이 B라면 전자의 토렌트 파일로는 B트래커의 피어 목록을 받을 수 없다.

트래커는 여러 개 있고, 각 트래커마다 관리하고 있는 피어 정보가 다르기 때문에 서로 다른 트래커를 사용하는 클라이언트간에는 파일을 공유할 수 없다. 

 

2. 트래커에 피어 목록 요청

m_mp4를 다운받고자 하는 사용자가 토렌트 프로그램에서 m_mp4.torrent파일을 실행하면 BitTorrent 클라이언트는 m_mp4에 포함되어있는 트래커 URL로 자신의 피어정보와 파일 해시를 전송한다.  이 메시지를 Tracker Request라고 하며, http프로토콜을 이용한다(method : GET). 이렇게 동일한 m_mp4.torrent를 공유하고 있는 모든 피어들은 트래커에 파일 해시를 전송하게 되며, 트래커는 이를 수신해 파일에 대한 hash를 기반으로 swarm을 생성하고 이 swarm으로 hash를 보낸 피어들의 IP 목록을 관리한다. 

 

3. 파일을 공유하고 있는 피어 리스트 반환

Tracker Request를 받은 트래커는 메시지에 포함된 hash값을 참조해 해당 hash에 대한 swarm이 존재하는지 확인한다.

swarm이 존재한다면 피어들의 IP리스트를 만들어 Tracker Response 메시지를 클라이언트에 전송하는데, 이 때 선정되는 피어는 랜덤이다. 디폴트로 50개 피어의 주소를 전송한다. 만약 swarm이 존재하지 않는다면, 해당 hash로 새로 swarm을 생성하고 다른 피어로부터 Tracker Request가 들어오기를 기다린다(다운 못 받음). 

 

4. 조각 다운로드

트래커로부터 피어들의 IP 목록을 받은 클라이언트는, 피어들과 hash를 교환한다. 

먼저 모든 피어들에게 m_mp4의 hash 값을 전송하고 해당 메시지를 받은 피어들 중 파일 공유가 가능한 피어는 다시 동일한 m_mp4의 hash로 응답한다. 이렇게 hash가 교환된 후 클라이언트와 피어는 세션을 생성하고(응답 온 피어일 경우) 생성된 세션을 통해 파일 조각을 교환한다. 

 

4. 토렌트 파일(.torrent) 구조

torrent

 ㄴ filename

 ㄴ info hash

tracker

 ㄴ tracker url

meta data

 ㄴ directory 

 ㄴ created on 

 ㄴ created by

 ㄴ comment

 ㄴ peice length

 ㄴ private

files 

 ㄴ filename

이름 파라미터 설명
torrent filename 토렌트 파일이름(m_mp4.torrent)
info hash 공유하고자 하는 파일 해시
tracker tracker url 피어 목록을 받아 올 트래커 주소
여러 개를 지정할 수 있다.
meta data directory 토렌트 파일이 저장되는 디렉터리 이름
created on 토렌트파일 생성 일자/시간
created by 토렌트파일 생성자 정보
comment 생성자가 적은 설명
piece length 파일조각 크기(기본값 128KB)
files filename 공유하는 실제 파일 이름(m.mp4)

파라미터 중 회색으로 하이라이팅 된 directory, piece lenth, private, filename은 hash값 생성을 위해 사용된다. 이 중 하나라도 변경되면 hash값이 달라지며, 기존 토렌트파일과 hash가 달라 트래커에서는 기존 파일과 변경된 파일을 다른 컨텐츠로 인식한다. 

신기하게도 토렌트는 하나의 토렌트 파일 안에 여러 개의 파일들을 포함시킬 수 있다. 이 파일들을 포함하는 것이 files다. 예를 들어, m_mp4.torrent파일 안에는 m.mp4파일, a.mp3파일, b.mp3파일 등이 포함될 수 있다.

directory는 이렇게 포함된 여러개의 파일이 저장되는 디렉터리 이름이다. m_mp4.torrent파일에서  b.mp3파일을 다운받으면 지정한 디렉터리에 저장된다. 

piece length를 통해 파일조각 크기를 설정할 수 있다. 따로 지정하지 않는 경우 BitTorrent프로토콜에서 정의한 파일크기 기반으로 알아서 조각이 나눠진다(ex. 1GB파일은 1조각 당 1MB).

 

5. 피어와 트래커 간 통신

Tracker Request

위에서 설명한 대로 피어와 트래커 간 통신은 HTTP프로토콜을 이용한다. 토렌트 프로그램에서 토렌트파일을 실행하면 토렌트파일에 포함된 정보를 기반으로 피어가 트래커에게 피어리스트를 요청하는 request를 보낸다.

요청을 받은 트래커는 hash에 해당하는 swarm을 검색해 피어 IP리스트를 반환한다.

Tracker Request의 메시지 형식은 다음과 같다.

파라미터 설명
info_hash 토렌트 파일에 포함된 공유파일의 hash
peer_id 클라이언트 식별을 위한 ID(20byte str)
port Tracker Response 메시지에서 사용되는 클라이언트의 포트
upload 클라이언트가 업로드 한 공유 파일의 총 바이트
download 클라이언트가 다운받은 공유 파일의 총 바이트
left 다운로드 받는 파일의 남은 크기(바이트)
key (option) 클라이언트 IP주소가 변경되도 식별가능하도록
피어마다 가지는 비공개 값
event started : 파일전송 시작
stopped : 파일전송 중지
completed : 파일전송 완료
numwant (option) 트래커에게 몇개 피어의 목록을 받을 것인지 지정(def.50)
compact 1 : 피어들의 IP주소와 Port 정보만 받음
0 : 주소, Port외 peer-id등 추가적인 정보를 받음
no_peer_id peer-id는 생략하고 정보를 받음
(compact=1의 설정이 우선된다)
ip (option) 클라이언트 IP주소

Tracker request 통신이 어떻게 이루어지는지 찾아봤다(직접 토렌트 깔긴 귀찮았다..)

Tracker request

 

HTTP라 평문으로 파라미터들이 다 노출되는 것을 볼 수 있다. 물론 hash나 id같은 것들은 해시된 값이라 알아볼 순 없다.

 

Tracker Response

파라미터 설명
complete 현재 파일을 공유하고 있는 시더들의 수
downloaded 해당 공유 파일의 다운로드 완료 횟수
incomplete 현재 파일을 받고 있는 리처들의 수
interval 클라이언트가 Tracker Request를 전송하는 간격(초단위)
min interval (option) 클라이언트가 Tracker Request를 전송하는 최소 간격(초단위)
클라이언트는 최소 간격보다 작은 간격으로 request를 보낼 수 없다.
peers 피어의 IP주소 리스트(딕셔너리 형식)

 

tracker response

사진 출처 : https://byzantinemysteries.wordpress.com/2017/10/30/bittorrent-tracker-protocol-examples/

 

BitTorrent Tracker Protocol examples

HTTP Tracker HTTP protocol is used and a typical request contains info_hash 20 byte sha1 hash of the bencoded form of the info value from the metainfo file key peer_id string of length 20 which thi…

byzantinemysteries.wordpress.com

6. 피어 간 통신

클라이언트가 피어 리스트를 다 받았다면 이제 리스트에 있는 피어들과 해시를 교환해야 한다.

다음은 피어 간 메시지 교환을 도식화한 것이다.

1. 클라이언트는 목록의 피어들에게 파일 hash, 본인의 peer id를 전송하여 연결 가능한지 확인한다.

2. 메시지를 받은 피어 중 연결이 가능한 피어는 다시 파일 hash, 본인의 peer id로 응답한다.

이 일련의 과정을 handshake라 한다. handshake가 완료되면 세션이 생성되고 파일 전송을 준비한다.

다음은 peer간 사용되는 메시지 종류다.

Message 설명
Keep-alive 대상 peer가 온라인 상태인지 확인
choke request를 받아도 응답할 수 없는 상태임을 알림
unchoke choke상태 해지 알림
have 자신이 갖고 있는 piece의 정보를 peer들에게 알림
request 받고자 하는 piece의 index와 offset정보를 대상 peer에게 알림
piece 실제 piece(파일 데이터), index, offset을 전송함

5, 6. 세션이 성립된 후 자신이 갖고 있는 조각의 정보를 클라이언트에게 알린다. 

이 메시지를 통해 클라이언트는 피어들이 갖고 있는 조각 정보를 보고 필요한 조각을 요청할 수 있게 된다.

7. 클라이언트는 필요한 조각정보를 담아 해당하는 피어들에게 조각을 요청한다.

8. 실제 조각 데이터를 전송

9, 10. 클라이언트는 조각 0x000002ed를 갖게 되었으므로 Have 메시지를 통해 자신이 이 조각을 갖고 있음을 다른 피어들에게 알린다. 향후 다른 피어가 조각 0x000002ed를 요청하면 클라이언트는 자신이 갖고 있는 조각이므로 요청한 피어에게 조각을 전송한다.

이렇게 모든 조각을 다 받게 되면 클라이언트는 reecher에서 seeder로 변경하고 업로드를 대기한다.

일련의 과정이 반복되며 피어와 피어 간 조각 교환이 계속 일어난다.

 

7. BitTorrent의 문제점

문제의 원인은 파일 조각을 갖고 있는 피어 리스트를 작성할 때, 피어가 랜덤으로 선정된다는 것이다.

이는 피어 간 거리나 현재 네트워크 상황(트래픽량) 등을 전혀 고려하지 않는다는 뜻이다.

따라서 필요한 조각을 갖고있는 피어가 가까이 있어도 먼 거리의 피어, 심지어 다른 나라의 피어까지 선정되는 문제가 발생한다. 이는 다시 다음 두 가지 문제점을 야기한다.

1. 파일 전송 속도 저하

2. 다른 나라의 네트워크망과 연결될 때, ISP사업자는 추가적인 비용을 지불해야 함(일반 사용자에겐 추가적인 비용이 발생하지 않음)

3. 멀티 세션 생성 + 다른 나라 피어 선정으로 트래픽이 과다 발생한다. 즉 소수의 p2p사용자가 대부분의 대역폭을 점유해 회선을 공유하는 다른 사용자들이 충분한 대역폭을 보장받지 못할 수도 있다.

 

이러한 문제점을 해결하기 위해 P4P가 소개되었다. 간단히 말하면, 피어의 네트워크 위치를 기반으로 피어 목록을 선정하는 것이다. 트래커와 클라이언트가 ISP사업자에게 피어들의 위치를 요청하고 이를 기반으로 피어 목록이 작성된다.

 

8. 토렌트는 불법인가?

토렌트 프로토콜 자체는 불법이 아니다. 토렌트를 잘 사용하면 사이트 운영자의 호스팅 부담을 덜고 서버 부하를 줄이며, 크기가 큰 파일을 빠른 속도로 공유할 수 있는 등 긍정적인 효과를 얻을 수 있다. 실제로 새 리눅스 배포판을 미러 서버에서 받는 것보다 토렌트를 통해서 받으면 빠르게 받을 수 있어 일부 배포판의 공식 사이트에서는 토렌트를 이용한 다운로드를 권장하고 있다.

다만 영화, 게임, 음악, 드라마, 19금 영상 등 저작권의 보호를 받거나 성범죄관련 법에 저촉되는 콘텐츠를 공유하는데 널리  이용이 되어 불법 복제의 대명사로 알려지게 되었다.

위에서 보았듯이 HTTP프로토콜을 이용한 통신으로 통신내용이 암호화되지 않기 때문에 피어의 IP가 그대로 노출된다.

또한, 파일 다운과 동시에 배포자가 되므로 저작권자가 IP주소를 수집해 고소하는 일도 자주 발생한다.

단순한 텍스트파일, 영화 등은 VPN을 사용해 수사를 피할 수도 있지만(외국 피어에서 받는 경우 해당 국가에 수사 공조를 받아야 함) 아동포르노와 같이 국제적으로 중대하게 다루는 사안은 외국 VPN사에서도 적극적으로 수사에 협조하므로 처벌을 피할 수 없다. 

기술은 죄가 없다. 이용하는 사람이 죄를 만드는 것이다.

 

이렇게 비트토렌트에 대해 알아보았다. 다음 포스팅에서는 비트토렌트를 기반으로 한 분산 웹, ZeroNet을 소개하겠다.

 

참고 자료 : https://www.netmanias.com/ko/?m=view&id=techdocs&no=10646 

'졸논 백업' 카테고리의 다른 글

JavaScript basic  (0) 2023.02.14
ZeroNet 동작 방식  (0) 2023.02.14
Zeronet content.db structure  (0) 2023.02.14
PyGeoIP 사용하기  (0) 2023.02.14
네트워크 트래픽 분석 파이썬 libs  (0) 2023.02.09