조회수: 0
목차
공인 IP가 없어도 외부 접속이 가능한 이유
보통 리눅스 서버에 외부에서 접속하려면 공인 IP와 포트포워딩을 떠올리게 된다.
하지만 요즘 가정용 인터넷이나 모바일 핫스팟, 일부 사무실 회선은 공유기 뒤에 한 번 더 NAT를 사용하는 CGNAT 환경인 경우가 많아 직접 포트포워딩이 안 되는 상황이 자주 발생한다.
이럴 때 필요한 것이 바로 “내 서버에서 먼저 밖으로 연결을 여는 방식”이다. 서버가 스스로 클라우드 서비스로 아웃바운드(나가는) 연결을 만들고, 그 연결을 통해 역방향으로 들어오는 요청을 전달받으면 공인 IP 없이도 외부에서 접속이 가능해진다. Cloudflare Tunnel, Tailscale, ZeroTier, frp 같은 도구들이 이 원리를 활용한다.
전체 해결 전략 한눈에 보기
공인 IP 없이 리눅스 서버에 접속하는 전략은 크게 이렇게 정리할 수 있다.
- 서버는 인터넷으로 나가는 트래픽(예: 443, 80 포트)은 대부분 허용된다.
- 이 아웃바운드 연결을 이용해 클라우드에 “터널”을 만든다.
- 외부 사용자는 도메인이나 클라이언트 앱을 통해 클라우드에 접속한다.
- 클라우드는 이미 열려 있는 터널을 통해 서버와 트래픽을 주고받는다.
즉, “외부 → 클라우드 → 터널 → 내 리눅스 서버” 구조로, 방화벽이나 NAT를 우회하는 셈이다. 이 글에서는 대표적인 솔루션인 Cloudflare Tunnel을 중심으로 설명하고, 마지막에 몇 가지 대안도 간단히 비교한다.
Cloudflare Tunnel 개념 이해
Cloudflare Tunnel은 리버스 프록시 개념을 기반으로 한다.
- 리눅스 서버에 cloudflared라는 경량 에이전트를 설치한다.
- cloudflared가 Cloudflare 네트워크로 443 포트 아웃바운드 연결을 맺고 터널을 형성한다.
- Cloudflare 계정에 연결된 도메인(예: server.example.com)에 요청이 오면, 그 요청을 터널을 통해 서버로 전달한다.
핵심 포인트는 다음 두 가지다. - 서버 측에서 공인 IP나 포트포워딩이 필요 없다.
- 접속자는 HTTPS 도메인 하나만 알면 되고, TLS·DDoS 대응 등은 Cloudflare가 처리해 준다.
SSH도 지원되지만 구조가 조금 다르다. SSH 자체를 인터넷에 직접 노출하는 대신 Cloudflare Access와 cloudflared 클라이언트 조합으로 안전하게 우회 접속하는 방식이다.
사전 준비 사항
Cloudflare Tunnel을 쓰기 전에 다음 정도를 준비해 두면 수월하다.
- 도메인
- Cloudflare에 위임된 도메인 하나 (서브 도메인도 가능)
- Cloudflare 계정
- 무료 플랜으로도 Tunnel과 Zero Trust 기본 기능을 사용할 수 있다.
- 리눅스 서버
- Ubuntu, Debian, CentOS 등 대부분 배포판 지원
- root 또는 sudo 권한
- 인터넷으로 443 포트 아웃바운드가 열려 있어야 한다.
- 기본적인 리눅스 명령어 사용 능력
- systemctl, vi/nano, ssh 등
리눅스 서버에 cloudflared 설치하기 (예: Ubuntu 기준)
배포판마다 약간씩 다르지만 전체 흐름은 비슷하다. Ubuntu를 기준으로 예시를 들면 다음과 같다.
- 패키지 저장소 추가 및 설치
curl -fsSL https://pkg.cloudflare.com/install.sh | sudo bash
sudo apt-get install -y cloudflared
- 버전 확인
cloudflared --version
정상 설치되었다면 버전이 출력된다.
- 서비스 계정으로 등록(예시)
Cloudflare에서 발급받는 토큰을 이용해 서비스로 등록할 수 있다.
sudo cloudflared service install <토큰>
토큰은 Cloudflare Zero Trust 대시보드에서 터널 생성 시 제공된다. 이 방식 대신, 터널을 먼저 만들고 나중에 설정 파일을 손으로 작성하는 흐름도 가능하다.
Cloudflare Tunnel 생성 절차 개요
터널 생성 과정은 크게 “대시보드 작업”과 “서버 작업” 두 단계로 나뉜다.
- Cloudflare Zero Trust 대시보드에서 터널 생성
- Zero Trust → Access → Tunnels 메뉴로 이동
- “Tunnel 만들기” 선택 후 tunnel 이름 지정
- “Connector” 타입으로 cloudflared 선택
- 생성 후 터널 ID와 자격 증명 파일 또는 설치 명령을 확인
- 리눅스 서버에서 터널 연결
- 대시보드에서 제시하는 명령을 서버에서 실행하면,
- /etc/cloudflared/ 경로에 자격 증명 파일이 생성되거나
- systemd 서비스가 자동으로 구성된다.
- 이후 cloudflared 서비스가 부팅 시 자동으로 올라오게 설정한다.
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo systemctl status cloudflared
웹 서비스 외부에 노출하기
리눅스 서버에서 이미 웹 서비스를 띄워두었다고 가정해 보자.
예를 들어 내부에서 8080 포트로 동작 중인 서비스가 있다면, 이를 도메인으로 노출하기 위한 설정은 다음과 같이 진행한다.
- 리눅스 서버에서 웹 서비스 확인
curl http://localhost:8080
여기서 응답이 정상적으로 돌아온다면 준비 완료다.
- Cloudflare Tunnel 인그레스 규칙 작성
보통 /etc/cloudflared/config.yml 파일에 터널 설정을 정의한다.
tunnel: <터널-이름-또는-ID>
credentials-file: /etc/cloudflared/<터널-ID>.json
ingress:
- hostname: server.example.com
service: http://localhost:8080
- service: http_status:404
- hostname: 외부에서 접속할 도메인
- service: 서버 내부에서 실제로 서비스가 동작하는 주소
- 마지막 http_status:404는 매칭되는 호스트가 없을 때 처리용 기본 규칙이다.
- cloudflared 재시작
sudo systemctl restart cloudflared
- DNS 레코드 연결
Cloudflare 대시보드에서 해당 도메인(server.example.com)에 대해
- Type: CNAME
- Target: 터널용 자동 호스트 이름 또는 지정 값
- Proxy status: Proxied(주황색 구름)
으로 설정하면, 이제 인터넷 어느 곳에서든 https://server.example.com 으로 접속할 수 있다. 공인 IP는 서버 쪽이 아닌 Cloudflare 쪽에 존재하고, 서버는 오직 터널을 통해서만 요청을 받는다.
SSH 외부 접속 구성하기
웹 서비스뿐 아니라 SSH도 Cloudflare Tunnel과 Access를 통해 외부에서 접속할 수 있다. 일반적인 구조는 다음과 같다.
- 서버: cloudflared가 터널을 열고, 내부 22번 포트(SSH)를 향하도록 설정
- 클라이언트: 로컬에 cloudflared를 설치하고, ssh 명령어는 localhost 포트를 향하게 구성
예시 인그레스 규칙은 다음과 비슷하다.
ingress:
- hostname: ssh.example.com
service: ssh://localhost:22
- service: http_status:404
클라이언트 측에서는 다음과 같이 터널을 열 수 있다.
cloudflared access ssh --hostname ssh.example.com
또는 cloudflared가 로컬에 포트를 열게 한 뒤, 일반 ssh로 접속하는 식의 설정도 가능하다. 이 과정에서 Cloudflare Access 정책을 함께 사용하면, 구글 계정 로그인이나 OTP 등 추가 인증 절차를 넣어 SSH 보안을 한층 강화할 수 있다.
보안 측면에서의 장점과 주의할 점
Cloudflare Tunnel을 쓰면 단순히 “공인 IP 없이 접속”하는 것을 넘어 몇 가지 부가적인 장점이 생긴다.
- 서버가 외부에서 직접 스캔되지 않는다.
- 포트 스캐너에 잡히지 않기 때문에 무차별 대입 공격 위험이 줄어든다.
- HTTPS, TLS 인증서, DDoS 보호를 Cloudflare에서 제공한다.
- 인증서 갱신 부담이 줄고, 기본적인 공격 방어를 덤으로 얻는다.
- Access 정책으로 세밀한 제어 가능
- 이메일 도메인, 그룹, 장치 보안 상태 등에 따라 접속 허용·차단 가능
다만 다음과 같은 점은 유의할 필요가 있다.
- 이메일 도메인, 그룹, 장치 보안 상태 등에 따라 접속 허용·차단 가능
- Cloudflare 서비스 장애 시 터널 접속도 영향을 받는다.
- 터널 설정 파일과 자격 증명 파일은 민감 정보이므로 권한 관리가 중요하다.
- 조직 정책에 따라 외부 클라우드 프록시 사용이 제한될 수 있으니 환경 규정을 확인해야 한다.
Cloudflare Tunnel 외 대안 솔루션 간단 비교
공인 IP 없이 리눅스 서버에 접속하는 방법은 Cloudflare Tunnel 외에도 여러 가지가 있다. 상황에 따라 적합한 도구를 고르는 것이 좋다.
- Tailscale
- WireGuard 기반의 메쉬 VPN
- 각 장비가 서로 가상 IP로 직접 통신
- 개인·소규모 팀 환경에서 매우 간편
- ZeroTier
- 가상 스위치를 만드는 느낌의 SD-WAN 솔루션
- 다양한 플랫폼 지원, 자유도가 높지만 약간의 학습 필요
- frp, ngrok 등
- 특정 포트를 외부로 노출하는 터널링 도구
- 단순 포트 터널링에 특화된 경우가 많다.
웹 서비스 중심에 도메인, HTTPS, WAF 같은 기능까지 한 번에 묶어 쓰고 싶다면 Cloudflare Tunnel이 편리하고, 여러 장비를 같은 사설망에 넣어 일상적인 SSH·RDP를 쓰고 싶다면 Tailscale·ZeroTier가 더 자연스러운 선택이 될 수 있다.
마무리: 나에게 맞는 방식으로 “안전한 우회로” 만들기
정리하면, 공인 IP가 없는 리눅스 서버라고 해서 외부 접속이 불가능한 것은 아니다.
터널링과 리버스 프록시 개념을 활용하면
- 공유기·CGNAT 뒤에 있는 서버도
- 도메인과 HTTPS를 사용해
- 안전하게 외부에서 접속할 수 있다.
Cloudflare Tunnel은 도메인, TLS, 방화벽, Access 정책까지 한 번에 엮을 수 있어 개인 개발자부터 소규모 팀까지 활용도가 높다. 여기에 Tailscale, ZeroTier 같은 메쉬 VPN 솔루션까지 고려하면, 각자 환경에 맞는 “공인 IP 없는 서버 접속” 전략을 충분히 설계할 수 있다.