Transmission with openvpn (Expressvpn) 최종판 (25.06.01)

시놀로지 Transmission with openvpn (Expressvpn) 최종판
✍️ 작성자: Heesung Jin (kage2k)
📅 마지막 업데이트: 2025-06-01
history : https://is.gd/5tlDEq
토렌트(Torrent)를 사용할 때 고려해야 할 사항
토렌트(Torrent)를 통해 자료를 다운로드하거나 업로드할 때는 다음과 같은 법적, 기술적, 윤리적 측면을 반드시 고려해야 합니다.
🔒 1. 법적 측면
• 저작권 침해 주의: 상업용 영화, 음악, 소프트웨어 등은 대부분 저작권 보호를 받고 있습니다. 이를 무단으로 공유하거나 다운로드하면 법적 책임을 질 수 있습니다. • 국내외 법률 확인: 국가마다 토렌트 사용에 대한 법적 기준이 다르므로, 관련 법률을 사전에 확인하는 것이 중요합니다.
🛠️ 2. 기술적 측면
• 바이러스 및 악성코드 위험: 불법 자료에는 악성코드가 포함되어 있는 경우가 많습니다. 다운로드 전 반드시 출처를 확인하고 백신 프로그램을 사용하세요. • IP 노출 위험: P2P 방식의 특성상 자신의 IP 주소가 다른 사용자에게 노출될 수 있어 보안상의 위험이 존재합니다. VPN 등을 사용하는 것이 좋습니다. • 트래픽 문제: 일부 토렌트 클라이언트는 백그라운드에서 지속적으로 데이터를 주고받아 네트워크 속도 저하를 유발할 수 있습니다.
🤝 3. 윤리적 측면
• 공정한 콘텐츠 소비: 제작자에게 정당한 대가를 지불하지 않고 콘텐츠를 이용하는 것은 윤리적으로 부당한 행위입니다. • 오픈소스 및 합법 공유 장려: 리눅스 배포판, 자유 소프트웨어, 창작자의 허가가 있는 자료 등 합법적 콘텐츠를 공유하는 데 토렌트를 활용하는 것은 매우 좋은 사용 예입니다.
⸻
✅ 결론 토렌트는 강력한 파일 공유 기술이지만, 이를 책임감 있게 사용하는 것이 중요합니다. 합법적이고 윤리적인 범위 내에서 활용하시기 바랍니다.
본론
내용은 시놀로지 이지만, 리눅스도커 아니면 다른 플레폼에서도 알맞게 변형 사용하시면 됩니다.
폴더 준비

yml 파일을 보면 알겠지만, complete / incomplete 위치가 다른 이유는 용량활용때문입니다.

USB1에 따로 2개폴더 생성
Expressvpn 에서 다운로드
수동으로 ovpn 파일을 다운로드 받아야합니다. 다운받는 내용은 설명하지 않습니다. 다운로드 받으셨다면, 해당파일을 openvpn 폴더에 업로드 합니다. (파일명 수정하지 않고) 필자의 경우 "my_expressvpn_japan_-_shibuya_udp.ovpn" 파일을 openvpn폴더 업로드하였습니다.
Torrent_remove.sh with Telegram
아래의 내용을 torrent_remove.sh 파일로 저장해서 [scripts] 폴더에 업로드 합니다. 주의! 중간에 민감한 부분은 직접 수정해야합니다.
#!/bin/sh
# ===========================================
# 개선된 Transmission 자동 관리 스크립트
# transmission-remote 위치 자동 탐지
# ===========================================
# 1. transmission-remote 위치 자동 탐지
TR_REMOTE=$(which transmission-remote)
# transmission-remote가 없으면 일반적인 위치들 검색
if [ -z "$TR_REMOTE" ]; then
echo "which 명령으로 찾을 수 없음. 일반적인 위치 검색 중..."
# 일반적인 설치 위치들 확인
COMMON_PATHS="/usr/local/bin/transmission-remote /usr/bin/transmission-remote /opt/transmission/bin/transmission-remote"
for path in $COMMON_PATHS; do
if [ -x "$path" ]; then
TR_REMOTE="$path"
echo "transmission-remote 발견: $TR_REMOTE"
break
fi
done
fi
# transmission-remote를 찾지 못했으면 종료
if [ -z "$TR_REMOTE" ]; then
echo "ERROR: transmission-remote를 찾을 수 없습니다"
exit 1
fi
echo "사용할 transmission-remote: $TR_REMOTE"
# ===========================================
# 설정값들 (민감한 정보는 실제 값으로 변경 필요)
# ===========================================
# transmission 서버 연결 정보
SERVER="localhost:9091 --auth [사용자명]:[비밀번호]"
# 텔레그램 봇 설정
TOKEN='[텔레그램_봇_토큰]'
CHAT_ID="[채팅방_ID]"
# 텔레그램 API URL 구성
URL='https://api.telegram.org/bot'$TOKEN
MSG_URL=$URL'/sendMessage?chat_id='
# 안정성을 위한 1초 대기
sleep 1s
# ===========================================
# 메인 로직 (변수 사용)
# ===========================================
# 토렌트 목록 가져오기 (변수 사용)
TORRENTLIST=`$TR_REMOTE $SERVER --list | sed -e '1d;$d;s/^ *//' | cut -s -d " " -f 1`
for TORRENTID in $TORRENTLIST
do
# 다운로드 완료 여부 확인 (변수 사용)
DL_COMPLETED=`$TR_REMOTE $SERVER --torrent $TORRENTID --info | grep "Percent Done: 100%"`
# 토렌트 상태 확인 (변수 사용)
STATE_STOPPED=`$TR_REMOTE $SERVER --torrent $TORRENTID --info | grep "State: Seeding\|Stopped\|Finished\|Idle"`
if [ "$DL_COMPLETED" ] && [ "$STATE_STOPPED" ]; then
# 토렌트 이름 가져오기 (변수 사용)
TORRENT_INFO=`$TR_REMOTE $SERVER --torrent $TORRENTID --info`
TORRENT_NAME=`echo "$TORRENT_INFO" | grep "Name:" | cut -d: -f2- | sed 's/^ *//'`
# 빈 이름 처리
if [ -z "$TORRENT_NAME" ]; then
TORRENT_NAME="[완료된 파일]"
fi
# 텔레그램 알림 전송
curl --data-urlencode "text=✅ Download Complete: $TORRENT_NAME
🕐 $(date '+%H:%M:%S')
🚫 자동삭제 (업로드차단됨)" "$MSG_URL"$CHAT_ID"&"
# 토렌트 삭제 (변수 사용)
$TR_REMOTE $SERVER --torrent $TORRENTID --remove
echo "삭제 완료: $TORRENT_NAME"
fi
done
# 메모리 정리 (보안)
unset TR_REMOTE TORRENT_NAME TORRENT_INFO TORRENTLIST TOKEN SERVER
Portainer in Stack
Docker를 사용하면 당연히 Portainer 사용이 필수? 인듯 (개인적 생각) Portainer에서 작업합니다.
ENV파일을 만들어서 업로드 하거나, 몇개 안되서 직접입력해도 됩니다.

version: '3.8'
services:
transmission-openvpn:
image: haugene/transmission-openvpn:5.3.1 # 고정 버전 사용 (보안)
container_name: transmission
restart: unless-stopped
# 포트 설정 (localhost만 접근 허용)
ports:
- '39091:9091' # 외부 접근 차단, 로컬만 접근
# 권한 설정 (Synology VPN 지원)
privileged: true # TUN 디바이스 생성을 위해 필요
cap_add:
- NET_ADMIN
cap_drop: # 불필요한 권한 제거
- ALL
# 보안 강화
security_opt:
- no-new-privileges:true # 권한 상승 방지
# 디바이스 매핑 (TUN 디바이스 직접 연결)
devices:
- "/dev/net/tun:/dev/net/tun"
# 볼륨 마운트 (읽기 전용 옵션 추가)
volumes:
# OpenVPN 설정 (읽기 전용)
- '/volume1/docker/transmission/openvpn:/etc/openvpn/custom:ro'
# 설정 파일 (최소 권한)
- '/volume1/docker/transmission/config:/config'
# 다운로드 경로
- '/volumeUSB1/usbshare/transmission/complete:/data/completed'
- '/volumeUSB1/usbshare/transmission/incomplete:/data/incomplete'
# 감시 폴더 (임시 파일 자동 삭제 설정)
- '/volume1/docker/transmission/watch:/data/watch'
# 백업 제거 (보안상 위험)
# - '/volume1/docker/transmission/backups:/data/backups' # 주석 처리
# 스크립트 경로 (읽기 전용)
- '/volume1/docker/transmission/scripts:/scripts:ro'
# 임시 폴더 (메모리에 마운트, 재부팅시 자동 삭제)
- type: tmpfs
target: /tmp
tmpfs:
size: 100m
mode: 1777
environment:
# ===========================================
# VPN 설정 (보안 강화)
# ===========================================
- OPENVPN_PROVIDER=EXPRESSVPN
- OPENVPN_CONFIG=my_expressvpn_japan_-_shibuya_udp
- OPENVPN_USERNAME=${VPN_USERNAME}
- OPENVPN_PASSWORD=${VPN_PASSWORD}
# OpenVPN 보안 옵션 강화
- OPENVPN_OPTS=--pull-filter ignore "auth-token" --ping 10 --ping-exit 60 --inactive 3600 --mute-replay-warnings --auth-nocache --verb 1 --cipher AES-256-GCM --tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384 --reneg-sec 3600 --tls-version-min 1.2 --compress lz4
# ===========================================
# Transmission 기본 설정
# ===========================================
- TRANSMISSION_RPC_AUTHENTICATION_REQUIRED=true
- TRANSMISSION_RPC_USERNAME=${TRANSMISSION_USER}
- TRANSMISSION_RPC_PASSWORD=${TRANSMISSION_PASS}
- TRANSMISSION_RPC_PORT=9091
- TRANSMISSION_WEB_UI=flood-for-transmission
# ===========================================
# 다운로드 관리 (최적화)
# ===========================================
- TRANSMISSION_DOWNLOAD_QUEUE_ENABLED=true
- TRANSMISSION_DOWNLOAD_QUEUE_SIZE=3 # 안정성을 위해 더 줄임
# ===========================================
# 업로드 완전 차단 (법적 보호) - 강화
# ===========================================
# 업로드 속도 완전 차단
- TRANSMISSION_UPLOAD_LIMIT=0
- TRANSMISSION_UPLOAD_LIMIT_ENABLED=true
- TRANSMISSION_SPEED_LIMIT_UP=0 # 업로드 속도 0KB/s
- TRANSMISSION_SPEED_LIMIT_UP_ENABLED=true
# 업로드 비율 완전 차단
- TRANSMISSION_RATIO_LIMIT=0 # 완전히 0
- TRANSMISSION_RATIO_LIMIT_ENABLED=true
# 시딩 완전 비활성화
- TRANSMISSION_IDLE_SEEDING_LIMIT=0 # 즉시 정지
- TRANSMISSION_IDLE_SEEDING_LIMIT_ENABLED=true
- TRANSMISSION_SEED_QUEUE_ENABLED=false
- TRANSMISSION_SEED_QUEUE_SIZE=0
# 추가 업로드 방지 설정
- TRANSMISSION_UPLOAD_SLOTS_PER_TORRENT=0 # 업로드 슬롯 0개
- TRANSMISSION_PEER_LIMIT_GLOBAL=50 # 전체 피어 제한 (다운로드만)
- TRANSMISSION_PEER_LIMIT_PER_TORRENT=10 # 토렌트당 피어 제한
# ===========================================
# 보안 설정 강화
# ===========================================
- TRANSMISSION_ENCRYPTION=2 # 강제 암호화
# 블록리스트 (보안 강화)
- TRANSMISSION_BLOCKLIST_ENABLED=true
- TRANSMISSION_BLOCKLIST_URL=https://raw.githubusercontent.com/Naunter/BT_BlockLists/master/bt_blocklists.gz
# P2P 프로토콜 비활성화 (익명성 강화)
- TRANSMISSION_DHT_ENABLED=false
- TRANSMISSION_PEX_ENABLED=false
- TRANSMISSION_LPD_ENABLED=false
- TRANSMISSION_UTP_ENABLED=false # μTP 비활성화
# ===========================================
# 로그 및 기록 최소화
# ===========================================
- TRANSMISSION_MESSAGE_LEVEL=1 # 에러만 로그
- TRANSMISSION_LOG_TO_FILE=false # 파일 로그 비활성화
# 세션 관리
- TRANSMISSION_RPC_SESSION_TIMEOUT=60 # 세션 타임아웃 단축
- TRANSMISSION_CACHE_SIZE_MB=4 # 캐시 크기 최소화
# 설정 강제 적용 (중요!)
- OVERRIDE_TRANSMISSION_SETTINGS_WITH_ENV_VARS=true
- TRANSMISSION_HOME=/config/transmission-home
# ===========================================
# 자동 정리 스크립트
# ===========================================
- TRANSMISSION_SCRIPT_TORRENT_DONE_ENABLED=true
- TRANSMISSION_SCRIPT_TORRENT_DONE_FILENAME=/scripts/torrent_remove.sh
# ===========================================
# 네트워크 설정
# ===========================================
- LOCAL_NETWORK=${LOCAL_NETWORK} # 환경변수 사용
- OVERRIDE_DNS_1=1.1.1.1 # Cloudflare DNS (빠름)
- OVERRIDE_DNS_2=8.8.8.8 # Google DNS (백업)
- CREATE_TUN_DEVICE=true
# ===========================================
# 시스템 설정
# ===========================================
- TZ=Asia/Seoul
# 연결 체크 (자주 확인하여 보안 유지)
- HEALTH_CHECK_HOST=1.1.1.1 # IP 사용 (DNS 우회)
- CHECK_CONNECTION_CRON=*/5 * * * * # 5분마다 체크
- RECREATE_VPN_CRON=0 */6 * * * # 6시간마다 VPN 재연결
# ===========================================
# 성능 최적화 및 업로드 방지
# ===========================================
- TRANSMISSION_MAX_PEERS_GLOBAL=50 # 전체 최대 피어 수 제한
# 메모리 사용량 제한
- TRANSMISSION_PREALLOCATION=0 # 사전 할당 비활성화
# 정체된 토렌트 관리 (안전한 설정)
- TRANSMISSION_QUEUE_STALLED_ENABLED=true
- TRANSMISSION_QUEUE_STALLED_MINUTES=60 # 1시간 완전 정체시에만 대기로 변경
# ===========================================
# 리소스 제한 (시스템 보호)
# ===========================================
deploy:
resources:
limits:
memory: 512M # 메모리 제한
reservations:
memory: 256M
# ===========================================
# 상태 확인
# ===========================================
healthcheck:
test: ["CMD", "/usr/local/bin/transmission-remote", "localhost:9091", "--auth", "${TRANSMISSION_USER}:${TRANSMISSION_PASS}", "--session-info"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
# ===========================================
# 네트워크 보안
# ===========================================
networks:
- transmission_net
# DNS 설정 (보안)
dns:
- 1.1.1.1
- 8.8.8.8
# ===========================================
# 네트워크 분리 (보안 강화)
# ===========================================
networks:
transmission_net:
driver: bridge
internal: false # 인터넷 접근 허용하되 격리
이후 로그를 살펴보면 많은 것 중에 아래 처럼 나올 것입니다.
Transmission will run as
-------------------------------------
User name: root
User uid: 0
User gid: 0
-------------------------------------
Updating Transmission settings.json with values from env variables
Attempting to use existing settings.json for Transmission
Successfully used existing settings.json /config/transmission-home/settings.json
Overriding bind-address-ipv4 because TRANSMISSION_BIND_ADDRESS_IPV4 is set to 10.115.0.68
Overriding blocklist-enabled because TRANSMISSION_BLOCKLIST_ENABLED is set to true
Overriding blocklist-url because TRANSMISSION_BLOCKLIST_URL is set to https://raw.githubusercontent.com/Naunter/BT_BlockLists/master/bt_blocklists.gz
Overriding cache-size-mb because TRANSMISSION_CACHE_SIZE_MB is set to 4
Overriding dht-enabled because TRANSMISSION_DHT_ENABLED is set to false
Overriding download-dir because TRANSMISSION_DOWNLOAD_DIR is set to /data/completed
Overriding download-queue-enabled because TRANSMISSION_DOWNLOAD_QUEUE_ENABLED is set to true
Overriding download-queue-size because TRANSMISSION_DOWNLOAD_QUEUE_SIZE is set to 3
Overriding encryption because TRANSMISSION_ENCRYPTION is set to 2
Overriding idle-seeding-limit because TRANSMISSION_IDLE_SEEDING_LIMIT is set to 0
Overriding idle-seeding-limit-enabled because TRANSMISSION_IDLE_SEEDING_LIMIT_ENABLED is set to true
Overriding incomplete-dir because TRANSMISSION_INCOMPLETE_DIR is set to /data/incomplete
Overriding lpd-enabled because TRANSMISSION_LPD_ENABLED is set to false
Overriding message-level because TRANSMISSION_MESSAGE_LEVEL is set to 1
Overriding peer-limit-global because TRANSMISSION_PEER_LIMIT_GLOBAL is set to 50
Overriding peer-limit-per-torrent because TRANSMISSION_PEER_LIMIT_PER_TORRENT is set to 10
Overriding pex-enabled because TRANSMISSION_PEX_ENABLED is set to false
Overriding preallocation because TRANSMISSION_PREALLOCATION is set to 0
Overriding queue-stalled-enabled because TRANSMISSION_QUEUE_STALLED_ENABLED is set to true
Overriding queue-stalled-minutes because TRANSMISSION_QUEUE_STALLED_MINUTES is set to 60
Overriding ratio-limit because TRANSMISSION_RATIO_LIMIT is set to 0
Overriding ratio-limit-enabled because TRANSMISSION_RATIO_LIMIT_ENABLED is set to true
Overriding rpc-authentication-required because TRANSMISSION_RPC_AUTHENTICATION_REQUIRED is set to true
Overriding rpc-password because TRANSMISSION_RPC_PASSWORD is set to [REDACTED]
Overriding rpc-port because TRANSMISSION_RPC_PORT is set to 9091
Overriding rpc-username because TRANSMISSION_RPC_USERNAME is set to killerj1
Overriding script-torrent-done-enabled because TRANSMISSION_SCRIPT_TORRENT_DONE_ENABLED is set to true
Overriding script-torrent-done-filename because TRANSMISSION_SCRIPT_TORRENT_DONE_FILENAME is set to /scripts/torrent_remove.sh
Overriding seed-queue-enabled because TRANSMISSION_SEED_QUEUE_ENABLED is set to false
Overriding seed-queue-size because TRANSMISSION_SEED_QUEUE_SIZE is set to 0
Overriding speed-limit-up because TRANSMISSION_SPEED_LIMIT_UP is set to 0
Overriding speed-limit-up-enabled because TRANSMISSION_SPEED_LIMIT_UP_ENABLED is set to true
Overriding upload-slots-per-torrent because TRANSMISSION_UPLOAD_SLOTS_PER_TORRENT is set to 0
Overriding utp-enabled because TRANSMISSION_UTP_ENABLED is set to false
Overriding watch-dir because TRANSMISSION_WATCH_DIR is set to /data/watch
sed'ing True to true
STARTING TRANSMISSION
Transmission startup script complete.
2025-06-01 07:20:01 Initialization Sequence Completed
yml 에서 설정한 내용이 overriding 되었다는 표시 입니다.
실제로 VPN에 접속되어서 IP 확인
[방법1]

portainer 내부 컨테이너에 접속해서 아래의 명령어로 ip체크 curl http://ipinfo.io/ip
본인 외부아이피가 아닌 다른 아이피가 보인다면 vpn적용된 것입니다.
[방법2]
링크로 대신합니다. (작성했던 글이 있습니다)
스크립트 안에 내용에서 저장되는 위치가 있으니 본인이 원하는 위치로 저장하세요. https://is.gd/wzKE1P