
Rust로 작성된, NAT 트래버설을 위한 경량 고성능 리버스 프록시입니다. frp 및 ngrok의 대안입니다.

NAT 트래버설을 위한 안전하고 안정적이며 고성능의 리버스 프록시, Rust로 작성됨
rathole은 frp나 ngrok처럼, 공인 IP를 가진 서버를 통해 NAT 뒤에 있는 장치의 서비스를 인터넷에 노출할 수 있게 도와줍니다.
완전한 기능의 rathole은 릴리스 페이지에서 얻을 수 있습니다. 또는 다른 플랫폼 및 바이너리 최소화를 위해 소스에서 빌드하세요. Docker 이미지도 사용 가능합니다.
rathole의 사용법은 frp와 매우 유사합니다. 후자에 경험이 있다면 설정이 매우 쉽습니다. 유일한 차이점은 서비스 설정이 클라이언트 측과 서버 측으로 분리되어 있고 토큰이 필수라는 점입니다.
rathole을 사용하려면 공인 IP를 가진 서버와 NAT 뒤에 있는 장치(인터넷에 노출해야 할 서비스가 있는)가 필요합니다.
예를 들어 NAT 뒤에 있는 NAS가 있고 SSH 서비스를 인터넷에 노출하려고 한다고 가정해 봅시다:
다음 내용으로 server.toml을 만들고 필요에 맞게 조정하세요.
# server.toml
[server]
bind_addr = "0.0.0.0:2333" # `2333`은 rathole이 클라이언트 연결을 수신할 포트를 지정합니다
[server.services.my_nas_ssh]
token = "use_a_secret_that_only_you_know" # 서비스에 대한 클라이언트 인증에 사용되는 토큰입니다. 임의의 값으로 변경하세요.
bind_addr = "0.0.0.0:5202" # `5202`는 `my_nas_ssh`를 인터넷에 노출하는 포트를 지정합니다
그런 다음 실행:
./rathole server.toml
다음 내용으로 client.toml을 만들고 필요에 맞게 조정하세요.
# client.toml
[client]
remote_addr = "myserver.com:2333" # 서버의 주소입니다. 포트는 `server.bind_addr`의 포트와 같아야 합니다.
[client.services.my_nas_ssh]
token = "use_a_secret_that_only_you_know" # 서버와 동일해야 검증을 통과할 수 있습니다.
local_addr = "127.0.0.1:22" # 전달되어야 하는 서비스의 주소입니다.
그런 다음 실행:
./rathole client.toml
2333에서 서버 myserver.com에 연결을 시도하며, myserver.com:5202로의 모든 트래픽은 클라이언트의 포트 22로 전달됩니다.따라서 ssh myserver.com:5202를 사용하여 NAS에 SSH로 접속할 수 있습니다.
Linux에서 rathole을 백그라운드 서비스로 실행하려면 systemd 예제를 확인하세요.
rathole은 빠른 시작의 예제처럼 설정 파일에 [server] 블록이나 [client] 블록 중 하나만 있는 경우, 서버 모드 또는 클라이언트 모드에서 실행할지를 자동으로 결정할 수 있습니다.
하지만 [client]와 [server] 블록을 하나의 파일에 함께 넣을 수도 있습니다. 그런 다음 서버 측에서는 rathole --server config.toml을 실행하고, 클라이언트 측에서는 rathole --client config.toml을 실행하여 rathole에 실행 모드를 명시적으로 알려줍니다.
전체 설정 명세로 넘어가기 전에 설정 예제를 훑어보고 설정 형식에 익숙해지는 것이 좋습니다.
암호화 및 transport 블록에 대한 자세한 내용은 Transport를 참조하세요.
다음은 전체 설정 명세입니다:
[client]
remote_addr = "example.com:2333" # 필수. 서버의 주소
default_token = "default_token_if_not_specify" # 선택. 서비스가 자신의 토큰을 정의하지 않은 경우 기본 토큰
heartbeat_timeout = 40 # 선택. 0으로 설정하면 애플리케이션 계층 하트비트 테스트를 비활성화합니다. 값은 `server.heartbeat_interval`보다 커야 합니다. 기본값: 40초
retry_interval = 1 # 선택. 서버 재연결 시도의 간격. 기본값: 1초
[client.transport] # 전체 블록은 선택 사항입니다. 사용할 전송 방식을 지정합니다.
type = "tcp" # 선택. 가능한 값: ["tcp", "tls", "noise"]. 기본값: "tcp"
[client.transport.tcp] # 선택. `noise`와 `tls`에도 영향을 미칩니다.
proxy = "socks5://user:[email protected]:1080" # 선택. 서버 연결에 사용되는 프록시. `http`와 `socks5`를 지원합니다.
nodelay = true # 선택. 적용 가능한 경우 TCP_NODELAY를 활성화하여 지연 시간을 개선하지만 대역폭을 줄입니다. 기본값: true
keepalive_secs = 20 # 선택. 적용 가능한 경우 `tcp(7)`에서 `tcp_keepalive_time`을 지정합니다. 기본값: 20초
keepalive_interval = 8 # 선택. 적용 가능한 경우 `tcp(7)`에서 `tcp_keepalive_intvl`을 지정합니다. 기본값: 8초
[client.transport.tls] # `type`이 "tls"인 경우 필수
trusted_root = "ca.pem" # 필수. 서버의 인증서에 서명한 CA의 인증서
hostname = "example.com" # 선택. 클라이언트가 인증서를 검증하는 데 사용하는 호스트 이름. 설정하지 않으면 `client.remote_addr`로 대체됩니다.
[client.transport.noise] # Noise 프로토콜. 자세한 설명은 `docs/transport.md` 참조
pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s" # 선택. 기본값은 표시된 대로
local_private_key = "key_encoded_in_base64" # 선택
remote_public_key = "key_encoded_in_base64" # 선택
[client.transport.websocket] # `type`이 "websocket"인 경우 필수
tls = true # `true`이면 `client.transport.tls`의 설정을 사용합니다.
[client.services.service1] # 전달이 필요한 서비스. `service1` 이름은 서버 설정의 이름과 동일하기만 하면 임의로 변경 가능
type = "tcp" # 선택. 전달해야 할 프로토콜. 가능한 값: ["tcp", "udp"]. 기본값: "tcp"
token = "whatever" # `client.default_token`이 설정되지 않은 경우 필수
local_addr = "127.0.0.1:1081" # 필수. 전달되어야 하는 서비스의 주소
nodelay = true # 선택. 서비스별로 `client.transport.nodelay`를 재정의합니다.
retry_interval = 1 # 선택. 서버 재연결 시도의 간격. 기본값: 전역 설정을 상속받습니다.
[client.services.service2] # 여러 서비스를 정의할 수 있습니다.
local_addr = "127.0.0.1:1082"
[server]
bind_addr = "0.0.0.0:2333" # 필수. 서버가 클라이언트를 수신하는 주소. 일반적으로 포트만 변경하면 됩니다.
default_token = "default_token_if_not_specify" # 선택
heartbeat_interval = 30 # 선택. 두 애플리케이션 계층 하트비트 사이의 간격. 하트비트 전송을 비활성화하려면 0으로 설정합니다. 기본값: 30초
[server.transport] # `[client.transport]`와 동일
type = "tcp"
[server.transport.tcp] # 클라이언트와 동일
nodelay = true
keepalive_secs = 20
keepalive_interval = 8
[server.transport.tls] # `type`이 "tls"인 경우 필수
pkcs12 = "identify.pfx" # 필수. 서버 인증서와 개인 키의 pkcs12 파일
pkcs12_password = "password" # 필수. pkcs12 파일의 비밀번호
[server.transport.noise] # `[client.transport.noise]`와 동일
pattern = "Noise_NK_25519_ChaChaPoly_BLAKE2s"
local_private_key = "key_encoded_in_base64"
remote_public_key = "key_encoded_in_base64"
[server.transport.websocket] # `type`이 "websocket"인 경우 필수
tls = true # `true`이면 `server.transport.tls`의 설정을 사용합니다.
[server.services.service1] # 서비스 이름은 클라이언트 측과 동일해야 합니다.
type = "tcp" # 선택. 클라이언트 `[client.services.X.type]`과 동일
token = "whatever" # `server.default_token`이 설정되지 않은 경우 필수
bind_addr = "0.0.0.0:8081" # 필수. 서비스가 노출되는 주소입니다. 일반적으로 포트만 변경하면 됩니다.
nodelay = true # 선택. 클라이언트와 동일
[server.services.service2]
bind_addr = "0.0.0.1:8082"
rathole은 다른 많은 Rust 프로그램처럼 로깅 레벨을 제어하기 위해 환경 변수를 사용합니다. info, warn, error, debug, trace를 사용할 수 있습니다.
RUST_LOG=error ./rathole config.toml
위 명령은 오류 수준 로깅만 사용하여 rathole을 실행합니다.
RUST_LOG가 없으면 기본 로깅 레벨은 info입니다.
v0.4.7부터 rathole은 기본적으로 TCP_NODELAY를 활성화하며, 이는 지연 시간과 rdp, Minecraft 서버 같은 대화형 애플리케이션에 이점이 있습니다. 그러나 대역폭이 약간 감소합니다.
대역폭이 더 중요하다면 nodelay = false로 TCP_NODELAY를 비활성화할 수 있습니다.
rathole은 frp와 비슷한 지연 시간을 가지지만, 더 많은 연결을 처리하고 더 큰 대역폭을 제공하며 메모리 사용량이 더 적습니다.
자세한 내용은 별도 페이지 벤치마크를 참조하세요.
하지만 여기서 rathole이 전달하는 서비스를 이전보다 몇 배 더 빠르게 만들어준다고 오해하지 마십시오. 벤치마크는 로컬 루프백에서 수행되었으며, 이는 CPU 집약적인 작업일 때의 성능을 나타냅니다. 네트워크가 병목이 아니라면 상당한 개선을 얻을 수 있습니다. 불행히도 많은 사용자에게는 해당되지 않습니다. 그런 경우 주요 이점은 더 낮은 리소스 소비이며, 대역폭과 지연 시간은 크게 개선되지 않을 수 있습니다.

범위 외 페이지에는 구현 계획이 없는 기능과 그 이유가 나열되어 있습니다.