infra
Platform

모듈 맵

[Infra Ops] SSH 접속 보안 강화와 배스천 호스트 기반 접근 제어

0 / 52 완료

펼치기
0 / 52 완료0%

Infra-ops · 07 / 52

[Infra Ops] SSH 접속 보안 강화와 배스천 호스트 기반 접근 제어

sshd_config 설정, 공개키 인증, AllowUsers 제한, 포트 변경, 배스천 호스트 구조까지 — 서버를 외부 공격으로부터 보호하는 SSH 보안 실무

🚨INCIDENT ALERT
HIGH

새벽 3시, 고객사 서버 로그에 이상한 패턴이 쌓입니다. root, admin, ubuntu 계정으로 초당 수십 번 로그인을 시도하는 기록들. 전 세계 수백 개 IP에서 쏟아지는 무차별 대입 공격입니다. 패스워드 123456, password, admin1234를 하나씩 넣어봅니다. 운이 나쁘면 한 번에 뚫립니다.

공개 IP에 22번 포트가 열려있는 모든 서버는 지금 이 순간도 같은 공격을 받고 있습니다. 이 모듈은 그 공격을 구조적으로 차단하는 방법을 다룹니다.

이번 챕터에서 배울 것
  • 1SSH 공개키 인증 구조를 이해하고 키를 생성해 서버에 등록할 수 있다
  • 2sshd_config 핵심 보안 설정을 적용하고 sshd -t로 검증한 뒤 안전하게 재로드할 수 있다
  • 3배스천 호스트 구조를 이해하고 ProxyJump로 내부 서버에 접속할 수 있다
  • 4SSH 접속 시도 로그를 확인하고 fail2ban으로 무차별 대입을 차단할 수 있다
  • 5Permission denied (publickey) 등 흔한 SSH 오류를 권한 문제와 설정 관점에서 해결할 수 있다
실습 환경 준비
OpenSSH 서버 상태 확인
systemctl status sshd 2>/dev/null || systemctl status ssh 2>/dev/null
sshd_config 백업
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak && echo backup OK

SSH 인증 방식

💡개념

패스워드 인증 vs 공개키 인증

공개 IP에 22번 포트를 열어둔 서버는 매 순간 자동화된 무차별 대입 공격의 표적이 됩니다. 패스워드 인증은 네트워크로 전달되는 값이 노출되거나 추측될 수 있어, 짧거나 단순한 비밀번호는 수만 건의 시도 끝에 뚫립니다. 공개키 인증은 비밀키가 클라이언트를 절대 벗어나지 않는 구조로, 서버에 탈취당할 정보가 없고 수학적으로 추측이 불가능합니다.

SSH 공개키 인증 구조 — 비밀키는 클라이언트에, 공개키는 서버에

22번 포트를 인터넷에 열어둔 서버는 지금 이 순간에도 자동화된 무차별 대입 공격을 받고 있습니다. 사무실 동료 계정이 password123이었다면, 수십만 개 비밀번호를 자동으로 시도하는 봇이 결국 뚫습니다. 한 번 뚫리면 그 서버를 발판 삼아 내부 네트워크로 이동하고, DB 서버까지 도달합니다. 공개키 인증은 이 경로를 구조적으로 차단합니다. 비밀키(private key)는 절대 클라이언트를 벗어나지 않습니다. 서버는 공개키(public key)만 갖고 있으며, 로그인 시 수학적 서명 검증으로 인증합니다. 추측하거나 가로챌 것이 없습니다.

로컬 터미널
# 키 쌍 생성
ssh-keygen -t ed25519 -C "infra-admin@company.com"
# 프로덕션에서는 패스프레이즈 반드시 설정

# 공개키를 서버에 등록
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@192.168.1.100

# 서버에서 권한 설정 (틀리면 인증 자체를 거부함)
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

핵심 권한 규칙:

대상권한
~/.ssh/ 디렉터리700 — 본인만 접근
~/.ssh/authorized_keys600 — 본인만 읽기/쓰기
~/.ssh/id_ed25519 (비밀키)600 — 본인만 읽기/쓰기

sshd 설정 강화

💡개념

sshd_config 핵심 보안 설정

기본 SSH 설정 그대로 운영 중인 서버는 보안 감사에서 예외 없이 지적을 받습니다. root 직접 로그인이 허용되어 있거나, 패스워드 인증이 켜져 있으면 — 공개 IP에 노출된 서버는 무차별 대입 공격의 직접 타겟입니다. 설정 하나하나가 공격 표면을 줄이는 역할을 하며, 잘못 적용하면 서버에 영구히 잠길 수 있습니다. 반드시 현재 세션을 유지한 채 새 터미널로 테스트합니다.

로컬 터미널
sudo vi /etc/ssh/sshd_config
로컬 터미널
# 기본 22는 자동화 스캐너가 항상 시도 — 비표준 포트로 노이즈 감소
Port 22222

# root 직접 로그인 금지 — 감사 추적을 위해 일반 계정 로그인 후 sudo
PermitRootLogin no

# 패스워드 인증 비활성화 — 공개키 등록 완료 확인 후 변경
PasswordAuthentication no
PubkeyAuthentication yes

# 허용할 계정 명시 — 목록에 없는 계정은 키가 있어도 접속 불가
AllowUsers infra-admin deploy-bot

# 인증 시간 초과 및 재시도 제한
LoginGraceTime 60
MaxAuthTries 4

PermitEmptyPasswords no
X11Forwarding no

설정 후 반드시 이 순서를 지킵니다.

로컬 터미널
# 1단계: 문법 검증 (오류 있으면 여기서 중단)
sudo sshd -t && echo CONFIG OK

# 2단계: 재로드 (기존 연결 유지, restart 아님)
sudo systemctl reload sshd

# 3단계: 새 터미널에서 접속 테스트 — 현재 세션 유지한 채
AllowUsers vs AllowGroups — 언제 무엇을 쓸까
접속 허용 계정이 3명 이하로 고정됨AllowUsers — 계정명을 명시적으로 나열
팀이 자주 바뀌거나 계정 수가 많음AllowGroups sshusers — 그룹으로 관리, usermod -aG sshusers username 으로 추가
특정 계정만 차단하고 싶음DenyUsers username — AllowUsers와 함께 쓰면 DenyUsers가 우선

배스천 호스트 구조

💡개념

단일 진입점으로 공격 표면 최소화

내부 서버 10대가 각각 22번 포트를 인터넷에 열어두면 공격자에게 10개의 진입 기회를 주는 셈입니다. 그중 하나라도 취약한 설정이 있으면 전체 내부망이 위험해집니다. 배스천 호스트는 외부에서 SSH로 접근 가능한 서버를 단 한 대로 줄이고, 나머지 내부 서버는 프라이빗 네트워크에만 존재하게 만듭니다. 접속 경로가 단일화되면 보안 설정 집중도가 높아지고, 모든 SSH 접근 기록이 한 곳에 남아 감사 추적도 훨씬 쉬워집니다.

배스천 호스트 아키텍처 — 내부 서버는 인터넷에 노출되지 않음

내부 서버 10대가 각각 22번 포트를 인터넷에 열면 공격 목표가 10개입니다. 배스천 호스트(Bastion Host)는 인터넷과 내부 네트워크 사이의 단일 진입점으로, 내부 서버는 공인 IP 없이 배스천을 통해서만 접근합니다. 모든 SSH 접속 로그가 한 곳에 집중되어 감사(audit) 추적도 쉬워집니다.

SSH 접속 후
# ProxyJump 방식 — 배스천을 경유해 내부 서버로 직접 접속
ssh -J infra-admin@bastion.company.com admin@10.0.1.50

# ~/.ssh/config에 등록해 단축 사용
로컬 터미널
# ~/.ssh/config
Host bastion
    HostName bastion.company.com
    User infra-admin
    Port 22222
    IdentityFile ~/.ssh/id_ed25519

Host web-01
    HostName 10.0.1.50
    User admin
    ProxyJump bastion
    IdentityFile ~/.ssh/id_ed25519

Host db-01
    HostName 10.0.2.10
    User dbadmin
    ProxyJump bastion
    IdentityFile ~/.ssh/id_ed25519
로컬 터미널
# 권한 설정
chmod 600 ~/.ssh/config

# 등록 후 사용 — bastion 경유가 자동으로 처리됨
ssh web-01
ssh db-01

SSH 접속 모니터링

💡개념

로그 확인과 fail2ban 무차별 대입 방어

무차별 대입 공격은 막고 있다고 생각했는데, 로그를 보니 하루에 수만 건의 실패 기록이 쌓이고 있었습니다. 동일한 IP에서 반복 시도하는데도 차단이 안 됐고, 결국 어느 날 취약한 비밀번호를 가진 계정이 뚫렸습니다. fail2ban은 지정 횟수 이상 실패한 IP를 방화벽에서 자동으로 차단합니다. 로그를 모니터링하지 않으면 이미 뚫리고 있다는 사실을 모를 수 있습니다.

로컬 터미널
# 접속 시도 로그 확인
sudo tail -50 /var/log/secure           # RHEL/Rocky
sudo tail -50 /var/log/auth.log         # Ubuntu/Debian
sudo journalctl -u sshd --since "1 hour ago" --no-pager  # systemd 공통

# 실패한 로그인 시도만 필터
sudo grep "Failed password" /var/log/secure | tail -20

# 무차별 대입 IP 상위 10개
sudo grep "Failed password" /var/log/secure | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head -10

# 성공한 로그인 이력 / 실패 이력 / 계정별 마지막 로그인
last -20 && sudo lastb | head -10 && lastlog | grep -v "Never logged"

fail2ban은 로그를 감시하다가 지정 횟수 이상 실패하면 해당 IP를 방화벽에서 자동 차단합니다.

로컬 터미널
sudo dnf install -y fail2ban      # RHEL/Rocky
sudo apt-get install -y fail2ban  # Ubuntu
로컬 터미널
# /etc/fail2ban/jail.local — jail.conf는 수정 금지, local에 오버라이드
[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 5

[sshd]
enabled  = true
port     = 22222
logpath  = /var/log/secure
maxretry = 3
bantime  = 86400
서버 터미널
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd                        # 차단 현황 확인
sudo fail2ban-client set sshd unbanip 45.33.32.156      # 실수 차단 해제
SSH 키 생성 및 서버 등록
🔍실행 후 확인할 것
  • ~/.ssh/ 에 비밀키와 .pub 공개키 두 파일이 생성되었는가
  • 비밀키 권한이 -rw------- (600)인가
  • 서버의 authorized_keys 권한이 -rw------- (600)인가
  • ssh -o PasswordAuthentication=no 로 패스워드 없이 접속되는가
  • journalctl -u sshd 에서 Accepted publickey 로그가 찍히는가
sshd_config 보안 강화
🔍실행 후 확인할 것
  • /etc/ssh/sshd_config.bak 파일이 존재하는가
  • sshd -t 결과 오류 없이 종료되었는가
  • systemctl status sshd 에서 active (running) 상태인가
  • 새 터미널에서 공개키 인증으로 접속이 성공하는가
  • 패스워드로 접속 시도 시 Permission denied (publickey) 가 뜨는가
💼
실무 맥락
현업 패턴

실제 업무에서 이 지식이 쓰이는 상황:

금융권과 공공기관 서버 운영에서 SSH 접근 통제는 정보보호 관리체계(ISMS-P) 심사 항목입니다. 심사관이 실제로 확인하는 것:

로컬 터미널
grep "PermitRootLogin" /etc/ssh/sshd_config   # → no
grep "PasswordAuthentication" /etc/ssh/sshd_config  # → no
grep "AllowUsers\|AllowGroups" /etc/ssh/sshd_config  # 허용 목록 존재
sudo fail2ban-client status sshd  # 차단 현황
sudo lastb | head -20  # 실패 로그인 이력

AWS로 처음 이전하는 스타트업이 흔히 겪는 실수가 내부 서버 보안 그룹에 0.0.0.0/0:22를 열어두는 것입니다. 올바른 구성은 배스천 EC2(공인 IP, 특정 사무실 IP만 허용) → 내부 서버(프라이빗 서브넷, 배스천 IP만 허용) 구조입니다. 이 구조에서 개발자 PC가 탈취되어도 배스천 계정과 키까지 없으면 내부 서버에 도달할 수 없습니다.

다음 모듈에서는 OS 보안 패치와 미들웨어 버전 업 절차를 다룹니다.

지식 확인

퀴즈 — 4문제

Q1

SSH 공개키 인증이 패스워드 인증보다 안전한 이유로 가장 적절한 것은?

Q2

/etc/ssh/sshd_config에서 PasswordAuthentication no 설정 후 즉시 적용하는 올바른 방법은?

Q3

배스천 호스트(Bastion Host)를 도입하는 가장 핵심적인 이유는?

Q4

AllowUsers와 DenyUsers 지시어가 동시에 설정되어 있을 때 어느 것이 우선 적용되는가?

0 / 4 답변

🧪 실습으로 확인하기

Nginx 설치 및 기동

초급

Linux 서버에 Nginx를 설치하고 systemd 서비스로 등록하여 80포트에서 응답하는 상태까지 만든다.

30📋 3단계💻 직접 환경
실습 시작하기 →

이것도 배워보세요

infra-ops중급 · 50
[Infra Ops] Web Server와 WAS 미들웨어 구조의 이해
인프라 서비스 운영 트랙 계속
linux입문 · 30
[Linux] 개발자가 왜 리눅스 서버와 커맨드라인을 반드시 배워야 하는가
Linux 트랙 시작점