Fail2Ban이란?

Fail2Ban은 무작위 대입 공격을 방어하는 프로그램이다. ssh라면 비밀번호를 마구 집어 넣어 보는 공격이 해당할 것이고, apache 같은 웹서버라면 /phpMyAdmin-5/index.php?lang=en 같은 식으로 찔러 보는 경로에 대한 요청을 검토해 IP를 차단할 수 있다. 다만 웹서버에 대한 공격은 추가 필터를 만들어야 한다. 예컨대 방금 예로 든 phpMyAdmin 폴더를 찔러보는 경우, 실제로 같은 경로에 phpMyAdmin이 있다면 IP를 차단해서는 안 되니까 말이다.

아래는 Fail2Ban 사이트의 소개다.

Fail2Ban은 로그 파일을 검사해서 (예컨대 /var/log/apache/error_log) 악의적 징후를 보여 주는 IP를 차단합니다(너무 많은 로그인 실패, 취약점을 찾는 요청 등). 따라서 일반적으로 Fail2Ban은 특정 시간동안 IP 주소를 차단하도록 방화벽 규칙을 업데이트하는 데 사용됩니다. 다른 많은 동작을 설정할 수도 있지만 말입니다(예컨대 이메일 보내기 같은 것). 기본적으로 Fail2Ban은 다양한 서비스를 위한 필터를 포함하고 있습니다(아파치, courier, ssh 등).

Fail2Ban은 잘못된 인증 시도의 비율을 줄일 수 있지만 취약한 인증 방법을 사용하는 데 따르는 위험을 완전히 없애지는 못합니다. 진정으로 서비스를 보호하려면 반드시 2단계 인증이나 공개키/개인키 인증 매커니즘 둘 중 하나를 사용하도록 설정하십시오.

기본 설치

우분투라면 아래 명령을 쓴다. 이하 설명은 기본적으로 우툰부(혹은 데비안 계열)에 대한 설명이다. 레드햇 계열이라면 설정 파일 경로나 명령어 같은 게 다를 수 있다.

sudo apt install fail2ban

설치 직후에 작동을 바로 할 것이다. 그렇지 않다면 맨 밑에 에러 확인 방법을 써 놨으니 확인하라.

버전에 대한 이해

Fail2Ban은 0.9.0 버전 때 많은 것이 변했다. 이 설명은 0.9.0 이후 버전에 대한 설명을 주로 다룬다. 따라서 자신의 버전을 확인해 보자.

fail2ban-client --version
# 결과: Fail2Ban v0.11.1

내 경우 0.11.1이었다.

설정 파일 - 기본

설정에 대해 자세히 알고 싶으면 /etc/fail2ban/jail.conf 파일의 설정 예시와 설명을 보거나 man jail.conf 명령어로 매뉴얼을 연다.

설정 파일 경로는 두 가지 방법으로 만든다. jail.conf의 맨 앞부분에 이런 설명이 씌어 있다.

대부분의 경우 이 파일을 수정할 필요가 없습니다. 하지만 jail.local 파일이나, jail.d/ 폴더 밑에 각각의 .conf로 사용자 설정을 제공합니다.

  1. 기본적인 설정은 jail.conf에 돼 있다.
  2. 설정 내용을 덮어쓰려면 jail.local을 만들거나 jail.d/ 폴더에 .conf 확장자로 설정 파일을 만들어서 저장한다.

jail.d/ 폴더에는 이미 파일이 하나 있다. sudo cat /etc/fail2ban/jail.d/defaults-debian.conf 명령으로 파일의 내용을 살펴 보자.

[sshd]
enabled = true

우리는 여기서 한 가지 문법을 유추할 수 있는데, [sshd]는 감시할 필터 규칙을 의미하는 것이고, enabled = true 설정으로 이 필터를 활성화한다는 것이다.

상태 확인

자, Fail2Ban을 설치한 것만으로 서버는 시작된 것이다. Fail2Ban이 제대로 실행중인지는 아래 명령으로 확인해 보자.

sudo fail2ban-client status

결과는 아래와 같은 식이다.

Status
|- Number of jail:  1
`- Jail list: sshd

이로써 우리는 ssh에 대한 무작위 대입 공격을 막을 수 있게 됐다.

만약 실행중이라는 결과가 나오지 않는다면 맨 아래 에러 대응 방법을 써 놨으니 그걸 참고하라.

설정 파일 - 한 발짝 더

한 발짝 더 나가보자. jail.conf에 있는 설정들을 jail.local 파일을 만들어서 덮어쓸 수 있다.

jail.local 파일을 만들고 몇 가지 기본 설정을 수정할 생각이다. 선호하는 에디터로 jail.local 파일을 열고 아래 설정을 넣는다.

[DEFAULT]
# 차단하지 않을 IP
ignoreip = 127.0.0.1/8 ::1 8.8.8.8

# IP 차단을 얼마동안 할지. 기본값은 10m
bantime  = 31536000m

맨 앞에 우선 차단하지 않을 IP를 설정했다(ignoreip). 띄어쓰기로 IP를 여러 개 넣을 수 있다. 우선 로컬 접속 IP가 기본으로 들어가 있고(127.0.0.1/8::1), 내 IP를 8.8.8.8이라고 가정했다(8.8.8.8은 실제로는 구글이 사용하는 DNS 서버의 IP다). 자신의 IP를 알고 싶다면 구글에서 what is my ip로 검색해 본다. 구글이 바로 알려 준다.

두 번째 설정으로, 차단 시간은 기본 10분인데 1년으로 늘렸다.

아래는 차단에 관여하는 설정인데, 기본값을 그대로 뒀지만 복사해서 [DEFAULT] 밑에 넣어 두자. 나중에 수정하기 쉽게 하려는 조처다.

# findtime 동안 maxretry에 설정된 수만큼 문제가 발견되면 IP를 차단한다.
# 기본값은 10m
findtime  = 10m

# IP를 차단할 때까지 최대 실패 횟수. 기본값은 5
maxretry = 5

추가 필터 활성화

/etc/fail2ban/filter.d/ 폴더를 보면 여러 필터가 있다. jail.conf를 봐도 여러 필터가 있는 것을 확인할 수 있다.

jail.local을 열고 Fail2Ban이 기본으로 제공하는 아파치 필터를 넣어 보자. 아까 입력한 [DEFAULT] 섹션의 밑에 넣는다.

[apache-badbots]
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
enabled  = true
port     = http,https
logpath  = %(apache_access_log)s
bantime  = 48h
maxretry = 1

설정을 보면 bantimemaxretry를 필터별로 정의할 수 있다는 것을 알 수 있다.

logpath 설정 방법

logpath라는 새로운 설정값이 나타났는데, %(apache_access_log)s라는 모양을 볼 때 apache_access_log라는 변수를 사용한다는 것을 유추할 수 있다. 이 변수는 /etc/fail2ban/paths-common.conf 파일에 정의돼 있는데, apache_access_log = /var/log/apache2/*access.log라고 돼 있다.

그런데 만약 /var/log/apache2/ 폴더 밑에 여러 가상 호스트별로 폴더를 만들고 로그를 저장하는 경우라면 경로 설정을 어떻게 해야 할까? 아래처럼 하면 된다.

logpath = /var/log/apache2/*/*.log

로그패스가 제대로 들어갔는지 확인하려면, fail2ban-client status 필터명 명령을 사용하면 된다. 아래 설명하고 있으니 계속 따라가 보자.

현재까지 jail.local의 모습

이로써 지금까지 넣은 jail.local 파일은 아래와 같은 모양이 됐다.

[DEFAULT]
# 차단하지 않을 IP
ignoreip = 127.0.0.1/8 ::1 8.8.8.8

# IP 차단을 얼마동안 할지. 기본값은 10m
bantime  = 31536000m

# findtime 동안 maxretry에 설정된 수만큼 문제가 발견되면 IP를 차단한다.
# 기본값은 10m
findtime  = 10m

# IP를 차단할 때까지 최대 실패 횟수. 기본값은 5
maxretry = 5

[apache-badbots]
# 이메일 주소를 크롤링하는 스팸 로봇의 에이전트 문자열을 식별해 IP를 차단한다.
enabled  = true
port     = http,https
logpath  = %(apache_access_log)s
bantime  = 48h
maxretry = 1

설정 적용하기

설정을 변경했으면 다시 읽어야 한다. 아래 명령으로 한다.

sudo systemctl reload fail2ban

혹은 아래 명령으로 할 수도 있다.

sudo fail2ban-server reload

이제 필터가 제대로 적용됐는지 확인해 보자.

sudo fail2ban-client status

아래처럼 Jail list에 apache-badbots가 추가됐으면 성공한 것이다.

 $ sudo fail2ban-client status
Status
|- Number of jail:  2
`- Jail list: apache-badbots, sshd

개별 필터 확인하기

각 필터의 상태를 따로 확인할 수도 있다. 예컨대 sshd 필터의 상태만 보려면 뒤에 sshd를 붙인다. 그러면 해당 필터가 차단한 IP와 감시하고 있는 로그파일 정보를 볼 수 있다.

$ sudo fail2ban-client status sshd

Status for the jail: sshd
|- Filter
|  |- Currently failed: 3
|  |- Total failed:  765
|  `- File list:  /var/log/auth.log
`- Actions
   |- Currently banned: 26
   |- Total banned:  26
   `- Banned IP list: (생략)

현재 필터에 걸리는 게 3개, 지금까지 누적해서 걸린 게 765개, 감시하는 파일 경로가 나온다. 그리고 차단한 아이피 개수가 그 밑에 나온다. 차단한 IP의 목록도 나오는 것을 볼 수 있다.

사용자 설정 필터 만들어 넣기

Fail2Ban의 필터는 /etc/fail2ban/filter.d/ 폴더에 있다. 예컨대 apache-badbots의 설정은 /etc/fail2ban/filter.d/apache-badbots.conf에 있다. 내용은 다음과 같다.

# Fail2Ban configuration file
#
# Regexp to catch known spambots and software alike. Please verify
# that it is your intent to block IPs which were driven by
# above mentioned bots.


[Definition]

badbotscustom = EmailCollector|WebEMailExtrac|TrackBack/1\.02|sogou music spider|(?:Mozilla/\d+\.\d+ )?Jorgee
badbots = Atomic_Email_Hunter/4\.0|atSpider/1\.0|autoemailspider|bwh3_user_agent|China Local Browse 2\.6|ContactBot/0\.2|ContentSmartz|DataCha0s/2\.0|DBrowse 1\.4b|DBrowse 1\.4d|Demo Bot DOT 16b|Demo Bot Z 16b|DSurf15a 01|DSurf15a 71|DSurf15a 81|DSurf15a VA|EBrowse 1\.4b|Educate Search VxB|EmailSiphon|EmailSpider|EmailWolf 1\.00|ESurf15a 15|ExtractorPro|Franklin Locator 1\.8|FSurf15a 01|Full Web Bot 0416B|Full Web Bot 0516B|Full Web Bot 2816B|Guestbook Auto Submitter|Industry Program 1\.0\.x|ISC Systems iRc Search 2\.1|IUPUI Research Bot v 1\.9a|LARBIN-EXPERIMENTAL \([email protected]\.net\)|LetsCrawl\.com/1\.0 \+http\://letscrawl\.com/|Lincoln State Web Browser|LMQueueBot/0\.2|LWP\:\:Simple/5\.803|Mac Finder 1\.0\.xx|MFC Foundation Class Library 4\.0|Microsoft URL Control - 6\.00\.8xxx|Missauga Locate 1\.0\.0|Missigua Locator 1\.9|Missouri College Browse|Mizzu Labs 2\.2|Mo College 1\.9|MVAClient|Mozilla/2\.0 \(compatible; NEWT ActiveX; Win32\)|Mozilla/3\.0 \(compatible; Indy Library\)|Mozilla/3\.0 \(compatible; scan4mail \(advanced version\) http\://www\.peterspages\.net/?scan4mail\)|Mozilla/4\.0 \(compatible; Advanced Email Extractor v2\.xx\)|Mozilla/4\.0 \(compatible; Iplexx Spider/1\.0 http\://www\.iplexx\.at\)|Mozilla/4\.0 \(compatible; MSIE 5\.0; Windows NT; DigExt; DTS Agent|Mozilla/4\.0 [email protected]\.net|Mozilla/5\.0 \(Version\: xxxx Type\:xx\)|NameOfAgent \(CMS Spider\)|NASA Search 1\.0|Nsauditor/1\.x|PBrowse 1\.4b|PEval 1\.4b|Poirot|Port Huron Labs|Production Bot 0116B|Production Bot 2016B|Production Bot DOT 3016B|Program Shareware 1\.0\.2|PSurf15a 11|PSurf15a 51|PSurf15a VA|psycheclone|RSurf15a 41|RSurf15a 51|RSurf15a 81|searchbot [email protected]\.com|ShablastBot 1\.0|snap\.com beta crawler v0|Snapbot/1\.0|Snapbot/1\.0 \(Snap Shots, \+http\://www\.snap\.com\)|sogou develop spider|Sogou Orion spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sogou spider|Sogou web spider/3\.0\(\+http\://www\.sogou\.com/docs/help/webmasters\.htm#07\)|sohu agent|SSurf15a 11 |TSurf15a 11|Under the Rainbow 2\.2|User-Agent\: Mozilla/4\.0 \(compatible; MSIE 6\.0; Windows NT 5\.1\)|VadixBot|WebVulnCrawl\.unknown/1\.0 libwww-perl/5\.803|Wells Search II|WEP Search 00

failregex = ^<HOST> -.*"(GET|POST|HEAD).*HTTP.*"(?:%(badbots)s|%(badbotscustom)s)"$

ignoreregex =

datepattern = ^[^\[]*\[({DATE})
              {^LN-BEG}

# DEV Notes:
# List of bad bots fetched from http://www.user-agents.org
# Generated on Thu Nov  7 14:23:35 PST 2013 by files/gen_badbots.
#
# Author: Yaroslav Halchenko

그런데 apache-badbots 필터는 너무 낡았다. 거의 걸리는 놈이 없다. User Agent String은 쉽게 속일 수 있기 때문이다. 따라서 URL 요청에 따른 악의적 공격을 가려내는 것이 필요할 텐데, 자신의 서버에 따라서 악의적 공격을 가려내야 한다.

내 경우 phpMyAdmin을 사용하지 않으므로 phpMyAdmin 폴더를 요청하는 IP는 악의적 의도를 가졌다고 생각할 수 있다. (다시 말하지만, 서버 상황에 따라 악의적 요청이 무엇인지 서버 관리자가 가려야 한다.)

필터 설정을 모아 두는 폴더에 파일을 만들자. /etc/fail2ban/filter.d/apache-custom.conf 파일을 만들고 선호하는 에디터로 연다. (주의!: 필터명은 24자를 넘으면 안 된다.)

필터 파일의 규칙은 맨 위에 [Definition]이라고 적고, failregex 변수와 ignoreregex 변수를 설정해 주는 것이다. 설정을 위해 변수도 사용할 수 있다.

나는 phpmyadmin이나 phpMyAdmin이 들어간 URL을 요청하는 경우 차단할 생각이다. 그러면 아래처럼 쓰면 된다.

[Definition]
failregex = failregex = ^<HOST> -.*"(GET|POST|HEAD) /[^ ]*?(?:phpmyadmin|phpMyAdmin)[^ ]*? HTTP.*".*$
ignoreregex =

아파치 로그 규칙에 맞춰서 정규식을 썼고, 핵심부는 phpmyadmin|phpMyAdmin 부분이다. |가 “또는”이라는 뜻이다.

자, 차단할 문자열이 늘어날수록 복잡하니까 phpmyadmin|phpMyAdmin 부분을 변수화하자. 아래처럼 하면 된다.

[Definition]
badrequests = phpmyadmin|phpMyAdmin
failregex = failregex = ^<HOST> -.*"(GET|POST|HEAD) /[^ ]*?(?:%(badrequest)s)[^ ]*? HTTP.*".*$
ignoreregex =

이제 차단하고 싶은 URL 호출이 생길 때마다 badrequests에 추가해 주면 된다. 예컨대 arm63.php라는 파일은 내 서버에 없는 파일인데, 해커가 설치해서 사용하는 파일이다. arm63.php가 포함된 URL을 호출하는 IP를 차단하려면 아래처럼 갱신한다.

[Definition]
badrequests = phpmyadmin|phpMyAdmin|arm63\.php
failregex = failregex = ^<HOST> -.*"(GET|POST|HEAD) /[^ ]*?(?:%(badrequests)s)[^ ]*? HTTP.*".*$
ignoreregex =

자, 주의할 점이 하나 나왔는데, 정규식에서 .은 “한 글자”를 가리키는 뜻을 가진다. 따라서 이스케이핑(\)을 해 줘야 실제 .이라는 문자를 가리키게 된다. 그래서 \.이라고 쓴 것이다.

필터 테스트

필터가 제대로 작성됐는지 테스트해 볼 차례다. fail2ban-regex라는 프로그램을 사용한다. 아래가 명령을 내리는 방법 설명이다.

sudo fail2ban-regex [옵션] <로그> <정규식>

로그와 정규식은 파일 경로를 넣어도 되고 문자열을 넣어도 된다. 우리는 파일을 만들었으니 파일 경로를 넣어 주자.

sudo fail2ban-regex /var/log/apache2/access.log /etc/fail2ban/filter.d/apache-custom.conf

제대로 됐다면 아래처럼 출력될 것이다.

Running tests
=============

Use   failregex filter file : apache-custom, basedir: /etc/fail2ban
Use         log file : /var/log/apache2/access.log
Use         encoding : UTF-8


Results
=======

Failregex: 0 total

Ignoreregex: 0 total

Date template hits:
|- [# of hits] date format
|  [200] Day(?P<_sep>[-/])MON(?P=_sep)ExYear[ :]?24hour:Minute:Second(?:\.Microseconds)?(?: Zone offset)?
`-

Lines: 200 lines, 0 ignored, 0 matched, 200 missed
[processed in 0.05 sec]

Missed line(s): too many to print.  Use --print-all-missed to print all 200 lines

로그에 200줄이 있었는데, 무시된 건 0개고, 필터에 걸린 것도 0개라고 한다. 200개는 필터에 걸리지 않은 로그 줄이라고 한다. 필터에 걸리지 않은 로그 줄을 다 보고 싶다면 --print-all-missed를 옵션으로 주라고 한다. 만약, 필터에 걸린 놈들만 다 보고 싶다면 --print-all-matched 옵션을 넣어 주면 된다.

Fail2Ban에 커스텀 필터 등록하기

이제 테스트도 통과했으니 커스텀 필터를 등록하자.

선호하는 에디터로 /etc/fail2ban/jail.local 파일을 열고 맨 밑에 아래 내용을 추가해 주면 된다.

[apache-custom]
enabled  = true
port     = http,https
logpath  = %(apache_access_log)s
maxretry = 2
findtime  = 60

나는 60초 동안 2번 동안 이 필터에 걸리는 URL 호출을 하면 IP를 차단하게 한 것이다.

Fail2Ban 서버 설정을 리로드하고 상태를 보자.

sudo systemctl reload fail2ban
sudo fail2ban-client status

아래처럼 등록된 필터로 apache-custom이 등장하면 성공한 것이다.

Status
|- Number of jail:  3
`- Jail list: apache-badbots, apache-custom, sshd

완료된 jail.local 모습

[DEFAULT]
# IP 차단을 얼마동안 할지. 기본값은 10m
bantime  = 31536000m

# findtime 동안 maxretry에 설정된 수만큼 문제가 발견되면 IP를 차단한다.
# 기본값은 10m
findtime  = 10m

# IP를 차단할 때까지 최대 실패 횟수. 기본값은 5
maxretry = 5

[apache-badbots]
# 이메일 주소를 크롤링하는 스팸 로봇의 에이전트 문자열을 식별해 IP를 차단한다.
enabled  = true
port     = http,https
logpath  = %(apache_access_log)s
bantime  = 48h
maxretry = 1

[apache-custom]
enabled  = true
port     = http,https
logpath  = %(apache_access_log)s
maxretry = 2
findtime  = 60

필터로 차단한 IP 목록 보기

어떤 필터가 어떤 IP를 차단하고 있는지 확인하고 싶을 때 아래 명령어를 사용한다.

sudo fail2ban-client status <필터이름>

apache-custom이 차단한 IP 목록을 보고 싶다면 아래처럼 명령을 내린다.

sudo fail2ban-client status apache-custom

아이피 차단 풀기

실수로 차단된 IP가 있다면 두 방법으로 풀 수 있다. 하나는 jail.localignoreip로 등록하는 것이고, 다른 하나는 명령으로 하는 것이다.

명령어로 차단을 풀려면 아래와 같이 한다. 0.9.0 이전과 이후가 다른데, 여기서는 0.9.0 이후 버전의 명령만 다룬다.

sudo fail2ban-client set <filter이름> unbanip <IP주소>

그래서 apache-custom이 차단한 아이피 1.1.1.1을 풀고 싶다면 아래처럼 쓴다.

sudo fail2ban-client set apache-custom unbanip 1.1.1.1

여러 IP 차단 풀기

필터에 상관없이 여러 IP에 대한 차단을 풀 수 있다. 아래 명령을 사용한다.

sudo fail2ban-client unban <IP> ... <IP>

그러니까, 실제 명령은 이렇게 될 것이다. 1.1.1.1부터 1.1.1.4까지 IP 4개를 차단해제하는 것이다.

sudo fail2ban-client unban 1.1.1.1 1.1.1.2 1.1.1.3 1.1.1.4

그냥 모든 IP의 차단을 풀어 버리려면 아래 명령을 사용한다.

sudo fail2ban-client unban --all

특정 필터가 차단한 IP 전부 풀기

어떤 경우에는 필터에 심각한 결함이 발견돼, 해당 필터가 차단한 IP를 전부 풀어야 할 수 있다. 그런 경우 우선 해당 필터가 차단하고 있는 IP를 전부 복사한 다음에 여러 IP 차단 풀기 명령을 사용하면 된다. 아래는 apache-custom 필터가 차단한 IP를 전부 차단해제하는 예시를 보여 준다. (예시에서 $는 프롬프트라는 것을 가리키는 뜻으로 사용한 것이다. 명령어의 일부가 아니다. $ 없이 시작되는 줄은 출력 내용을 의미한다.)

$ sudo fail2ban-client status apache-custom

Status for the jail: apache-custom
|- Filter
|  |- Currently failed: 0
|  |- Total failed: 34
|  `- File list:  /var/log/apache2/access.log
`- Actions
   |- Currently banned: 2
   |- Total banned: 223
   `- Banned IP list: 1.1.1.1 1.1.1.2

$ sudo fail2ban-client unban 1.1.1.1 1.1.1.2

수동으로 IP 차단하기

아래와 같은 식으로 IP를 수동으로 차단할 수 있다.

sudo fail2ban-client set <필터이름> banip <IP나열>

그러니까 아래와 같은 식으로 한다.

sudo fail2ban-client set apache-custom banip 1.1.1.1 1.1.1.2 1.1.1.3 1.1.1.4

차단한 IP 알림 받기

이건 설명하자면 길다. IP를 차단할 때마다 알림을 받으면 좀 피곤하다. 그래서 Fail2Ban의 sqlite 디비에 접속해서 알림을 보내는 PHP 프로그램을 만들었다. GitLab에 fail2ban-notification 프로그램의 코드를 공개해 놨으니 참고하면 된다.

Fail2Ban의 log 파일

log 파일 경로는 /var/log/fail2ban.log이다. 아래와 같은 형식으로 돼 있다.

2022-01-15 18:50:54,899 fail2ban.filter         [10249]: INFO    [sshd] Found xxx.xxx.154.120 - 2022-01-15 18:50:54
2022-01-15 18:50:55,372 fail2ban.actions        [10249]: NOTICE  [sshd] Ban xxx.xxx.154.120

필터 이름을 지을 때 주의 - 이름 글자수 24자 이하

filter 이름은 최대 24자를 넘으면 안 된다. iptable 설정에서 체인 이름(chain name)은 29자를, 대상 이름(target name)은 28자를 넘기면 안 되는데, fail2ban이 이 이름을 구성할 때 filter 이름을 사용하기 때문이다.

Fail2Ban은 filter 이름 앞에 f2b- 접두어를 붙여서 이름을 만든다. 내가 필터 이름을 apache-mytory-bad-requests로 했더니 체인 이름과 대상 이름이 f2b-apache-mytory-bad-requests으로 30자가 돼 아래와 같은 에러가 발생했다.

2022-01-09 07:15:17,928 fail2ban.filter         [1103]: INFO    [apache-mytory-bad-requests] Found xxx.xxx.52.134 - 2022-01-09 07:15:17
2022-01-09 07:15:18,067 fail2ban.actions        [1103]: NOTICE  [apache-mytory-bad-requests] Ban xxx.xxx.52.134
2022-01-09 07:15:18,081 fail2ban.utils          [1103]: Level 39 7fd340459030 -- exec: iptables -w -N f2b-apache-mytory-bad-requests
iptables -w -A f2b-apache-mytory-bad-requests -j RETURN
iptables -w -I INPUT -p tcp -m multiport --dports http,https -j f2b-apache-mytory-bad-requests
2022-01-09 07:15:18,081 fail2ban.utils          [1103]: ERROR   7fd340459030 -- stderr: "iptables v1.6.1: chain name `f2b-apache-mytory-bad-requests' too long (must be under 29 chars)"
2022-01-09 07:15:18,081 fail2ban.utils          [1103]: ERROR   7fd340459030 -- stderr: "iptables v1.6.1: Invalid target name `f2b-apache-mytory-bad-requests' (28 chars max)"
2022-01-09 07:15:18,082 fail2ban.utils          [1103]: ERROR   7fd340459030 -- stderr: "Try `iptables -h' or 'iptables --help' for more information."
2022-01-09 07:15:18,082 fail2ban.utils          [1103]: ERROR   7fd340459030 -- returned 2
2022-01-09 07:15:18,082 fail2ban.actions        [1103]: ERROR   Failed to execute ban jail 'apache-mytory-bad-requests' action 'iptables-multiport' (이하 생략)

실행이 안 되는 경우 에러 확인

fail2ban이 실행되지 않는다면 아래 명령으로 에러를 확인한다.

sudo fail2ban-server start

나 같은 경우 아래와 같은 에러를 만난 적이 있다. 오라클 클라우드의 우분투 서버였다.

2022-01-16 07:53:39,944 fail2ban                [3011039]: ERROR   Failed during configuration: Have not found any log file for sshd jail
2022-01-16 07:53:39,945 fail2ban                [3011039]: ERROR   Async configuration of server failed

# 아래는 번역
2022-01-16 07:53:39,944 fail2ban                [3011039]: ERROR   설정 실패: sshd jail에 대한 로그를 찾지 못했습니다.
2022-01-16 07:53:39,945 fail2ban                [3011039]: ERROR   비동기적인 서버 설정이 실패했습니다.

검사용 로그 파일이 없으면 Fail2Ban 서버 시작이 안 된다.

에러 내용은 /var/log/auth.log 파일이 없어서 sshd 실패 검사를 할 수 없고, 그래서 Fail2Ban을 시작할 수 없다는 내용이었다.

확인해 보니 오라클 클라우드의 우분투 서버는 rsyslog 패키지가 깔려 있지 않아 syslog 등 기본적 시스템 로그를 기록하지 않고 있었다.

아래 명령으로 rsyslog 패키지를 설치했다.

sudo apt install rsyslog -y

그리고 Fail2Ban 서버를 시작해 보니 제대로 시작됐다.

$ sudo fail2ban-server start
Server Ready

Fail2Ban 상태를 체크하니 정상 출력됐다.

$ sudo fail2ban-client status
Status
|- Number of jail:  1
`- Jail list: sshd

나가며

이정도면 내가 Fail2Ban을 다루며 익힌 노하우는 대충 다 정리한 것 같다.