- 침입 차단 소프트웨어
- 서버를 무차별 대입 공격으로부터 보호함
- 문제가 되는 IP 주소를 로컬방화벽(iptables 또는 TCP 래퍼) 활용하여 차단
- 작성언어: Python
- 라이선스: GPLv2+
- SSH 이외에 Apache, Lighttpd, sshd, vsftpd, qmail, Postfix 그리고 Courier 메일 서버를 위한 필터들과 함께 제공 됩니다.
SSH 로그인 시도 IP를 확인
[root@localhost ~]# ls /var/log/secure | xargs grep -E “[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+” -o | sort | uniq
공개망에 연결된 서버라면 생각보다 많은 IP가 나와 놀랄수도 있습니다. IP들 중 자신이 아는 IP를 제외하면 대부분이 위에 언급한 공격일 확률이 높습니다.
최근 로그인 실패 기록을 확인
[root@localhost ~]# last -f /var/log/btmp | more
20 Linux Log Files that are Located under /var/log Directory에 보면 /var/log/btmp에 대한 설명을 확인 할 수 있습니다.
fail2ban은 지정된 시간 내에 지정된 횟수 이상으로 ssh 로그인을 실패하면 해당 IP에서의 접근을 지정된 시간만큼 차단하는 역할을 합니다.
yum epel 저장소 추가
Extra Packages for Enterprise Linux yum 저장소 추가
epel-release 설치
[root@gldigital ~]# yum repolist Loaded plugins: changelog, fastestmirror Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast Determining fastest mirrors * base: mirror.anigil.com * extras: mirror.anigil.com * updates: mirror.anigil.com .......생략 [root@gldigital ~]# yum list epel-release Loaded plugins: changelog, fastestmirror Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast Loading mirror speeds from cached hostfile * base: mirror.anigil.com * extras: mirror.anigil.com * updates: mirror.anigil.com Available Packages .......생략 [root@gldigital ~]# yum install epel-release .......생략 Total download size: 15 k Installed size: 24 k Is this ok [y/d/N]: y .......생략 Complete!
확인
[root@gldigital ~]# rpm -qa epel-release epel-release-7-11.noarch [root@gldigital ~]# yum repolist Loaded plugins: changelog, fastestmirror Loading mirror speeds from cached hostfile epel/x86_64/metalink ....... * epel: mirror-jp.misakamikoto.network .......
redhat 계열에서 접근로그파일은 /var/log/secure 입니다.
centos 7 이전에는 secure 로그파일에 의존하여 동작했으나 centos 7 부터는 systemd에서 통합적으로 관리합니다.
※ 이 설정과 관련하여 별도의 파일로 설정할 때는 2가지 옵션을 추가해야 합니다.
backend = polling
banaction = iptables-multiport
로그파일이 없으면 fail2ban동작불가하기 때문에 fail2ban-systemd를 같이 설치 진행합니다.
[root@gldigital ~]# yum install python-pip sqlite [root@gldigital ~]# pip install --upgrade pip # pip install --upgrade pip 시 아래와 같이 에러가 발생할 경우 Complete output from command python setup.py egg_info: Traceback (most recent call last): File "", line 1, in File "/tmp/pip-build-q4J0ib/pip/setup.py", line 7 def read(rel_path: str) -> str: ^ SyntaxError: invalid syntax [root@gldigital ~]# wget https://bootstrap.pypa.io/pip/2.7/get-pip.py [root@gldigital ~]# python get-pip.py Collecting pip<21.0 Downloading pip-20.3.4-py2.py3-none-any.whl (1.5 MB) |################################| 1.5 MB 1.7 MB/s Collecting wheel Downloading wheel-0.37.0-py2.py3-none-any.whl (35 kB) Installing collected packages: pip, wheel Attempting uninstall: pip Found existing installation: pip 8.1.2 Uninstalling pip-8.1.2: Successfully uninstalled pip-8.1.2 [root@gldigital ~]# yum install fail2ban fail2ban-systemd ....... Installed: ....... Dependency Installed: ....... Complete! [root@gldigital ~]# pip install pyinotify
시작 시 systemd 서비스 등록
# jail.local 파일 생성 및 작성 [root@gldigital ~]# cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local [root@gldigital ~]# vi /etc/fail2ban/jail.local # 아래 내용을 입력해 적절히 수정/추가 하여 사용 합니다 [DEFAULT] # 차단하지 않을 IP ignoreip = 127.0.0.1/8 ::1 # 인증 실패시 차단할 차단시간입니다 600 = 10분 # -1이면 영구차단입니다. (단위 : 초) # bantime = 10800 = 3시간 bantime = -1 # 아래 시간동안 maxretry 횟수만큼 실패시 차단 #findtime = 10m <-- default #findtime = 86400 - 24시간 findtime = 24h # 차단되기전까지 인증시도를 위한 허용횟수 maxretry = 10 # backend 설명 # 로그 파일 변경을 감지할 방법으로 pyinotify, gamin, polling,systemd, auto 방식이 있습니다 backend = auto - pyinotify: pyinotify (파일 변경 모니터)를 되어있어야 합니다. pyinotify 가 설치되지 않은 경우 Fail2ban은 auto를 사용합니다. 참고로 포스팅에서는 처음에 pyinotify 를 설치 하였습니다. - gamin: Gamin (파일 변경 모니터)을 설치 해야 합니다. Gamin이 설치되어 있지 않으면 Fail2ban은 auto를 사용합니다. - polling: 외부 라이브러리가 필요하지 않은 polling 알고리즘을 사용합니다. - systemd: systemd python 라이브러리를 사용하여 systemd 저널에 액세스합니다. 이 백엔드에는 "logpath" 지정이 유효하지 않을 경우 사용 됩니다("logpath" is not valid) auto: 다음 순서대로 동작 합니다 pyinotify, gamin, polling # 메일 알림기능 destemail = root@localhost # => 수신 메일 주소 sender = root@ # =>발신 메일 주소 # banaction ip 차단 방법입니다. /etc/fail2ban/action.d 디렉토리에 있는 action 을 사용할 수 있습니다. 여러 룰이 있으며 대표적인 iptables 와 firewalld 룰은 아래와 같이 설정파일이 있습니다. [root@gldigital ~]# ls -al /etc/fail2ban/action.d | grep iptables -rw-r--r--. 1 root root 1514 11월 24 2020 iptables-allports.conf -rw-r--r--. 1 root root 2738 11월 24 2020 iptables-common.conf -rw-r--r--. 1 root root 2088 11월 24 2020 iptables-ipset-proto4.conf -rw-r--r--. 1 root root 2742 11월 24 2020 iptables-ipset-proto6-allports.conf -rw-r--r--. 1 root root 2785 11월 24 2020 iptables-ipset-proto6.conf -rw-r--r--. 1 root root 2170 11월 24 2020 iptables-multiport-log.conf -rw-r--r--. 1 root root 1508 11월 24 2020 iptables-multiport.conf -rw-r--r--. 1 root root 1585 11월 24 2020 iptables-new.conf -rw-r--r--. 1 root root 2672 11월 24 2020 iptables-xt_recent-echo.conf -rw-r--r--. 1 root root 1427 11월 24 2020 iptables.conf [root@gldigital ~]# ls -al /etc/fail2ban/action.d | grep firewall -rw-r--r--. 1 root root 1501 11월 24 2020 firewallcmd-allports.conf -rw-r--r--. 1 root root 2649 11월 24 2020 firewallcmd-common.conf -rw-r--r--. 1 root root 2719 11월 24 2020 firewallcmd-ipset.conf -rw-r--r--. 1 root root 1322 11월 24 2020 firewallcmd-multiport.conf -rw-r--r--. 1 root root 1950 11월 24 2020 firewallcmd-new.conf -rw-r--r--. 1 root root 1021 11월 24 2020 firewallcmd-rich-logging.conf -rw-r--r--. 1 root root 1801 11월 24 2020 firewallcmd-rich-rules.conf banaction = iptables-multiport banaction_allports = iptables-allports # CentOS/RHEL 7 버전 이상 일 경우 # firewalld 가 설치되어있는 CentOS/RHEL7 에서는 firewall 을 통해 관리하려면 firewallcmd-new 을 입력하면 되며 또는 기본 값인 iptables 를 그대로 사용해도 됩니다. banaction = firewallcmd-new banaction_allports = firewallcmd-allports # banaction iptables 을 사용시 "iptables-multiport" firewalld 을 사용시 "firewallcmd-new" 값 입력 포스팅에서는 기본 값 으로 사용하였습니다. # [참고] firewalld 사용시 정책에 의해서 차단 된 ip 리스트는 --get-all-rules 를 통해 확인 할 수 있습니다. [root@gldigital ~]# firewall-cmd --direct --get-all-rules [sshd] #여러 포트를 사용할 경우 다음과 같이 지정 : port = ssh,10022 port = ssh enabled = true # enabled = true 를 입력 해줍니다. ignoreip=127.0.0.1,10.10.10.0/24,192.168.56.15 protocol = all banaction = iptables-allports # enabled = true # ssh 외 여러 서비스에 대해서 감지 할 수 있습니다. # 사용 하려는 항목(속성) 에서 enabled 속성을 true 로 변경 혹은 추가 해야 합니다. # ignoreip 를 지정하여 차단하지 않아야 하는 인증된 PC IP나 문제 시 꼭1개의 IP 는 허용을 하여 접속을 할 수 있도록 설정이 필요합니다. 콤마나 공백(띄워쓰기) 로 여러개의 ip를 입력 할 수 있습니다.(위의 IP는 설정의 예시 입니다) # protocol 과 banaction 을 별도로 지정하지 않으면 ssh 를 통해 잘못된 접속을 시도하여 block(ban) 되었을 경우 ssh 프로토콜만 차단 됩니다. ssh 외 다른 모든 포트도 차단, 즉 IP 자체를 차단 하려면 위의 설정과 같이 protocol, banaction 을 추가로 입력하면 됩니다 # Fail2ban 서비스 시작 위에서 추가/수정이 완료 되었다면 Fail2ban 을 재시작 합니다. [root@gldigital ~]# systemctl enable fail2ban [root@gldigital ~]# systemctl restart fail2ban [root@gldigital ~]# systemctl status fail2ban
Fail2ban 로그 및 상태 확인
Fail2ban 로그 확인
파일 : /var/log/fail2ban.log
ubuntu$ tail -100f /var/log/fail2ban.log
차단 현황 확인
ubuntu$ sudo fail2ban-client status sshd
sqlite3 DB 확인
Fail2ban 은 차단된 IP 목록을 sqlite3 DB 파일로 저장됩니다.
파일 위치 확인
ubuntu$ sudo fail2ban-client get dbfile
Current database file is:
`- /var/lib/fail2ban/fail2ban.sqlite3
sqlite 로 DB 파일 내용 확인
$ sudo sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 .table
sqlite3 스키마 정보 확인
$ sudo sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 .schema
Bans 테이블에서 차단된 IP 조회
$ sudo sqlite3 /var/lib/fail2ban/fail2ban.sqlite3 “select distinct ip from bips;”
xxx.xxx.xxx.101
xxx.xxx.xxx.103
xxx.xxx.xxx.105
차단된 IP해제(복구) 하기
다음 명령어로 IP 차단을 해제합니다.
ubuntu$ sudo fail2ban-client set sshd unbanip IP주소
수동으로 IP 차단 추가 하기
firewalld/iptables 에 차단할 IP 정책(룰)을 추가 하는 것처럼 fail2ban 에서 아이피 별로 별도로 추가를 할 수 있습니다.
# ip ban/unban 기능 명령어 sudo fail2ban-client set banip sudo fail2ban-client set unbanip # Jail 목록 조회 sudo fail2ban-client status Status |- Number of jail: 1 `- Jail list: sshd # Jail - sshd 로 차단 된 내역 확인 sudo fail2ban-client status sshd Status for the jail: sshd |- Filter | |- Currently failed: 131 | |- Total failed: 13290 | `- File list: /var/log/auth.log `- Actions |- Currently banned: 493 |- Total banned: 494 `- Banned IP list: 123.123.123.123 # 차단/차단 해제 명령어 실제 예시 fail2ban-client set sshd banip 12.12.12.12 fail2ban-client set sshd unbanip 12.12.12.12
sshd 보안옵션 참고
설정 파일은 /etc/ssh/sshd_config 입니다.
• Protocol 2
ssh 1 과 2 중 2.0만 사용하겠다라는 의미 입니다.
1.0 버전이 취약하며 공격자는 중간자 공격으로 SSH Downgrade Attack 할 수 있으므로 반드시 2.0만 사용하도록 sshd_config 설정을 해야 합니다
• LoginGraceTime
=>LoginGraceTime 60
해석을 해보면 “로그인 허용 시간” 정도가 되겠는되요
주석을 풀고 60을 써주면 60초 만 허용하겠다 라는 의미로써 시간은 짧은 수록좋을 것 같습니다
• PermitRootLogin no
root 계정의 접속을 허용치 않겠다 라는 것입니다 yes는 접속허용한다는것임으로 no 로 설정 하시면 됩니다.
• Allow/Deny 옵션
주석에는 없지만 쓸수 있는 옵션으로 아래와 같은 옵션이 있습니다.
AllowGroups
AllowUsers
DenyGoups
DenyUsers
예를 들어 OS 계정의 그룹을 member 라고 설정 하였다면 아래와 같이 설정할 수 있습니다.
AllowGroups member
DenyGroups root
위와 같이 구성 시 member 그룹에 속한 일반계정만 접속이 가능하게 됩니다.
또한 AllowUsers testuser@192.168.0.25 와 같이 IP까지 접속 가능/불가 정책의 기준으로 내용을 넣을 수도 있습니다.
정리하면 root 계정의 로그인 차단/거부와 AllowGroups 나 AllowUsers 를 이용하여 실제 사용하는 유저들만 접속 가능하게 설정 할 수 있습니다.
• PasswordAuthentication no
password 인증을 비활성화 함으로써 키 인증으로만 사용 가능하도록 설정 하는 내역 입니다.
추가적으로 같이 설정할 부분이 공개키 정보의 인증키 파일명 입니다.
AuthorizedKeysFile .ssh/authorized_keys
공개키 정보를 입력할 인증키 파일을 설정 하는 옵션 으로 기본값인 authorized_keys 파일을 사용하면 됩니다.
IPTABLES로 상태확인
# 차단된 아이피 목록 [root@mail ~]# awk '($(NF-1) = /Ban/){print $NF}' /var/log/fail2ban.log | sort | uniq -c | sort -n # IPTABLES 차단목록 확인 [root@mail ~]# iptables -nL [root@mail ~]# iptables -L f2b-sshd # 차단풀기 [root@mail ~]# fail2ban-client set sshd unbanip 000.000.000.000 # 로그 초기화 [root@mail ~]# systemctl stop fail2ban [root@mail ~]# truncate -s 0 /var/log/fail2ban.log sudo rm /var/lib/fail2ban/fail2ban.sqlite3 [root@mail ~]# systemctl start fail2ban