fail2ban 으로 SSH 강화하기


만약 여러 가지 이유로 이동하면서 다양한 장소에서 인터넷을 통해 원격 서버에 접속해서 작업해야 할 일이 생긴다면 SSH 서비스를 공용으로 열수 밖에 없습니다.

하지만 이럴 경우 앞에서 설명한 추가 보안 조치를 적용해도 공용으로 서비스가 오픈되었으므로 외부에서 무작위로 로그인을 시도할 수 있습니다.


fail2ban 은 이렇게 무작위로 로그인을 시도할 경우 해당 IP 를 커널 방화벽에 등록하여 원천적으로 차단해 주는 제품으로 SSH 를 공용으로 열어야 하는 경우 보안 강화를 위해 꼭 설치하는 것을 권장합니다.


설치

fail2ban 은 파이썬으로 개발 되었으므로 2.6 또는 3.2 이상 파이썬이 설치되어 있어야 합니다.


RHEL/CentOS

CentOS 7 에 포함된 파이썬은 요구사항을 충족하며 리눅스 커널의 netfilter 방화벽과 IP 묶음 단위로 방화벽 정책을 수정할 수 있는 ipset 유틸리티를 필요로 하지만 yum 으로 설치시 자동으로 같이 설치합니다.


  1. CentOS 의 추가 저장소인 EPEL(Extra Packages for Enterprise Linux yum) 를 설치합니다.

    $ sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
  2. 이제 epel 저장소에서 fail2ban 을 설치합니다.

    $ sudo yum --enablerepo epel install fail2ban

Ubuntu

우분투는 다음 명령어로 fail2ban 을 설치합니다.

$ sudo apt install fail2ban


서비스 활성화

부팅시 자동으로 시작되도록 설정하고 fail2ban 을 구동합니다.

$ sudo systemctl enable fail2ban
$ sudo systemctl restart fail2ban


설정

fail2ban 의 기본 설정은 /etc/fail2ban/jail.conf  이며 설정을 수정할 필요가 있을 경우 이 파일보다는 개인화 설정 파일인 /etc/fail2ban/jail.local 을 사용하는 것이 좋습니다.

설정 파일은 Windows 의 ini 파일처럼 [항목명] 밑에 key=value 형식으로 기술하면 되며 # 은 주석이며 주요 설정은 [DEFAULT] 항목 밑에 기술하며 여러 기능중에 주요 설정 항목을 알아 봅시다.


ignoreip

ignoreip 에 설정된 IP 는 로그인을 실패해도 차단하지 않으며 기본 설정은 localhost 입니다. IP를 추가할 경우 jail.local 파일 의 [DEFAULT] 항목에 기술해 주면 되며 여러개를 기술할 경우 공백이나 , 로 구분해 주면 되며 아래는 로컬호스트와 192.168.10.x 대역은 차단하지 않는 설정입니다.


ignoreip = 127.0.0.1/8 192.168.10.0/24


bantime 

bantime 은 지정된 조건(아래에서 설명할 findtime, maxretry)에 따라 인증에 실패한 클라이언트를 차단할 시간을 초 단위로 지정하며 기본 설정은 600초(10분)입니다.


findtime, maxretry

findtimemaxretry 는 클라이언트를 차단하기 위한 조건을 지정하며 findtime 에 지정한 시간(초 단위)내에 maxretry 에 설정한 횟수만큼 인증을 실패하면 차단하게 됩니다.

즉 위 설정은 600초(10분) 내에 5번을 인증 실패할 경우 bantime 만큼 차단합니다.

특정 IP에서 차단후에도 지속적으로 인증을 시도할 경우 bantime 을 점점 길게 해서 시도 횟수를 줄이는 게 필요하지만 이 기능은 개발 버전(0.10.x)에만 반영되어 있고 0.9 버전에는 구현되어 있지 않습니다.

실제 운영 환경에서는 bantime 을 몇 시간 정도로 길게 주는 것이 보안상 유리합니다.


mail 알림

# 1
destemail = sysadmin@example.com


# 2
sender = fail2ban@my-server.com

# 3
mta = sendmail

# 4
action = %(action_mw)s

fail2ban 으로 차단한 정보를 메일로 전송할 경우 destemail 에 수신자 이메일 주소를  설정하고 sender 에는  "보낸 사람"의 정보를 설정합니다.


sender 항목에는 차단 메일을 보낼 발신자 주소를, mta(Mail Transfer Agent) 항목은 메일을 보내는 데 사용할 메일 전송 에이전트를 설정하며 기본은 sendmail 입니다.


중요한 부분은 action 항목으로 차단했을 때 실행할 액션을 의미하며 기본 설정은 아무 일도 안 하는 설정인 "action = %(action_)s" 입니다.

기본 설정으로는 차단 내용을 메일로 전송하지 않으므로 action_action_mwaction_mwl 로 지정해야 메일을 전송하며 차이는 아래와 같습니다.

  • action_mw : 메일을 전송하고 whois 로 IP 정보를 조회한 결과를 첨부
  • action_mwl : 메일을 전송하고 whois 로 IP 정보를 조회한 결과와 관련된 로그를 첨부


권장 설정은 다음과 같이 메일을 전송하고 whois 와 log 를 첨부하는 설정입니다.

action = %(action_mwl)s



whois 가 설치되지 않은 경우 $ sudo yum install whois 를 실행합니다.



개별 jail 설정

기본적으로 fail2ban 은 차단하지 않으므로 차단할 서비스를 [sshd] 처럼 항목명에 서비스를 등록하고 enabled = true 를 추가해 주면 차단됩니다.


포트 번호 변경

ssh 를 다른 포트로 사용할 경우 port 항목에 해당 포트를 기술해 주면 됩니다. 만약 ssh 가 여러 포트를 사용한다면 , 를 구분자로 해서 포트를 모두 기술하며 아래는 ssh 기본 포트와 10022 를 사용할 경우 설정입니다.

[sshd]
enabled = true
port = 10022
sshd jail 설정

 ssh 는 기본 포트 22로 구동하지 말고 다른 포트를 사용하는 걸 권장합니다.

최종 설정

이제 ssh 를 위한 최종 /etc/fail2ban/jail.local 파일을 완성해 보면 아래와 같습니다.

[DEFAULT]

## 차단하지 않을 IP
ignoreip = 127.0.0.1/8 192.168.10.0/24

# 3시간 차단
bantime  = 10800

# 1분동안 maxretry(3회) 실패시 차단
findtime  = 60

# 최대 허용 횟수
maxretry = 3

# 메일 수신자, 다중 수신자는 지원 안 함 
destemail = sysadmin@example.com

# 메일 보낸 사람
sender = fail2ban@my-server.com

# 메일 전송 프로그램
mta = sendmail


# 차단시 whois 정보와 관련 로그를 첨부하여 메일 전송
action = %(action_mwl)s

# sshd 서비스 차단
[sshd]
enabled = true
port     = ssh, 10022


설정을 마쳤으면 서비스를 재시작하여 변경 사항을 반영합니다. 

$ sudo systemctl restart fail2ban

fail2ban 동작 로그는 /var/log/fail2ban.log 에 기록되므로 tail -f /var/log/fail2ban.log 명령어로 확인해 볼 수 있습니다.


이제 firewall-cmd 로 커널 방화벽 설정 규칙을 확인해 보겠습니다.

$ sudo firewall-cmd --direct --get-all-rules
ipv4 filter INPUT 0 -p tcp -m multiport --dports ssh -m set --match-set fail2ban-sshd src -j REJECT --reject-with icmp-port-unreachable
fail2ban이 추가한 firewall 설정 규칙

결과에 보이는 "--match-set fail2ban-sshd src" 는 ipset 그룹명이 fail2ban-sshd 인 source 에서 ssh 서비스로 전송한 패킷은 REJECT 하라는 의미입니다.


설정된 ipset 의 정보는 --list 옵션으로 확인할 수 있습니다.

$ sudo ipset --list    


Name: fail2ban-sshd
Type: hash:ip
Revision: 1
Header: family inet hashsize 1024 maxelem 65536 timeout 10800
Size in memory: 16592
References: 1
Members:
192.168.58.1 timeout 89
ipset 정책 목록

이제 fail2ban-sshd 규칙의 Header 항목에 있는 "timeout 10800 에 따라 인증에 실패한 IP 는 3시간 동안 차단됩니다.


전체 차단 정보는 fail2ban 의 클라이언트 유틸리티인 fail2ban-client 명령어를 통해서 확인해 볼 수 있습니다.

$ sudo fail2ban-client status sshd




Status for the jail: sshd
|- Filter
|  |- Currently failed: 1
|  |- Total failed:     8
|  `- Journal matches:  _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
   |- Currently banned: 0
   |- Total banned:     2
   `- Banned IP list:
fail2ban 차단 정보 확인



Ref