-
fail2ban 및 GeoIP 와 BlackIP를 이용한 IP 차단하기Linux 2019. 1. 3. 14:41
IP 차단하기
작성일: 2019년 1월 04일
최종 수정: 2020년 4월 23일
레퍼런스들
0. 머리글
외부 접근이 되지 않는 환경에서 테스트하던 PC 를 외부 접근이 되는 공간으로 이전한지 원격에서 로그인시 다음과 같은 메시지를 볼 수 있다.
마지막 로그인: 목 1월 3 13:23:59 KST 2019 일시 pts/0
마지막 로그인 실패: 목 1월 3 17:15:22 KST 2019 122.194.229.3에서 시작 일시 ssh:notty
마지막 로그인 후 1830 번의 로그인 시도가 실패하였습니다.
아주 짧은 시간동안에도 수많은 불법 로그인이 시도되고 있다.
로그인관련 로그를 살펴보면, /var/log/secure
Dec 31 01:16:07 localhost sshd[80983]: Failed password for root from 122.194.229.41 port 54340 ssh2
...
Jan 3 17:16:49 localhost sshd[99212]: Failed password for root from 122.194.229.3 port 64254 ssh2
122.194.xxx.xxx 대역폭에서 IP 가 바꿔가며 계속 로그인을 시도하고 있다.
IP 하나를 보면, (google 에서 그냥 whois 122.194.229.3)
122.194.229.3 IP Address Information
ISP China Unicom Jiangsu Province Network Usage Type Unknown Domain Name chinaunicom.com Country City Lianyungang, Jiangsu 외부에 연결된 컴퓨터의 필수 프로그램인 fail2ban 을 설치해서 이러한 IP 들을 차단하도록 한다.
1. fail2ban
*** 리눅스 설치시에 반드시 설치하라 ***
1) 소개
fail2ban 은 로그 파일을 스캔해서 로그인 암호 실패를 한 IP 주소들을 방화벽 도구를 이용해 차단하는 프로그램이다. 스캔하는 로그파일은 sshd 및 아파치 웹 서버등의 로그 파일등으로 여러가지 서비스들의 로그 파일을 읽을 수 있다.
설치하면, 이러한 로그파일들을 읽고 차단하는 룰에 대한 기본 설정파일을 함께 설치한다.
2) 설치
가) RPM 패키지 설치
CentOS 7 기본 저장소에는 이 프로그램 패키지가 없으며, EPEL 저장소에서 제공하고 있다. 설치 전 먼저, EPEL 저장소를 yum 저장소 목록에 추가해야 한다.
# yum install epel-release
# yum search fail2ban
...
=============================================================== N/S matched: fail2ban ================================================================
fail2ban-all.noarch : Install all Fail2Ban packages and dependencies
fail2ban-firewalld.noarch : Firewalld support for Fail2Ban
fail2ban-hostsdeny.noarch : Hostsdeny (tcp_wrappers) support for Fail2Ban
fail2ban-mail.noarch : Mail actions for Fail2Ban
fail2ban-sendmail.noarch : Sendmail actions for Fail2Ban
fail2ban-server.noarch : Core server component for Fail2Ban
fail2ban-shorewall.noarch : Shorewall support for Fail2Ban
fail2ban-systemd.noarch : Systemd journal configuration for Fail2Ban
fail2ban-tests.noarch : Fail2Ban testcases
fail2ban.noarch : Daemon to ban hosts that cause multiple authentication errors
위와 같은 fail2ban 패키지들이 존재한다.
여기서는 fail2ban 과 fail2ban-systemd 패키지를 설치한다. (핵심 패키지는 fail2ban-server 패키지로 함께 설치된다.)
# yum install fail2ban fail2ban-systemd
나) 소스 컴파일 설치
fail2ban 의 최신 릴리스 소스를 내려받을 설치할 수 있다.
Python 으로 작성되었기에 Python 관련 도구들이 필요하다.
# yum install python-devel python-inotify
$ tar xvfj fail2ban-0.11.0.tar.bz2
$ cd fail2ban-0.11.0
$ sudo python setup.py install
릴리스 또는 최신 소스로부터 빌드할 때에는 몇 가지 옵션을 CentOS 에 맞도록 수정해야 한다.
특히, jail.conf 파일의 INCLUDE 섹션을 수정한다.
[INCLUDES]
#before = paths-distro.conf
before = paths-fedora.conf
files/fail2ban.service.in 파일을 수정한다.
PartOf=iptables.service firewalld.service ip6tables.service ipset.servicePartOf=firewalld.service
고칠것이 이것저것 많다.
그냥, 시스템에 맞게 잘 수정된 패키지를 설치해서 잘 쓰도록 하자 !!!!
3) 설정
설치하면 /etc/fail2ban 폴더에 설정파일 및 차단 룰이 있으며, 각 운영체제에서 스캔할 로그파일을 정의한 파일을 볼 수 있다.
CentOS 의 경우 /etc/fail2ban/paths-fedora.conf 파일에 해당 로그파일들이 명시되어 있다.
먼저, 다음과 같이 기본 설정파일을 복사한다.
# cd /etc/fail2ban
# cp jail.conf jail.local
모든 변경 사항을 jail.local 에 적용하게 될 것이다.
주요 공통 설정 옵션
[DEFAULT]
ignoreip = 127.0.0.1/8 192.168.0.0/24 # 자신이 주로 사용하는 IP 및 내부 네트워크를 추가해 둬서, 내 IP가 차단당하지 않도록 한다.
bantime = -1 # IP 차단 시간을 초로 정의한다. 기본값을 6000 초다. -1 은 영구 차단을 한다.
findtime = 600 # 600 초안에 maxretry(5) 시도 실패의 경우를 정의한다.
maxretry = 5
paths-common.conf 파일의 아래 설정을 반드시 변경한다.
(auto 로 사용할 경우, CPU 점유율이 100%를 차지하게 된다.)
[DEFAULT]
##default_backend = auto
default_backend = polling
Too many open file 에러 발생시를 위해 파일 Open 제한 설정
# mkdir -p /etc/systemd/system/fail2ban.service.d
# cat << EOF > /etc/systemd/system/fail2ban.service.d/limits.conf
[Service]
LimitNOFILE=2048
EOF
# systemctl daemon-reload
가) sshd 로그인 차단
가장 중요한 서비스인 SSHD 로그인에 대한 IP 차단을 설정한다.
모든 설정 섹션을 동작시킬려면, enabled = true 옵션을 추가해 줘야 한다.
/etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
maxretry = 3
[sshd-ddos]
enabled = true
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
나) 아파치 웹 서버 IP 차단
아파치 웹 서버의 경우, mod_security 등의 모듈과 함께 fail2ban 에서 차단할 수 있는 옵션들이 다음과 같이 있다.
웹 서버가 Apache Server 가 아닌 엔진 X (nginx) 인 경우에는 해당 섹션을 활성화시켜주고 옵션 상태를 수정하면 된다.
[apache-auth]
enabled = true
port = http,https
logpath = %(apache_error_log)s
[apache-badbots]enabled = trueport = http,httpslogpath = %(apache_access_log)sbantime = 172800maxretry = 1[apache-noscript]enabled = trueport = http,httpslogpath = %(apache_error_log)s[apache-overflows]enabled = trueport = http,httpslogpath = %(apache_error_log)smaxretry = 2[apache-nohome]enabled = trueport = http,httpslogpath = %(apache_error_log)smaxretry = 2[apache-botsearch]enabled = trueport = http,httpslogpath = %(apache_error_log)smaxretry = 2[apache-fakegooglebot]enabled = trueport = http,httpslogpath = %(apache_access_log)smaxretry = 1ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot <ip>[apache-modsecurity]enabled = trueport = http,httpslogpath = %(apache_error_log)smaxretry = 2[apache-shellshock]enabled = trueport = http,httpslogpath = %(apache_error_log)smaxretry = 1다) PHP
php 로 url 파일 열기를 시도하는 IP 를 차단한다.
[php-url-fopen]
enabled = true
port = http,https
logpath = %(nginx_access_log)s
%(apache_access_log)s
라) 메일 서버 (sendmail, qmail, postfix 등)메일 서버를 사용하는 경우 해당 메일 서버 옵션을 활성화시킨다.
[sendmail-auth]
enabled = true
port = submission,465,smtp
logpath = %(syslog_mail)s
backend = %(syslog_backend)s
[sendmail-reject]
enabled = true
port = smtp,465,submission
logpath = %(syslog_mail)s
backend = %(syslog_backend)s
마) Oracle 차단
예정
바) Postgresql DB 접속 차단
먼저, 필터를 생성한다.
/etc/fail2ban/filter.d/postgresql.conf
[Definition]
failregex = <HOST>\(\d+\) FATAL: password authentication failed for .+$
<HOST>\(\d+\) FATAL: no pg_hba.conf entry for host .+$
ignoreregex = duration:
필터의 regex 내용은 로그 환경에 따라 맞게 수정되어야 한다.
Action 파일을 생성한다.
/etc/fail2ban/action.d/postgresql.conf
[postgresql]
enabled = true
filter = postgresql
action = iptables[name=PostgreSQL, port=5432, protocol=tcp]
sendmail-whois[name=PostgreSQL, dest=root@localhost]
logpath = /var/log/postgresql/postgresql-9.log
maxretry = 3
필터 테스트
# fail2ban-regex /var/log/postgresql/postgresql-9.log /etc/fail2ban/filter.d/postgresql.conf
Results
=======
Failregex: 0 total
Ignoreregex: 0 total
위와 같이 새로 만든 필터가 로그파일에 대해 제대로 동작하는지 확인 후 사용해야 한다.
Failregex 에 검출되어야 한다.
PostgreSQL 로그 관련 참조
사) Jenkins 차단
예정
아) Wordpress 차단
4) 상태
fail2ban 이 감시하는 서비스 상태를 볼려면 다음과 같이 한다.
# fail2ban-client status
Status
|- Number of jail: 13
`- Jail list: apache-auth, apache-badbots, apache-botsearch, apache-fakegooglebot, apache-nohome, apache-noscript, apache-overflows, apache-shellshock, php-url-fopen, sendmail-auth, sendmail-reject, sshd, sshd-ddos
특정 서비스의 Jail 상태를 보기 위해서는 다음과 같이 한다.
# fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 180773
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 1867
|- Total banned: 1867
`- Banned IP list: 1.237.178.27 1.238.85.187 100.14.70.124 101.0.78.66 101.206.156.122 101.235.114.131 101.88.90.168 101.91.125.57 103.11.74.107
방화벽 차단된 상태 보기
# iptables -L
...
...
Chain f2b-apache-shellshock (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Chain f2b-php-url-fopen (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Chain f2b-sendmail-auth (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Chain f2b-sendmail-reject (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Chain f2b-sshd-ddos (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Chain f2b-sshd (1 references)
target prot opt source destination
REJECT all -- 056-153-158-163.dynamic.caiway.nl anywhere reject-with icmp-port-unreachable
REJECT all -- 85.1222offices.com anywhere reject-with icmp-port-unreachable
REJECT all -- 162.243.165.39 anywhere reject-with icmp-port-unreachable
REJECT all -- 162.243.158.198 anywhere reject-with icmp-port-unreachable
REJECT all -- 162.243.158.185 anywhere reject-with icmp-port-unreachable
REJECT all -- 162.243.10.64 anywhere reject-with icmp-port-unreachable
REJECT all -- 162-12-217-156.ip.weelax.fr anywhere reject-with icmp-port-unreachable
REJECT all -- 161.132.195.76 anywhere reject-with icmp-port-unreachable
REJECT all -- 161.10.238.226 anywhere reject-with icmp-port-unreachable
REJECT all -- 160.20.53.2 anywhere reject-with icmp-port-unreachable
REJECT all -- baikalweb.jinr.ru anywhere reject-with icmp-port-unreachable
SSHD 서버의 암호오류로 차단된 IP 목록을 볼 수 있다.
fail2ban 로그 보기
# cat /var/log/fail2ban.log | grep "] Ban" | awk '{print $NF}' | sort | uniq -c | sort -n
...
3 145.239.82.192
3 146.0.128.157
3 146.148.22.11
3 146.185.148.67
3 218.92.1.166
5) 차단된 IP 복구하기
가끔 암호가 생각나지 않아서, 내가 사용하는 IP 가 차단되는 경우가 있다. 이럴 경우, 다음과 같이 사용 IP 차단을 해제한다.
# fail2ban-client set sshd unbanip IP주소
fail2ban 은 차단된 IP 목록을 sqlite3 DB 파일로 저장한다.
# fail2ban-client get dbfile
Current database file is:
`- /var/lib/fail2ban/fail2ban.sqlite3
sqlite 로 DB 파일의 내용을 볼 수 있다.
# sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 .table
bans fail2banDb jails logs
# sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 .schema
CREATE TABLE fail2banDb(version INTEGER);
CREATE TABLE jails(name TEXT NOT NULL UNIQUE, enabled INTEGER NOT NULL DEFAULT 1);
CREATE INDEX jails_name ON jails(name);
CREATE TABLE logs(jail TEXT NOT NULL, path TEXT, firstlinemd5 TEXT, lastfilepos INTEGER DEFAULT 0, FOREIGN KEY(jail) REFERENCES jails(name) ON DELETE CASCADE, UNIQUE(jail, path),UNIQUE(jail, path, firstlinemd5));
CREATE INDEX logs_path ON logs(path);
CREATE INDEX logs_jail_path ON logs(jail, path);
CREATE TABLE bans(jail TEXT NOT NULL, ip TEXT, timeofban INTEGER NOT NULL, data JSON, FOREIGN KEY(jail) REFERENCES jails(name) );
CREATE INDEX bans_jail_timeofban_ip ON bans(jail, timeofban);
CREATE INDEX bans_jail_ip ON bans(jail, ip);
CREATE INDEX bans_ip ON bans(ip);
Bans 테이블의 차단된 IP 를 직접 볼 수 있다.
# sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 "select distinct ip from bans;"
1.160.8.216
1.179.175.58
1.237.178.27
1.238.85.187
1.246.10.93
100.14.70.124
...이 테이블에 직접 IP 를 추가해서 사용할 수도 있다.
6) 서비스 사용하기
fail2ban 서비스를 시작하기전 방화벽 서비스를 시작한다. (당연히 사용하고 있을 것이다.)
# systemctl enable firewalld
# systemctl start firewalld
같은 방식으로 fail2ban 을 시작한다.
# systemctl enable fail2ban
# systemctl start fail2ban
7) Log 파일 설정 수정하기
fail2ban 은 cron 을 사용하는 logrotate 를 이용해서 로그 파일을 관리한다.
기본 설정은 1주일 단위로 로그파일을 갱신한다.
로그 파일이 커지면, fail2ban 서버의 성능이 떨어지므로, 이 파일크기가 과도하게 커지는 경우, 로그 파일 갱신 단위를 daily 등으로 수정해서 관리한다.
/etc/logrotate.d/fail2ban
/var/log/fail2ban.log {
daily
rotate 7
missingok
compress
notifempty
postrotate
/usr/bin/fail2ban-client flushlogs >/dev/null || true
endscript
}
2. GeoIP
1) 소개
GeoIP 는 IP 의 지리적 위치, 즉 국가가 어디인가를 알려주는 것이다. 이미 웹 서버에서는 GeoIP 를 사용해서 특정 국가를 차단하는 방법이 있다.
2) 설치하기
가) GeoIP 관련 패키지 설치하기
# yum search GeoIP
...
========================================== N/S matched: GeoIP ==========================================
GeoIP-data.noarch : Static snapshot of GeoIP databases
GeoIP-devel.i686 : Development headers and libraries for GeoIP
GeoIP-devel.x86_64 : Development headers and libraries for GeoIP
lighttpd-mod_geoip.x86_64 : GeoIP module for lighttpd to use for location lookups
mod_geoip.x86_64 : GeoIP module for the Apache HTTP Server
nginx-mod-http-geoip.x86_64 : Nginx HTTP geoip module
opensips-mmgeoip.x86_64 : Wrapper for the MaxMind GeoIP API
pdns-backend-geoip.x86_64 : GeoIP backend for pdns
python-GeoIP.x86_64 : Python bindings for the GeoIP geographical lookup libraries
python-geoip2-doc.noarch : Documentation for python-geoip2
python-pygeoip.noarch : Pure Python GeoIP API
python2-geoip2.noarch : Documentation for python-geoip2
syslog-ng-geoip.x86_64 : geoip support for syslog-ng
uwsgi-plugin-geoip.x86_64 : uWSGI - Plugin for GeoIP support
GeoIP.i686 : Library for country/city/organization to IP address or hostname mapping
GeoIP.x86_64 : Library for country/city/organization to IP address or hostname mapping
GeoIP-update.noarch : Crontab entry to facilitate automatic updates of databases
perl-Geo-IP.x86_64 : Efficient Perl bindings for the GeoIP location database
php-pecl-geoip.x86_64 : Extension to map IP addresses to geographic places
나) 아파치 웹서버에 GeoIP 사용하기
다) GeoIP CSV 파일 내려받기
CSV 로 국가별 IP 대역폭이 정리된 파일을 내려받을 수 있다.
# wget http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
# unzip GeoIPCountryCSV.zip
3) 특정 국가 IP 차단하기
CSV 파일은 다음과 같이 구성되어 있다.
"1.0.0.0","1.0.0.255","16777216","16777471","AU","Australia"
"1.0.1.0","1.0.3.255","16777472","16778239","CN","China"
"1.0.4.0","1.0.7.255","16778240","16779263","AU","Australia"
모두들 아는 그 국가를 차단해보자.
가) iptable 의 xtable 모듈을 이용하는 방법
귀챦다. (https://root.so/26)
나) CSV 로부터 직접 iptable 로 추가하는 방법
그냥 BASH 셀 스크립트로 처리하자.
block_china.sh
#!/bin/sh
DATA=/root/GeoIPCountryWhois.csv
iptables -N GeoIP-China
iptables -A GeoIP-China -j DROP
for IPRANGE in `egrep "China" $DATA | cut -d, -f1,2 | sed -e 's/"//g' | sed -e 's/,/-/g'`
do
iptables -I INPUT -p all -m iprange --src-range $IPRANGE -j GeoIP-China
done
GeoIP-China 라는 체인 룰을 새로 생성하고, DROP 으로 처리한다.
CSV 파일의 특정 국가를 읽어서 새로 생성한 룰로 Jump 하도록 한다.
다음과 같이 실행한다.
# ./block_china.sh
..
# iptables -L | grep China
...
GeoIP-China all -- anywhere anywhere source IP range 1.1.0.0-1.1.0.255
GeoIP-China all -- anywhere anywhere source IP range 1.0.32.0-1.0.63.255
GeoIP-China all -- anywhere anywhere source IP range 1.0.8.0-1.0.15.255
GeoIP-China all -- anywhere anywhere source IP range 1.0.1.0-1.0.3.255
Chain GeoIP-China (4539 references)
이 IP 차단을 시스템 시작시 적용하려면,
/etc/rc.d/rc.local 에 실행 스크립트를 추가해 둔다.
# chmod +x /etc/rc.d/rc.local
같은 방식으로 특정 국가 목록을 더 추가해서 만들어 적용할 수 있다.(예, 남미 국가들...)
3. BlackIP
1) 소개
BlackIP 는 프로젝트 Honeypot 과 같이 Black IP 로 신고된 IP 들의 목록을 제공하는 Public 서비스들의 목록을 말한다.
이 BlackIP 들을 모아둔 정보가 다음 깃허브에 있다.
2) IP 제공 소스들
가) Public 블랙 IP 리스트
나) TOR
다) 압축
라) 중단된 사이트
Blocklist and Blocklist Export. Replaced by Ultimate Hosts IPs Blacklist
Firehold Level 1 (Excluded for containing CIDR)
StopForumSpam Toxic CIDR (Excluded for containing CIDR)
OpenBL (Server Down since Ago 2017)
3) 소스 및 데이터 내려받기
git 으로 해당 저장소를 내려받는다.
# git clone --depth=1 https://github.com/maravento/blackip.git
# cd blackip
# tar xvfz blackip.tar.gz
blackip.txt
blackip.txt 파일에는 순수하지 않은 IP 들만 순수하게 들어 있다.
...
36.81.144.179
36.81.148.211
36.81.148.223
36.81.151.140
36.81.154.13
36.81.154.29
36.81.157.193
36.81.160.2
36.81.161.230
36.81.170.3
36.81.175.248
36.81.177.157
...4) 차단하기
GeoIP 처럼 iptable 을 이용해서 직접추가해준다.
ipset 으로 Blacklist 를 만들어 사용하는 방법은 다음을 참조한다.
block_blackip.sh
#!/bin/sh
DATA=./blackip.txt
iptables -N BlackIP
iptables -A BlackIP -j DROP
for IP in `cat $DATA`
do
iptables -I INPUT -p all -s $IP -j BlackIP
done
5) fail2ban 에 추가하기
위 방식과 달리 fail2ban 에 IP 를 직접 추가해주는 방식도 가능하다.
#!/bin/sh
DATA=./blackip.txt
for IP in `cat $DATA`
do
fail2ban-client set sshd banip $IP
done
설정 보기
# iptables -L | grep Black
...
BlackIP all -- 1.207.37.118 anywhere
BlackIP all -- 1.207.37.28 anywhere
BlackIP all -- 1.207.37.8 anywhere
BlackIP all -- 1.207.36.125 anywhere
BlackIP all -- 1.207.36.9 anywhere
...4. 마무리
줄었을까...
암호:
마지막 로그인: 금 1월 4 12:34:08 KST 2019 일시 pts/0
마지막 로그인 실패: 금 1월 4 14:19:45 KST 2019 host-212-159-148-72.static.as13285.net에서 시작 일시 ssh:notty
마지막 로그인 후 3385 번의 로그인 시도가 실패하였습니다.
2 시간 동안 3385번의 로그인 시도가 있었다.
IP 차단을 하고 나서, 2시간이 지났을 때는 어떻게 되었을 까?
마지막 로그인: 금 1월 4 15:07:33 KST 2019 일시 pts/1
마지막 로그인 실패: 금 1월 4 15:54:16 KST 2019 ip64.ip-54-36-151.eu에서 시작 일시 ssh:notty
마지막 로그인 후 6 번의 로그인 시도가 실패하였습니다.
현저하게 줄어든 것을 볼 수 있다.
5. CentOS 8 을 위한 jail.local 수정
CentOS 8 의 방화벽 백엔드는 iptable 이 아니라, nftable 이다.
따라서, jail.local 의 벡엔드도 다음과 같이 수정해준다.
# banaction = iptables-multiport
# banaction_allports = iptables-allports
banaction = nftables-multiport
banaction_allports = nftables-allports
혹시라도 iptable 을 사용한 커스텀 액션이 있다면,, 모두 nftable 로 변경해준다.
며칠 사용해 본 느낌상 nftable 이 훨씬 안정적이다.
'Linux' 카테고리의 다른 글
TmaxOS 3.9.1 x64 설치기 (0) 2019.08.20 북한 폰트 (0) 2019.08.08 CentOS Hardware Raid 설치 - Gigabyte X399 AROUS GAMING 7 (0) 2018.11.19 CentOS 7 에서 Oracle 12c 설치하기(Silent Mode 설치) (2) 2018.10.17 CentOS 7 에서 Oracle 12c 설치하기(GUI 원격 설치) (0) 2018.10.17