ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • fail2ban 및 GeoIP 와 BlackIP를 이용한 IP 차단하기
    Linux 2019. 1. 3. 14:41

    IP 차단하기


    작성일: 2019년 1월 04일


    레퍼런스들

    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

    ISPChina Unicom Jiangsu Province Network
    Usage TypeUnknown
    Domain Namechinaunicom.com
    Country
    CityLianyungang, 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.service

    PartOf=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 = true
    port     = http,https
    logpath  = %(apache_access_log)s
    bantime  = 172800
    maxretry = 1

    [apache-noscript]
    enabled = true
    port     = http,https
    logpath  = %(apache_error_log)s

    [apache-overflows]
    enabled = true
    port     = http,https
    logpath  = %(apache_error_log)s
    maxretry = 2

    [apache-nohome]
    enabled = true
    port     = http,https
    logpath  = %(apache_error_log)s
    maxretry = 2

    [apache-botsearch]
    enabled = true
    port     = http,https
    logpath  = %(apache_error_log)s
    maxretry = 2

    [apache-fakegooglebot]
    enabled = true
    port     = http,https
    logpath  = %(apache_access_log)s
    maxretry = 1
    ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot <ip>

    [apache-modsecurity]
    enabled = true
    port     = http,https
    logpath  = %(apache_error_log)s
    maxretry = 2


    [apache-shellshock]
    enabled = true
    port    = http,https
    logpath = %(apache_error_log)s
    maxretry = 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


    다) 압축

    라) 중단된 사이트



    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 번의 로그인 시도가 실패하였습니다.


    현저하게 줄어든 것을 볼 수 있다.

    댓글 0

Designed by Tistory.