13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[태그:] SSH 하드닝

  • [보안] 리눅스 서버 하드닝 전략 재점검 체크리스트

    [보안] 리눅스 서버 하드닝 전략 재점검 체크리스트

    리눅스 서버 하드닝 전략 재점검 체크리스트

    요즘 보안 메일함 열어보면 심장이 조금 빨리 뛰죠. 특히 리눅스 서버 하드닝 관점에서 보면, 커널과 사용자 공간(User space, 커널 밖에서 도는 일반 프로세스) 취약점 공지가 꽤 자주 올라옵니다. 저도 홈랩이랑 운영 서버를 같이 굴리다 보니, 처음엔 “요즘 왜 이렇게 Linux CVE가 많아졌지?” 싶었거든요. 그런데 실제로 뜯어보니, 단순히 숫자만 늘었다기보다 공개 체계가 더 촘촘해진 부분, 그리고 실제로 빨리 패치해야 하는 취약점이 섞여 있더라고요.

    특히 2024년 2월 13일에 kernel.org가 CVE Numbering Authority(CNA, CVE 번호 발급 권한 기관)로 추가된 뒤부터는 Linux 커널 취약점에 CVE가 더 체계적으로 붙기 시작했습니다. 거기에 CISA가 실제 악용 사례가 있는 Linux kernel 취약점들을 Known Exploited Vulnerabilities(KEV) 목록에 올리면서, “아, 이건 숫자 구경만 할 게 아니구나” 싶었거든요. 리눅스 보안은 결국 패치 속도만의 문제가 아니라, 노출면(Attack Surface, 공격 가능 면적)을 줄이는 운영 습관의 문제이기도 합니다.

    리눅스 서버 하드닝 전체 구조를 보여주는 아키텍처 이미지

    커널, SSH, 방화벽, MAC 정책, 패치 자동화, 검증 흐름까지 한눈에 보여주는 개요 이미지입니다.

    1. 최근 Linux CVE가 많이 보이는 이유부터 정리해보겠습니다

    쉽게 말해, 요즘 보이는 “급증”은 두 가지가 섞여 있습니다. 발견과 공개가 더 적극적이 된 점, 그리고 실제 운영자가 체감할 정도로 대응 압박이 커진 점이 같이 온 겁니다.

    구분 무슨 뜻인가 운영자가 봐야 할 포인트
    CVE 공개 체계 변화 kernel.org가 2024-02-13부터 CNA 역할 수행 이전보다 커널 취약점이 더 잘 드러날 수 있음
    실제 악용 사례 CISA가 Linux kernel CVE를 KEV에 추가 패치 우선순위를 높게 잡아야 함
    자동화된 버그 탐지 fuzzing과 정적/동적 분석이 더 활발 작은 버그도 더 빨리 공론화됨

    여기서 중요한 포인트가 있습니다. CVE 숫자가 늘었다 = 리눅스가 갑자기 위험해졌다로 바로 연결하면 좀 단순합니다. 제가 직접 홈랩 커널 업데이트 흐름을 따라가 보니까, 예전엔 배포판 공지 뒤에 숨어 지나가던 수정이 이제는 CVE로 더 명확하게 드러나는 경우도 꽤 있더라고요. 반대로, KEV에 들어간 건 진짜 우선순위가 다릅니다. 이건 “나중에 점검”이 아니라 즉시 확인 쪽입니다.

    2. 리눅스 서버 하드닝 체크리스트, 우선순위는 이렇게 잡으시면 됩니다

    저는 보통 패치, 접근 통제, 권한 축소, 관측성 순으로 봅니다. 이유는 간단하거든요. 멋진 보안 솔루션보다 먼저, 뚫릴 구멍을 줄이는 게 훨씬 싸고 빠릅니다.

    1. 커널과 패키지 업데이트 기준선 만들기: 지금 어떤 커널을 쓰는지, 보안 업데이트가 몇 건 밀렸는지 숫자로 확인합니다.
    2. SSH 노출면 줄이기: 비밀번호 로그인, root 직접 로그인, 불필요한 포트 노출을 먼저 줄입니다.
    3. 방화벽 기본 정책 정리: 허용 목록(Allowlist, 허용 대상만 열기) 방식으로 바꿉니다.
    4. SELinux/AppArmor 같은 MAC 적용: 뚫려도 옆으로 번지는 걸 막습니다.
    5. systemd sandboxing: 서비스 단위로 권한을 더 잘게 자릅니다.
    6. 감사 로그와 검증 루틴: 적용 후 확인하지 않으면 하드닝이 아니라 기분만 좋아지는 설정이 됩니다.

    3. 실전 구현 1단계: 패치 상태와 커널 노출 범위부터 확인합니다

    처음엔 이게 뭔가 싶었는데, 결국 출발점은 단순합니다. 무엇이 돌아가고 있는지 알아야 CVE 대응도 빠릅니다. 아래 명령은 제가 새 서버 잡으면 거의 습관처럼 먼저 칩니다.

    uname -r
    cat /etc/os-release
    ss -tulpn
    systemctl --failed
    

    uname -r은 현재 커널 버전, ss -tulpn은 외부에 열려 있는 포트와 프로세스를 같이 보여줍니다. 여기서 예상 밖 포트가 보이면, 그 서버는 이미 서버 보안 강화 대상입니다.

    Debian/Ubuntu 계열이면 보안 업데이트 확인은 이렇게 시작하시면 됩니다.

    sudo apt update
    apt list --upgradable
    sudo unattended-upgrades --dry-run -d
    

    RHEL 계열은 보통 이렇게 봅니다.

    sudo dnf check-update
    sudo dnf updateinfo list security
    

    Ubuntu를 쓰신다면 Livepatch(재부팅 없이 일부 커널 보안 수정 적용)도 검토할 만합니다. 다만 Canonical 문서 기준으로 Livepatch만 믿고 장기간 재부팅을 미루면 안 됩니다. 지원되는 커널 ABI 범위와 재부팅 주기가 따로 있거든요. 실제로 써보니까 편하기는 한데, 이것도 결국 정식 커널 교체를 완벽히 대체할 수는 없더라고요.

    4. 실전 구현 2단계: SSH와 네트워크부터 조입니다

    제가 제일 먼저 손대는 부분입니다. CVE가 터졌을 때 제일 아쉬운 서버가 어떤 서버냐 하면, 패치가 늦은 서버보다도 불필요하게 다 열어둔 서버더라고요. 삽질 좀 했습니다 ㅎㅎ

    sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F)
    sudoedit /etc/ssh/sshd_config
    
    PermitRootLogin no
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    PubkeyAuthentication yes
    MaxAuthTries 3
    AllowUsers adminops
    

    적용 전에는 반드시 문법 검사를 하세요.

    sudo sshd -t && sudo systemctl reload sshd
    

    방화벽은 nftables 기준으로 아주 단순하게 시작하는 편이 좋습니다.

    sudo mkdir -p /etc/nftables
    sudoedit /etc/nftables.conf
    
    #!/usr/sbin/nft -f
    flush ruleset
    
    table inet filter {
      chain input {
        type filter hook input priority 0;
        policy drop;
        iif lo accept
        ct state established,related accept
        tcp dport { 22, 80, 443 } accept
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept
      }
    
      chain forward {
        type filter hook forward priority 0;
        policy drop;
      }
    
      chain output {
        type filter hook output priority 0;
        policy accept;
      }
    }
    
    sudo nft -f /etc/nftables.conf
    sudo nft list ruleset
    sudo systemctl enable --now nftables
    
    리눅스 서버 하드닝에서 SSH와 방화벽 정책을 설명하는 이미지

    SSH 접근 제한, 허용 포트 최소화, 상태 기반 방화벽 정책을 시각적으로 보여주는 이미지입니다.

    5. 실전 구현 3단계: SELinux, AppArmor, systemd sandboxing으로 한 번 더 막습니다

    Mandatory Access Control(MAC, 강제 접근 통제)은 초반엔 귀찮아 보여도, 사고 났을 때 진짜 값어치를 합니다. Red Hat 문서도 SELinux를 추가 보안 계층으로 설명하고 있고, Ubuntu 문서도 AppArmor를 경로 기반 MAC으로 안내합니다. 쉽게 말해 프로세스가 원래 해야 할 일만 하게 만드는 장치입니다.

    RHEL 계열에서는 SELinux 상태를 먼저 확인하세요.

    getenforce
    sestatus
    sudo setenforce 1
    

    Ubuntu 계열에서는 AppArmor 상태를 확인합니다.

    sudo apparmor_status
    sudo aa-enforce /etc/apparmor.d/*
    

    그리고 요즘 제가 자주 같이 보는 게 systemd-analyze security입니다. 서비스별 노출 점수를 빠르게 볼 수 있어서, 감으로 하드닝하는 느낌이 훨씬 줄어들더라고요.

    sudo systemd-analyze security nginx.service
    

    서비스 오버라이드(override)로 샌드박싱을 추가하는 예시는 아래처럼 시작하시면 됩니다.

    sudo systemctl edit nginx.service
    
    [Service]
    NoNewPrivileges=yes
    PrivateTmp=yes
    ProtectSystem=strict
    ProtectHome=yes
    PrivateDevices=yes
    RestrictSUIDSGID=yes
    LockPersonality=yes
    MemoryDenyWriteExecute=yes
    RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
    SystemCallArchitectures=native
    
    sudo systemctl daemon-reload
    sudo systemctl restart nginx
    sudo systemd-analyze security nginx.service
    

    이거 실제로 써보니까 꽤 좋더라고요. 다만 여기서 중요한 건, 서비스별로 필요한 권한이 다르다는 점입니다. DB나 백업 에이전트는 너무 세게 조이면 바로 깨집니다.

    6. 커널 노출면 줄이는 sysctl과 감사 로그도 같이 가야 합니다

    리눅스 서버 하드닝에서 빠지기 쉬운 게 커널 파라미터와 로그입니다. 공격 자체를 막는 것도 중요하지만, 이상 징후를 빨리 보는 것도 중요하거든요.

    sudoedit /etc/sysctl.d/99-hardening.conf
    
    net.ipv4.conf.all.accept_redirects = 0
    net.ipv4.conf.default.accept_redirects = 0
    net.ipv4.conf.all.send_redirects = 0
    net.ipv4.conf.default.send_redirects = 0
    net.ipv4.conf.all.rp_filter = 1
    net.ipv4.conf.default.rp_filter = 1
    net.ipv4.tcp_syncookies = 1
    kernel.kptr_restrict = 2
    kernel.dmesg_restrict = 1
    fs.protected_symlinks = 1
    fs.protected_hardlinks = 1
    
    sudo sysctl --system
    

    감사 로그(audit log)도 최소한은 잡아두는 편이 좋습니다.

    sudo apt install auditd -y || sudo dnf install audit -y
    sudo systemctl enable --now auditd
    
    sudo auditctl -w /etc/ssh/sshd_config -p wa -k ssh_config_change
    sudo auditctl -w /etc/sudoers -p wa -k sudoers_change
    sudo auditctl -w /usr/bin/sudo -p x -k sudo_exec
    

    여기서 정말 중요한 포인트예요. 로그는 쌓는 것보다 어떤 이벤트를 보면 위험 신호로 판단할지가 더 중요합니다. SSH 설정 변경, sudo 실행 급증, 예상하지 못한 서비스 재시작 같은 건 바로 알아채야 하거든요.

    리눅스 서버 하드닝에서 SELinux AppArmor 시스템 샌드박싱을 보여주는 이미지

    프로세스 권한 최소화와 서비스 격리를 여러 층으로 적용하는 장면을 표현한 이미지입니다.

    7. ⚠️ 실제로 자주 겪는 문제와 트러블슈팅

    하드닝은 설정 넣는 순간보다, 그 뒤에 안 깨지게 만드는 과정이 더 어렵습니다. 저도 처음엔 자신 있게 적용했다가 웹 서비스가 파일 못 읽어서 502 띄운 적 있습니다.

    • SELinux/AppArmor 적용 후 서비스 장애: 먼저 비활성화하지 말고 로그를 봅니다. SELinux는 /var/log/audit/audit.log, AppArmor는 journalctl -xe나 /var/log/syslog 쪽부터 확인하세요.
    • systemd sandboxing 후 서비스 기동 실패: ProtectSystem=strict, ProtectHome=yes가 자주 원인입니다. 서비스가 실제로 써야 하는 경로를 ReadWritePaths=로 열어줘야 할 수 있습니다.
    • SSH 설정 변경 후 원격 접속 끊김: 운영 중인 세션을 유지한 상태에서 새 세션으로 테스트하고, 가능하면 콘솔 접근 수단을 남겨두세요.
    • 방화벽 적용 후 내부 통신 장애: 모니터링, 백업, 노드 간 헬스체크 포트를 빼먹는 경우가 많습니다. 홈랩에서 Kubernetes 올릴 때 저도 이걸로 반나절 썼습니다.

    그래서 저는 항상 한 번에 다 바꾸지 않고, 서비스 하나씩 묶어서 적용합니다. 보안 체크리스트는 체크만 하면 끝나는 문서가 아니라, 배포 순서를 정리하는 운영 문서여야 하더라고요.

    8. 검증, 결과 확인, 그리고 다음 단계

    설정이 들어갔으면 반드시 검증해야 합니다. 아래 정도는 최소 루틴으로 가져가면 좋습니다.

    1. 커널/패키지 버전 확인: 패치 적용 전후 버전 차이를 기록합니다.
    2. 포트 노출 재검사: ss -tulpn 결과를 저장해 비교합니다.
    3. 서비스 샌드박스 점검: systemd-analyze security로 전후 점수를 비교합니다.
    4. 로그 확인: SELinux/AppArmor 거부 로그, audit 로그, 인증 로그를 같이 봅니다.
    5. 재부팅 리허설: 커널 업데이트 후 서비스가 정상 복구되는지 꼭 확인합니다.
    uname -r
    ss -tulpn
    sudo systemd-analyze security
    sudo journalctl -p warning -b
    sudo ausearch -k ssh_config_change
    

    제가 직접 해보니 가장 효과가 큰 건 화려한 솔루션이 아니라 패치 기준선 + SSH 제한 + 방화벽 기본 거부 + MAC + 서비스 샌드박스 이 5개였습니다. 드디어 됐다! 싶은 순간이 오긴 오는데, 사실 그 뒤가 더 중요합니다. 운영 환경은 계속 바뀌니까요.

    리눅스 서버 하드닝 적용 전후 결과를 보여주는 검증 이미지

    적용 전후 비교 결과를 대시보드 형태로 보여주는 검증 이미지입니다.

    정리: 지금 바로 다시 볼 체크포인트

    • 리눅스 서버 하드닝은 CVE 개수보다 노출면 축소가 핵심입니다.
    • kernel.org CNA 전환과 실제 악용 사례 공개를 보면, 공개량 증가와 실제 위험 신호를 구분해서 봐야 합니다.
    • CVE 대응은 패치만이 아니라 SSH, nftables, SELinux/AppArmor, systemd sandboxing까지 묶어서 봐야 합니다.
    • 검증 없는 하드닝은 절반짜리입니다. 적용 후 로그와 서비스 상태를 꼭 확인하세요.

    다음 글에서는 systemd 서비스별 하드닝 템플릿을 좀 더 깊게 다뤄볼 예정입니다. 이전 글에서 다뤘던 로그 수집 파이프라인이 있으시면 그쪽과 묶어서 보셔도 좋고요.

    패치, 접근 통제, MAC, 샌드박스, 로그 검증을 우선순위별로 정리한 요약 이미지입니다.

    참고한 공개 자료

  • [Linux] SSH 하드닝 실전 가이드: 무단 접근 방어 5단계 보안 강화

    [Linux] SSH 하드닝 실전 가이드: 무단 접근 방어 5단계 보안 강화

    SSH 하드닝 실전 가이드: 무단 접근 방어 5단계 보안 강화

    홈랩이든 업무 서버든, 인터넷에 붙어 있는 리눅스 서버라면 결국 한 번쯤은 SSH 보안 강화를 제대로 해야 할 순간이 옵니다. 저도 처음엔 “포트만 바꾸면 되지 않을까?” 싶었는데요, 실제로 운영하다 보니 그 정도로는 부족하더라고요. 특히 봇(bot, 자동화된 공격 도구)이 SSH 포트에 무차별 로그인 시도를 넣는 걸 보고 나서는 생각이 확 바뀌었습니다. 오늘은 제가 홈랩과 실제 운영 환경에서 반복해서 적용했던 SSH 하드닝(SSH Hardening, SSH 보안 강화) 방법을 기준으로, 무단 접근 방어를 위한 5단계 보안 강화 절차를 정리해보겠습니다.

    핵심은 복잡한 장비를 들이는 게 아니라, 기본 기능을 제대로 조합하는 겁니다. OpenSSH 설정, 공개키 인증, 접근 제한, 침입 시도 차단, 그리고 마지막 검증까지요. 혹시 아직도 비밀번호 로그인만 열어두고 계셨다면, 여기서 중요한 포인트! 오늘 글만 따라가셔도 리눅스 서버 보안 수준이 꽤 달라질 겁니다.

    SSH 보안 강화 전체 구조를 보여주는 다이어그램 이미지

    SSH 보안 강화의 전체 흐름을 한눈에 보여주는 개요 이미지입니다. 외부 공격 시도, 방화벽, 공개키 인증, 접근 제한, 로그 모니터링 순서를 시각화하면 이해가 훨씬 빠릅니다.

    1. SSH 하드닝이 정말 필요한 이유

    SSH(Secure Shell, 암호화된 원격 접속 프로토콜)는 서버 운영에서 거의 기본입니다. 문제는 이 기본이 공격자에게도 너무 잘 알려져 있다는 점이죠. 인터넷에 노출된 서버는 생각보다 빨리 스캔(scan, 포트 탐색) 대상이 됩니다. 제가 집에서 굴리던 작은 홈랩 서버도 공개 IP를 붙이고 나서 얼마 안 돼서 인증 실패 로그가 쌓이기 시작했거든요. 처음엔 “누가 내 서버를 보겠어” 했었는데, 봇은 그런 감정이 없습니다 ㅎㅎ 포트가 열려 있으면 그냥 때려봅니다.

    쉽게 말해 SSH 하드닝은 문에 자물쇠 하나 다는 수준이 아니라, 현관 비밀번호를 바꾸고, 출입 가능한 사람을 줄이고, 이상 행동이 보이면 자동으로 막는 작업입니다. 이걸 해두면 무차별 대입 공격(brute-force attack, 비밀번호 반복 추측), 계정 탈취 시도, 설정 실수로 인한 노출 위험을 꽤 줄일 수 있습니다.

    2. SSH 보안 강화의 핵심 개념

    SSH 하드닝에서 중요한 건 한 가지 기술이 아닙니다. 여러 방어층(defense in depth, 다층 방어)을 쌓는 게 핵심입니다. 저도 예전엔 공개키 인증만 쓰면 끝인 줄 알았는데, 실제로 써보니까 접근 가능한 계정 제한이나 방화벽 정책까지 같이 묶어야 훨씬 안정적이더라고요.

    항목 기본 상태 SSH 보안 강화 후
    인증 방식 비밀번호 로그인 허용 공개키 인증 중심
    관리자 접속 root 직접 접속 가능 일반 계정 후 sudo 사용
    접근 범위 모든 계정 시도 가능 허용 계정만 접속
    네트워크 노출 전체 인터넷 개방 방화벽으로 IP 또는 포트 제어
    공격 대응 로그만 남음 자동 차단 도구 연동

    정리하면 이런 방향입니다.

    • 인증을 강하게: 비밀번호보다 공개키 인증(Public Key Authentication, 공개키 기반 인증)을 우선합니다.
    • 권한을 작게: root 직접 로그인 대신 일반 계정 + sudo 구조를 씁니다.
    • 노출을 줄이기: 방화벽(Firewall, 네트워크 접근 제어)과 AllowUsers 같은 SSH 설정으로 접속 대상을 좁힙니다.
    • 자동 대응하기: Fail2ban 같은 도구로 반복 공격을 차단합니다.
    • 검증까지 마무리: 설정 바꾸고 끝이 아니라 실제로 재접속과 로그 확인을 해야 합니다.

    3. 실전 구현: 무단 접근 방어 5단계

    여기부터는 제가 실제로 자주 쓰는 순서입니다. 중요한 건 기존 SSH 세션을 끊지 않은 상태로 하나씩 적용하는 겁니다. 저도 예전에 원격 서버에서 너무 자신 있게 설정 바꿨다가 그대로 문 닫힌 적 있습니다. 그날 진짜 식은땀 났습니다.

    3-1. 1단계: 공개키 인증으로 전환하기

    가장 먼저 할 일은 공개키를 준비하는 겁니다. 로컬 PC에서 키를 만들고, 서버에 배포합니다.

    ssh-keygen -t ed25519 -C "admin@homelab"
    ssh-copy-id admin@your-server-ip

    ed25519는 현재 OpenSSH 환경에서 널리 쓰이는 공개키 알고리즘 중 하나입니다. 생성이 간단하고 관리도 편합니다. 서버에 키가 들어갔으면 먼저 새 터미널에서 접속 테스트를 해보세요.

    ssh admin@your-server-ip

    비밀번호 대신 키로 잘 들어가면 첫 단계는 성공입니다. 여기서 중요한 포인트! 아직 비밀번호 로그인은 바로 끄지 마세요. 키 접속이 확실히 되는 걸 먼저 확인해야 합니다.

    3-2. 2단계: sshd_config 설정으로 기본값 강화하기

    다음은 SSH 데몬 설정 파일인 /etc/ssh/sshd_config를 조정합니다. 배포판마다 약간 다를 수 있지만, 핵심 방향은 거의 같습니다.

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

    제가 자주 넣는 기본 설정 예시는 이렇습니다.

    Port 22
    PermitRootLogin no
    PasswordAuthentication no
    PubkeyAuthentication yes
    ChallengeResponseAuthentication no
    UsePAM yes
    MaxAuthTries 3
    LoginGraceTime 30
    X11Forwarding no
    AllowUsers admin

    각 항목은 이렇게 보시면 됩니다.

    1. PermitRootLogin no: root 직접 로그인 차단
    2. PasswordAuthentication no: 비밀번호 로그인 비활성화
    3. PubkeyAuthentication yes: 공개키 인증 사용
    4. MaxAuthTries 3: 인증 시도 횟수 제한
    5. LoginGraceTime 30: 로그인 유예 시간 축소
    6. AllowUsers admin: 접속 가능한 계정 제한

    포트 변경은 선택 사항입니다. 예를 들어 22 대신 다른 포트를 쓰는 경우가 많죠. 다만 이건 보안의 본질이라기보다 노이즈 감소 효과에 가깝습니다. 즉, 스캐너 봇을 조금 피하는 정도라고 보시면 됩니다. 그래서 저는 포트 변경만 믿지는 않습니다.

    SSH 설정 파일 기반의 SSH 보안 강화 예시 이미지

    실제 SSH 설정 파일에서 어떤 옵션을 바꾸는지 보여주는 이미지입니다. PermitRootLogin, PasswordAuthentication, AllowUsers 같은 항목을 강조하면 독자가 따라오기 좋습니다.

    3-3. 3단계: 방화벽으로 SSH 접근 범위 줄이기

    SSH 하드닝에서 종종 놓치는 부분이 방화벽입니다. SSH 설정만 좋아도, 네트워크 레벨에서 아무나 접속 시도를 넣을 수 있으면 로그는 계속 더러워집니다. 저도 처음엔 이게 뭔가 싶었는데, 실제로 써보니까 방화벽을 함께 걸어두는 게 체감이 큽니다.

    Ubuntu 계열이라면 UFW(Uncomplicated Firewall, 간편 방화벽)로 쉽게 적용할 수 있습니다.

    sudo ufw default deny incoming
    sudo ufw default allow outgoing
    sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
    sudo ufw enable
    sudo ufw status verbose

    만약 고정 IP가 있다면 특정 관리 IP만 허용하는 방식이 가장 깔끔합니다. 고정 IP가 없으면 VPN(Virtual Private Network, 가상 사설망) 뒤에 SSH를 두는 방법도 좋고요. 이 부분은 다음 글에서 홈랩 기준으로 따로 다뤄볼 예정입니다.

    Rocky Linux나 RHEL 계열에서는 firewalld를 많이 씁니다.

    sudo firewall-cmd --permanent --add-service=ssh
    sudo firewall-cmd --reload
    sudo firewall-cmd --list-all

    여기서 한 가지. 포트를 바꿨다면 방화벽 정책도 꼭 같이 바꿔야 합니다. 예전에 SSH 포트는 바꿨는데 UFW 허용 포트는 그대로 둬서, 왜 접속이 안 되나 한참 삽질한 적 있습니다 ㅎㅎ

    3-4. 4단계: 반복 공격 자동 차단하기

    무차별 대입 공격은 로그를 보면 금방 티가 납니다. 이런 시도는 사람이 일일이 대응하기보다 자동 차단이 낫습니다. 이럴 때 많이 쓰는 게 Fail2ban입니다. 로그를 보고 일정 횟수 이상 실패하면 해당 IP를 잠시 차단합니다.

    sudo apt update
    sudo apt install fail2ban -y

    기본 설정은 배포판마다 다를 수 있어서, 보통은 로컬 설정 파일을 따로 둡니다.

    sudo vi /etc/fail2ban/jail.local
    [sshd]
    enabled = true
    port = 22
    logpath = %(sshd_log)s
    maxretry = 5
    findtime = 10m
    bantime = 1h

    설정 후에는 서비스를 재시작하고 상태를 확인합니다.

    sudo systemctl restart fail2ban
    sudo fail2ban-client status
    sudo fail2ban-client status sshd

    이거 진짜 편하더라고요. 특히 외부에 노출된 테스트 서버에서 체감이 큽니다. 다만 회사 VPN이나 NAT 환경처럼 여러 명이 같은 공인 IP를 쓰는 경우엔 차단 정책을 너무 공격적으로 잡지 않는 게 좋습니다.

    무단 접근 방어를 위한 SSH 하드닝 자동 차단 이미지

    인증 실패가 누적되면 IP가 자동 차단되는 과정을 보여주는 이미지입니다. 로그 분석, 차단 룰 적용, 일정 시간 후 해제 흐름을 함께 표현하면 좋습니다.

    3-5. 5단계: 로그와 실제 재접속으로 검증하기

    설정을 다 바꿨다면 마지막은 검증입니다. 여기서 대충 넘어가면 나중에 더 크게 고생합니다. 저는 항상 기존 세션은 유지한 채 새 터미널로 다시 붙어보고, 실패 로그와 서비스 상태까지 확인합니다.

    sudo sshd -t
    sudo systemctl restart sshd
    sudo systemctl status sshd
    sudo journalctl -u sshd -n 50 --no-pager

    배포판에 따라 서비스 이름이 ssh 또는 sshd일 수 있습니다. Debian/Ubuntu 계열은 ssh, RHEL 계열은 sshd인 경우가 많으니 현재 환경에 맞춰 확인해보세요.

    ssh -i ~/.ssh/id_ed25519 admin@your-server-ip

    검증할 때는 다음 항목을 체크합니다.

    • 공개키 인증으로 정상 접속되는지
    • root 직접 로그인은 막혔는지
    • 비밀번호 로그인 시도가 거절되는지
    • 허용하지 않은 계정은 접근 불가인지
    • 로그에 이상한 반복 시도가 남는지

    4. ⚠️ 주의사항과 트러블슈팅

    이 섹션은 진짜 경험에서 나옵니다. 문서만 보면 쉬워 보이는데, 실제 적용할 땐 자잘한 함정이 꽤 있습니다.

    4-1. 공개키 권한 문제

    키를 넣었는데도 접속이 안 되면 파일 권한부터 보세요. SSH는 권한이 느슨하면 키를 무시하는 경우가 있습니다.

    chmod 700 ~/.ssh
    chmod 600 ~/.ssh/authorized_keys

    서버 쪽 홈 디렉터리 권한까지 확인하면 더 좋습니다.

    4-2. 설정 테스트 없이 재시작한 경우

    이건 정말 위험합니다. 문법 오류가 있으면 SSH 서비스가 안 올라올 수 있습니다. 그래서 재시작 전에 꼭 아래처럼 테스트합니다.

    sudo sshd -t

    저도 예전에 옵션 하나 오타 내고 바로 재시작했다가 콘솔 붙을 때까지 식겁했습니다.

    4-3. AllowUsers 설정 실수

    AllowUsers는 강력하지만, 자기 계정을 빼먹으면 그대로 잠깁니다. 여러 관리자 계정을 운영한다면 미리 목록을 정리해두세요.

    4-4. 포트 변경 후 SELinux 또는 방화벽 누락

    RHEL 계열에서 SELinux(Security-Enhanced Linux, 보안 정책 프레임워크)를 쓰고 있다면, SSH 포트를 바꿀 때 추가 설정이 필요한 경우가 있습니다. 방화벽만 열고 끝이라고 생각하면 안 됩니다. 이 구간은 환경마다 차이가 있어서 변경 후 반드시 실제 접속 테스트를 해야 합니다.

    5. 검증 결과: 적용 후 무엇이 달라졌나

    SSH 보안 강화를 마치고 나면 가장 먼저 보이는 변화는 로그의 질이 달라진다는 점입니다. 무작정 인증 실패가 쌓이던 서버도, 허용 계정 제한과 공개키 인증을 적용하면 의미 없는 로그인 시도가 대부분 초기에 걸러집니다. Fail2ban까지 붙이면 반복적인 시도는 자동으로 정리되고요.

    제가 직접 해보니 운영 피로도가 줄어드는 게 제일 컸습니다. 예전엔 auth.log나 journalctl을 볼 때 괜히 찝찝했는데, 하드닝 후에는 “들어오려 해도 못 들어오게 해놨다”는 안정감이 생기더라고요. 물론 보안은 한 번 세팅했다고 끝이 아닙니다. 계정 관리, 패치, 키 교체 주기 같은 운영 습관까지 같이 가야 합니다.

    SSH 보안 강화 적용 후 검증 결과를 보여주는 이미지

    정상 접속은 성공하고, 반복 공격 IP는 차단되는 결과를 보여주는 이미지입니다. 운영자가 검증해야 할 포인트를 한 화면에 담는 구성이 좋습니다.

    6. 보안 조치별 효과와 주의사항

    보안 조치 효과 주의할 점
    공개키 인증 비밀번호 추측 공격 감소 키 백업과 권한 관리 필수
    root 로그인 차단 관리자 계정 직접 공격 표면 축소 sudo 가능한 일반 계정 필요
    AllowUsers 허용 계정만 접속 가능 계정 누락 시 본인도 차단
    방화벽 제한 접속 가능한 출발지 축소 원격 관리 IP 변경 시 규칙 수정 필수
    Fail2ban 반복 공격 자동 차단 공유 IP 환경에서는 과차단 주의

    결국 SSH 하드닝은 하나만 바꾸는 게임이 아닙니다. 네트워크, 인증, 계정, 로그가 함께 움직여야 리눅스 서버 보안 수준이 진짜 올라갑니다.

    7. 자주 묻는 질문

    Q1. SSH 포트만 바꾸면 충분한가요?

    아닙니다. 포트 변경은 노이즈를 줄이는 데는 도움이 되지만, 근본적인 SSH 보안 강화가 아닙니다. 공개키 인증, root 로그인 차단, 방화벽 제한을 같이 보셔야 합니다.

    Q2. 비밀번호 로그인을 바로 꺼도 되나요?

    새 터미널에서 공개키 접속이 정상 확인된 뒤에 끄는 걸 권장합니다. 저도 처음엔 성급하게 껐다가 다시 들어가지 못할 뻔했습니다.

    Q3. 홈랩에도 이 정도까지 해야 하나요?

    인터넷에 노출되어 있다면 네, 하는 게 맞습니다. 특히 포트 포워딩(port forwarding, 공유기 포트 개방)을 해둔 환경이라면 더 그렇습니다.

    8. 마무리: SSH 보안 강화, 기본이 최고

    오늘 정리한 5단계는 화려한 고급 보안 장비 이야기가 아닙니다. 하지만 실제 운영에서는 이런 기본기가 제일 오래 갑니다. 저도 13년 가까이 인프라 쪽 일을 하면서 느낀 게, 큰 사고를 막는 건 대단한 한 방보다 이런 기본 설정의 누적이더라고요. 처음엔 귀찮아 보여도 한 번 잡아두면 이후 운영이 훨씬 편해집니다. 드디어 됐다! 하는 순간이 옵니다.

    정리하면 이렇습니다.

    1. 공개키 인증으로 전환합니다.
    2. root 로그인과 비밀번호 로그인을 줄입니다.
    3. 허용 계정과 방화벽으로 노출 범위를 좁힙니다.
    4. Fail2ban으로 반복 공격을 자동 차단합니다.
    5. 마지막으로 반드시 재접속과 로그 검증까지 합니다.

    혹시 지금 운영 중인 서버에서 SSH 보안 강화를 손봐야 하는데 어디부터 건드려야 할지 막막하셨다면, 오늘 글 순서대로 하나씩 해보시면 됩니다. 다음 글에서는 VPN 뒤에 SSH 숨기기, 그리고 홈랩 기준 점프 서버(Jump Server, 중간 접속 서버) 구성도 다뤄볼 예정입니다. 이전 글에서 다뤘던 로그 모니터링과 함께 묶으면 더 탄탄해집니다.

    SSH 하드닝 5단계 요약 인포그래픽 이미지

    글 전체 내용을 5단계 체크리스트로 요약한 인포그래픽 이미지입니다. 마무리 섹션 직전에 배치해 독자가 핵심을 빠르게 복습할 수 있게 합니다.