Skip to main content
Summary

보안은 거창한 기술보다 노출을 줄이는 습관입니다

Linux 보안을 집에 비유하면 이해하기 쉽습니다. 좋은 자물쇠를 사는 것도 중요하지만, 쓰지 않는 문을 열어 두지 않고, 열쇠를 아무에게나 주지 않고, 누가 드나들었는지 확인하는 일이 먼저입니다. 서버도 같습니다. 강력한 도구를 설치하기 전에 누가 무엇을 할 수 있는지, 어떤 포트가 밖으로 열려 있는지, 업데이트와 백업이 유지되는지를 점검해야 합니다.

이 장의 기준은 최소 권한 원칙입니다. 필요한 사용자에게 필요한 권한만 주고, 필요한 서비스만 외부에 노출하며, 필요한 기간만 접근을 허용합니다. 개인 PC라도 인터넷에 연결되어 있고 SSH, 웹 서버, 파일 공유 서비스를 켜 두었다면 보안은 남의 일이 아닙니다.

먼저 현재 시스템을 확인합니다.

cat /etc/os-release
whoami
sudo -l
sudo ss -tulpen

sudo -l은 현재 사용자가 어떤 관리자 명령을 실행할 수 있는지 보여 줍니다. ss -tulpen은 열려 있는 TCP/UDP 포트와 관련 프로세스를 보여 줍니다. 일반 사용자로도 일부 정보는 볼 수 있지만, 프로세스와 사용자 정보를 정확히 보려면 sudo가 필요한 경우가 많습니다. 출력에서 0.0.0.0:22, *:80처럼 모든 주소에서 듣는 서비스는 외부 접근 가능성이 있습니다. 반대로 127.0.0.1:5432처럼 로컬 주소에만 묶인 서비스는 같은 컴퓨터 안에서만 접근할 수 있습니다.

Linux 보안의 기본기AI 생성 이미지

최소 권한으로 계정과 파일을 관리하기

sudo는 관리자 권한으로 명령 하나를 실행하는 도구입니다. 편리하지만 만능 열쇠이기도 합니다. 그래서 관리자 셸에 오래 머무르기보다 필요한 명령만 sudo 명령 형태로 실행하는 편이 안전합니다.

sudo -l
id
getent group sudo

Ubuntu/Debian 계열에서는 보통 sudo 그룹 사용자가 관리자 명령을 실행할 수 있습니다. Fedora/RHEL 계열은 wheel 그룹을 쓰는 경우가 많습니다.

# Ubuntu/Debian
getent group sudo

# Fedora/RHEL 계열
getent group wheel

사용자를 관리자 그룹에 넣는 일은 신중해야 합니다.

# Ubuntu/Debian
sudo usermod -aG sudo 사용자명

# Fedora/RHEL 계열
sudo usermod -aG wheel 사용자명

-aG에서 -a는 기존 그룹을 유지하면서 추가한다는 뜻입니다. -a 없이 -G만 쓰면 기존 보조 그룹 구성이 바뀔 수 있으므로 조심해야 합니다.

파일 권한도 같은 원칙으로 봅니다. 설정 파일은 보통 모두가 읽을 필요가 없고, 개인 SSH 키는 본인만 읽을 수 있어야 합니다.

ls -ld ~/.ssh
ls -l ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys 2>/dev/null
chmod 600 ~/.ssh/id_ed25519 2>/dev/null

chmod 777은 문제 해결용 만능 처방이 아닙니다. 모두에게 읽기, 쓰기, 실행을 허용하므로 임시로라도 습관처럼 쓰면 위험합니다. 권한 문제가 생기면 먼저 ls -l로 소유자와 권한을 읽고, 필요한 대상에게 필요한 권한만 더합니다.

공개 쓰기 권한이 있는 파일을 찾을 때는 다음처럼 점검할 수 있습니다.

find ~/linux-practice -type f -perm /002 -ls
find ~/linux-practice -type d -perm /002 -ls

/002는 기타 사용자에게 쓰기 권한이 있는 대상을 찾는 조건입니다. 실습 디렉터리에서는 괜찮을 수 있지만, 설정 파일이나 스크립트가 이렇게 열려 있다면 원인을 확인해야 합니다.

방화벽은 기본적으로 닫고 필요한 문만 엽니다

방화벽은 건물 출입문 관리표와 비슷합니다. 모든 문을 열어 둔 뒤 문제가 생기면 막는 방식보다, 기본적으로 닫아 두고 필요한 문만 명시적으로 여는 방식이 안전합니다.

Ubuntu 계열에서는 초보자가 ufw를 쓰기 쉽습니다. ufw는 복잡한 방화벽 규칙을 간단한 명령으로 관리하게 해 주는 도구입니다. 내부적으로는 배포판과 버전에 따라 iptables 또는 nftables 계층을 사용합니다. 초보자는 직접 iptables 규칙을 수정하기보다 ufw status로 정책을 읽고, ufw allow와 ufw deny로 관리하는 편이 안전합니다.

설치 명령은 배포판마다 다릅니다.

# Ubuntu/Debian
sudo apt update
sudo apt install ufw

# Fedora 계열: 기본은 firewalld를 많이 사용하지만 ufw도 설치 가능할 수 있습니다.
sudo dnf install ufw

# Arch 계열
sudo pacman -S ufw

Fedora와 RHEL 계열 서버에서는 firewalld가 기본 방화벽 도구인 경우가 많습니다. 이 책에서는 초보자가 이해하기 쉬운 ufw 흐름을 중심으로 설명하지만, 회사나 클라우드 환경에서 이미 firewalld를 쓰고 있다면 기존 정책을 확인한 뒤 운영 기준에 맞는 도구를 선택해야 합니다.

원격 서버에서 방화벽을 켤 때 가장 큰 위험은 스스로 SSH 접속을 막아 버리는 것입니다. 반드시 현재 SSH 포트를 먼저 확인합니다.

sudo ss -tulpen | grep ssh
sudo systemctl status ssh 2>/dev/null || sudo systemctl status sshd

Ubuntu에서 기본 SSH 포트가 22번이라면 다음 순서로 진행합니다.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw status verbose
sudo ufw enable
sudo ufw status verbose

웹 서버를 운영한다면 HTTP와 HTTPS만 추가로 엽니다.

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status numbered

특정 규칙을 지울 때는 번호를 확인한 뒤 삭제합니다.

sudo ufw status numbered
sudo ufw delete 번호

iptables는 Linux 방화벽 규칙을 다루는 전통적인 도구입니다. 지금은 nftables를 쓰는 시스템도 많지만, iptables -S는 여전히 현재 규칙을 읽는 데 도움이 됩니다. 직접 수정하기 전에는 읽는 명령부터 익힙니다.

sudo iptables -S
sudo nft list ruleset 2>/dev/null | less

SSH 원격 접속 보호하기

SSH는 서버의 현관문입니다. 인터넷에 공개된 SSH에는 자동화된 로그인 시도가 계속 들어올 수 있습니다. 그래서 비밀번호만 믿기보다 키 인증을 사용하고, root 직접 로그인을 막고, 실패가 반복되는 IP를 차단하는 방식으로 방어합니다.2

먼저 내 컴퓨터에서 키를 만듭니다.

ssh-keygen -t ed25519 -C "my-linux-key"

공개 키를 서버에 복사합니다.

ssh-copy-id 사용자명@서버IP

서버에서 새 터미널을 하나 더 열어 키 로그인이 되는지 확인합니다. 기존 접속을 끊지 말고 두 번째 접속으로 테스트해야 합니다.

ssh 사용자명@서버IP

그다음 서버의 SSH 설정을 백업하고 수정합니다.

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F)
sudo nano /etc/ssh/sshd_config

다음 항목을 확인하거나 추가합니다.

PubkeyAuthentication yes
PermitRootLogin no
PasswordAuthentication no

최근 배포판에서는 /etc/ssh/sshd_config.d/ 아래의 추가 설정 파일이 함께 적용될 수 있습니다. 설정이 예상과 다르게 동작한다면 sshd -T로 실제 적용값을 확인하는 것도 도움이 됩니다.

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

PasswordAuthentication no는 키 로그인이 확실히 되는 경우에만 적용합니다. 회사 VPN, 클라우드 콘솔, 복구 콘솔처럼 비상 접근 수단이 없는 서버라면 더 조심해야 합니다.

설정 문법을 검사합니다.

sudo sshd -t

오류가 없을 때만 SSH 서비스를 다시 읽게 합니다.

sudo systemctl reload ssh 2>/dev/null || sudo systemctl reload sshd

SSH 포트를 바꾸는 것은 필수 보안책은 아닙니다. 자동 공격 로그를 줄이는 효과는 있지만, 핵심은 키 인증과 root 로그인 차단입니다. 포트를 바꾼다면 방화벽 규칙을 먼저 열어야 합니다.

# 예: 2222번 포트를 쓸 때
sudo ufw allow 2222/tcp
sudo nano /etc/ssh/sshd_config
sudo sshd -t
sudo systemctl reload ssh 2>/dev/null || sudo systemctl reload sshd
ssh -p 2222 사용자명@서버IP

새 포트 접속이 확인된 뒤에만 예전 포트 규칙을 닫습니다.

fail2ban으로 반복 실패를 늦추기

ufw가 "어떤 문을 열 것인가"를 정한다면, fail2ban은 "수상한 방문자를 잠시 막는 경비원"에 가깝습니다. 로그를 감시하다가 SSH 로그인 실패가 일정 횟수 이상 반복되면 해당 IP를 방화벽 규칙으로 차단합니다.13

설치합니다.

# Ubuntu/Debian
sudo apt update
sudo apt install fail2ban

# Fedora 계열
sudo dnf install fail2ban

# RHEL 계열은 환경에 따라 EPEL 같은 추가 저장소가 필요할 수 있습니다.
sudo dnf install fail2ban

# Arch 계열
sudo pacman -S fail2ban

기본 설정 파일을 직접 고치기보다 로컬 설정 파일을 만듭니다.

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

[sshd] 항목을 찾아 활성화합니다.

[sshd]
enabled = true

필요하면 기본 구역에서 차단 시간을 조정합니다.

bantime = 10m
findtime = 10m
maxretry = 5

bantime은 차단 시간, findtime은 실패 횟수를 셀 시간 범위, maxretry는 허용할 실패 횟수입니다. 너무 강하게 잡으면 본인도 오타 몇 번으로 차단될 수 있습니다.

서비스를 켜고 상태를 확인합니다.

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

로그도 함께 봅니다.

sudo tail -f /var/log/fail2ban.log

Fail2ban은 완벽한 방어막이 아닙니다. 약한 비밀번호를 계속 허용한 채 fail2ban만 믿으면 안 됩니다. 키 인증, 방화벽, 업데이트와 함께 사용할 때 효과가 있습니다.

업데이트, 정리, 백업 검증을 루틴으로 만들기

보안 업데이트는 새 기능을 얻기 위한 일이 아니라 이미 알려진 구멍을 막는 일입니다. 한 달에 한 번이라도 정해진 시간에 업데이트하고 재부팅 필요 여부를 확인합니다.

# Ubuntu/Debian
sudo apt update
apt list --upgradable
sudo apt upgrade
sudo apt autoremove --dry-run

# Fedora/RHEL 계열
sudo dnf check-update
sudo dnf upgrade
sudo dnf autoremove

# Arch 계열
sudo pacman -Syu
pacman -Qtdq

autoremove나 불필요 패키지 삭제는 목록을 읽고 실행합니다. 서버에서 어떤 패키지가 어떤 서비스에 필요한지 모르면 바로 지우지 않습니다.

백업은 "파일을 복사했다"가 아니라 "복구할 수 있음을 확인했다"까지 포함합니다. 압축 백업이라면 목록을 확인합니다.

tar -tzf backup.tar.gz | head

rsync 백업은 먼저 모의 실행으로 바뀔 내용을 봅니다.

rsync -av --dry-run ~/important/ /mnt/backup/important/

가장 좋은 검증은 임시 디렉터리에 일부 파일을 복원해 열어 보는 것입니다.

tmpdir=$(mktemp -d)
tar -xzf backup.tar.gz -C "$tmpdir"
find "$tmpdir" -maxdepth 2 -type f | head

로그인 기록과 인증 실패 확인하기

보안은 설정하고 끝나는 일이 아닙니다. 기록을 읽어 이상 징후를 찾는 습관이 필요합니다.

현재 접속자는 다음처럼 확인합니다.

who
w

최근 로그인 기록은 last로 봅니다.

last -a | head -20

실패한 로그인 기록은 시스템마다 위치가 다릅니다.

# Ubuntu/Debian
sudo grep "Failed password" /var/log/auth.log | tail -20

# Fedora/RHEL 계열
sudo grep "Failed password" /var/log/secure | tail -20

# systemd journal 사용
sudo journalctl -u ssh --since today 2>/dev/null || sudo journalctl -u sshd --since today

lastb는 실패한 로그인 기록을 보여 주지만, 배포판 설정에 따라 파일이 없거나 권한이 필요할 수 있습니다.

sudo lastb -a | head -20

낯선 IP에서 실패가 많다면 바로 세 가지를 확인합니다. 첫째, SSH가 인터넷 전체에 열려 있는가. 둘째, 비밀번호 로그인이 켜져 있는가. 셋째, fail2ban이 동작 중인가.

sudo ufw status verbose
sudo grep -E '^(PasswordAuthentication|PermitRootLogin|Port)' /etc/ssh/sshd_config
sudo fail2ban-client status sshd

설정 파일에 주석 처리된 줄만 보이거나 결과가 없을 수 있습니다. 이때는 실제 적용값을 확인합니다.

sudo sshd -T | grep -E 'passwordauthentication|permitrootlogin|port'

짧은 실습 과제

  1. sudo ss -tulpen으로 현재 열린 포트를 확인하고, 어떤 서비스가 외부 주소에 묶여 있는지 적어 보세요.

  2. sudo -l과 id로 현재 사용자의 권한을 확인하세요.

  3. Ubuntu 계열 실습 환경이라면 ufw에서 기본 정책을 deny incoming, allow outgoing으로 설정하고 SSH 포트를 열기 전후의 상태를 비교하세요.

  4. SSH 서버가 있다면 키 로그인을 먼저 확인한 뒤 PermitRootLogin no를 적용하세요.

  5. last, journalctl, /var/log/auth.log 또는 /var/log/secure에서 최근 인증 실패 기록을 찾아보세요.

문제 해결 시나리오: SSH 실패 로그가 급증했다

상황을 가정해 보겠습니다. 서버 로그에 Failed password가 수백 줄 보입니다.

먼저 열린 포트를 확인합니다.

sudo ss -tulpen | grep ':22'
sudo ufw status verbose

SSH가 모든 주소에 열려 있다면 필요한 접근인지 판단합니다. 특정 사무실 IP에서만 접속한다면 다음처럼 제한할 수 있습니다.

sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
sudo ufw status numbered

그다음 SSH 설정을 확인합니다.

sudo grep -E '^(PasswordAuthentication|PermitRootLogin|PubkeyAuthentication)' /etc/ssh/sshd_config
sudo sshd -T | grep -E 'passwordauthentication|permitrootlogin|pubkeyauthentication'

키 로그인이 준비되어 있다면 비밀번호 로그인과 root 직접 로그인을 끕니다. 설정 변경 전 백업, 변경 후 sshd -t, 두 번째 세션 테스트를 반드시 지킵니다.

마지막으로 fail2ban 상태를 봅니다.

sudo systemctl status fail2ban
sudo fail2ban-client status sshd

공격 시도가 보인다고 해서 곧바로 침해를 뜻하지는 않습니다. 그러나 성공 로그인 기록에 낯선 IP가 있거나, 새 사용자가 생겼거나, 알 수 없는 프로세스와 포트가 열려 있다면 더 깊은 조사가 필요합니다. 실전 문제 해결 시나리오에서는 이런 단서를 모아 실제 문제를 좁혀 가는 절차를 다룹니다.

참고

1Protect SSH with Fail2ban on Ubuntu: Tutorial

2How to Secure SSH on Ubuntu/Debian (Keys, Fail2Ban, UFW)

3Configuring fail2ban and UFW: Basic Linux Server Protection in 30 Minutes

책 목록

처음부터 실전까지, 터미널이 두렵지 않은 Linux 활용법

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기