CGNAT 뒤에 있는 서비스의 고정 공용 URL 확보 방법 (ssh + systemd만 사용)
요약
CGNAT 환경에서 포트 포워딩이 불가능할 때, systemd와 SSH -R 방식을 조합하여 안정적인 리버스 터널링을 구축하는 방법을 설명합니다. 특히 재부팅이나 네트워크 끊김에도 연결을 유지하고 고정된 공용 URL을 확보하기 위한 구체적인 설정과 팁을 제공합니다.
핵심 포인트
- systemd 유닛 파일을 사용하여 SSH 터널링 서비스를 영구적으로 실행할 수 있습니다.
- Restart=always와 RestartSec 설정을 통해 시스템 재부팅이나 연결 끊김 시 자동 복구가 가능합니다.
- 자체 VPS를 사용하면 Caddy 등을 이용해 고정된 도메인과 HTTPS를 확보할 수 있습니다.
- tunnl.gg 같은 공개 릴레이 서비스를 사용하면 별도의 VPS 없이도 안정적인 공용 URL을 얻을 수 있습니다.
제 ISP가 저를 CGNAT 뒤에 두어서 포트 포워딩이 불가능합니다. 또한 집에서 또 다른 에이전트를 실행하고 싶지 않아서, 저는 다시 순수한 ssh -R 방식을 사용하게 되었습니다. 이 방식은 포워딩을 잘 처리해 줍니다. 다만 짜증 나는 부분 두 가지는 Wi-Fi 끊김과 재부팅 시 연결을 유지하는 것, 그리고 매번 동일한 URL을 받는 것이었습니다. 혹시 누군가 저녁 시간을 아낄 수 있을까 하여 제가 사용하게 된 방법을 공유합니다.
시스템d 사용자 유닛 ( ~/.config/systemd/user/tunnel.service ):
[Unit]
Description=Reverse SSH tunnel
[Service]
ExecStart=/usr/bin/ssh -N -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o ExitOnForwardFailure=yes -R 8080:localhost:8123 you@your-vps
Restart=always
RestartSec=5
[Install]
WantedBy=default.target
ServerAliveInterval/CountMax : 네트워크 변경 후 영원히 끊기지 않고 약 90초 후에 연결이 끊겼음을 감지합니다.
ExitOnForwardFailure : 포워딩 설정에 실패하면 종료되므로, systemd가 연결을 터널 없이 방치하는 대신 재시작하게 합니다.
-N : 포워드만 하고 원격 셸은 실행하지 않습니다.
Restart=always + RestartSec=5 : 서버를 과부하 시키지 않고 스스로 복구됩니다.
그 다음 systemctl --user enable --now tunnel을 실행하고, 사용자가 로그인하지 않아도 실행되도록 sudo loginctl enable-linger $USER를 추가합니다. SSH가 호스트 키를 저장할 수 있도록 처음에는 직접 한 번 연결하여 설정해야 합니다. 서비스는 이 프롬프트에 응답할 수 없습니다. 키는 암호 구문(passphrase)이 필요 없거나 에이전트에 로드되어야 합니다.
어디로 지정할 것인가:
자신의 VPS를 사용하는 경우: 포워딩은 VPS의 localhost:8080에 도달하며, 그곳에서 리버스 프록시(Caddy: reverse_proxy localhost:8080)를 사용하면 자신의 도메인으로 HTTPS를 얻을 수 있습니다. Caddy가 제공하는 것 이상은 노출되지 않습니다.
VPS를 사용하지 않는 경우: 저는 정확히 이런 목적을 위해 오픈 소스 릴레이인 tunnl.gg를 유지 관리합니다 (공개: 제 프로젝트이며, MIT 라이선스이고, 직접 실행할 수도 있습니다: https://github.com/klipitkas/tunnl.gg). ExecStart의 끝 부분을 -T ...로 교체하세요.
-R 80:localhost:8123 [email protected] ( -T 대신 사용하면 세션에 URL이 출력되어 journalctl --user -u tunnel에서 확인할 수 있습니다) 그리고 SSH 키에서 파생된 HTTPS 서브도메인을 제공하므로, 재연결 후에도 URL이 동일합니다. 공개 릴레이(public relay)를 사용하는 것의 장단점들을 정리해 드리겠습니다. 이로 인해 아무도 이를 찾을 필요가 없습니다: TLS는 릴레이에서 종료되므로 종단 간 암호화(end-to-end encrypted)가 아닙니다; 무료 터널은 트래픽이 없으면 2시간 후에, 최대 24시간 후에 종료됩니다 (Restart=always를 사용하면 동일한 URL로 바로 복구됩니다); 그리고 브라우저에서는 하루에 한 번 피싱 방지 인터스티셜(anti-phishing interstitial)을 받게 됩니다. 자체 VPS를 사용한다면 이 모든 것이 해당되지 않습니다. 어느 쪽이든, 이제 서비스가 공개되었으니 자체 인증(auth) 기능을 유지하세요. 여러분은 무엇을 사용하고 계신가요? frp, Cloudflare Tunnel, VPS로의 WireGuard인가요? 순수 SSH가 어떤 면에서 부족한지 궁금합니다. /u/Jealous-Educator-369 님이 제출했습니다 [링크] [댓글]
AI 자동 생성 콘텐츠
본 콘텐츠는 r/SelfHosted (AI filter)의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기