[서버 보안] 서버 보안 설정하기

Bulgogi-Pizza·2025년 1월 27일

웹 서버 구축

목록 보기
15/16

소 잃지 않고 외양간 고치기

로컬 서버를 구축할 때에는, NCP와 AWS에서 제공하는 ACG, Network ACL등의 보안 서비스를 사용할 수 없어 보안상 취약점이 많을 수 밖에 없다. 특히, 외부 접근이 가능한 SSH, Docker, Jenkins, K8s에 대해 적절한 보안 구성을 하지 않으면 공격 대상이 되기 쉽다.

사실 이런 글을 쓰는 것도 내 서버에 어떤 보안이 사용되고 있는지 노출하는 것이기 때문에 좋을 것이 전혀 없다. 그래도 정보 전달은 하고 살아야지. 그것이 프로그래머니까 (끄덕)

보안 선택 사항

  1. SSH 보안
  • 포트 변경, 비밀번호 인증 비활성화, Root 로그인 비활성화
  • 공개 키 인증
  • Fail2Ban 설치
  • IP 접근 제한
  1. Firewalld 설정 강화
  • 불필요한 포트 차단
  • 포트 스캔 방지
  • 외부에서 접근이 필요 없는 서비스 차단
  1. Docker 보안
  • Docker 데몬 접근 제한
  • Docker 사용자 권한
  • Docker 컨테이너 권한 최소화
  1. Jenkins 보안
  • HTTPS 설정
  • IP 제한
  • Admin 계정 보안
  • 플러그인 관리
  1. K8s(Kubernetes) 보안
  • RBAC(Role-Based Access Control)
  • API 서버 보안
  • Etcd 보안
  • Pod 보안 정책
  • 네트워크 정책 설정
  1. 일반 보안 설정
  • 시스템 업데이트
  • 로그 모니터링
  • 침입 탐지 및 방지 시스템
  • 침입 탐지 도구 설치

Docker, Jenkins, k8s의 보안은 따로 다루는 것으로 하고, 오늘은 SSH 보안과 Firewalld 보안 설정, 일반 보안 설정을 진행해보자.

1. SSH 보안

내 서버는 SSH 연결을 허용하고 있기 때문에, 연결을 어렵게 하고, 기본 설정값을 변경하여 보안을 강화하려 한다.

1.1. 공개 키 세팅

sshd config를 수정하기 전에 공개 키부터 넣어두어야 한다.
비밀번호 기반의 인증을 막아두면, ssh-copy-id 명령에서 permission denied가 발생하기 때문이다.
비밀번호 기반의 인증을 막아둔 뒤에는 ssh 공개 키를 수동으로 넣어주어야 공개 키 인증이 된다.

SSH 키를 사용하기 위해 SSH키를 생성하고 SSH키를 복사한다.
해당 과정은 내가 접속할 기기(로컬 기기)에서 실행한다.
맥북의 경우 Unix 기반이기 때문에 ssh가 기본적으로 설치되어 있어 터미널에서 실행하면 되고, 안드로이드나 윈도우의 경우 Termius에서 Keychain - Generate Key 기능을 사용해 진행하면 된다.

# public, private key 생성
ssh-keygen -t rsa

# Enter file in which to save the key : 엔터 (디폴트 경로에 저장)
# Enter passphrase (empty for no passphrase) : passphrase(암호) 설정
# Enter same passphrase again : passphrase 재설정

# public key를 원격 호스트에 복사
ssh-copy-id user@your_server

# 처음 접근하는 경우 유저 비밀번호를 입력하라고 뜬다. 
# 비밀번호 입력 후 passphrase를 입력하면 로컬 서버에 ssh key가 복사 및 저장된다.

1.2. SSHD config 수정

SSH 기본 연결 포트인 22번 포트 대신 다른 포트를 사용하고, 비밀번호 인증과 Root 로그인을 비활성화 하자.
그리고 PubkeyAuthetication을 허용해주면 된다.

# ssh 설정 파일 열기
sudo nano /etc/ssh/sshd_config

설정 예시

# 포트 변경
Port 2222

# Root 로그인 비활성화
PermitRootLogin no

# 비밀번호 인증 비활성화
PasswordAuthetication no

# 공개키 인증 활성화
PubkeyAuthetication yes

설정을 완료했다면 :wq로 종료해준 뒤,

# ssh 데몬 재시작
sudo systemctl restart sshd

포트를 변경했다면, firewall에 해당 포트를 열어주고, 재시작한다.

# firewall에 포트 추가
sudo firewall-cmd --add-port=[PORT]/tcp --permanent

# firewall 서비스 재시작
sudo systemctl restart firewalld

1.3. Fail2Ban 설치

https://velog.io/@quitendexit/서버-생성-Rocky-8.10에서-GUI-원격-연결을-위해-XRDP-설치하기

위 글에서 Fail2Ban 설치와 규칙 설정에 대한 글을 다룬 적 있지만, 여기에 다시 구성하는 것이 좋을 것 같아 다시 작성한다.

접속 시도를 모니터링하고, 의심스러운 IP를 제한하기 위해 Fail2Ban을 설치한다.
주로 SSH 무차별 대입 공격(SSH Brute-Force Attack)에 대응할 수 있다.

1.3.1. Fail2Ban 설치 및 실행

# Fail2Ban 설치
sudo yum install fail2ban -y

# Fail2Ban을 시작프로그램으로 등록
sudo systemctl enable fail2ban

# Fail2Ban 서비스 시작
sudo systemctl start fail2ban

1.3.2.Fail2Ban 규칙 설정 방법

설치 후, Fail2Ban 규칙을 설정한다.
설정을 위한 기본 정보는 /etc/fail2ban/jain.conf에 파일 설정 예시가 나와있으며, man jail.conf 명령어로 매뉴얼을 열 수도 있다.

설정 파일 경로는 jail.local파일을 수정하거나 /etc/fail2ban/jail.d 디렉토리 밑에 *.conf 설정 파일을 만들어 저장한다.

필자는 SSH 연결과 XRDP 연결을 사용하기 때문에, 두 가지 접속에 대한 규칙을 정해줄 것이다.

1.3.2. Fail2Ban 규칙 설정하기 - 필터 파일 생성

먼저, sshd와 xrdp에 대한 필터 파일이 존재하는지 확인한다.

ls /etc/fail2ban/filter.d/sshd.conf
ls /etc/fail2ban/filter.d/xrdp.conf

만약 존재하지 않는다면 conf 파일을 직접 만들어 주어야 한다.
필자의 경우 sshd 파일은 존재했지만 xrdp 파일이 존재하지 않아 ChatGPT의 도움을 받아 만들어주었다.

sudo vi /etc/fail2ban/filter.d/xrdp.conf
[Definition]
# 인증 실패를 감지하는 failregex 정의
failregex = ^.* pam_unix\(xrdp-sesman:auth\): authentication failure.* rhost=<HOST>.*$
            ^.* xrdp-sesman\[.*\]: pam_authenticate.*failure.* rhost=<HOST>.*$

# 무시할 로그 패턴을 정의 (필요 시 추가)
ignoreregex =

1.3.3. jail conf 파일 생성

그 후, /etc/fail2ban/jail.d 디렉토리에 원하는 이름으로 *.conf 파일을 생성하고 설정 값을 입력한다.

sudo vi /etc/fail2ban/jail.d/default.conf
[DEFAULT]
# allowed ip
ignoreip = <허용할 ip를 입력하면 된다. 띄어쓰기로 구분한다.>

# during time to ban ip addr
bantime = <차단된 ip의 차단 시간을 지정한다. 기본값은 1h이다.>

# if n tries in m minutes, ban ip
findtime = <이 시간동안>
maxretry = <n번 시도하면 ip를 차단한다.>

[sshd]
# 필터 활성화
enabled = true
port = <sshd port>

[xrdp]
#필터 활성화
enabled = true
port = <xrdp port>
logpath = <로그파일 위치>

설정을 변경했으면 아래 명령어로 다시 읽고, 필터가 제대로 적용됐는지 확인할 수 있다.

sudo systemctl reload fail2ban
#or
sudo fail2ban-server reload

#필터 적용 확인
sudo fail2ban-client status

sshd, xrdp 가 jail list에 추가됐으면 성공한 것이다.
IP 접근 제한은 하지 않으려고 한다. 팀원들이 원하는 장소에서 자유롭게 접근할 수 있도록 하고 싶었고, SSH-key 인증이 있으니 그 이상은 현재 서비스 규모에 비해 오버 엔지니어링이라고 판단했다.

2. Firewalld 설정

그 다음은 방화벽 설정을 강화해보도록 하자.

2.1. 불필요한 포트 차단

먼저 불필요한 포트를 차단하고 필요한 서비스만 열어두기 위한 절차를 밟아보자.

# 방화벽 리스트를 확인한다.
sudo firewall-cmd --list-all

# 포트 열기
sudo firewall-cmd --add-port=[열어둘 포트]/[프로토콜 보통 tcp] --permanent

# 포트 닫기
sudo firewall-cmd --remove-port=[열어둘 포트]/[프로토콜 보통 tcp] --permanent

# 서비스 허용하기
sudo firewall-cmd --add-service=[service 이름, ssh] --permanent

# 서비스 차단하기
sudo firewall-cmd --remove-service=[service 이름, ssh] --permanent

# firewall 설정 변경 적용하기
sudo firewall-cmd --reload

서비스로 적용을 하든, 포트로 적용을 하든 원하는 포트와 서비스만 남도록 적용하면 된다.

3. 일반 보안 설정

3.1. 시스템 업데이트

대부분의 업데이트에는 보안 취약점에 대한 업데이트가 많이 포함되어있기 때문에, 이를 습관화 하는 것만으로도 보안에 큰 도움이 된다.

sudo dnf update
sudo yum update

3.2. 로그 모니터링

위의 fail2ban에서 설정했던 log 파일과 기본으로 제공하는 secure, messages 파일을 모니터링하면 침입 시도를 확인하고 방어할 수 있다.
모니터링할 중요한 로그 파일들로는

  • /var/log/secure
  • /var/log/messages
  • /var/log/docker.log
  • /var/log/jenkins/jenkins.log
    등이 있겠다.

3.3. 침입 탐지 및 방지 시스템

3.3.1. AIDE(Advanced Intrusion Detection Environment)

파일 시스템의 무결성을 검사하기 위해 다음 aide를 사용하면 파일 시스템의 위변조를 감지할 수 있다.

aide는 특정 디렉터리와 파일의 상태(크기, 권한, 해시값 등)를 데이터베이스에 저장한 뒤, 변경 사항을 감지하여 무결성을 확인한다.

# aide 설치
sudo yum install aide

# aide 초기 설정
# /var/lib/aide/aide.db.new.gz 라는 이름으로 데이터베이스 생성
sudo aide --init

# 데이터베이스 활성화
# 초기 데이터베이스를 AIDE가 사용할 수 있도록 활성화
sudo mv /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

# AIDE 구성 파일 설정
sudo nano /etc/aide.conf

설정 파일에서 검사할 디렉토리나 파일을 지정하려면

/etc FREQ
/var FREQ
/usr !M

등으로 지정하면 된다. FREQ는 파일의 크기, 권한, 해시값을 확인하는 명령어이고, !M은 파일의 수정 시간은 무시한다는 명령어이다.

!/var/log/lastlog

등과 같이 지정하면 특정 파일이나 디렉토리를 검사 대상에서 제외할 수 있다.

파일 시스템 검증은 다음 명령어로 확인할 수 있다.

sudo aide --check

파일 시스템 상태가 변경되었지만 허용 가능한 경우, 새로운 데이터베이스를 생성하여 업데이트한다.

sudo aide --init
sudo mv /var/lib/aide.db.new.gz /var/lib/aide/aide.db.gz

정기적으로 검사를 설정하려면 크론 잡(Cron Job)을 설정하면 된다.

sudo nano /etc/cron.daily/aide

파일에 다음 스크립트를 추가하면 매일 실행된다.

#!/bin/bash
/usr/sbin/aide --check

스크립트에 실행 권한을 부여한다.

sudo chmod +x /etc/cron.daily/aide

끝!

이정도면 일반적인 보안 설정은 완료했다고 보아도 될 것 같다.

추후에 침입 탐지 도구인 OSSEC나 Snort를 추가해도 좋을 것 같다.

profile
궁금증은 못참는 편, 궁금한 개발자

0개의 댓글