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을 실행합니다.
- PuTTYgen 실행
- EdDSA 선택
- Generate 클릭 후 마우스를 빈 공간에서 랜덤하게 움직입니다
- 공개키 텍스트 전체 복사해두기
- 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 포트를 완전히 없애서 공격 표면 자체를 제거하는 건 보안 측면에서 정말 강력한 방법입니다.
불편함을 감수하고 보안을 강화할지는 결국 운영자 본인이 결정하는 거지만
저는 이 방법이 정말 마음에 들어요. 😊