13년차의 서버실

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

[태그:] UFW

  • [보안] 리눅스 서버 보안 강화 체크리스트: SSH부터 시스템까지 10가지 필수 점검

    [보안] 리눅스 서버 보안 강화 체크리스트: SSH부터 시스템까지 10가지 필수 점검

    [보안] 리눅스 서버 보안 강화 체크리스트: SSH부터 시스템까지 10가지 필수 점검

    리눅스 서버 보안은 서버를 한두 대 운영할 때보다, 서비스가 붙고 계정이 늘어나기 시작할 때 더 절실해집니다. 저도 처음엔 “일단 서비스부터 띄우자” 모드로 달렸었는데요. 그러다가 SSH(에스에스에이치, 원격 접속 프로토콜) 설정 하나 느슨했던 탓에 로그가 지저분하게 쌓이고, 괜히 마음까지 불안해졌던 적이 있습니다. 그 뒤로는 새 서버를 올릴 때마다 꼭 보는 리눅스 서버 보안 체크리스트를 따로 만들어서 관리하고 있습니다. 오늘은 그 체크리스트를 기준으로 서버 하드닝, SSH 보안 강화, 그리고 시스템 전반에서 꼭 확인해야 할 10가지를 한 번에 정리해보겠습니다.

    새 서버 구축 시 SSH, 방화벽, 계정, 로그, 업데이트 순서로 점검하는 전체 흐름을 보여주는 개요 이미지입니다.

    1. 왜 리눅스 서버 보안 체크리스트가 필요한가

    쉽게 말해 체크리스트는 “내가 뭘 빼먹었는지”를 막아주는 안전장치입니다. 보안 사고가 꼭 대단한 취약점 때문에만 나는 건 아니거든요. 실제로는 기본 계정 방치, 불필요한 포트 오픈, 로그 미확인, 패키지 업데이트 누락 같은 아주 평범한 실수에서 시작되는 경우가 많습니다. 저도 홈랩에서 VM(버추얼 머신, 가상 머신)을 자주 갈아엎다 보니, 사람이 하는 일은 결국 반복 실수가 나오더라고요. 그래서 설정을 잘 아는 것보다 항상 같은 기준으로 확인하는 습관이 더 중요했습니다.

    특히 리눅스 보안 체크리스트는 아래 같은 상황에서 힘을 발휘합니다.

    • 새 VPS나 클라우드 인스턴스를 처음 올렸을 때
    • 운영 중인 서버를 다른 사람이 함께 관리하게 됐을 때
    • 서비스는 커졌는데 초기 설정이 그대로 남아 있을 때
    • 문제 없던 서버를 장기간 방치했다가 다시 점검할 때

    2. 서버 하드닝, 어디까지 해야 하나

    서버 하드닝(Server Hardening, 시스템을 더 단단하게 만드는 작업)은 무조건 복잡하게 가는 게 정답은 아닙니다. 과한 보안은 운영 피로도를 높이고, 반대로 너무 느슨하면 공격 표면(Attack Surface, 공격 가능한 면적)이 넓어집니다. 여기서 중요한 포인트! 운영 가능한 수준에서 꾸준히 유지되는 보안이 제일 현실적입니다.

    제가 실무와 홈랩에서 기준으로 삼는 우선순위는 이렇습니다.

    1. 원격 접속 통제
    2. 계정과 권한 최소화
    3. 네트워크 노출 최소화
    4. 업데이트와 취약점 패치
    5. 로그와 감사(Audit, 추적 기록) 확보
    6. 자동 차단과 복구 준비

    즉, 리눅스 서버 보안은 좋은 툴을 많이 붙이는 것보다, 기본기를 빠짐없이 닫아주는 쪽이 먼저입니다.

    3. 리눅스 서버 보안 체크리스트 10가지

    아래 10가지는 제가 새 서버를 만들 때 거의 습관처럼 점검하는 항목입니다. 배포판마다 명령은 조금 다를 수 있지만 원리는 같습니다.

    항목 왜 중요한가 우선도
    1. 패키지 업데이트 기본 취약점 패치 매우 높음
    2. SSH 포트/접속 정책 무차별 대입 공격 감소 매우 높음
    3. root 직접 로그인 차단 고위험 계정 보호 매우 높음
    4. 비밀번호 대신 키 인증 인증 강도 향상 매우 높음
    5. sudo 최소 권한 권한 오남용 방지 높음
    6. 방화벽 기본 정책 불필요한 포트 차단 매우 높음
    7. 불필요한 서비스 비활성화 공격 표면 축소 높음
    8. 로그/감사 활성화 이상 징후 추적 높음
    9. Fail2ban 등 자동 방어 반복 공격 완화 중간 이상
    10. 백업과 복구 점검 사고 이후 복원 가능 매우 높음

    4. 실전 구현: SSH 보안 강화부터 시스템 보안까지

    이제 실제로 손대는 순서입니다. Ubuntu 계열 기준으로 예시를 들겠지만, Debian이나 Rocky Linux 계열도 큰 흐름은 비슷합니다.

    4-1. 패키지 최신 상태 유지

    가장 먼저 하는 작업입니다. 별거 아닌 것 같아도 이걸 미루면 뒤에 하는 설정이 다 무색해질 수 있습니다.

    sudo apt update
    sudo apt upgrade -y
    sudo apt autoremove -y

    RHEL 계열이면 dnf update -y 또는 yum update -y 형태로 하시면 됩니다.

    4-2. SSH 설정 파일 점검

    /etc/ssh/sshd_config는 진짜 자주 봅니다. 처음엔 옵션 이름이 낯설어서 저도 헷갈렸는데, 몇 번 손으로 바꿔보니까 감이 오더라고요.

    sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
    sudo editor /etc/ssh/sshd_config
    Port 2222
    PermitRootLogin no
    PasswordAuthentication no
    PubkeyAuthentication yes
    ChallengeResponseAuthentication no
    UsePAM yes
    X11Forwarding no
    MaxAuthTries 3
    LoginGraceTime 30
    AllowUsers adminuser

    Port 변경은 보안의 전부가 아닙니다. 하지만 자동 스캔 로그를 줄이는 데는 체감이 꽤 됩니다. 다만 포트만 바꾸고 방심하면 안 됩니다. 핵심은 root 직접 로그인 차단과 키 기반 인증입니다.

    리눅스 서버 보안에서 SSH 보안 강화를 설명하는 키 기반 인증 구성 이미지

    sshd_config 핵심 옵션과 공개키 인증 흐름을 한눈에 보여주는 설명 이미지입니다.

    4-3. SSH 키 인증 적용

    로컬 PC에서 키를 만들고 서버에 공개키를 넣어줍니다.

    ssh-keygen -t ed25519 -C "admin@homelab"
    ssh-copy-id -p 2222 adminuser@server-ip

    서버에서 권한도 꼭 맞춰주세요.

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

    여기서 많이 하는 실수가 하나 있습니다. 키 로그인 테스트 전에 기존 세션을 끊어버리는 거예요. 저도 예전에 자신 있게 설정 저장했다가 접속 끊겨서 콘솔로 복구한 적 있습니다. 삽질 좀 했습니다 ㅎㅎ 기존 SSH 세션은 유지한 채로 새 터미널에서 먼저 접속 테스트하세요.

    4-4. sudo 권한 최소화

    모든 사용자를 관리자처럼 쓰는 순간, 사고 나면 추적도 어렵고 범위도 커집니다. 운영 계정은 분리하고, 필요한 사용자만 sudo 그룹에 넣습니다.

    sudo adduser adminuser
    sudo usermod -aG sudo adminuser
    id adminuser

    가능하면 공용 계정보다는 개인별 계정을 두는 게 좋습니다. 누가 어떤 작업을 했는지 남기기 쉽거든요.

    4-5. 방화벽(UFW 또는 firewalld) 적용

    리눅스 서버 보안에서 방화벽은 기본 중의 기본입니다. 외부에 꼭 필요한 포트만 열어두세요.

    sudo ufw default deny incoming
    sudo ufw default allow outgoing
    sudo ufw allow 2222/tcp
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw enable
    sudo ufw status verbose

    웹 서버가 아니라면 80, 443도 열 필요가 없겠죠. 제가 직접 해보니, “나중에 쓸 수도 있으니 열어두자”가 제일 위험한 생각이더라고요.

    4-6. 불필요한 서비스 정리

    열려 있지 않아야 할 서비스는 생각보다 많습니다. 먼저 현재 리스닝(Listening, 포트 대기) 상태를 확인합니다.

    sudo ss -tulpn
    sudo systemctl list-unit-files --type=service | grep enabled

    사용하지 않는 서비스는 비활성화합니다.

    sudo systemctl disable --now avahi-daemon
    sudo systemctl disable --now cups

    물론 어떤 서비스가 필요한지는 서버 역할에 따라 다릅니다. 그래서 무조건 지우기보다 “왜 필요한가”를 먼저 확인해야 합니다.

    4-7. 로그와 감사 설정

    보안은 막는 것도 중요하지만, 나중에 되짚어볼 수 있어야 합니다. 최소한 인증 로그와 시스템 로그는 꾸준히 확인해야 합니다.

    sudo journalctl -p warning -b
    sudo journalctl -u ssh --since today
    sudo tail -f /var/log/auth.log

    auditd(Audit Daemon, 감사 로그 데몬)를 쓰는 환경이라면 주요 파일 변경까지 추적할 수 있습니다.

    sudo apt install auditd -y
    sudo systemctl enable --now auditd
    리눅스 서버 보안 모니터링 화면, 방화벽 규칙과 로그 확인 예시 이미지

    허용 포트, 차단 트래픽, SSH 로그인 시도 로그를 함께 보여주는 운영 관점의 보안 모니터링 이미지입니다.

    4-8. Fail2ban으로 반복 공격 완화

    Fail2ban은 로그를 보고 반복 실패한 IP를 자동 차단하는 도구입니다. 엄청 화려한 건 아닌데, 실무적으로 꽤 든든합니다.

    sudo apt install fail2ban -y
    sudo systemctl enable --now fail2ban
    sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
    sudo editor /etc/fail2ban/jail.local
    [sshd]
    enabled = true
    port = 2222
    logpath = %(sshd_log)s
    maxretry = 5
    findtime = 10m
    bantime = 1h

    설정 후 상태를 확인합니다.

    sudo fail2ban-client status
    sudo fail2ban-client status sshd

    4-9. 자동 업데이트 검토

    운영 정책에 따라 다르지만, 보안 업데이트 자동 적용은 꽤 유용합니다. 다만 서비스 영향도를 꼭 고려하세요.

    sudo apt install unattended-upgrades -y
    sudo dpkg-reconfigure -plow unattended-upgrades

    저는 인터넷에 직접 노출된 소규모 서버는 자동 보안 업데이트를 선호하고, 민감한 서비스는 점검 창구를 따로 둡니다.

    4-10. 백업과 복구 테스트

    여기서 진짜 많이 놓칩니다. 백업이 있는 것과 복구가 되는 것은 다릅니다. 설정 파일, 애플리케이션 데이터, 데이터베이스 덤프를 분리해서 챙기고, 실제로 복원 테스트까지 해보셔야 합니다.

    sudo tar czf /backup/etc-$(date +%F).tar.gz /etc
    sudo rsync -av /backup backupuser@backup-host:/data/server1/

    시스템 보안은 사고를 막는 것만이 아니라, 사고 이후 버틸 수 있는 상태를 만드는 일입니다.

    5. ⚠️ 실제로 자주 겪는 문제와 해결 방법

    여기서는 제가 많이 겪었거나 주변에서 자주 보는 함정을 정리해보겠습니다.

    • SSH 포트만 바꾸고 방화벽에 새 포트를 안 열어둠: 설정 반영 후 바로 접속 불가가 납니다. SSH 재시작 전에 방화벽부터 먼저 수정하세요.
    • PasswordAuthentication no를 너무 빨리 적용: 공개키 권한이 틀리면 바로 잠깁니다. 새 세션으로 키 로그인 테스트 후 적용하세요.
    • Fail2ban이 로그 경로를 못 읽음: 배포판마다 SSH 로그 위치가 다를 수 있습니다. journalctl 기반인지 파일 기반인지 확인해야 합니다.
    • 불필요한 서비스라고 생각하고 무작정 disable: 의존 서비스까지 영향을 줄 수 있습니다. systemctl status와 사용 목적을 먼저 보세요.
    • 백업만 있고 복구 절차 문서가 없음: 복원 명령, 순서, 인증 정보 위치를 적어두지 않으면 실제 장애 때 더 혼란스럽습니다.

    혹시 이런 경험 있으신가요? 저는 예전에 원격지 장비에서 SSH와 UFW를 한 번에 바꾸다가, 접속이 안 돼서 콘솔 접속권 있는지부터 확인했던 적이 있습니다. 그 뒤로는 꼭 “현재 세션 유지, 새 세션 테스트, 그 다음 재시작” 순서를 지킵니다.

    6. 검증: 설정이 제대로 적용됐는지 확인하는 방법

    보안 설정은 했다고 끝이 아닙니다. 검증이 빠지면 체크리스트가 아니라 희망사항이 되거든요. 아래 명령으로 확인해보세요.

    1. SSH가 원하는 포트로만 열려 있는지 확인
    2. root 직접 로그인 차단 여부 확인
    3. 비밀번호 로그인 차단 여부 확인
    4. 방화벽 허용 포트 목록 확인
    5. Fail2ban 차단 상태 확인
    6. 로그에 반복 실패 흔적이 줄었는지 확인
    sudo ss -tulpn | grep ssh
    sudo sshd -t
    sudo ufw status numbered
    sudo fail2ban-client status sshd
    sudo grep "Failed password" /var/log/auth.log | tail

    외부 호스트에서 포트 스캔을 점검할 수도 있습니다.

    nmap -Pn server-ip

    정상이라면 꼭 필요한 포트만 보이고, 인증 실패 로그가 과하게 쌓이지 않으며, root 직접 로그인은 막혀 있어야 합니다. 이런 상태가 되면 드디어 됐다! 싶은 순간이 옵니다. 눈에 띄는 성능 향상은 없지만, 운영자 마음은 훨씬 편해집니다.

    리눅스 서버 보안 점검 완료 후 검증 결과를 보여주는 이미지

    포트 점검, Fail2ban 상태, 인증 로그 확인 결과가 정리된 검증 완료 이미지입니다.

    7. 리눅스 서버 보안 운영 팁

    한 번 설정해두고 끝나는 보안은 거의 없습니다. 운영하면서 계속 봐야 합니다.

    • 월 1회 이상 보안 점검 루틴 만들기
    • 사용하지 않는 계정 즉시 잠금 또는 삭제
    • 새 서비스 배포 시 포트와 권한부터 검토
    • 로그 보관 기간과 백업 정책 분리
    • 가능하면 테스트 서버에서 설정 검증 후 운영 반영

    이전 글에서 다뤘던 Docker 격리와 reverse proxy 구성도 함께 보면 더 도움이 됩니다. 다음 글에서는 리눅스 서버 보안의 연장선으로 침입 탐지(IDS, Intrusion Detection System)와 로그 중앙화 쪽도 다뤄볼 예정입니다.

    8. 자주 묻는 질문 FAQ

    SSH 포트 변경만으로 충분한가요?

    아닙니다. 포트 변경은 소음 감소에는 도움이 되지만 본질적인 인증 강화를 대신하진 못합니다. 공개키 인증, root 로그인 차단, 방화벽 정책이 함께 가야 합니다.

    비밀번호 로그인을 꼭 꺼야 하나요?

    가능하면 그렇습니다. 특히 외부 공개 서버라면 더 그렇고요. 다만 운영 절차상 필요한 경우엔 MFA(다중 인증)나 IP 제한 같은 추가 통제가 필요합니다.

    소규모 홈서버도 이렇게까지 해야 하나요?

    인터넷에 노출된다면 규모와 상관없이 기본 점검은 필요합니다. 실제로 홈랩이 더 느슨해지기 쉬워서 오히려 체크리스트가 더 유용합니다.

    9. 마무리: 기본기만 잘 지켜도 보안 수준이 달라집니다

    오늘 정리한 리눅스 서버 보안 체크리스트 10가지는 화려한 고급 기술이 아닙니다. 그런데 신기하게도, 사고 예방에는 이런 기본기가 제일 오래 갑니다. 저도 처음엔 서버 하드닝이 너무 번거롭게 느껴졌는데, 한 항목씩 루틴으로 만들고 나니까 운영이 훨씬 안정적이더라고요. 특히 SSH 보안 강화, 방화벽 정책, 로그 확인, 백업 검증 이 네 가지는 체감 효과가 큽니다.

    처음부터 완벽하게 다 하려고 하기보다, 오늘 바로 할 수 있는 것부터 적용해보세요. 공개키 로그인 전환, root 차단, UFW 기본 deny, 이 세 가지만 해도 출발은 충분합니다. 그리고 마지막으로, 꼭 기억하셔야 할 건 하나입니다. 보안은 설정이 아니라 습관입니다.

    리눅스 서버 보안 체크리스트 10가지를 요약한 인포그래픽 이미지

    10가지 필수 점검 항목을 한 장으로 정리한 요약 인포그래픽 이미지입니다.

  • [보안] 방화벽 설정, 이것만은 꼭! 10가지 필수 점검 항목

    [보안] 방화벽 설정, 이것만은 꼭! 10가지 필수 점검 항목

    [보안] 방화벽 설정, 이것만은 꼭! 10가지 필수 점검 항목

    서버를 올리고 포트만 열어둔 뒤 불안했던 경험, 아마 한 번쯤 있으실 겁니다. 저도 홈랩에서 테스트 서버를 굴리다가 방화벽 설정을 대충 해두고 넘어갔다가 나중에 로그를 보고 식은땀을 흘린 적이 있거든요. 방화벽 설정은 단순히 포트를 열고 닫는 작업이 아니라, 네트워크 보안의 기본선(baseline, 최소 보안 기준)을 만드는 일입니다. 이번 글에서는 실무와 홈랩에서 반복해서 확인하는 방화벽 보안 체크리스트 중심으로, 꼭 봐야 할 필수 점검 항목 10가지를 정리해보겠습니다.

    특히 이 글은 “방화벽 설정 후 뭘 먼저 확인해야 하지?” 하고 막막하신 분들을 위해 썼습니다. Linux 서버 기준 예시를 넣겠지만, 원칙 자체는 온프레미스(on-premise, 사내 구축 환경), 클라우드, 가상화 환경 모두에 그대로 적용됩니다.

    방화벽 설정이 적용된 홈랩 네트워크 아키텍처 이미지

    방화벽 설정 점검 항목이 DMZ, 내부망, 관리망으로 나뉘어 보이는 전체 개요 이미지입니다.

    1. 왜 방화벽 설정 점검은 항상 사고 전에 해야 할까요

    방화벽(Firewall, 트래픽을 제어하는 보안 장치)은 평소엔 조용합니다. 그래서 더 무섭습니다. 문제가 생기기 전까지는 존재감이 없거든요. 그런데 실제 장애나 침해사고 대응에서는 거의 항상 “이 포트 왜 열려 있었지?”, “관리 포트가 왜 외부에 노출됐지?” 같은 질문이 나옵니다.

    제가 직접 경험해보니 방화벽 설정 검토는 잘한 티는 안 나는데, 한 번 놓치면 문제가 됩니다. 특히 다음 상황에서 실수가 많이 나옵니다.

    • 테스트 서버를 운영 서버처럼 오래 끌고 갔을 때
    • 임시 오픈한 포트를 닫지 않았을 때
    • 소스 IP 제한 없이 관리 포트를 공개했을 때
    • 클라우드 보안 그룹(Security Group, 가상 방화벽)과 OS 방화벽 정책이 따로 놀 때

    여기서 중요한 포인트는 이것입니다: 방화벽은 “설정해뒀다”보다 “지금도 맞는 상태인지 확인하는 것”이 더 중요합니다.

    2. 좋은 방화벽 설정의 기본 원칙

    좋은 방화벽 설정은 결국 한 문장으로 정리됩니다: 필요한 통신만 허용하고, 나머지는 기본 차단(Default Deny, 기본 거부)하는 상태입니다. 이 원칙 하나만 제대로 잡아도 절반은 갑니다.

    방화벽 설정 점검 기준은 세 가지로 보면 편합니다.

    1. 누가 들어오나: 소스 IP, 네트워크 대역
    2. 어디로 들어오나: 목적지 포트, 서비스
    3. 왜 열어두나: 실제 업무 필요성, 운영 근거

    결국 방화벽 설정은 ACL(Access Control List, 접근 제어 목록)을 얼마나 명확하게 관리하느냐의 문제더라고요. “웹 서비스라서 80/443 허용”, “운영자만 SSH 22 접근”, “DB 3306은 앱 서버만 허용” 이런 식으로요.

    3. 방화벽 설정 점검 체크리스트: 필수 10가지 항목

    아래 10가지는 제가 서버 오픈 전에 거의 습관처럼 확인하는 필수 점검 항목입니다. 이 순서로 보면 빠르고, 빠뜨릴 것도 줄어듭니다.

    항목 무엇을 확인하나 핵심 이유
    1 기본 정책(Default Policy) 미정의 트래픽 차단
    2 허용 포트 최소화 공격 표면 축소
    3 관리 포트 접근 제한 SSH, RDP 등 보호
    4 소스 IP 대역 제한 불필요한 외부 접근 차단
    5 인바운드/아웃바운드 구분 양방향 정책 명확화
    6 불필요한 Any 허용 제거 과도한 허용 방지
    7 로그 활성화 추적과 감사 가능
    8 규칙 우선순위 확인 예상과 다른 매칭 방지
    9 예외 정책 문서화 운영 지속성 확보
    10 검증 명령과 정기 점검 설정 드리프트 방지

    보안 체크리스트는 화려할 필요 없습니다. 대신 반복 가능해야 합니다. 그리고 누가 봐도 같은 결론이 나와야 합니다.

    10가지 필수 항목을 짧게 풀어보면

    • 기본 정책은 deny: 허용보다 차단을 기본값으로 둡니다.
    • 포트는 최소한만: 서비스와 무관한 포트는 닫습니다.
    • 관리 포트는 외부 전체 공개 금지: Bastion(배스천, 중계 관리 서버)이나 VPN 뒤로 넣는 게 좋습니다.
    • 소스 제한: 가능하면 특정 사무실 IP나 관리망만 허용합니다.
    • 아웃바운드도 본다: 내부 서버가 외부로 아무 데나 나가는 것도 위험할 수 있습니다.
    • Any-Any 규칙 제거: 편하지만 위험합니다. 저도 급할 때 열었다가 나중에 후회했었습니다.
    • 로그는 꼭 남긴다: 침해 대응의 시작점입니다.
    • 우선순위 확인: 먼저 걸리는 규칙 때문에 뒤 규칙이 무의미해질 수 있습니다.
    • 예외는 기록: 왜 열었는지 안 적어두면 몇 달 뒤 아무도 모릅니다.
    • 정기 검증: 월 1회만 해도 효과가 큽니다.

    4. 실전 구현: Linux 서버의 방화벽 설정 기본

    여기서는 Ubuntu 계열에서 많이 쓰는 UFW(Uncomplicated Firewall, 간단 방화벽 관리 도구) 기준으로 보여드리겠습니다. 환경에 따라 nftables(리눅스 패킷 필터 프레임워크)나 iptables(전통적 패킷 필터)를 쓰실 수도 있는데, 원칙은 같습니다.

    1. 현재 열려 있는 서비스와 포트를 먼저 확인합니다.
    2. 기본 정책을 설정합니다.
    3. 서비스별 허용 규칙을 최소 권한으로 추가합니다.
    4. 로그와 검증을 수행합니다.
    ss -tulpn
    sudo ufw status verbose
    sudo ufw default deny incoming
    sudo ufw default allow outgoing
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp
    sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
    sudo ufw logging on
    sudo ufw enable
    sudo ufw status numbered

    위 예시는 정말 기본형입니다. 웹 서버라면 80/443만, SSH는 관리 IP에서만 허용하는 식이죠. 실제로 써보니까 처음부터 이렇게 보수적으로 잡는 게 나중에 훨씬 편하더라고요.

    서비스별 방화벽 설정 기준

    서비스 권장 접근 방식 비고
    SSH 특정 관리 IP만 허용 가능하면 VPN 뒤에서 접근
    HTTP/HTTPS 외부 공개 허용 리버스 프록시 뒤 구성 가능
    DB 포트 앱 서버 IP만 허용 인터넷 직접 공개 지양
    모니터링 포트 관리망만 허용 Prometheus 등 내부 수집 권장
    방화벽 설정에서 허용 포트를 구분한 서버 구성 이미지

    웹 포트와 관리 포트가 구분되어 보이는 실전 방화벽 설정 예시 이미지입니다.

    5. 더 실무적으로: 인바운드와 아웃바운드를 함께 점검하세요

    많이 놓치는 부분이 아웃바운드(Outbound, 서버에서 외부로 나가는 트래픽)입니다. 인바운드만 막아두면 끝이라고 생각하기 쉬운데, 실제 운영에서는 그렇지 않거든요. 만약 서버가 침해당했다면 외부 C2(Command and Control, 원격 제어 서버)와 통신을 시도할 수도 있습니다.

    그래서 저는 최소한 아래는 꼭 봅니다.

    • 패키지 저장소, 시간 동기화, 외부 API 등이 꼭 필요한 목적지인지
    • 내부 서버가 임의 포트로 외부에 나가고 있지 않은지
    • 백업, 모니터링, 알림 전송 경로가 정책과 충돌하지 않는지

    예를 들어 DB 서버는 인터넷으로 직접 나갈 이유가 거의 없습니다. 그런 서버는 아웃바운드 정책도 보수적으로 잡는 편이 낫습니다.

    sudo ufw default deny outgoing
    sudo ufw allow out 53
    sudo ufw allow out 123/udp
    sudo ufw allow out 443/tcp
    sudo ufw status verbose

    물론 이렇게 하면 처음엔 업데이트나 에이전트 통신이 막혀서 좀 삽질했습니다. ㅎㅎ 그래서 운영 서버에 바로 적용하기보다는, 먼저 필요한 통신 목록부터 뽑아보시는 걸 추천드립니다.

    6. 규칙 우선순위, 로그, 문서화: 운영 품질을 갈라놓는 세 가지

    방화벽 설정이 당장은 맞아 보여도, 시간이 지나면 예외 규칙이 늘어나면서 복잡해집니다. 그때 진짜 차이가 나는 게 규칙 우선순위(rule order), 로그(logging), 문서화(documentation)입니다.

    규칙 우선순위 확인하기

    특히 iptables나 클라우드 ACL에서는 먼저 매칭된 규칙이 적용되는 경우가 많습니다. 그래서 아래처럼 번호나 순서를 보고 정리해야 합니다.

    sudo ufw status numbered

    분명 차단 규칙을 넣었는데 접속이 되는 경험 있으신가요? 나중에 보면 위쪽에 더 넓은 허용 규칙이 먼저 있더라고요. 저도 처음엔 꽤 헷갈렸습니다.

    로그는 최소한 이 정도는 남기세요

    • 거부된 접속 시도
    • 관리 포트 접근 시도
    • 비정상적으로 반복되는 스캔 패턴

    로그가 있어야 Fail2ban 같은 자동 방어 도구를 붙이기도 쉽고, 나중에 보안 체크리스트 점검 결과를 설명하기도 편합니다.

    예외 정책은 꼭 기록하세요

    예를 들어 “협력사 고정 IP에서만 임시 허용, 만료일은 2026-08-03” 같은 걸 남겨야 합니다. 안 그러면 임시가 영구가 됩니다. 이거 진짜 자주 봅니다.

    방화벽 설정 결과를 모니터링하는 네트워크 보안 대시보드 이미지

    차단 로그와 관리 포트 접근 시도가 보이는 결과 검증용 모니터링 이미지입니다.

    7. ⚠️ 실제로 겪었던 문제들: 방화벽 트러블슈팅 포인트

    실무든 홈랩이든 방화벽 설정에서 가장 무서운 건 “서비스를 보호하려다가 내가 못 들어가는 상황”입니다. 저도 원격지 장비에서 SSH를 제 손으로 막아본 적 있습니다. “드디어 됐다!” 하고 나갔는데 다시 접속이 안 되더라고요.

    자주 겪는 문제 1: SSH를 너무 빨리 막음

    해결 방법은 간단합니다: 현재 접속 중인 세션을 유지한 상태에서 새 세션으로 재접속 테스트를 먼저 하세요.

    sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
    ssh user@server-ip

    새 세션 접속이 확인되기 전에는 기존 세션을 끊지 않는 게 안전합니다.

    자주 겪는 문제 2: 클라우드 방화벽과 OS 방화벽이 충돌

    AWS Security Group, GCP VPC Firewall, Azure NSG 같은 상위 정책과 OS 내부 정책이 둘 다 있으면, 어디서 막히는지 헷갈립니다. 이런 경우는 아래 순서로 확인하면 됩니다.

    1. 클라우드 보안 그룹에서 허용 여부 확인
    2. OS 방화벽에서 동일 포트 허용 여부 확인
    3. 서비스 데몬이 실제로 Listen(포트 대기) 중인지 확인
    4. 라우팅과 NAT(Network Address Translation, 주소 변환) 경로 확인
    ss -tulpn
    sudo ufw status verbose
    ip addr
    ip route

    자주 겪는 문제 3: IPv4만 보고 끝냄

    이 부분도 은근히 놓칩니다. IPv6이 활성화된 환경이라면 IPv4 규칙만 보고 안심하면 안 됩니다. 방화벽 설정 점검 시 IPv6 정책도 같이 봐야 합니다.

    8. 검증 방법: 설정했으면 반드시 확인하세요

    보안은 추측으로 끝내면 안 됩니다. 설정 후에는 꼭 검증해야 합니다. 저는 보통 서버 내부 확인과 외부 확인을 나눠서 봅니다.

    서버 내부에서 확인

    sudo ufw status verbose
    sudo ufw status numbered
    ss -tulpn
    • 열려 있어야 하는 포트만 열려 있는지
    • 허용 대상 IP가 의도와 맞는지
    • 기본 정책이 incoming deny인지

    외부에서 확인

    nc -vz server-ip 22
    nc -vz server-ip 80
    nc -vz server-ip 443

    관리 PC에서는 열려야 하고, 허용되지 않은 위치에서는 막혀야 정상입니다. 이 차이를 직접 확인해보면 훨씬 마음이 놓입니다.

    방화벽 설정 검증 체크리스트

    1. 기본 정책이 차단 중심인지 확인
    2. 불필요한 포트가 남아 있지 않은지 확인
    3. 관리 포트가 특정 IP로 제한됐는지 확인
    4. 로그가 남고 있는지 확인
    5. 예외 정책이 문서화됐는지 확인

    이 정도만 해도 네트워크 보안 수준이 꽤 안정됩니다. 화려한 장비보다 이런 기본기가 훨씬 오래 갑니다.

    방화벽 설정 필수 점검 항목을 요약한 네트워크 보안 이미지

    점검 전후 차이와 필수 점검 항목 10가지를 한눈에 보여주는 요약 이미지입니다.

    9. 정리: 방화벽 설정은 결국 운영 습관입니다

    정리하면 방화벽 설정의 핵심은 세 가지입니다: 기본 차단, 최소 허용, 지속 검증. 사실 특별한 비법은 없습니다. 대신 귀찮아도 반복해야 합니다. 저도 처음엔 규칙 몇 개 넣고 끝내려 했었는데, 시간이 지나 보니 결국 방화벽 보안 체크리스트를 얼마나 성실하게 돌리느냐가 차이를 만들더라고요.

    다음 글에서는 홈랩 기준으로 리버스 프록시(역방향 프록시)와 방화벽을 함께 구성하는 방법도 다뤄볼 예정입니다. 이전 글에서 다뤘던 로그 모니터링 내용과 연결해서 보시면 더 이해가 쉬우실 겁니다.

    자주 묻는 질문

    Q. 방화벽 설정은 서버마다 다르게 해야 하나요?
    네, 서비스 역할이 다르면 달라져야 합니다. 웹 서버, DB 서버, 모니터링 서버는 필요한 포트와 접근 주체가 다르거든요.

    Q. 클라우드 보안 그룹만 있으면 OS 방화벽은 안 써도 되나요?
    환경에 따라 다르지만, 저는 이중으로 두는 편입니다. 방어 계층(다층 방어)이 생기기 때문입니다.

    Q. 제일 먼저 바꿔야 할 한 가지는 뭔가요?
    기본 정책을 정리하고, SSH 같은 관리 포트의 소스 IP 제한부터 거세요. 체감 효과가 가장 큽니다.

    마지막으로 한 줄만 드리면, 방화벽 설정은 한 번 잘해두는 작업이 아니라 계속 점검하는 운영 루�ine입니다. 오늘 서버 한 대라도 체크리스트대로 다시 보시면 분명 놓친 게 하나쯤은 보일 겁니다.

  • [Proxmox] Proxmox LXC 컨테이너 보안 강화 체크리스트: 프로덕션 필수 설정

    [Proxmox] Proxmox LXC 컨테이너 보안 강화 체크리스트: 프로덕션 필수 설정

    Proxmox LXC 컨테이너 보안 강화 체크리스트: 프로덕션 필수 설정

    안녕하세요, 13년차의 서버실 주인장입니다. 오늘은 제가 홈랩에서, 그리고 실제 프로덕션 환경에서 Proxmox LXC 컨테이너를 운영하면서 뼈저리게 느꼈던 보안 강화에 대한 이야기를 해보려고 합니다. Proxmox LXC는 가볍고 빠르며 효율적이라서 저도 정말 애용하는 기술 스택인데요. 근데 이 편리함 뒤에는 간과하기 쉬운 보안 위협이 숨어있다는 사실, 혹시 알고 계셨나요? ⚠️

    처음에는 LXC가 워낙 가볍고 VM(Virtual Machine)만큼 복잡하지 않으니까, ‘이 정도면 괜찮겠지?’ 하고 안일하게 생각했던 적도 있습니다. 하지만 몇 번의 삽질과 실제 보안 사고(아찔한 순간이었죠… 휴)를 겪으면서, 컨테이너 환경도 강력한 보안 대책이 필수적이라는 것을 깨달았죠. 특히 프로덕션 환경에서는 더더욱 그렇습니다.

    오늘은 제가 직접 해보고 효과를 본 Proxmox LXC 컨테이너 보안 강화 체크리스트와 베스트 프랙티스를 여러분께 멘토처럼 알려드릴게요. 저처럼 삽질하지 마시라고, 제가 겪었던 시행착오와 해결 과정까지 솔직하게 공유해드리겠습니다! 자, 그럼 시작해볼까요? 🎉

    Proxmox LXC 컨테이너 보안 강화를 위한 주요 구성 요소를 보여주는 개요 다이어그램

    Proxmox LXC 컨테이너 환경에서 보안 강화를 위한 주요 구성 요소와 상호작용을 보여주는 다이어그램입니다.

    1. LXC 컨테이너, 왜 보안이 중요할까요? (개념 설명)

    Proxmox VE (Virtual Environment)에서 LXC (Linux Containers)는 도커(Docker) 컨테이너와 VM의 중간 지점에 있다고 생각하시면 편합니다. VM처럼 완벽한 격리는 아니지만, 도커보다는 더 OS에 가까운 환경을 제공하죠. 호스트 OS의 커널을 공유하기 때문에 가상화 오버헤드가 적고 성능이 좋습니다. 하지만 바로 이 커널 공유 때문에 보안에 취약점이 생길 수 있습니다.

    만약 하나의 LXC 컨테이너가 해킹당하면, 공격자가 호스트 OS의 커널에 접근할 수 있는 경로를 확보하게 될 수도 있습니다. 이는 곧 다른 컨테이너나 심지어 호스트 시스템 전체까지 위험에 빠뜨릴 수 있다는 뜻이거든요. 그래서 LXC 컨테이너는 VM만큼은 아니더라도, 최소한의 보안 장치들을 꼭 마련해두는 것이 좋습니다. 제가 처음 이걸 알았을 때, 등골이 오싹했더랬죠.

    2. 실전 구현: Proxmox LXC 보안 강화 체크리스트

    자, 이제 실질적으로 어떤 작업을 해야 하는지 단계별로 살펴보겠습니다. 제가 직접 구축하면서 가장 효과적이라고 느꼈던 방법들 위주로 구성했어요.

    2.1. ✅ Unprivileged 컨테이너 사용 (권한 분리)

    가장 기본 중의 기본입니다. Unprivileged container (비특권 컨테이너)는 컨테이너 내부의 root 사용자가 호스트 시스템의 root 권한을 가지지 못하도록 격리하는 방식입니다. 이게 핵심이에요. 만약 컨테이너가 Compromise (침해)되더라도, 공격자가 호스트 시스템에 직접적인 root 권한을 행사하기 어렵게 만드는 거죠.

    새 LXC 컨테이너를 생성할 때 Proxmox UI에서 ‘Unprivileged container’ 옵션을 체크하거나, CLI에서는 --unprivileged 1 옵션을 추가하면 됩니다. 저는 주로 CLI로 작업하기 때문에 다음과 같이 명령어를 사용합니다.

    pct create 101 local:vztmpl/debian-11-standard_11.0-1_amd64.tar.zst \
      --hostname my-secure-lxc \
      --password mysecretpassword \
      --memory 512 --swap 512 \
      --rootfs local-lvm:8 \
      --unprivileged 1 # 여기가 중요!

    이렇게 컨테이너를 생성하면 Proxmox가 자동으로 UID/GID 매핑 설정을 해줍니다. /etc/subuid와 /etc/subgid 파일에 호스트 시스템의 사용자 ID와 그룹 ID를 컨테이너 내부의 ID에 매핑하는 규칙이 추가되죠. 처음엔 이게 뭔가 싶었는데, 결국 호스트와 컨테이너 간의 권한 분리 장치더라고요.

    2.2. ✅ AppArmor 프로파일 적용 (강제적 접근 제어)

    AppArmor (앱아머)는 Linux 커널의 MAC (Mandatory Access Control, 강제적 접근 제어) 보안 시스템 중 하나입니다. 특정 프로그램이 접근할 수 있는 파일, 네트워크 리소스 등을 미리 정의된 프로파일에 따라 제한합니다. 쉽게 말해, ‘이 프로그램은 딱 이것만 할 수 있어!’라고 미리 정해주는 거죠.

    Proxmox는 기본적으로 LXC 컨테이너에 AppArmor 프로파일을 적용하지만, 더 세밀하게 제어하고 싶을 때가 있습니다. 예를 들어, 웹 서버 컨테이너가 불필요한 시스템 파일에 접근하는 것을 막는 것이죠.

    현재 AppArmor 상태는 다음 명령어로 확인할 수 있습니다.

    sudo aa-status

    특정 컨테이너나 서비스에 대한 커스텀 AppArmor 프로파일을 작성하여 /etc/apparmor.d/ 디렉토리에 넣고, sudo apparmor_parser -r /etc/apparmor.d/my-lxc-profile 명령어로 로드하면 됩니다. 제가 예전에 특정 서비스가 계속 죽어서 살펴보니, AppArmor 프로파일 때문에 필요한 파일에 접근을 못 하고 있더라고요. aa-complain 모드로 변경해서 로그를 보면서 디버깅했던 기억이 납니다.

    2.3. ✅ UFW를 이용한 네트워크 방화벽 설정

    컨테이너 내부에서도 방화벽을 설정하는 것은 정말 중요합니다. UFW (Uncomplicated Firewall)는 iptables의 복잡한 규칙들을 좀 더 쉽게 관리할 수 있게 해주는 도구입니다. LXC 컨테이너 내부에서 UFW를 설치하고 활성화하여, 필요한 포트만 외부에 노출하도록 설정할 수 있습니다.

    # 컨테이너 내부에서 실행
    sudo apt update
    sudo apt install ufw -y
    sudo ufw enable
    sudo ufw default deny incoming # 기본적으로 모든 외부 접근 차단
    sudo ufw allow ssh # SSH (22번 포트) 허용
    sudo ufw allow http # HTTP (80번 포트) 허용
    sudo ufw allow https # HTTPS (443번 포트) 허용
    sudo ufw status verbose

    이렇게 설정하면 컨테이너 내부에서 불필요한 포트가 열려 외부 공격에 노출되는 것을 방지할 수 있습니다. 혹시 LXC 안에서 서비스가 안 열려서 헤매신 적 있나요? 거의 십중팔구 UFW나 iptables 때문일 겁니다. 💡

    LXC 컨테이너 내부에서 UFW 명령어를 사용하여 네트워크 방화벽 규칙을 설정하고 확인하는 CLI 화면

    LXC 컨테이너 내부에서 UFW 명령어를 사용하여 네트워크 방화벽 규칙을 설정하고 확인하는 CLI 화면입니다.

    2.4. ✅ 정기적인 시스템 업데이트 및 패치

    너무 당연한 이야기 같지만, 잊지 않고 꾸준히 해야 할 가장 기본적인 보안 수칙입니다. OS와 설치된 모든 패키지를 최신 상태로 유지하여 알려진 취약점을 제거해야 합니다. 저는 unattended-upgrades를 설정해서 자동으로 업데이트되도록 해두는 편입니다. 물론 중요한 서비스는 수동으로 확인하고 적용하지만요.

    # 컨테이너 내부에서 실행
    sudo apt update && sudo apt upgrade -y
    
    # 자동 업데이트 설정 (옵션)
    sudo apt install unattended-upgrades -y
    sudo dpkg-reconfigure --priority=low unattended-upgrades

    2.5. ✅ SSH 보안 강화

    컨테이너에 접근하는 주요 방법 중 하나가 SSH입니다. SSH 보안을 강화하는 것은 컨테이너 전체의 보안을 높이는 데 큰 역할을 합니다.

    • 비밀번호 대신 키 기반 인증 사용: 가장 강력한 방법입니다.
    • 기본 SSH 포트 변경 (22번 외 다른 포트): 기본적인 스캐닝 공격을 회피할 수 있습니다.
    • Root 로그인 비활성화: PermitRootLogin no 설정.
    • 강력한 비밀번호 정책: (비밀번호 인증을 사용해야 할 경우)

    /etc/ssh/sshd_config 파일을 수정하여 위 항목들을 적용할 수 있습니다. 변경 후에는 꼭 sudo systemctl restart sshd 명령어로 SSH 서비스를 재시작해주세요.

    2.6. ✅ 로깅 및 모니터링

    아무리 보안을 강화해도 100% 완벽할 수는 없습니다. 중요한 것은 이상이 발생했을 때 얼마나 빨리 알아차리고 대응하느냐입니다. 컨테이너 내부의 로그를 중앙 집중식으로 관리하고, 주요 지표들을 모니터링하는 시스템을 구축하는 것이 좋습니다.

    • syslog-ng 또는 rsyslog 설정: 호스트 또는 별도의 로깅 서버로 로그를 전송.
    • Prometheus + Grafana: CPU, 메모리, 네트워크 트래픽 등 리소스 사용량과 서비스 상태 모니터링.
    • Fail2ban: SSH 무차별 대입 공격(Brute-force attack)과 같은 침입 시도를 자동으로 차단.

    물론 이 모든 걸 한 번에 다 하기는 어렵겠지만, 중요한 서비스부터 차근차근 적용해보는 것이 좋습니다. 제가 처음 홈랩을 구성할 때 로깅과 모니터링을 소홀히 했다가, 나중에 문제 터지고 나서야 뒤늦게 붙잡고 후회했던 적이 많거든요. 😅

    3. ⚠️ 주의사항 및 트러블슈팅: 제가 겪었던 삽질들

    위에서 말씀드린 내용을 적용하다 보면 분명히 문제가 발생할 수 있습니다. 저도 그랬거든요. 몇 가지 흔한 문제와 해결 방법을 공유해 드릴게요.

    • UID/GID 매핑 오류로 인한 컨테이너 시작 실패:

      • 증상: 컨테이너가 시작되지 않거나, 내부에서 파일 권한 문제로 서비스가 실행되지 않습니다. lxc-start 로그를 보면 Operation not permitted 같은 에러가 보입니다.
      • 해결: /etc/subuid와 /etc/subgid 파일에 올바른 매핑이 설정되어 있는지 확인합니다. pct create 시 --unprivileged 1 옵션을 제대로 사용했는지도 중요하고요. 이미 생성된 컨테이너라면 /etc/pve/lxc/VMID.conf 파일의 lxc.idmap 설정을 확인해야 합니다. 제가 이걸로 반나절을 날린 적이 있습니다.
    • AppArmor 프로파일로 인한 서비스 장애:

      • 증상: 특정 서비스가 AppArmor 정책 때문에 필요한 파일에 접근하지 못해 실행되지 않거나 비정상적으로 종료됩니다.
      • 해결: sudo aa-status로 AppArmor 상태를 확인하고, 문제가 되는 프로파일을 sudo aa-complain /etc/apparmor.d/my-lxc-profile 명령어로 complain 모드로 변경합니다. 이 모드에서는 정책 위반 시 로그만 남기고 차단하지 않으므로, 로그를 확인하여 필요한 접근 권한을 프로파일에 추가한 후 다시 sudo aa-enforce로 enforce 모드로 전환합니다.
    • UFW 포트 블로킹으로 인한 서비스 접근 불가:

      • 증상: 분명히 서비스는 실행 중인데 외부에서 접근이 안 됩니다.
      • 해결: 컨테이너 내부에서 sudo ufw status verbose 명령어로 현재 UFW 규칙을 확인합니다. 필요한 포트가 ALLOW 되어 있는지 확인하고, 만약 막혀있다면 sudo ufw allow [PORT] 명령어로 허용해줍니다.

    4. 검증 및 결과 확인

    보안 설정을 마쳤다면, 제대로 적용되었는지 확인하는 과정이 필수입니다.

    1. 컨테이너 권한 확인:

      # 호스트에서 실행
      lxc-info -n VMID -p

      lxc.idmap 설정이 올바르게 되어 있고, unprivileged 컨테이너로 생성되었는지 확인합니다.

    2. AppArmor 상태 확인:

      # 호스트에서 실행
      sudo aa-status

      적용된 프로파일이 enforce 모드로 잘 동작하는지 확인합니다.

    3. UFW 방화벽 규칙 확인:

      # 컨테이너 내부에서 실행
      sudo ufw status verbose

      필요한 포트만 열려 있고, 나머지는 잘 차단되어 있는지 확인합니다.

    4. 외부 포트 스캔:

      # 외부 시스템에서 실행 (예: 공격자 시점)
      nmap -sV -p- [LXC_컨테이너_IP]

      실제 외부에서 접근했을 때 불필요한 포트가 열려있지 않은지 nmap 같은 도구로 스캔해보는 것도 좋은 방법입니다. 저는 이 과정을 통해 ‘드디어 됐다!’ 하는 뿌듯함을 느꼈습니다. 😄

    LXC 컨테이너 보안 설정 완료 후 nmap 스캔 결과 및 AppArmor 상태를 보여주는 대시보드

    LXC 컨테이너 보안 설정이 완료된 후, nmap 스캔을 통해 열린 포트를 확인하고 AppArmor 상태를 점검하는 결과 화면입니다.

    5. 마무리하며: 지속적인 관심이 중요합니다

    오늘은 Proxmox LXC 컨테이너의 보안을 강화하기 위한 핵심 체크리스트를 저의 경험을 녹여가며 알려드렸습니다. Unprivileged 컨테이너, AppArmor, UFW, 정기 업데이트, SSH 보안 강화, 로깅 및 모니터링까지, 이 여섯 가지만 잘 지켜도 여러분의 LXC 컨테이너는 훨씬 더 안전해질 겁니다. 🛡️

    사실 보안은 한 번 설정하고 끝나는 것이 아니라, 지속적인 관심과 관리가 필요한 영역입니다. 새로운 취약점은 계속해서 발견되고, 공격 기술도 진화하거든요. 그러니 늘 최신 보안 동향에 귀 기울이고, 여러분의 시스템을 꾸준히 점검해주시길 바랍니다.

    다음 글에서는 LXC 컨테이너 환경에서 SELinux (Security-Enhanced Linux) 적용 방안이나, IDS/IPS (침입 탐지/방지 시스템)를 구축하는 방법에 대해 좀 더 깊이 있게 다뤄볼까 합니다. 혹시 궁금한 점이나 ‘이런 내용도 다뤄줬으면 좋겠다!’ 하는 아이디어가 있다면 언제든지 댓글로 남겨주세요! 여러분의 안전하고 튼튼한 서버실을 응원합니다. 💪

    Proxmox LXC 컨테이너 보안 강화를 위한 주요 체크리스트 항목들을 시각적으로 요약한 인포그래픽입니다.