YGH

[홈서버 만들기] 12. 토렌트

2020년 11월 17일

개요

홈서버에 토렌트 클라이언트 프로그램을 넣어두고 웹 서비스를 하면 시드파일이나 마그넷을 툭 던져주고 다운받으라고 시켜 놓을 수가 있다.

영상 같은 경우는 다운이 완료되면 클라우드 스토리지에서 미디어 서버의 폴더로 영상을 옮기면 간편하게 시청할 수 있다.

요약하자면 다운로드 > 분류 > 시청 이다.

Transmission 설치

$ sudo apt install transmission-daemon

Transmission 폴더 생성

생성할 폴더는 Nextcloud에서도 확인 해야하므로 Nextcloud 계정 데이터 폴더 최상위 부분에 Plex/Donwloads 라는 폴더를 만들어주자.

$ su -
# cd /mnt/sdb/nextcloud-data/[Nextcloud계정명]/files
# sudo -u www-data mkdir -m 750 Plex
# cd Plex
# sudo -u www-data mkdir -m 770 Downloads

폴더 권한과 소유자 및 그룹이 잘 설정되었는지 확인하자.

# ls -l
drwxrwx--- 2 www-data www-data 4096 Sep 28 01:06 Downloads/

Transmission이 이 폴더에 그룹 권한으로 접근하여 파일을 쓸 수 있도록 그룹에 추가해주고 www-data가 있는지 확인하자.

# usermod -a -G www-data debian-transmission
# id debian-transmission
uid=118(debian-transmission) gid=124(debian-transmission) groups=124(debian-transmission),33(www-data)

Transmission이 파일을 전부 다운받았을 경우 파일의 소유자와 그룹은 debian-transmission으로 설정되어 있고 이후에 umask 설정까지 되었다 생각하면 그룹 권한은 읽기/쓰기가 가능한 상태일 것이다.

따라서 Nextcloud에서 이 파일을 옮기기 위해서는 www-data 계정이 debian-transmission 그룹으로 들어가야한다.

추가한 후 debian-transmission이 있는지 확인하자.

# usermod -a -G debian-transmission www-data
# id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data),123(ds),124(debian-transmission)

이로써 권한 설정까지 마무리되었는데 만약 파일 다운로드 중 Permission denied 라는 오류 메시지가 나타날 경우 폴더 생성부터 권한 설정까지 다시한번 체크해라.

Transmission 설정

우선 transmission을 중지하고 설정을 하자.

$ sudo service transmission-daemon stop

많은 옵션들 중 필요한 것들만 건드려 보자.

{
...
    "blocklist-enabled": true,
    "blocklist-url": "http://john.bitsurge.net/public/biglist.p2p.gz",
    "download-dir": "/mnt/sdb/nextcloud-data/[Nextcloud계정명]/files/Plex/Downloads",
    "download-queue-enabled": false, 
    "rpc-authentication-required": false,
    "rpc-host-whitelist": "rpc.ygh.kr",
    "rpc-host-whitelist-enabled": true
    "rpc-port": 9091, 
    "speed-limit-up": 0,
    "speed-limit-up-enabled": true,
    "trash-original-torrent-files": true,
    "umask": 2,
...
}

Nginx 설정

외부에서 Transmission 웹 서비스에 접속하는 기본 방법은 9091 포트의 포트 포워딩, 방화벽 설정을 해주고 http://[홈서버도메인]:9091 주소를 입력하는 것이다.

필자는 모든 웹 서비스가 https인 443포트로 안전하게 접속하면 좋다.

따라서 Nginx 에서 리버스 프록시를 구성하고 외부에서 https://rpc.ygh.kr 로 접속하면 내부에서 http://localhost:9091로 접속한 페이지를 전달 해주도록 설정하자.

또한 Transmission의 인증 설정을 해제하였기 때문에 Nginx에서 인증을 다뤄줘야한다.

먼저, 인증 파일을 만들자.

htpasswd 명령어로 파일 이름을 계정명으로 하고 비밀번호를 입력해서 인증 파일을 생성하자.

$ sudo apt install apache2-utils
$ sudo htpasswd -c /etc/transmission-daemon/.htpasswd [Transmission계정명]

서버블록을 만들자.

다른 서버블록들과 다르게 error_log를 작성하지 않았고 기본값을 사용하도록 되어있다.

이는 나중에 보안 설정 할 fail2ban을 위한 것이다.

server {
        listen 80;
        server_name rpc.ygh.kr;
        return 301 https://$server_name$request_uri;
}

server {
        listen 443 ssl http2;
        server_name rpc.ygh.kr;

        access_log /var/log/nginx/rpc.access.log;

        ssl_certificate /etc/letsencrypt/live/ygh.kr/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/ygh.kr/privkey.pem;
        ssl_trusted_certificate /etc/letsencrypt/live/ygh.kr/chain.pem;
        ssl_dhparam /etc/ssl/dhparam.pem;
        ssl_session_timeout 10m;
        ssl_session_cache shared:SSL:10m;
        ssl_session_tickets off;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_prefer_server_ciphers on;
        ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256;
        ssl_ecdh_curve secp384r1;
        ssl_stapling on;
        ssl_stapling_verify on;

        add_header Strict-Transport-Security max-age=15552000;
        add_header X-Content-Type-Options "nosniff" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;

        client_max_body_size 0;
        auth_basic "";
        auth_basic_user_file /etc/transmission-daemon/.htpasswd;

        location / {
                proxy_pass http://127.0.0.1:9091;
                proxy_http_version 1.1;
                proxy_pass_header X-Transmission-Session-Id;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}
$ sudo ln -s /etc/nginx/sites-available/rpc.ygh.kr /etc/nginx/sites-enabled/

설정을 반영하고 테스트를 위해 서비스를 시작하자.

$ sudo service transmission-daemon start
$ sudo nginx -t
$ sudo service nginx restart

웹 브라우저로 https://rpc.[도메인] 에 접속해서 Transmission config 파일에서 설정한 계정으로 로그인 하자.

왼쪽 위 폴더 모양을 누르고 토렌트 시드 파일이나 마그넷을 넣어주면 다운로드 된다.

안드로이드 앱도 있으니 시도 해보길 바라고 앱으로 할 때 웹 브라우저로 접속한 주소 그대로 입력하면 연결할 수 있다.

RSS 피드백을 사용하면 매주 새로운 예능이나 드라마 프로그램을 자동으로 다운받아 분류까지 해준다고 하는데 다음에 한번 시도해보도록 하겠다.

fail2ban 적용

우선 Transmission 웹 로그인 창에서 여러 번 틀리게 입력해서 로그가 남도록 해보자.

그 후, 로그를 확인해보자.

첫 번째 줄을 예시로 들면 192.168.0.1에서 rpc.ygh.kr로 유저 qwer가 로그인을 시도했는데 실패했다고 에러 기록이 남았다.

$ tail /var/log/nginx/error.log
2020/09/29 13:07:37 [error] 7148#7148: *1 user "qwer" was not found in "/etc/transmission-daemon/.htpasswd", client: 192.168.0.1, server: rpc.ygh.kr, request: "GET / HTTP/2.0", host: "rpc.ygh.kr"
2020/09/29 13:16:18 [error] 7148#7148: *135 user "qwe" was not found in "/etc/transmission-daemon/.htpasswd", client: 192.168.0.1, server: rpc.ygh.kr, request: "GET / HTTP/2.0", host: "rpc.ygh.kr"
2020/09/29 13:16:19 [error] 7148#7148: *135 user "asd" was not found in "/etc/transmission-daemon/.htpasswd", client: 192.168.0.1, server: rpc.ygh.kr, request: "GET / HTTP/2.0", host: "rpc.ygh.kr"
2020/09/29 13:16:20 [error] 7148#7148: *135 user "zxc" was not found in "/etc/transmission-daemon/.htpasswd", client: 192.168.0.1, server: rpc.ygh.kr, request: "GET / HTTP/2.0", host: "rpc.ygh.kr"
2020/09/29 13:16:22 [error] 7148#7148: *135 user "cvb" was not found in "/etc/transmission-daemon/.htpasswd", client: 192.168.0.1, server: rpc.ygh.kr, request: "GET / HTTP/2.0", host: "rpc.ygh.kr"

fail2ban에서는 이 라인 필터링 정규식을 기본으로 제공해주므로 이를 이용해서 fail2ban을 적용해보자.

[nginx-http-auth]
backend = auto
enabled = true
port = 80,443
protocol = tcp
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
$ sudo service fail2ban restart
$ sudo service nginx restart

잘 실행되었는지 확인해보자.

$ sudo fail2ban-client status nginx-http-auth
Status for the jail: nginx-http-auth
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     1
|  `- File list:        /var/log/nginx/error.log
`- Actions
   |- Currently banned: 0
   |- Total banned:     0
   `- Banned IP list:

이제 스마트폰 모바일 데이터 환경으로 5번 이상 웹으로 접속 시도를 해본 뒤 확인해보면 정상적으로 벤 당한 것을 확인할 수 있다.

$ sudo fail2ban-client status nginx-http-auth
Status for the jail: nginx-http-auth
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     4
|  `- File list:        /var/log/nginx/error.log
`- Actions
   |- Currently banned: 1
   |- Total banned:     1
   `- Banned IP list:   223.39.149.49