security

인바운드 포트 0개 만들기: Cloudflare Tunnel과 Zero Trust로 서버를 숨기는 법

열린 포트를 없애 무차별 공격의 전제 자체를 무너뜨리는 실전 가이드

2026년 05월 22일
Cloudflare Tunnel Zero Trust 포트 보안 공격면 축소 SSH 하드닝 오리진 IP 보호 방화벽
2분 읽기

공격자가 두드릴 문이 아예 없다면 어떨까요? 인바운드 포트를 0개로 만드는 것은 보안 강화 중에서도 가장 결정적인 한 수입니다. 이 글은 Cloudflare Tunnel과 Zero Trust로 서버를 인터넷에서 "보이지 않게" 만드는 실전 절차를, 자기 자신을 잠가 버리지 않는 안전한 순서와 함께 정리합니다.

서버를 운영하다 보면 보안 점검 항목이 끝도 없이 나옵니다. 패치, 방화벽 규칙, 로그 모니터링, 침입 탐지... 하나하나 중요하지만, 이 모든 노력에는 공통 전제가 하나 깔려 있습니다. 공격자가 닿을 수 있는 열린 포트가 존재한다는 것입니다.

그렇다면 질문을 거꾸로 던져 봅시다. 그 전제 자체를 없애면 어떻게 될까요? 인터넷을 향해 단 하나의 인바운드 포트도 열지 않는다면, 위에서 나열한 위협의 절반 이상이 시작 지점에서 무력화됩니다. 이 글에서 다루는 것이 바로 그 발상입니다.

닫힌 포트가 왜 그렇게 강력한가

흔히 마주치는 자동화된 공격 — SSH 무차별 대입, 전수 포트 스캔, 웹 취약점 탐색 — 을 떠올려 보세요. 이것들이 작동하려면 반드시 두드릴 수 있는 열린 포트가 있어야 합니다. 22번이 인터넷에 열려 있으니 SSH 무차별 대입이 가능하고, 80·443번이 응답하니 웹 공격 페이로드가 도달합니다.

서버가 인터넷을 향해 어떤 포트도 열지 않으면, 공격자의 스캐너는 닫힌 벽 앞에 서게 됩니다. 두드릴 문이 없으니 인증 공격이 성립하지 않고, 응답하는 서비스가 없으니 취약점 탐색도 빈 손으로 돌아갑니다. 서버는 인터넷에서 사실상 존재하지 않는 것처럼 됩니다.

이게 한가한 이론이 아닌 이유는 발견 속도에 있습니다. 2026년 현재, 새로 띄운 IP가 자동 스캐너 망에 걸려 첫 공격 트래픽을 받기까지는 보통 몇 분이면 충분합니다. 인터넷 전체가 24시간 쉬지 않고 훑이고 있고, "내 작은 서버는 아직 아무도 모를 것"이라는 가정은 더 이상 통하지 않습니다. 그래서 포트를 닫는 전략은 유행을 타지 않는, 가장 확실한 공격면 축소입니다.

열린 포트는 24시간 켜진 초대장

인터넷을 향해 열린 포트는 전 세계 누구에게나 "여기 연결을 받습니다"라고 광고하는 영구 초대장입니다. 정당한 사용자만 그 초대에 응하면 좋겠지만, 현실에서는 전 세계의 봇과 스캐너가 먼저 도착합니다.

더 근본적인 문제는, 포트 뒤의 서비스가 인증보다 먼저 노출된다는 점입니다. SSH를 예로 들면, 공격자가 비밀번호를 전혀 몰라도 SSH 서비스와의 대화는 이미 시작할 수 있습니다. 그 대화에서 SSH 소프트웨어의 취약점을 노릴 수 있고, 무차별 대입으로 인증을 두드릴 수 있으며, 버전 정보를 수집해 다음 공격을 준비할 수 있습니다. 인증은 가장 마지막 관문일 뿐, 그 앞에서 이미 상당한 공격면이 펼쳐져 있습니다.

웹 서비스도 다르지 않습니다. 80·443번이 열려 있으면, 로그인을 요구하는 관리 페이지조차 그 존재가 노출되고 곧바로 무차별 로그인과 취약점 스캔의 표적이 됩니다.

이것이 추상적 우려가 아님은 실제 사건이 증명합니다. 인터넷에 노출된 서비스에서 심각한 취약점이 터지면 공격은 전 세계로 동시에 번집니다.

사건 CVE 핵심
MOVEit Transfer CVE-2023-34362 Cl0p 랜섬웨어 조직이 대량 악용, 수많은 기관 데이터 유출
Citrix Bleed CVE-2023-4966 패치가 이미 나와 있었는데도 미적용 장비 대규모 침해

두 사건의 공통점은 단순합니다 — 그 서비스가 인터넷에서 닿을 수 있었다는 것. 내일 어떤 취약점이 공개될지는 아무도 모르지만, 닫힌 포트 뒤의 서비스는 그 폭풍이 와도 직접 닿지 않습니다. 실제 악용 중인 취약점은 미국 CISA가 KEV(실제 악용 취약점 목록)으로 공개하는데, 그 목록의 상당수가 "인터넷에 노출된 게이트웨이·전송 솔루션"이라는 사실은 결코 우연이 아닙니다.

"포트 번호만 바꾸면 되지 않나"가 안 되는 이유

가장 흔한 절충안은 SSH를 22번이 아닌 엉뚱한 번호로 옮기는 것입니다. 이건 전형적인 "모호함을 통한 보안(security through obscurity)"입니다. 22번만 노리는 게으른 봇은 실제로 상당수 떨어져 나가므로, 잡음 감소 효과는 분명히 있습니다.

그러나 근본 해결은 못 됩니다. 전수 스캐너는 모든 포트를 훑고 서비스 지문을 채취하기 때문에, SSH가 2222번에 있든 49152번에 있든 결국 찾아냅니다. 포트를 옮기는 것은 가장 게으른 봇을 걸러내는 작은 손질일 뿐, 결연한 공격자나 정교한 스캐너 앞에서는 무력합니다. 문의 번호를 바꾼다고 문 자체가 사라지지는 않으니까요.

결론은 명확합니다. 문을 옮기는 게 아니라 문을 없애야 합니다. 인터넷을 향한 인바운드 포트 자체를 닫는 것, 그것이 목표입니다.

시작하기 전 안전 경고. 방화벽과 원격 접속 설정 변경은 한 번의 실수로 자기 자신을 서버에서 영구히 잠가 버릴 수 있는 작업입니다. 이 글의 모든 변경은 반드시 별도의 작동하는 접속 경로를 확보하고, 되돌릴 수 있는 안전장치를 켜 둔 상태에서 진행해야 합니다. 구체적 방법은 뒤의 "자기 자신을 잠그지 않는 안전한 순서" 절에서 다루니, 그 부분을 읽기 전에는 실제 변경을 시작하지 마십시오.

연결의 방향을 뒤집는다: Cloudflare Tunnel의 원리

"웹 서비스를 하려면 포트를 열어야 하는 것 아닌가?"라는 반문이 자연스럽습니다. 바로 이 지점에서 Cloudflare Tunnel의 발상이 빛납니다. 설정 명령을 외우기 전에 원리를 정확히 이해하는 것이 먼저입니다. 원리를 알아야 응용할 수 있고, 문제가 생겼을 때 진단할 수 있기 때문입니다.

전통적인 구조에서 트래픽의 흐름은 이렇습니다. 외부 사용자가 서버 IP로 연결을 시도하고, 서버는 열린 포트에서 그 연결을 받습니다. 연결의 시작점이 외부이고 서버는 받는 쪽입니다. 이 구조에서는 인바운드 포트를 열어 둘 수밖에 없고, 그 포트가 그대로 공격에 노출됩니다.

Cloudflare Tunnel은 이 방향을 통째로 뒤집습니다. 서버에서 cloudflared라는 작은 프로그램(데몬 — 화면 없이 백그라운드에서 늘 돌아가는 상주 프로그램)을 실행하면, 이 프로그램이 서버에서 Cloudflare를 향해 바깥으로 연결을 맺습니다. 연결의 시작점이 서버 자신이 되는 것입니다. 이 연결은 아웃바운드(나가는 방향)이므로, 인바운드 포트를 단 하나도 열 필요가 없습니다. 이 기능은 Cloudflare가 무료 등급을 포함해 제공하며, 모든 설정의 1차 출처는 Cloudflare One(Zero Trust) 공식 문서입니다.

서버와 Cloudflare 사이에 이런 안전한 통로(터널)가 만들어지면, 외부 사용자의 요청은 다음 경로로 흐릅니다.

[사용자] → [Cloudflare] → (미리 맺어 둔 아웃바운드 터널) → [내 서버]
                  ↑                                            │
                  └──────────── 응답도 같은 터널을 거쳐 ───────┘

사용자는 당신의 서버와 직접 연결하지 않습니다. 언제나 Cloudflare를 경유합니다.

이 구조가 얻는 세 가지

  • 인바운드 포트가 0개가 됩니다. 서버는 외부에서 오는 연결을 전혀 받지 않고, 자신이 시작한 아웃바운드 터널만 유지합니다. 외부에서 포트 스캔을 돌려도 열린 포트가 보이지 않습니다.
  • 오리진 IP가 숨겨집니다. 모든 트래픽이 Cloudflare를 거치므로, 외부에서 보이는 것은 Cloudflare의 IP뿐입니다. 실제 서버 IP(오리진 IP)는 드러나지 않습니다.
  • Cloudflare의 보호 계층을 자동으로 얻습니다. 모든 트래픽이 Cloudflare를 통과하므로 대규모 트래픽 공격(DDoS) 완화, 악성 트래픽 필터링 같은 보호가 서버 앞에 자연스럽게 놓입니다.

정직하게 따져 보는 트레이드오프

이 방식은 Cloudflare를 신뢰 경로의 중심에 두는 선택입니다. 모든 트래픽이 그곳을 거치므로, Cloudflare가 트래픽을 볼 수 있는 위치에 서게 됩니다. 대부분의 조직에게 이는 합리적인 교환입니다. 직접 운영하는 것보다 전문 인프라가 더 안전한 경우가 많고, 인바운드 0개와 오리진 IP 은폐라는 이득이 워낙 크기 때문입니다.

다만 극도로 민감한 데이터를 다뤄 어떤 중간 경로도 허용할 수 없는 특수한 상황이라면, 이 트레이드오프는 따로 검토해야 합니다. 보안 설계는 언제나 자신의 위협 모델에 비추어 판단해야 합니다.

웹 서비스를 터널로 옮기는 실전 설정

원리를 잡았으니 실제 설정으로 들어갑니다. 가장 흔한 경우인 웹 서비스를 먼저 다룹니다. 다시 강조하지만, 뒤의 안전 순서 절을 읽지 않았다면 실제 적용은 그 부분을 본 뒤에 시작하세요. 특히 SSH를 터널로 옮기는 작업은 순서가 곧 생명입니다.

사전 준비

Cloudflare Tunnel을 쓰려면 도메인이 Cloudflare를 통해 관리되고 있어야 합니다(도메인의 네임서버가 Cloudflare를 향하도록 설정). 그다음 서버에 cloudflared를 설치합니다. 설치 방법은 운영체제마다 다르고 패키지 버전이 자주 바뀌므로, Cloudflare One 공식 문서의 최신 설치 안내를 그대로 따르는 것이 가장 정확합니다. 아래 명령도 버전에 따라 옵션이 달라질 수 있으니, 막히면 항상 공식 문서를 기준으로 삼으세요.

1단계 — 인증과 터널 생성

# 1) cloudflared를 Cloudflare 계정에 인증
#    브라우저가 열리며 로그인 및 도메인 선택을 요청합니다.
cloudflared tunnel login

# 2) 새 터널 생성 (이름은 원하는 대로)
cloudflared tunnel create my-tunnel

# 위 명령은 터널의 고유 ID와 자격 증명 파일을 생성합니다.
# 자격 증명 파일의 경로를 기억해 두십시오 (보통 ~/.cloudflared/ 아래).

# 3) 생성된 터널 목록 확인
cloudflared tunnel list

터널을 만들면 그것을 인증하는 자격 증명 파일이 생성됩니다. 이 파일은 사실상 터널의 열쇠이므로, 외부에 노출되거나 유출되지 않도록 안전하게 보관해야 합니다.

2단계 — 터널 설정 파일 작성

어떤 요청을 서버의 어떤 로컬 서비스로 전달할지를 설정 파일에 정의합니다. config.yml의 형태는 다음과 같습니다.

# ~/.cloudflared/config.yml
tunnel: <터널 ID>
credentials-file: /home/user/.cloudflared/<터널 ID>.json

ingress:
  # example.com으로 오는 요청을 로컬 웹 서버(127.0.0.1:8080)로 전달
  - hostname: example.com
    service: http://127.0.0.1:8080
  # 그 외 모든 요청은 거부 (필수: 마지막에 catch-all 규칙)
  - service: http_status:404

여기서 핵심은 웹 서비스를 이제 로컬 인터페이스(127.0.0.1)에만 바인딩해도 된다는 점입니다. 외부에서 직접 접근할 일이 없으니, 웹 서버를 0.0.0.0이 아니라 127.0.0.1에서만 듣게 설정하면, 설령 방화벽에 구멍이 나도 외부에서 그 서비스에 직접 닿을 수 없습니다. 바인딩 점검은 이 구조를 한층 더 단단하게 만드는 추가 보험입니다.

3단계 — DNS 연결과 터널 실행

# 4) 도메인을 터널로 라우팅 (DNS 레코드 자동 생성)
cloudflared tunnel route dns my-tunnel example.com

# 5) 터널 실행 (테스트)
cloudflared tunnel run my-tunnel

# 6) 정상 동작을 확인했다면, 서비스로 등록하여 상시 실행
sudo cloudflared service install

여기까지 마치면 example.com으로 오는 요청이 Cloudflare를 거쳐 터널을 통해 당신의 로컬 웹 서버로 전달됩니다. 그리고 이제 — 이것이 핵심입니다 — 서버 방화벽에서 80·443번 인바운드 포트를 닫을 수 있습니다. 외부 트래픽은 전부 아웃바운드 터널을 통해 들어오므로 인바운드 웹 포트가 더는 필요 없기 때문입니다. 단, 포트를 닫기 전에 반드시 뒤의 안전 절차를 먼저 따르세요.

오리진 IP가 새는 길을 막아라

Cloudflare Tunnel을 쓰면 오리진 IP가 숨겨진다고 했습니다. 그러나 이 은폐가 저절로 완벽해지는 것은 아닙니다. 오리진 IP가 다른 경로로 새어 나가면, 공격자는 Cloudflare를 우회해 서버를 직접 때릴 수 있습니다.

오리진 IP가 노출되면 앞에서 얻은 보호가 무너집니다. 공격자가 실제 서버 IP를 알면 Cloudflare를 건너뛰고 서버에 직접 연결을 시도할 수 있습니다. 이때 인바운드 포트를 닫아 둔 것이 첫 번째 방어선이 되지만, 만약 어떤 포트라도 직접 접근이 가능하다면 DDoS 완화·필터링 같은 Cloudflare의 보호를 전부 건너뛰고 공격이 들어옵니다.

오리진 IP가 새는 흔한 경로

누출 경로 무슨 일이 일어나는가
과거 DNS 기록 Cloudflare 적용 전 도메인이 실제 IP를 직접 가리켰다면, 그 기록이 패시브 DNS에 영구히 남을 수 있음
이메일 헤더 서버에서 직접 발송한 메일의 헤더에 서버 실제 IP가 담길 수 있음
서버가 시작하는 외부 연결 웹훅·외부 API 호출 등 서버가 바깥으로 보내는 요청의 출발지 IP가 노출될 수 있음
별도 서브도메인 메인은 Cloudflare 뒤에 있지만, 어떤 서브도메인이 Cloudflare를 거치지 않고 직접 서버 IP를 가리킬 수 있음
SSL 인증서·콘텐츠 단서 서버에 직접 접속했을 때 응답하는 인증서나 고유 콘텐츠가 IP와 연결될 수 있음

마지막 항목은 특히 주의해야 합니다. Shodan·Censys 같은 인터넷 전수 검색 엔진은 서버가 직접 응답할 때의 인증서·콘텐츠를 IP와 묶어 색인합니다. 발급된 인증서 자체도 crt.sh에서 누구나 조회할 수 있어, 무심코 만든 서브도메인 인증서 하나가 오리진을 가리키는 단서가 되기도 합니다.

오리진 IP를 지키는 방법

가장 근본적인 방어는 서버가 Cloudflare의 트래픽만 받도록 강제하는 것입니다. 누군가 오리진 IP를 알아내더라도, 서버가 Cloudflare 이외의 출처에서 오는 직접 연결을 거부하게 만드는 것이죠.

터널을 쓰면 이게 자연스럽게 달성됩니다. 인바운드 포트를 모두 닫고 아웃바운드 터널만 유지하면, 오리진 IP를 알아도 직접 연결할 포트 자체가 없기 때문입니다. 이것이 터널 방식의 가장 큰 장점 중 하나입니다.

만약 터널이 아니라 전통적 방식(Cloudflare를 프록시로 두되 서버가 인바운드 포트를 여는 방식)을 쓴다면, 방화벽에서 Cloudflare의 IP 대역에서 오는 연결만 허용하고 그 외 모든 직접 연결을 차단해야 합니다. 이렇게 하면 오리진 IP가 노출돼도 공격자의 직접 연결이 방화벽에서 막힙니다. Cloudflare는 자사의 IP 대역 목록을 공개하므로, 이를 방화벽 허용 규칙에 반영하면 됩니다.

추가로, 위 누출 경로들을 하나씩 점검해 막아야 합니다. 과거 DNS 기록이 노출된 정황이 있으면 서버 IP 변경을 고려하고, 메일은 별도 발송 서비스를 통해 보내 서버 IP가 헤더에 남지 않게 하며, 모든 서브도메인이 빠짐없이 Cloudflare를 거치는지 확인하세요.

자기 자신을 잠그지 않는 안전한 순서

이제 이 글에서 가장 중요한 부분입니다. 지금까지 배운 것을 실제로 적용할 때, 자기 자신을 서버에서 영구히 잠가 버리는 사고를 어떻게 막을 것인가입니다.

과장이 아닙니다. 원격 서버의 방화벽이나 SSH 설정을 건드리다가 자신의 접속 경로를 끊어 버려 더 이상 서버에 못 들어가게 되는 일은 정말 흔하게 일어납니다. 특히 물리적 접근이 불가능한 클라우드 서버에서 유일한 접속 경로였던 SSH를 잘못 만지면, 복구가 매우 번거롭거나 최악의 경우 서버를 새로 만들어야 할 수도 있습니다. 솔직히 말하면, 저도 실무 초년에 방화벽 규칙 한 줄을 적용하는 순간 SSH 세션이 그대로 얼어붙는 경험을 했습니다. 그 뒤로는 예외 없이 아래 자동 롤백 안전장치를 먼저 걸고 작업합니다. 이 절은 그 비싼 교훈의 압축본입니다.

다행히, 몇 가지 원칙만 지키면 이 사고는 거의 완전히 예방할 수 있습니다.

원칙 1 — 새 경로를 먼저 만들고, 옛 경로는 나중에 닫는다

가장 중요한 원칙입니다. 절대로 작동을 확인하지 않은 새 방법으로 갈아타면서 옛 방법을 먼저 닫지 마세요. 순서가 전부입니다.

올바른 순서는 언제나 이렇습니다. 먼저 새 접속 경로(예: 터널을 통한 SSH)를 구축하고, 그것이 실제로 작동함을 완전히 확인한 뒤에, 비로소 옛 경로(직접 SSH 포트)를 닫습니다. 새 경로를 검증하기 전에 옛 경로를 닫으면, 새 경로에도 문제가 있을 때 둘 다 막혀 버립니다.

원칙 2 — 두 번째 터미널을 열어 둔다

방화벽이나 SSH 설정을 바꿀 때는, 변경을 수행하는 세션과 별도로 이미 연결된 또 하나의 세션을 열어 두세요. 변경 후 새 접속이 안 되더라도, 이미 살아 있는 두 번째 세션으로 변경을 되돌릴 수 있습니다.

핵심은, 변경 직후 그 두 번째 세션은 그대로 둔 채 새로운 세 번째 세션으로 접속이 되는지 확인하는 것입니다. 새 접속이 성공하면 변경이 안전한 것이고, 실패하면 열어 둔 두 번째 세션으로 즉시 되돌립니다. 모든 세션을 닫은 채 "다음에 접속되겠지" 하고 기대하는 일은 절대 하지 마세요.

원칙 3 — 자동 롤백 안전장치를 건다

더 강력한 안전장치는, 변경이 잘못됐을 때 일정 시간 뒤 자동으로 원상 복구되도록 미리 장치를 걸어 두는 것입니다.

예를 들어 방화벽 규칙을 바꾸기 전에 "N분 뒤 방화벽을 원래대로 되돌리는" 예약 작업을 걸어 둡니다. 변경 후 새 접속이 정상임을 확인하면 그 예약을 취소합니다. 만약 변경이 잘못돼 접속이 끊겼다면, 아무것도 하지 않아도 N분 뒤 방화벽이 자동 복구되어 다시 들어갈 수 있습니다.

주의: 아래는 방화벽을 직접 건드리는 명령입니다. 반드시 이미 열려 있는 두 번째 세션(원칙 2)을 띄워 둔 상태에서, 백업·예약·확인 순서를 그대로 지키며 실행하세요. 한 줄이라도 순서가 어긋나면 자기 자신이 잠길 수 있습니다.

# 예시: 방화벽 변경 전, 10분 뒤 자동 복구 예약
# (변경이 성공하면 이 예약 작업을 반드시 취소해야 합니다)

# 1) 현재 방화벽 규칙을 백업
sudo iptables-save > /root/iptables.backup

# 2) 10분 뒤 백업을 복원하는 예약 작업 등록
echo "iptables-restore < /root/iptables.backup" | sudo at now + 10 minutes

# 3) 이제 방화벽 변경을 수행하고, 새 접속을 테스트
#    - 새 접속이 정상이면: 예약 작업을 취소 (atq로 작업 번호 확인 후 atrm)
#    - 새 접속이 안 되면: 아무것도 하지 않으면 10분 뒤 자동 복구됨

이 자동 롤백 패턴은 원격 서버에서 위험한 변경을 할 때 가장 신뢰할 수 있는 안전망입니다. "내가 실수해도 시스템이 스스로 되돌아온다"는 보장이 있으면, 변경을 훨씬 과감하고 안전하게 시도할 수 있습니다.

원칙 4 — 클라우드 콘솔의 비상 접속 경로를 확인해 둔다

클라우드 서버를 쓴다면, SSH가 막혔을 때 쓸 수 있는 비상 접속 경로(클라우드 제공자가 제공하는 콘솔 접속, 시리얼 콘솔 등)가 있는지 미리 확인하고 그 사용법을 익혀 두세요. 이것은 마지막 안전망입니다. SSH가 완전히 막혀도 이 경로로 들어가 복구할 수 있다면 최악의 상황을 피할 수 있습니다.

한눈에 보는 SSH-over-Tunnel 전환 순서

위 원칙들을 종합해, SSH를 Cloudflare Tunnel로 안전하게 전환하는 권장 순서를 정리하면 다음과 같습니다.

  1. 현재의 직접 SSH 접속을 유지한 채, 터널을 통한 SSH 접근을 추가로 구성합니다(Zero Trust 설정 포함, 아래 절 참고).
  2. 별도의 새 세션으로 터널 SSH가 정상 작동하는지 완전히 확인합니다. 이때 기존 직접 SSH 세션은 그대로 열어 둡니다.
  3. 터널 SSH가 확실히 작동함을 확인한 뒤, 방화벽 자동 롤백 안전장치(원칙 3)를 걸어 둡니다.
  4. 방화벽에서 직접 SSH 포트(22번)의 인바운드를 차단합니다.
  5. 또 다른 새 세션으로 터널 SSH가 여전히 작동하는지 확인합니다. 직접 SSH는 이제 막혔어야 하므로, 외부에서 시도해 확인합니다.
  6. 모든 것이 정상이면 자동 롤백 안전장치를 취소합니다. 문제가 있으면 안전장치가 작동하기를 기다리거나 비상 콘솔로 복구합니다.
  7. 최종적으로 외부에서 포트 스캔을 수행해 22번 포트가 더 이상 보이지 않음을 확인합니다. 직접 스캔은 Nmap으로, "남이 보는 내 모습"은 Shodan에서 내 IP를 조회해 교차 확인하면 좋습니다(자기 소유 서버·자기 IP에 한해서만).

이 순서를 지키면 각 단계에서 항상 작동하는 접속 경로가 보장되고, 어느 단계에서 실패하더라도 되돌아갈 수 있습니다. 서두르지 마세요. 확인 단계를 건너뛰지 마세요. 보안을 강화하려던 작업이 자기 자신을 가두는 사고로 끝나는 것만큼 허무한 일은 없습니다.

Zero Trust Access: 신원으로 지키는 마지막 관문

Cloudflare Tunnel이 "어떻게 연결되는가"를 다룬다면, Zero Trust Access는 "누가 연결할 수 있는가"를 다룹니다. 이 둘을 결합하면 SSH 22번을 인터넷에서 완전히 제거하면서도 정당한 사용자는 안전하게 접속할 수 있습니다.

위치가 아니라 신원을 본다

Zero Trust(제로 트러스트)는 "침해를 가정하라"는 원칙과 직결됩니다. 전통적 보안은 "경계"를 신뢰했습니다. 방화벽 안쪽에 들어온 사용자는 믿고 바깥은 안 믿는 방식이죠. 그러나 이 모델은 경계가 한 번 뚫리면 내부 전체가 노출된다는 치명적 약점이 있습니다. 침입자가 내부에서 옆으로 옮겨 다니는 측면 이동(lateral movement)이 그 전형입니다.

Zero Trust는 이 전제를 버립니다. 네트워크의 위치를 신뢰의 근거로 삼지 않습니다. 안쪽이든 바깥쪽이든 모든 접근 요청을 동등하게 검증합니다. 핵심 질문은 "어디에서 왔는가"가 아니라 "누구이며, 이 접근이 허용되는가"입니다. 매 요청마다 신원을 확인하고, 그 신원이 해당 자원에 접근할 권한이 있는지를 그때그때 검증합니다.

SSH를 Zero Trust 뒤에 두기

Cloudflare의 Zero Trust Access를 SSH에 적용하면 다음 구조가 됩니다. SSH 접근은 더 이상 인터넷에 노출된 22번 포트를 통하지 않고 Cloudflare의 Zero Trust 계층을 거칩니다. 사용자가 SSH에 접속하려면 먼저 신원을 증명해야 합니다 — 예를 들어 인증된 이메일 계정으로 로그인하고, 정책에 따라 다단계 인증(MFA — 비밀번호 외에 일회용 코드·인증 앱 등 두 번째 증거를 추가로 요구하는 방식)을 통과하는 식입니다. 이 신원 검증을 통과한 사용자만 터널을 통해 SSH에 도달할 수 있습니다. 구체적 설정 절차(Access 애플리케이션 정의, 정책 작성, 신원 공급자 연결)는 Cloudflare One 공식 문서에 단계별로 안내되어 있습니다.

이 구조의 이점은 명확합니다.

  • 22번 포트가 인터넷에서 사라집니다. 위의 안전 순서로 직접 SSH 포트를 닫았으므로 인터넷에는 SSH가 보이지 않습니다. SSH 무차별 대입은 두드릴 문조차 찾지 못합니다.
  • 신원 기반 접근 제어가 적용됩니다. SSH 키나 비밀번호를 아는 것만으로는 부족하고, 인증된 신원이 있어야 접근할 수 있습니다. 접근 권한을 사람 단위로 부여·회수할 수 있고, 누가 언제 접근했는지 기록이 남습니다.
  • 정책을 중앙에서 관리합니다. 어떤 사용자가, 어떤 조건에서(특정 국가, 특정 기기 상태 등), 어떤 자원에 접근할 수 있는지를 정책으로 정의하고 한곳에서 관리할 수 있습니다.

한 겹을 더하는 것이지 대체가 아니다

중요한 점은, Zero Trust Access가 SSH 자체의 보안(공개키 인증 등)을 대체하는 것이 아니라 그 앞에 한 겹을 더하는 것이라는 사실입니다. "깊이로 방어하라(defense in depth)"의 실천입니다.

이제 SSH에 도달하려면 공격자는 독립된 두 관문을 모두 통과해야 합니다. 먼저 Zero Trust의 신원 검증을 통과해야 하고(인증된 신원이 없으면 여기서 막힙니다), 설령 그것을 뚫더라도 SSH 자체의 공개키 인증을 통과해야 합니다. 한 겹이 뚫려도 다음 겹이 막습니다. 그리고 인터넷에 노출된 포트가 없으니, 무차별 자동 공격은 첫 관문에조차 도달하지 못합니다.

적용 체크리스트

지금까지의 내용을 실제로 실행할 때 따라갈 수 있도록 정리했습니다.

  • 안전 원칙을 먼저 숙지한다. 실제 변경 전에 새 경로 우선·두 번째 세션·자동 롤백·비상 콘솔을 반드시 준비한다.
  • 웹 서비스를 Cloudflare Tunnel로 전환한다. 그 후 80·443 인바운드 포트를 닫는다(안전 절차 준수).
  • 백엔드 서비스를 로컬(127.0.0.1)에만 바인딩한다. 외부 직접 접근의 여지를 없앤다.
  • 오리진 IP 누출 경로를 점검·차단한다. 과거 DNS, 이메일 헤더, 직접 가리키는 서브도메인을 확인한다.
  • SSH를 Zero Trust Access 뒤로 옮긴다. 위 7단계 전환 순서를 그대로 따른다.
  • 전환 후 외부 포트 스캔으로 검증한다. 22번을 포함한 인바운드 포트가 더 이상 보이지 않음을 확인한다.

핵심을 한 문장으로 압축하면 이렇습니다. 가장 안전한 포트는 닫힌 포트이고, 가장 안전한 서버는 인터넷에서 그 존재조차 보이지 않는 서버입니다. Cloudflare Tunnel은 연결의 방향을 뒤집어 인바운드를 0개로 만들고, Zero Trust Access는 위치가 아니라 신원으로 마지막 관문을 지키며, 안전한 적용 순서는 그 모든 강화 작업이 자기 자신을 가두는 사고로 변질되지 않도록 지켜 줍니다.

자주 묻는 질문 (FAQ)

Q. Cloudflare Tunnel은 유료인가요? 비용이 부담스러운데요. 핵심 기능은 무료 등급으로 충분히 쓸 수 있습니다. cloudflared로 아웃바운드 터널을 맺어 웹 서비스를 노출하는 것, 그리고 Zero Trust Access로 신원 기반 접근 제어를 거는 것 모두 무료 범위에 포함됩니다. 다만 사용자 수나 고급 정책 기능 등에서 등급별 제한이 있으니, 규모가 커지면 최신 요금 정책을 Cloudflare One 공식 문서에서 확인하세요.

Q. 인바운드를 다 막으면 서버가 외부와 완전히 단절되는 것 아닌가요? 아닙니다. 막는 것은 외부에서 서버로 들어오는 인바운드 연결뿐입니다. 서버가 바깥으로 나가는 아웃바운드 연결(패키지 업데이트, 외부 API 호출, 그리고 Cloudflare로 향하는 터널 자체)은 그대로 동작합니다. 사용자 트래픽은 서버가 먼저 맺어 둔 아웃바운드 터널을 타고 들어오므로, 인바운드 포트가 0개여도 웹 서비스는 정상적으로 제공됩니다.

Q. SSH 포트를 22번에서 다른 번호로 바꾸는 것만으로는 왜 부족한가요? 포트 변경은 22번만 노리는 게으른 봇을 걸러내는 잡음 감소 효과는 있지만 근본 해결은 아닙니다. 전수 스캐너는 모든 포트를 훑고 서비스 지문을 채취하므로, SSH가 어느 포트에 있든 결국 찾아냅니다. 문의 번호를 바꿔도 문 자체는 그대로 있습니다. 진짜 해법은 인바운드 포트를 닫아 문 자체를 없애고, 접근은 신원 검증을 거친 터널로만 허용하는 것입니다.

Q. 설정을 바꾸다 SSH가 끊겨서 서버에 못 들어가게 될까 봐 무섭습니다. 그 두려움은 정당하며, 실제로 매우 흔한 사고입니다. 네 가지 안전장치를 함께 쓰세요. (1) 새 접속 경로를 먼저 검증한 뒤 옛 경로를 닫고, (2) 변경 중에는 이미 연결된 두 번째 세션을 살려 두며, (3) iptables-save 백업과 at 예약으로 N분 뒤 자동 롤백을 걸어 두고, (4) 클라우드 콘솔의 비상 접속 경로를 미리 익혀 둡니다. 이 네 겹이 있으면 한 단계가 실패해도 항상 되돌아갈 길이 남습니다.

Q. Zero Trust Access를 적용하면 SSH 키 인증은 더 안 해도 되나요? 아닙니다. Zero Trust Access는 SSH 자체의 보안을 대체하는 것이 아니라 그 앞에 한 겹을 더하는 것입니다. 공격자는 먼저 신원 검증을 통과한 뒤에도 SSH의 공개키 인증을 또 통과해야 합니다. 한 겹이 뚫려도 다음 겹이 막는 깊이 방어 구조이므로, 비밀번호 인증을 끄고 공개키 인증을 강제하는 SSH 하드닝은 여전히 함께 해야 합니다.


원문 출처 및 더 알아보기

이 글은 (주)뎁팀 웹 보안팀이 운영하는 보안 가이드 사이트 SGAEPS(시그앱스)의 가이드를 바탕으로 재구성했습니다. 더 깊은 원문은 SGAEPS 가이드 원문에서 확인하실 수 있습니다.

웹 보안 점검·긴급 대응이 필요하시면 DevTeam의 웹 긴급지원 또는 개발/보안 문의를 이용해 주세요.

개발 파트너가 필요하신가요?

DevTeam은 MVP·웹·앱·AI 개발을 설계부터 배포·운영까지 한 팀이 책임집니다.

이 글 공유하기
Twitter LinkedIn
최종 수정: 2026년 06월 19일

security 관련 글

더 많은 스타트업 노하우와 비즈니스 인사이트를 확인해보세요

이메일 보안 실전 가이드: SPF·DKIM·DMARC 설정과 BEC 거래 가로...

발신자 인증으로 도메인 사칭을 막고, 대역 외 확인으로 송금 탈취를 끊고, 2채널 인...

침해를 가정하라: 로깅·탐지·사고대응부터 랜섬웨어 막는 3-2-1...

완벽한 예방은 없다 — 체류 시간을 줄이는 탐지부터 랜섬웨어를 무력화하는 불변 백업...

SameSite 쿠키 문제 해결: 보안 정책 설정 개선으로 사용자 데이...

불안정한 인터넷 환경에서 SameSite 쿠키 정책으로 안전한 사용자 데이터를 어떻게 보...

모의침투가 밝혀내는 진짜 약점 정리: 노출된 파일·디버그 모드·...

0-day가 아니라 사소한 방치가 회사를 무너뜨린다 — 펜테스트 현장에서 가장 흔히 발...

웹 공격자 분류와 위협 모델링 완전 정리: 자동화 봇부터 랜섬웨...

누구로부터 무엇을 지킬 것인가 — 동기와 역량으로 공격자를 읽고 방어를 설계하는 법

지속 가능한 보안 운영: 1인·소규모 팀을 위한 패치 자동화와 우...

영웅적 노력은 사흘 만에 무너진다 — 부족한 자원을 자동화로 메우고 보안을 배경에서...

전문가 도움이 필요하신가요?

스타트업과 비즈니스 성장을 위한 전문 컨설팅을 받아보세요.
확장 가능하고 비즈니스 성과로 이어지는 솔루션을 구축할 수 있도록 도와드립니다.