홈으로 돌아가기

Nginx와 함께 443 포트의 MTProxy: Telegram을 위한 숨겨진 설정

Telegram MTProxy를 443 포트에 Nginx로 설정하는 상세 가이드: stream module과 TLS masking을 사용해 차단 우회. IT 전문가를 위해.

443에서의 Nginx + MTProxy: 숨겨진 Telegram 설정 가이드
Advertisement 728x90

Telegram용 Nginx 443 포트 스텔스 MTProxy 설정 가이드

이 글은 시스템 관리자와 개발자가 직면하는 중요한 과제, 즉 기존 Nginx 관리 웹 서비스를 방해하지 않으면서 표준 HTTPS 포트 443에 Telegram MTProxy를 배포하는 방법을 다룹니다. 이 구성은 MTProxy 트래픽을 일반 웹 트래픽으로 위장하여 탐지 및 차단에 대한 프록시의 복원력을 크게 향상시킵니다. 주요 복잡성은 Nginx가 동일한 포트를 사용하면서도 대상 HTTP/HTTPS 사이트와 MTProxy를 구별하여 요청을 올바르게 라우팅하는 능력에 있습니다. 이 가이드는 Nginx stream 모듈의 작동 메커니즘과 mtprotoproxy와의 통합을 통해 강력하고 은밀한 솔루션을 만드는 방법을 자세히 설명합니다.

다중화를 위한 Nginx Stream 작동 방식

MTProxy와 Nginx가 포트 443에서 성공적으로 공존하려면 지능적인 라우팅 메커니즘이 필수적입니다. TCP/UDP 계층에서 작동하는 Nginx stream 모듈은 전체 애플리케이션 계층 처리 전에 초기 연결 데이터를 분석할 수 있도록 합니다. 중요한 점은 TLS ClientHello 메시지의 SNI(Server Name Indication) 필드가 암호화된 연결에서도 일반 텍스트로 전송된다는 것입니다. 이를 통해 Nginx는 전체 SSL 스트림을 해독하지 않고도 요청된 호스트 이름을 읽을 수 있습니다.

제안된 솔루션은 다음 논리를 사용합니다.

Google AdInline article slot
  • HTTPS 호스트의 포트 재할당: 이전에 포트 443에서 수신 대기하던 모든 기존 Nginx HTTPS 가상 호스트는 4443과 같은 내부 포트로 이동됩니다. 이는 중앙 핸들러를 위해 포트 443을 비워줍니다.
  • 중앙 라우터로서의 Nginx Stream: 이제 사용 가능한 포트 443에 Nginx stream 서버가 구성됩니다. 이 서버는 ssl_preread on 지시문을 사용하여 수신 SSL 연결에서 SNI를 추출합니다.
  • 동적 라우팅: 추출된 SNI를 기반으로 Nginx stream은 다음과 같이 결정합니다.

* SNI가 MTProxy용으로 선택된 도메인 이름(예: myprovider.ru)과 일치하면 연결은 MTProxy(로컬 포트 7788에서 수신 대기)로 전달됩니다.

* SNI가 다른 도메인 이름과 일치하면 연결은 Nginx로 다시 리디렉션되지만, 표준 HTTPS 가상 호스트에 의해 처리될 내부 포트 4443으로 리디렉션됩니다.

  • 실제 IP 보존: 정확한 로깅, 트래픽 분석 및 Nginx 뒤의 애플리케이션의 올바른 작동을 위해 proxy_protocol이 사용됩니다. 이를 통해 실제 클라이언트 IP 주소가 프록시 체인을 따라 전달될 수 있습니다.

이 접근 방식은 MTProxy가 웹 서버와 동일한 포트를 사용하여 일반 HTTPS 트래픽으로 위장할 수 있도록 합니다. 이는 탐지 및 차단에 대한 복원력을 크게 높여 트래픽을 표준 웹 연결과 구별할 수 없게 만듭니다.

Google AdInline article slot

공존을 위한 Nginx 구성

첫 번째 단계는 모든 기존 Nginx HTTPS 가상 호스트의 구성을 수정하는 것입니다. 수신 대기하는 포트를 443에서 127.0.0.1:4443과 같은 내부 포트로 변경해야 합니다. 이렇게 하면 stream 모듈이 요청을 리디렉션한 후 Nginx가 이러한 요청을 처리하게 됩니다.

server 블록 수정 예시:

server {
  server_name mywebsite.ru;
  listen 127.0.0.1:4443 ssl http2 proxy_protocol;
  set_real_ip_from 127.0.0.1;    # PROXY Protocol 소스로 localhost를 신뢰합니다.
  real_ip_header proxy_protocol; # PROXY Protocol 헤더에서 IP를 추출합니다.
  real_ip_recursive on;          # 올바른 IP 결정을 위해 재귀적으로 적용합니다.
  # ... 서버 블록의 다른 지시문 ...
  ssl_certificate /etc/letsencrypt/live/mywebsite.ru/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/mywebsite.ru/privkey.pem;
  # ... 다른 SSL/TLS 설정 ...
}

listenproxy_protocol 지시문은 Nginx에게 PROXY Protocol 헤더를 기대하도록 지시합니다. set_real_ip_fromreal_ip_header는 Nginx가 클라이언트의 실제 IP 주소를 올바르게 식별하고 전달하는 데 중요합니다. 이는 Nginx Stream이 사용할 로컬 호스트의 IP(127.0.0.1)가 아닌 실제 IP를 의미합니다. 이러한 설정이 없으면 사이트로의 모든 요청은 127.0.0.1에서 시작된 것으로 나타나 애플리케이션 기능, 로깅 및 보안 시스템을 방해할 수 있습니다.

Google AdInline article slot

다음 단계는 Nginx stream 모듈을 위한 새 구성 파일을 만드는 것입니다. /etc/nginx/conf.d/stream.conf 또는 Nginx가 로드하도록 보장하는 다른 적절한 위치에 배치하는 것이 좋습니다.

stream {
    log_format stream '$remote_addr [$time_local] host=$ssl_preread_server_name '
                      'prot=$protocol status=$status out=$bytes_sent in=$bytes_received';

    # 선택 사항: 디버깅을 위한 로깅 활성화
    #access_log /var/log/nginx/stream_access.log stream;
    #error_log /var/log/nginx/stream_error.log;

    map $ssl_preread_server_name $backend_name {
        myprovider.ru      tg_proxy;    # 선택된 MTProxy 도메인으로의 트래픽
        default            nginx_https; # 다른 모든 HTTPS 트래픽
    }

    upstream nginx_https {
        server 127.0.0.1:4443; # Nginx의 내부 포트로 리디렉션
    }

    upstream tg_proxy {
        server 127.0.0.1:7788; # MTProxy의 로컬 포트로 리디렉션
    }

    server {
        listen 443 reuseport; # 주 443 포트에서 수신 대기
        proxy_pass $backend_name;
        ssl_preread on;       # 호스트 이름 결정을 위해 SNI 읽기 활성화
        proxy_protocol on;    # 실제 IP 전달을 위해 PROXY Protocol 활성화
    }
}

이 블록에서 map은 SNI($ssl_preread_server_name)를 백엔드 이름과 연결하는 데 사용됩니다. $backend_name은 요청된 도메인에 따라 tg_proxy 또는 nginx_https가 됩니다. upstream 지시문은 각 백엔드로 트래픽이 전달될 위치를 정의합니다. listen 443 reuseport는 여러 Nginx 프로세스가 동일한 포트에서 수신 대기할 수 있도록 하여 성능과 내결함성을 향상시킵니다. ssl_preread on은 Nginx가 전체 SSL 트래픽을 해독하지 않고도 SNI를 얻을 수 있도록 하는 중요한 지시문입니다.

현재 Nginx 설치가 stream 모듈을 지원하지 않는 경우(예: 최소 빌드인 경우), 설치해야 합니다. Debian/Ubuntu에서는 다음 명령으로 수행됩니다.

sudo apt install nginx-full

모든 변경 사항을 적용한 후 Nginx 구성을 확인하고 다시 시작해야 합니다.

nginx -t && sudo systemctl restart nginx

service nginx restart 대신 systemctl restart를 사용하는 것이 systemd 기반 시스템에서 더 현대적이고 선호되는 접근 방식입니다.

MTProxy 설치 및 구성

이 설정에서 MTProxy를 구현하기 위해 Nginx proxy_protocol과 잘 통합되고 필요한 TLS 위장 모드를 지원하는 alexbers의 고효율 Python 구현인 mtprotoproxy를 사용합니다.

설치 프로세스에는 저장소를 복제하고 적절한 브랜치로 전환하는 것이 포함됩니다.

(cd /opt || sudo mkdir /opt && sudo chown $(whoami):$(whoami) /opt) && cd /opt
git clone https://github.com/alexbers/mtprotoproxy.git
cd mtprotoproxy
# 중요: 이 글을 쓰는 시점에는 master 브랜치에서 이 구성으로 안정적인 작동이 이루어집니다.
git checkout master

다음으로, MTProxy용 비밀 키를 생성합니다. 이 비밀 키는 Telegram 클라이언트의 인증에 사용되며 고유해야 합니다.

head -c 16 /dev/urandom | xxd -ps

생성된 32자 16진수 값은 저장해야 합니다. 이제 mtprotoproxy 디렉토리에 config.py 파일을 생성하거나 편집해야 합니다.

# /opt/mtprotoproxy/config.py
PORT = 7788 # Nginx Stream이 트래픽을 리디렉션할 로컬 포트
LISTEN_ADDR_IPV4 = "127.0.0.1" # 보안을 위해 localhost에 바인딩
LISTEN_ADDR_IPV6 = None # 필요 없거나 구성되지 않은 경우 IPv6 비활성화

# 사용자 및 비밀 키 사전. 여러 그룹에 대해 여러 개를 생성할 수 있습니다.
USERS = {
    "tg_user_1":  "YOUR_GENERATED_SECRET_HERE",
    # "tg_user_2": "0123456789abcdef0123456789abcdef", # 추가 비밀 키 예시
}

# MTProxy 작동 모드
MODES = {
    "classic": False, # 클래식 모드, 쉽게 탐지됨
    "secure": False,  # 개선된 모드이지만 위장에는 최적이 아님
    "tls": True       # TLS 위장 모드, 탐지에 가장 강함
}

# TLS 모드용 도메인. MTProxy는 시작 시 가용성을 확인합니다.
# Nginx Stream 구성에서 선택한 도메인을 사용하십시오.
TLS_DOMAIN = "myprovider.ru" # MTProxy에 사용될 도메인
PROXY_PROTOCOL = True # Nginx Stream과의 연동을 위한 필수 설정
# AD_TAG = "GET_YOUR_AD_TAG_FROM_@MTProxybot" # 선택 사항: 광고 태그용

여기서 주요 설정은 다음과 같습니다: LISTEN_ADDR_IPV4 = "127.0.0.1"은 MTProxy가 동일 서버의 Nginx를 통해서만 접근 가능하도록 하여 보안을 강화합니다. MODES = {"tls": True}는 TLS 위장 모드를 활성화하여 MTProxy 트래픽을 일반 HTTPS와 구별할 수 없게 만듭니다. TLS_DOMAIN은 Nginx가 트래픽을 올바르게 식별하고 전달하도록 Nginx Stream map 지시문에 지정된 도메인 이름과 일치해야 합니다. 마지막으로, PROXY_PROTOCOL = True는 MTProxy가 Nginx로부터 클라이언트의 실제 IP 주소를 수신할 수 있도록 하여 올바른 작동 및 로깅에 중요합니다.

확인 및 자동 시작

Nginx와 MTProxy를 구성한 후에는 전체 시스템의 기능을 철저히 확인하는 것이 필수적입니다.

MTProxy 및 Nginx 기능 확인

  • 수동 MTProxy 시작: /opt/mtprotoproxy 디렉토리로 이동하여 초기 확인을 위해 MTProxy를 수동으로 시작합니다.

```bash

python3 mtprotoproxy.py

```

콘솔에 프록시 연결 매개변수가 포함된 줄이 나타나야 합니다. 예를 들어:

```

tg_user_1: tg://proxy?server=YOUR_VM_IP&port=7788&secret=LONG_SECRET

```

중요 참고: 여기에 표시된 비밀 키는 ee 접두사를 가지며 config.py에 지정된 인코딩된 TLS_DOMAIN을 포함합니다. 이는 TLS 위장 메커니즘의 일부입니다. 이 링크를 복사하십시오.

  • Telegram 클라이언트로 테스트:

* 복사한 링크에서 포트를 7788에서 443으로 변경합니다.

* 결과 링크를 Telegram의 "저장된 메시지"로 보냅니다.

* 링크를 클릭하고 "연결"을 선택합니다.

* 모든 것이 올바르게 구성되었다면 Telegram은 프록시를 통해 성공적으로 연결되어야 합니다. 추가 확인을 위해 모든 봇(예: @MTProxybot)에 /ping 명령을 보낼 수 있습니다. 현재 프록시 핑이 포함된 메시지가 반환될 것입니다.

  • HTTPS 위장 확인: MTProxy가 일반 웹사이트로 올바르게 위장하는지 확인하려면 다음 검사를 수행하십시오.

* 로컬 hosts 파일에 다음 줄을 추가합니다(Linux/macOS의 경우 /etc/hosts; Windows의 경우 %SystemRoot%\System32\drivers\etc\hosts).

```

YOUR_VM_IP myprovider.ru

```

* YOUR_VM_IP를 서버의 실제 IP 주소로 바꿉니다.

* 브라우저에서 https://myprovider.ru를 엽니다.

* 모든 것이 올바르게 작동한다면 myprovider.ru의 콘텐츠(귀하의 공급자 웹사이트 또는 TLS_DOMAIN에 지정한 다른 도메인)가 표시되어야 합니다. 이는 Nginx Stream이 요청을 MTProxy로 리디렉션했고, MTProxy는 이를 비-Telegram 트래픽으로 인식하여 원래 웹 리소스로 투명하게 프록시했음을 확인시켜주며, 성공적인 TLS 위장을 보여줍니다.

* 확인 후 hosts 파일에서 추가된 줄을 삭제하는 것을 잊지 마십시오.

MTProxy를 Systemd 서비스로 설정

MTProxy가 시스템 부팅 시 자동으로 시작되고 지속적으로 실행되도록 하려면 systemd 서비스로 구성하는 것이 좋습니다.

  • 수동으로 실행 중인 MTProxy를 중지합니다(Ctrl+C).
  • /etc/systemd/system/mtprotoproxy.servicesystemd 단위 파일을 생성합니다.

```ini

[Unit]

Description=MTProto Proxy

After=network.target

[Service]

Type=simple

User=nobody

Group=nogroup

WorkingDirectory=/opt/mtprotoproxy

ExecStart=/usr/bin/python3 /opt/mtprotoproxy/mtprotoproxy.py

Restart=always

RestartSec=3

[Install]

WantedBy=multi-user.target

```

여기서 User=nobodyGroup=nogroup은 최소한의 권한으로 서비스를 실행하여 보안을 강화합니다. WorkingDirectorymtprotoproxy.py 스크립트가 있는 디렉토리를 가리킵니다.

  • systemd 구성을 다시 로드하고 서비스를 활성화한 다음 시작합니다.

```bash

sudo systemctl daemon-reload

sudo systemctl enable mtprotoproxy.service

sudo systemctl start mtprotoproxy.service

```

  • 서비스 상태를 확인합니다.

```bash

systemctl status mtprotoproxy.service

```

출력은 서비스가 active (running)임을 나타내야 합니다.

  • 로그 보기: 디버깅 또는 모니터링을 위해 다음을 사용합니다.

```bash

journalctl -u mtprotoproxy.service -e

```

이 포괄적인 설정은 Telegram MTProxy를 포트 443에서 사용할 수 있도록 하며, 이를 일반 HTTPS 트래픽으로 효과적으로 위장하는 동시에 동일 서버의 기존 웹사이트 기능을 완전히 보존합니다.

중요한 점:

  • Nginx Stream에서 ssl_preread를 사용하면 복호화 없이 SNI를 기반으로 트래픽을 라우팅할 수 있으며, 이는 단일 포트에서 MTProxy와 HTTPS 트래픽을 분리하는 데 중요합니다.
  • Nginx와 MTProxy 모두에서 proxy_protocol을 구성하면 클라이언트의 실제 IP 주소가 전송되어 로깅 및 보안에 필수적입니다.
  • MTProxy는 TLS_DOMAIN이 지정된 tls: True 모드로 구성되어 프록시 트래픽을 해당 도메인에 대한 일반 HTTPS 연결과 구별할 수 없게 만듭니다.
  • MTProxy를 127.0.0.1에 바인딩하면 직접적인 외부 접근을 제한하여 보안을 강화합니다.
  • systemd 서비스는 MTProxy의 자동 시작 및 모니터링을 보장하여 지속적인 작동을 보장합니다.

— Editorial Team

Advertisement 728x90

다음 읽기