Tropic Host

초보자를 위한 VPS 보안: SSH 키, 방화벽, Fail2ban

읽는 데 13분
Tropic

초보자를 위한 VPS 보안: SSH 키, 방화벽, Fail2ban

Ubuntu를 설치했다고 해서 새 VPS가 바로 안전해지는 것은 아닙니다. 접근 설정을 마치기 전에도 서버는 스캐너에 노출됩니다. 스캐너는 SSH 비밀번호를 무작위로 시도하고, 공개된 관리 패널을 찾으며, 흔히 사용되는 취약점을 확인합니다. 이 글에서는 VPS를 처음부터 기본적으로 보호하는 방법을 살펴봅니다. 별도의 사용자를 만들고, SSH 키 로그인과 UFW를 설정하고, Fail2ban을 추가하는 과정입니다. 모든 단계는 sudo 권한이 있는 사용자로 명령을 실행한다는 전제에서 Ubuntu 22.04와 24.04에 적용할 수 있습니다.

설정 전: 사용할 포트 목록을 작성하세요

“혹시 모르니” 포트를 열어 두지 마세요. 일반적인 웹 서버에 필요한 포트는 다음과 같습니다.

  • 22/tcp — SSH. 가능하면 IP 주소로 접근을 제한하고, 다른 포트로 옮기는 것은 추가적인 조치로만 사용합니다.
  • 80/tcp — HTTP. 보통 HTTPS로 리디렉션하거나 인증서를 발급할 때 필요합니다.
  • 443/tcp — HTTPS.

Nginx나 Caddy가 앞단에서 동작한다면 3000, 8080, 9000 같은 애플리케이션 포트를 인터넷에 공개하지 않아야 합니다. 애플리케이션을 127.0.0.1에 바인딩하거나, 해당 포트를 내부 네트워크에서만 허용하세요. 먼저 서버에서 어떤 프로세스가 포트를 수신하고 있는지 확인합니다.

sudo ss -tulpn

Docker를 설치한 뒤에는 iptables 규칙도 별도로 확인하세요. -p 3000:3000으로 포트를 게시하면 예상한 방화벽 구성과 다르게 포트가 열릴 수 있습니다. 공개 서비스라면 HTTPS 프록시를 사용하고 내부 포트를 외부에 노출하지 않는 편이 안전합니다.

1단계. 시스템을 업데이트하고 관리자 계정을 만드세요

발급받은 계정으로 VPS에 연결한 뒤 업데이트를 설치합니다.

sudo apt update
sudo apt full-upgrade -y
sudo apt install -y ufw fail2ban unattended-upgrades

개인용 사용자를 만듭니다. alex 대신 자신의 이름을 사용하세요.

sudo adduser alex
sudo usermod -aG sudo alex

새 계정이 정상적으로 동작하는지 별도의 터미널 창에서 확인하기 전까지 기존 접근 방법을 삭제하지 마세요. 현재 세션이 열려 있을 때가 SSH 설정 오류를 수정하기 가장 쉽습니다.

2단계. SSH 키를 만들고 서버에 설치하세요

Linux, macOS 또는 Windows PowerShell을 사용하는 컴퓨터에서 다음을 실행합니다.

ssh-keygen -t ed25519 -C "alex@my-computer"

Enter 키를 눌러 기본 파일에 저장하고 passphrase를 설정하세요. 개인 키는 채팅으로 보내거나 저장소에 넣거나 VPS에 복사해서는 안 됩니다. 서버에는 .pub 확장자를 가진 공개 키 파일만 전달해야 합니다.

ssh-copy-id alex@SERVER_IP

ssh-copy-id를 사용할 수 없다면 PowerShell에서 Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub를 실행해 공개 키를 확인한 다음, 서버에 추가합니다.

sudo install -d -m 700 -o alex -g alex /home/alex/.ssh
sudo nano /home/alex/.ssh/authorized_keys
sudo chown alex:alex /home/alex/.ssh/authorized_keys
sudo chmod 600 /home/alex/.ssh/authorized_keys

공개 키를 한 줄로 붙여 넣고, 비밀번호 로그인을 끄기 전에 키로 접속할 수 있는지 확인합니다.

ssh alex@SERVER_IP
sudo whoami

마지막 명령의 예상 결과는 root입니다. SSH 클라이언트가 키를 찾지 못하면 다음처럼 키를 명시하세요. ssh -i ~/.ssh/id_ed25519 alex@SERVER_IP.

3단계. root 로그인과 비밀번호 로그인을 차단하세요

SSH 설정 파일을 먼저 백업합니다.

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config

파일에 다음 매개변수가 있는지 확인하세요.

PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
MaxAuthTries 3

Ubuntu에서는 설정이 /etc/ssh/sshd_config.d/*.conf에 있을 수도 있으므로 최종 적용 구성을 확인해야 합니다.

sudo sshd -t
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries'

sshd -t에서 오류가 나오면 문법을 수정하기 전에는 서비스를 재시작하지 마세요. 검사가 성공한 뒤 다음 명령으로 설정을 적용합니다.

sudo systemctl reload ssh

기존 SSH 연결은 그대로 열어 두고, 새 터미널 창에서 키를 사용해 로그인해 보세요. 키를 확인하지 않은 상태에서 비밀번호 로그인을 끄는 것은 서버 접근 권한을 잃는 가장 흔한 원인입니다.

4단계. SSH를 차단하지 않도록 UFW를 설정하세요

UFW는 Linux 네트워크 규칙을 편리하게 관리하는 인터페이스입니다. 먼저 안전한 기본값을 설정한 다음 SSH와 웹 포트를 허용합니다.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw enable

SSH 규칙을 먼저 추가한 뒤에만 활성화를 확인하세요. 결과를 확인합니다.

sudo ufw status verbose
sudo ufw status numbered

사무실의 공인 IP가 고정되어 있다면 SSH 접근을 해당 주소로 제한할 수 있습니다.

sudo ufw delete allow 22/tcp
sudo ufw allow from YOUR.PUBLIC.IP to any port 22 proto tcp comment 'SSH office'

이 방법은 IP가 고정되어 있고 공급업체의 콘솔을 사용할 수 있을 때만 적용하세요. IP가 바뀌면 스스로 접속을 차단할 수 있습니다.

애플리케이션 포트를 임시로 여는 방법

서비스를 직접 확인해야 한다면 허용 출발지를 제한한 규칙을 만들 수 있습니다.

sudo ufw allow from YOUR.PUBLIC.IP to any port 8080 proto tcp

테스트가 끝나면 ufw status numbered의 번호를 확인해 규칙을 삭제합니다.

sudo ufw delete RULE_NUMBER

sudo ufw allow 1:65535/tcp는 사용하지 마세요. 이런 규칙은 방화벽을 사실상 형식적인 장치로 만들어 버립니다.

5단계. SSH에 Fail2ban을 활성화하세요

Fail2ban은 로그를 분석하고 로그인 실패가 일정 횟수 이상 발생하면 임시 차단 규칙을 추가합니다. SSH 키와 방화벽을 대신하지는 않지만, 자동화된 무차별 대입 시도에서 발생하는 불필요한 로그와 트래픽을 줄여 줍니다.

패키지 업데이트가 설정을 덮어쓰지 않도록 로컬 설정 파일을 만듭니다.

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

[DEFAULT] 섹션에 합리적인 값을 지정합니다.

[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
banaction = ufw

[sshd]
enabled = true
port = 22

서비스를 시작하고 jail을 확인합니다.

sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd

sshd 출력에서 실패한 시도 횟수와 차단된 주소를 확인하세요. 자신의 IP를 차단 목록에 넣지 않도록 주의합니다. 영구적으로 제외할 주소가 있다면 [DEFAULT]에 다음과 같이 ignoreip = 127.0.0.1/8 YOUR.PUBLIC.IP를 지정하세요.

6단계. 자동 업데이트를 활성화하세요

보안 패키지에는 자동 업데이트가 유용하지만, 커널 재시작 여부는 여전히 직접 관리해야 합니다.

sudo dpkg-reconfigure -plow unattended-upgrades
sudo systemctl status unattended-upgrades

일주일에 한 번 재시작이 필요한지 확인하세요.

test -f /var/run/reboot-required && echo 'Требуется перезапуск'

수동으로 재시작하기 전에 정상적으로 작동하는 키와 VPS 콘솔 접근 권한이 있는지 확인하세요. 재부팅 후에는 애플리케이션 서비스, Nginx, UFW, Fail2ban이 모두 정상인지 점검합니다.

7단계. 외부에서 결과를 확인하세요

설정 파일의 내용만 확인하지 말고, 다른 컴퓨터에서 실제 보호 상태를 테스트하세요.

ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no alex@SERVER_IP

이 명령은 거부되어야 합니다. 키를 사용한 정상적인 접속은 별도로 확인합니다.

ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 alex@SERVER_IP

VPS에서는 수신 대기 중인 주소와 규칙을 확인합니다.

sudo ss -lntup
sudo ufw status numbered
sudo fail2ban-client status sshd

직접 외부 접근을 제공할 목적이 아니라면 애플리케이션 포트는 127.0.0.1에서만 수신해야 합니다. 외부 노드에서는 nmap SERVER_IP를 사용할 수 있지만, 반드시 자신이 소유한 서버만 스캔하세요. 허가 없이 다른 인프라를 점검하면 법률이나 공급업체 규정을 위반할 수 있습니다.

백업과 복구

SSH 보안만으로는 데이터 삭제, 관리자 실수 또는 애플리케이션 침해를 막을 수 없습니다. 데이터베이스, 설정 파일, 사용자 파일의 사본을 VPS와 분리된 곳에 보관하세요. 최소한의 구성은 매일 백업하고, 지난 며칠간의 여러 버전을 유지하며, 주기적으로 복구를 테스트하는 것입니다.

비밀번호와 토큰을 평문 스크립트에 기록하지 마세요. 비밀 정보가 유출되면 즉시 해당 시크릿을 폐기하고 새로 발급해야 합니다.

보안 프로젝트에 적합한 VPS 선택 방법

보안은 인프라를 통제하는 것에서 시작합니다. VPS에서는 운영체제, 방화벽 규칙, 접근 방식, 백업 방법, 서비스 배치를 직접 선택할 수 있습니다. 소규모 사이트나 API라면 가상 CPU가 지나치게 많은 상품보다 안정적인 네트워크, SSD, 복구 콘솔을 우선하는 편이 중요합니다.

tropic.host에서 VPS로 프로젝트를 시작할 때는 외부에 공개할 진입점을 먼저 정하세요. 대부분의 경우 SSH, HTTP, HTTPS만 있으면 충분합니다. 데이터베이스와 관리 패널은 내부 영역에 두세요. 프로젝트가 성장하면 애플리케이션, 데이터베이스, 모니터링을 별도의 VPS로 분리해 장애 영역을 나눌 수 있습니다.

자주 발생하는 실수

  • 키 로그인 확인 전에 비밀번호 로그인을 끄는 것. 기존 세션을 유지하고 별도의 창에서 새 로그인을 테스트하세요.
  • 신뢰할 수 있는 주소만 허용할 수 있는데도 22/tcp를 전 세계에 공개하는 것.
  • Docker 포트를 직접 공개하는 것. 먼저 Docker와 UFW의 규칙을 확인하세요.
  • Fail2ban을 설치한 뒤 로그를 전혀 확인하지 않는 것. 변경 후에는 journalctl -u ssh와 jail 상태를 점검하세요.

결론

VPS 기본 보안은 순서를 지켜 진행하면 오래 걸리지 않습니다. 별도 사용자를 만들고, SSH 키를 설치하고, 접근을 확인한 뒤 root와 비밀번호 로그인을 차단합니다. 그 다음 UFW, Fail2ban, 자동 업데이트를 활성화하세요. 이후 백업, 로깅, 외부 모니터링을 추가하면 됩니다.

이 단계들이 서버를 완전히 무결하게 만들지는 않지만, 초기 설정에서 가장 흔한 실수를 막아 줍니다. 다음 단계에서는 애플리케이션에 맞게 보안 프로필을 조정해야 합니다. 의존성을 업데이트하고, 서비스 권한을 제한하고, 관리자 패널을 보호하며, 공개 포트를 정기적으로 확인하세요.

FAQ

SSH 기본 포트를 변경해야 하나요?

반드시 변경할 필요는 없습니다. 포트를 옮기면 자동화된 스캔으로 발생하는 소음은 줄어들 수 있지만, SSH 키, 비밀번호 로그인 차단, UFW, Fail2ban을 대신할 수는 없습니다. 포트를 변경한다면 방화벽 규칙과 Fail2ban jail의 port 매개변수도 함께 업데이트하세요.

UFW를 설정한 뒤 접속을 잃으면 어떻게 해야 하나요?

공급업체의 웹 콘솔이나 rescue 콘솔을 사용해 SSH 규칙과 sshd 설정을 확인하세요. 새 접속이 확인되기 전까지 기존에 작동하는 세션을 종료하지 않는 것이 좋습니다.

SSH 보호에 Fail2ban만으로 충분한가요?

아니요. Fail2ban은 이미 발생한 로그인 실패에 반응하는 도구입니다. 기본은 SSH 키, 비밀번호 인증 비활성화, 최소 권한 사용자, 제한된 방화벽이어야 합니다.

SSH를 하나의 IP에서만 허용할 수 있나요?

가능합니다. IP 주소가 고정되어 있다면 해당 주소에 대한 allow from UFW 규칙을 추가하세요. IP가 변경되면 접속이 차단되므로, 미리 공급업체 콘솔이나 예비 접근 방법을 준비해야 합니다.

VPS 보안을 얼마나 자주 점검해야 하나요?

SSH, 방화벽 또는 Docker 포트 공개를 변경할 때마다 포트와 로그인 테스트를 실행하세요. 정기적으로는 적어도 일주일에 한 번 업데이트와 로그를 확인하고, 백업 복구 테스트도 계획적으로 수행해야 합니다.