개인용 MTProto 프록시 Erlang 구현: 정책 시스템과 고유 시크릿
MTProto 프록시는 검열 환경에서 텔레그램 접근을 제공합니다. 기존 모델은 모든 사용자가 단일 시크릿 키를 공유해 접근 제어 부재, 사용자 활동 분석 불가, 수익화 제한 등의 문제가 있었습니다. 해결책은 각 클라이언트마다 고유 SNI 도메인을 갖는 개인 시크릿을 Erlang mtproto_proxy의 정책 시스템으로 구현하는 것입니다.
이 구현은 O(1) 연결 검증과 런타임 구성 가능 규칙으로 확장됩니다. 서버 재시작 없이 연결 제한, 접근 차단, 활동 추적을 지원합니다.
고부하 프록시에 적합한 Erlang의 장점
Erlang/OTP는 수백만 개의 장기 연결을 위해 설계된 아키텍처로 MTProto 프록시에 이상적입니다:
- 프로세스 격리: 각 연결은 별도의 경량 프로세스(~2 KB)입니다. 하나의 충돌이 다른 연결에 영향을 미치지 않습니다.
- 자동 확장: BEAM이 모든 CPU 코어에 프로세스를 분배해 수동 관리가 필요 없습니다.
- 선점형 멀티태스킹: 단일 클라이언트가 코어를 독점할 수 없습니다.
- 비트 구문 분석: TLS ClientHello를 한 줄로 안전하게 파싱합니다:
parse_client_hello(
<<?TLS_REC_HANDSHAKE, ?TLS_10_VERSION, TlsFrameLen:16,
?TLS_TAG_CLIENT_HELLO, HelloLen:24, ?TLS_12_VERSION,
Random:32/binary,
SessIdLen, SessId:SessIdLen/binary,
CipherSuitesLen:16, CipherSuites:CipherSuitesLen/binary,
CompMethodsLen, CompMethods:CompMethodsLen/binary,
ExtensionsLen:16, Extensions:ExtensionsLen/binary>>
) when TlsFrameLen >= 512, HelloLen >= 508 -> ...
- 실시간 모니터링: 원격 콘솔로 테이블과 상태를 점검할 수 있습니다.
- 핫 업데이트: 연결을 끊지 않고 코드와 구성을 변경할 수 있습니다.
전체 코드량은 3500줄로 대부분의 대안보다 적습니다.
SNI와 Fake-TLS 시크릿 형식
서버 이름 표시(SNI)는 클라이언트가 TLS 핸드셰이크 완료 전에 ClientHello에서 도메인을 지정할 수 있게 합니다. Fake-TLS는 합법적인 SNI로 TLS 1.3 ClientHello를 모방해 MTProto를 암호화된 필드 내에 숨깁니다.
개인 시크릿 형식:
0xEE | <16 랜덤 바이트> | <UTF-8 SNI 도메인>
t.me/proxy용 16진수 문자열:
ee<32 16진수 토큰><16진수 인코딩 SNI>
검증: 기본 시크릿(포트당 하나)으로 HMAC ClientHello를 사용합니다. 고유성은 확장에서 가져온 SNI 도메인을 기반으로 합니다.
정책 시스템: 접근 규칙
정책은 각 연결에 대한 순서가 지정된 규칙 목록입니다. 첫 번째 충족되지 않은 규칙이 연결을 거부합니다.
규칙 유형
| 규칙 | 설명 |
|------|-------------|
| {in_table, Key, Table} | Key가 Table에 있음 |
| {not_in_table, Key, Table} | Key가 Table에 없음 |
| {max_connections, [Key,...], N} | 키별 연결 ≤ N |
연결에서 추출한 키
tls_domain— fake-TLS의 SNIport_name— 포트 이름client_ipv4/client_ipv6— 클라이언트 IP{client_ipv4_subnet, Mask}— 서브넷
테이블은 메모리 내 해시 테이블로, 구성 재로드 시 저장되며 재시작 시 손실됩니다.
개인 프록시용 정책
기본 정책:
{policy, [
{in_table, tls_domain, personal_domains},
{max_connections, [tls_domain], 30}
]}
- 화이트리스트:
tls_domain이personal_domains에 포함됨. - 제한: 도메인당 동시 연결 ≤30개(링크 공유 방지).
추가 사항:
{max_connections, [client_ipv4], 30},
{not_in_table, client_ipv4, ip4_blacklist}
표준 개인 프록시 실행
sys.config
{mtproto_proxy, [
{ports, [
#{name => mtp_handler,
listen_ip => "0.0.0.0",
port => 443,
secret => <<"d0d6e111bada5511fcce9584deadbeef">>,
tag => <<"dcbe8f1493fa4cd9ab300891c0b5b326">>}
]},
{allowed_protocols, [mtp_fake_tls]},
{policy, [
{in_table, tls_domain, personal_domains},
{max_connections, [tls_domain], 100}
]}
]}
도메인 등록
mtp_proxy eval '
mtp_policy_table:add(personal_domains, tls_domain, "alice42.example.com").'
도메인이 즉시 활성화됩니다.
핵심 포인트
- 개인 SNI 도메인은 기본 시크릿 변경 없이 접근 제어와 분석을 가능하게 합니다.
- 정책은 O(1)로 검증되어 수천 명의 사용자로 확장됩니다.
- Erlang은 연결 격리와 무중단 운영을 보장합니다.
- 정책 테이블은 Erlang RPC를 통해 런타임에 관리됩니다.
- 도메인당 30개 연결 제한으로 남용을 방지합니다.
— Editorial Team
아직 댓글이 없습니다.