Cloudflare Tunnel로 SSH 공격 표면 완전히 없애기

목차

요즘 서버 운영하면서 가장 신경 쓰이는 게 보안이잖아요.
특히 SSH 포트 열어두면 하루에도 수천 번씩 무차별 대입 공격이 들어오는 거 로그 보면서 항상 찜찜했습니다.
그래서 이번에 아예 SSH 포트 자체를 닫아버리고 Cloudflare Tunnel을 통해서만 접속하는 방식으로 바꿔봤습니다.
결론부터 말하면 정말 만족스럽습니다!

macOS Terminal과 Windows PuTTY 둘 다 설정했으니 참고하시기 바랍니다.
서버 환경은 Rocky Linux 9.7 기준입니다.

서버에 cloudflared 설치

cloudflared는 Cloudflare Tunnel을 사용하기 위해 Cloudflare가 만든 클라이언트 프로그램입니다.
서버에서는 터널 서버 역할을 하고
내 컴퓨터에서는 터널 클라이언트 역할을 합니다.

Rocky Linux는 아래처럼 RPM으로 설치할 수 있습니다.

wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-x86_64.rpm -O cloudflared.rpm
sudo rpm -ivh cloudflared.rpm
cloudflared --version

버전이 출력되면 설치 완료입니다!

설치에 관한 자세한 사항이 필요하면 아래 URL에서 확인할 수 있습니다.
https://github.com/cloudflare/cloudflared/?tab=readme-ov-file#installing-cloudflared


Cloudflare Tunnel 생성 및 설정

인증

cloudflared tunnel login

위 명령어를 입력하면 터미널에 URL이 출력됩니다.
그 URL을 복사하여 웹브라우저 주소창에 넣고 접속하면 Cloudflare 서비스가 나타나고 연결할 도메인을 선택합니다.
성공하면 자동으로 서버에 ~/.cloudflared/cert.pem 파일이 생성됩니다.

터널 생성

cloudflared tunnel create andy-tunnel

생성되면 터널 ID와 인증 파일 경로가 출력됩니다.
인증 파일은 절대 외부에 유출하면 안 됩니다!

config.yml 작성

vi ~/.cloudflared/config.yml
tunnel: 여기에-터널-ID
credentials-file: /etc/cloudflared/여기에-터널-ID.json

ingress:
  - hostname: ssh.andytips.com
    service: ssh://localhost:22
  - service: http_status:404

DNS CNAME 자동 생성

cloudflared tunnel route dns andy-tunnel ssh.andytips.com

그리고 이 명령어를 실행하면 Cloudflare DNS에 CNAME 레코드가 자동으로 생성됩니다.
Cloudflare에는 자동으로 생성되니 따로 직접 설정할 필요 없습니다.

나중에 Cloudflare 대시보드 → Zero Trust → Networks → Tunnels 에서 터널 상태를 확인할 수 있고,
DNS → Records 에서 ssh.andytips.com CNAME 레코드가 자동 생성된 것도 볼 수 있습니다.

systemd 서비스 등록

이제 설정 파일을 /etc/cloudflared/로 복사하고 서비스를 등록합니다.

sudo mkdir -p /etc/cloudflared
sudo cp ~/.cloudflared/config.yml /etc/cloudflared/
sudo cp ~/.cloudflared/여기에-터널-ID.json /etc/cloudflared/
sudo cp ~/.cloudflared/cert.pem /etc/cloudflared/

/etc/cloudflared/config.yml에서 credentials-file 경로를 /etc/cloudflared/로 수정해 주세요.

sudo cloudflared service install
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo systemctl status cloudflared

active (running) 이 보이면 터널이 정상 동작하는 것입니다!


방화벽에서 SSH 포트 차단

이게 핵심입니다.
SSH 포트를 아예 방화벽에서 제거해버립니다.

sudo firewall-cmd --remove-service=ssh --permanent
sudo firewall-cmd --reload

이제 외부에서 22번 포트로는 절대 접근할 수 없습니다.
포트 번호가 아예 서비스하지 않기 때문에 SSH 접근이 완전히 차단되는 것이죠.

Cloudflare Tunnel을 통해서만 접속이 가능합니다.


macOS 클라이언트 설정

cloudflared 설치

brew install cloudflared

macOS에서는 brew 명령어로 간편하게 설치할 수 있습니다.

~/.ssh/config 설정

Host andy
    HostName ssh.andytips.com
    User 여기에-사용자명
    ProxyCommand cloudflared access ssh --hostname ssh.andytips.com
    ServerAliveInterval 60
    ServerAliveCountMax 3

앞으로 편리하게 서버에 연결하기 위해 config를 설정합니다.
이제 터미널에서 ssh andy 한 줄만 입력하면 바로 서버에 접속할 수 있습니다!


Windows PuTTY 클라이언트 설정

cloudflared 설치

윈도우의 경우 macOS보다는 조금 더 번거롭습니다.
우선 Cloudflared를 설치하기 위해 관리자 권한 PowerShell에서 아래 명령어를 실행합니다.

winget install Cloudflare.cloudflared

설치 후 PowerShell을 새로 열고 경로를 확인합니다.
나중에 Putty에 옵션을 넣을 때 cloudflared의 정확한 경로가 필요합니다.

where.exe cloudflared

PuTTYgen으로 ED25519 키쌍 생성

이제 공개키와 개인키를 생성하기 위해 Puttyget을 실행합니다.

  1. PuTTYgen 실행
  2. EdDSA 선택
  3. Generate 클릭 후 마우스를 빈 공간에서 랜덤하게 움직입니다
  4. 공개키 텍스트 전체 복사해두기
  5. Save private key.ppk 파일 저장

공개키를 서버에 등록

macOS에서 서버 접속 후 아래 명령어로 공개키를 등록합니다.

echo "여기에-복사한-공개키" >> ~/.ssh/authorized_keys

PuTTY 설정

이제 Putty를 설정합시다!

Connection → Data:

  • Auto-login username: 사용자명

Connection → SSH → Auth → Credentials:

  • Private key file: 저장한 .ppk 파일 경로 지정

Connection → Proxy:

  • Proxy type: Local
  • Command: C:\Users\사용자명\AppData\Local\Microsoft\WinGet\Links\cloudflared.exe access ssh --hostname ssh.andytips.com

위 내용은 예시이고 진행하면서 자신의 서버 환경에 맞게 적절히 수정하세요.

Session:

  • Host Name: ssh.andytips.com
  • Port: 22

포트번호를 기입하기는 하지만 실제로 22번 포트를 이용하여 접속하는 것은 아닙니다.


보안 강화 마무리

패스워드 로그인 비활성화 확인

sudo vi /etc/ssh/sshd_config
PasswordAuthentication no

좀 더 명확하게 보안을 점검하기 위해 sshd_config에 패스워드 로그인이 비활성화 되어 있는지 확인합니다.

현재 이 설정에서는 서버의 authorized_keys에 등록된 공개키와 클라이언트의 개인키가 쌍으로 일치해야만 로그인이 허용됩니다.

즉 Cloudflare Tunnel을 통과하더라도 올바른 개인키가 없으면 절대 로그인이 안 됩니다.
Zero Trust 정책을 아직 설정하지 않은 상태에서도 이미 충분히 강한 보안이 유지되고 있습니다.

Zero Trust Access Policy (권장 추가 사항)

나중에 Cloudflare Zero Trust → Access → Applications에서 ssh.andytips.com에 대한 접근 정책을 추가하면 이메일 OTP 인증 등 다중 인증을 터널 입구에서도 적용할 수 있습니다.
현재는 SSH 키 인증만으로도 충분하지만 더 강화하고 싶다면 설정해 보시기 바랍니다.


결론: 보안 강화 사항

더 강화되는 점

  • 포트 스캐닝이 의미 없습니다: SSH 포트 자체를 서비스 하지 않으니 공격자가 스캔해도 아무것도 보이지 않습니다.
  • IP ACL의 한계를 극복합니다: 고전적인 IP 화이트리스트 방식은 IP가 변경되거나 유출되면 위험한데, Cloudflare Tunnel은 IP와 무관하게 작동합니다
  • Cloudflare의 DDoS 방어와 TLS 암호화가 자동 적용됩니다
  • Zero Trust 정책 추가 시 이메일 OTP 등 다중 인증까지 가능합니다
  • 사설망의 서버 접근 가능: 조금 다른 얘기지만 포트 접근이 아니다보니 서버가 사설망에 있더라도 외부에서 연결 가능합ㄴ디ㅏ.

단점 및 제한

  • Cloudflare 서비스 장애 시 SSH 접속 자체가 불가능합니다. Cloudflare는 항상 서비스 될 것이라고 믿고 쓰는거죠.
  • 클라이언트 PC마다 cloudflared를 설치해야 합니다
  • Cloudflare라는 제3자에 대한 의존성이 생깁니다
  • 마지막으로 전송되는 모든 데이터가 Cloudflare를 경유한다는게 조금 찝찝하기는 합니다.

이런 단점들이 있지만, SSH 포트를 완전히 없애서 공격 표면 자체를 제거하는 건 보안 측면에서 정말 강력한 방법입니다.
불편함을 감수하고 보안을 강화할지는 결국 운영자 본인이 결정하는 거지만

저는 이 방법이 정말 마음에 들어요. 😊