우분투 20.04에서 Fail2Ban으로 SSH 보호하는 방법

소개

SSH는 클라우드 서버에 연결하는 사실상의 방법입니다. 이것은 견고하며, 확장 가능합니다. 새로운 암호화 표준이 개발됨에 따라 새로운 SSH 키를 생성하는 데 사용할 수 있어 핵심 프로토콜이 안전하게 유지됩니다. 그러나 어떤 프로토콜이나 소프트웨어 스택도 완벽하게 방어되지 않으며, 인터넷 전역에 SSH가 널리 배포되어 있기 때문에 매우 예측 가능한 공격 대상 또는 공격 벡터로 작용하여 사용자가 액세스를 시도할 수 있습니다.

네트워크에 노출된 모든 서비스는 이와 같은 잠재적인 대상입니다. 널리 알려진 서버에서 실행 중인 SSH 서비스의 로그를 검토하면 사용자 및 봇에 의한 반복적이고 체계적인 로그인 시도를 자주 볼 수 있습니다. 이러한 공격이 성공할 가능성을 거의 제로에 가깝게 줄이기 위해 SSH 키를 사용하여 암호 인증을 비활성화하는 등 SSH 서비스에 일부 최적화를 수행할 수 있지만, 이러한 공격은 여전히 소규모이고 지속적인 위협이 될 수 있습니다.

대규모 생산 배포에서는 이러한 책임이 완전히 용인되지 않는 경우가 일반적으로 VPN을 구현합니다. 예를 들어 WireGuard 와 같은 것을 사용하여 SSH 서비스 앞에 두어 외부 인터넷에서 기본 SSH 포트 22에 직접 연결할 수 없게 하고 추가 소프트웨어 추상화나 게이트웨이 없이는 연결할 수 없게 합니다. 이러한 VPN 솔루션은 널리 신뢰되지만, 복잡성을 추가하며, 일부 자동화나 기타 소프트웨어 훅을 망가뜨릴 수 있습니다.

VPN 설정을 완전히 적용하기 전이나 추가로, Fail2ban이라는 도구를 구현할 수 있습니다. Fail2ban은 로그인 시도 횟수가 일정 수준 이상인 특정 IP를 금지하는 방화벽 구성을 자동으로 변경하여 암호 공격을 심각하게 줄일 수 있습니다. 이렇게 하면 서버가 개입없이 액세스 시도에 대항하여 스스로를 강화할 수 있습니다.

이 가이드에서는 Ubuntu 20.04 서버에 Fail2ban을 설치하고 사용하는 방법을 살펴보겠습니다.

전제 조건

이 가이드를 완료하려면 다음이 필요합니다:

  • Ubuntu 20.04 서버 및 sudo 권한이 있는 비루트 사용자. 이러한 권한을 가진 사용자를 설정하는 방법에 대해 자세히 알아보려면 Ubuntu 20.04에서 초기 서버 설정 가이드를 참조하십시오.

  • 선택적으로, 첫 번째 서버에 연결할 수 있는 두 번째 서버가 있습니다. 이 서버는 의도적으로 차단되는 것을 테스트하는 데 사용됩니다.

단계 1 — Fail2ban 설치

Fail2ban은 우분투의 소프트웨어 저장소에서 사용할 수 있습니다. 패키지 목록을 업데이트하고 Fail2ban을 설치하려면 다음 명령을 비루트 사용자로 실행합니다:

  1. sudo apt update
  2. sudo apt install fail2ban

Fail2ban은 설치 후 자동으로 백그라운드 서비스를 설정합니다. 그러나 기본적으로 비활성화되어 있습니다. 기본 설정 중 일부는 원하지 않는 효과를 일으킬 수 있기 때문입니다. 다음 명령을 사용하여 이를 확인할 수 있습니다:

  1. systemctl status fail2ban.service
Output
○ fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; disabled; vendor preset: enabled Active: inactive (dead) Docs: man:fail2ban(1)

Fail2ban을 즉시 활성화할 수 있지만, 먼저 몇 가지 기능을 검토합니다.

단계 2 – Fail2ban 구성

fail2ban 서비스는 설정 파일을 /etc/fail2ban 디렉터리에 보관합니다. 기본 파일 이름은 jail.conf입니다. 해당 디렉터리로 이동하고 head -20을 사용하여 그 파일의 첫 20 줄을 출력하세요:

  1. cd /etc/fail2ban
  2. head -20 jail.conf
Output
# # 경고: 0.9.0 릴리스에서 크게 재구성되었습니다. 설정을 검토하고 # 귀하의 설정에 맞게 사용자 지정하십시오. # # 변경 사항: 대부분의 경우 이 파일을 수정하지 않아야하지만 # jail.local 파일이나 jail.d/ 디렉토리 아래의 별도의 .conf 파일에서 사용자 지정을 제공하십시오. # 예를 들어: # # JAIL을 활성화하는 방법: # # 이 파일을 수정해서는 안됩니다. # # 배포 업데이트에서 덮어쓰거나 개선될 가능성이 있습니다. # # jail.local 파일 또는 jail.d/customisation.local에 사용자 지정을 제공하십시오. # 예를 들어, 모든 jail의 기본 차단 시간을 변경하고 # ssh-iptables jail을 활성화하려면 (.local 파일에 주석 처리 된) # 아래와 같이 나타납니다.# 자세한 내용은 man 5 jail.conf를 참조하십시오. # # [DEFAULT]

파일의 처음 여러 줄은 주석 처리되어 있습니다 – 이것들은 # 문자로 시작하여 설정이 아닌 문서로 읽히도록 지시합니다. 또한 이러한 주석이 이 파일을 직접 수정하지 말라고 안내하고 있습니다. 대신 두 가지 옵션이 있습니다. Fail2ban에 대한 개별 프로필을 jail.d/ 디렉토리 내의 여러 파일에 생성하거나 로컬 설정을 jail.local 파일에 만들고 수집합니다. jail.conf 파일은 Fail2ban 자체가 업데이트될 때 정기적으로 업데이트되며, 생성하지 않은 기본 설정의 원본으로 사용됩니다.

이 튜토리얼에서는 jail.local을 생성합니다. 이를 위해 jail.conf을 복사할 수 있습니다:

  1. sudo cp jail.conf jail.local

이제 구성 변경을 시작할 수 있습니다. 파일을 nano 또는 선호하는 텍스트 편집기로 엽니다:

  1. sudo nano jail.local

파일을 스크롤하는 동안이 튜토리얼에서는 업데이트하고자 하는 몇 가지 옵션을 검토합니다. 파일 상단 근처에 있는 [DEFAULT] 섹션 아래에 있는 설정은 Fail2ban이 지원하는 모든 서비스에 적용됩니다. 파일의 다른 곳에는 [sshd] 및 기타 서비스에 대한 헤더가 있으며, 이 헤더에는 기본 설정보다 우선적으로 적용되는 서비스별 설정이 포함됩니다.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
bantime = 10m
. . .

bantime 매개변수는 클라이언트가 올바르게 인증하지 못했을 때 차단될 시간을 설정합니다. 이는 초 단위로 측정됩니다. 기본적으로 10분으로 설정되어 있습니다.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
findtime = 10m
maxretry = 5
. . .

다음 두 매개변수는 findtimemaxretry입니다. 이들은 클라이언트가 금지되어야 하는 불법 사용자로 판명되는 조건을 설정하는 데 함께 작동합니다.

maxretry 변수는 클라이언트가 금지되기 전에 findtime에 의해 정의된 시간 창 내에서 인증을 시도할 수 있는 횟수를 설정합니다. 기본 설정에서, fail2ban 서비스는 10분간 5회의 로그인 시도에 실패한 클라이언트를 금지합니다.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
destemail = root@localhost
sender = root@<fq-hostname>
mta = sendmail
. . .

Fail2ban이 조치를 취할 때 이메일 알림을 받으려면 destemail, sendername, 그리고 mta 설정을 평가해야 합니다. destemail 매개변수는 금지 메시지를 받을 이메일 주소를 설정합니다. sendername은 이메일의 “보낸 사람” 필드의 값을 설정합니다. mta 매개변수는 메일을 보내는 데 사용할 메일 서비스를 구성합니다. 기본적으로, 이는 sendmail이지만, Postfix나 다른 메일 솔루션을 사용할 수도 있습니다.

/etc/fail2ban/jail.local
[DEFAULT]
. . .
action = $(action_)s
. . .

이 매개변수는 Fail2ban이 금지를 시행할 때 취하는 조치를 구성합니다. 값 action_은 이 매개변수 바로 전 파일에서 정의됩니다. 기본 조치는 금지 시간이 경과할 때까지 거부된 호스트의 트래픽을 방화벽 구성을 업데이트하는 것입니다.

위에서 $(action_)을 대체할 수 있는 기본 제공 action_ 스크립트가 있습니다:

/etc/fail2ban/jail.local
…
# 금지 및 whois 보고서를 destemail로 이메일로 보내십시오.
action_mw = %(action_)s
            %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

# 금지 및 whois 보고서 및 관련 로그 라인을 포함하여 이메일을 보내십시오.
# to the destemail로
action_mwl = %(action_)s
             %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]

# 이 작업을 사용하는 시기에 대한 중요한 참고 사항은 action.d/xarf-login-attack에서 확인하십시오
#
# 금지 및 IP 주소의 위반자에 대한 xarf 이메일을 보내고 관련 로그 라인을 포함하십시오
# to the destemail로
action_xarf = %(action_)s
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]

# CloudFlare에서 IP를 차단하고 whois 보고서 및 관련 로그 라인을 이메일로 보내십시오
# to the destemail로
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
                %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]
…

예를 들어, action_mw가 작업을 수행하고 이메일을 보내고, action_mwl이 작업을 수행하고 이메일을 보내고 로깅을 포함하며, action_cf_mwl은 모두 수행하며 Cloudflare에 대한 업데이트를 보내 이곳에 위반자를 차단합니다.

개별 감옥 설정

다음은 개별 서비스에 대한 구성 파일 부분입니다. 이들은 [sshd]와 같은 섹션 헤더로 지정됩니다.

이러한 각 섹션은 헤더 아래에 enabled = true 줄을 추가하여 개별적으로 활성화되어야 합니다. 다른 설정과 함께.

/etc/fail2ban/jail.local
[jail_to_enable]
. . .
enabled = true
. . .

기본적으로 SSH 서비스가 활성화되어 있고 다른 서비스는 모두 비활성화되어 있습니다.
여기에 설정된 몇 가지 다른 설정은 로그의 특정 서비스에 대한 로그가 실패한 인증을 나타내는지 결정할 filter와 해당 서비스의 로그가 위치한 위치를 fail2ban에 알려주는 logpath입니다.

filter 값은 실제로 /etc/fail2ban/filter.d 디렉토리에 있는 파일을 가리키며, 여기서는 .conf 확장자가 제거됩니다. 이러한 파일에는 로그의 특정 라인이 실패한 인증 시도인지를 결정하는 정규 표현식(텍스트 파싱의 일반적인 약칭)이 포함되어 있습니다. 이 가이드에서는 이러한 파일을 자세히 다루지 않겠습니다. 왜냐하면 그들은 꽤 복잡하고 미리 정의된 설정이 적절한 라인과 잘 일치하기 때문입니다.

그러나 해당 디렉토리를 살펴보면 사용 가능한 필터 유형을 확인할 수 있습니다:

  1. ls /etc/fail2ban/filter.d

사용 중인 서비스와 관련된 것으로 보이는 파일을 찾으면 텍스트 편집기로 열어야 합니다. 대부분의 파일은 꽤 잘 주석이 달려 있으며 적어도 스크립트가 어떤 유형의 조건을 막기 위해 설계되었는지 알 수 있어야 합니다. 이러한 필터 대부분은 원하는 경우 jail.conf 파일에서 활성화할 수 있는 적절한 (비활성화된) 섹션을 가지고 있습니다.

예를 들어, Nginx를 사용하여 웹 사이트를 제공하고 있으며 사이트의 암호로 보호된 부분이 로그인 시도로 인해 과부하되고 있다고 가정해보십시오. Fail2ban에게 /var/log/nginx/error.log 파일 내에서 이 조건을 확인하도록 nginx-http-auth.conf 파일을 사용하도록 지시할 수 있습니다.

실제로 이것은 이미 /etc/fail2ban/jail.conf 파일의 [nginx-http-auth] 섹션에 설정되어 있습니다. 단지 enabled 매개변수를 추가하면 됩니다:

/etc/fail2ban/jail.local
. . .
[nginx-http-auth]

enabled = true
. . .

편집을 마치면 파일을 저장하고 닫으십시오. 이 시점에서 Fail2ban 서비스를 활성화하여 앞으로 자동으로 실행되도록 할 수 있습니다. 먼저 systemctl enable을 실행하십시오:

  1. sudo systemctl enable fail2ban

그런 다음 첫 번째로 수동으로 시작하십시오. systemctl start를 사용하여:

  1. sudo systemctl start fail2ban

실행 여부를 확인할 수 있습니다. systemctl status를 사용하여:

  1. sudo systemctl status fail2ban
Output
● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enab> Active: active (running) since Tue 2022-06-28 19:29:15 UTC; 3s ago Docs: man:fail2ban(1) Main PID: 39396 (fail2ban-server) Tasks: 5 (limit: 1119) Memory: 12.9M CPU: 278ms CGroup: /system.slice/fail2ban.service └─39396 /usr/bin/python3 /usr/bin/fail2ban-server -xf start Jun 28 19:29:15 fail2ban20 systemd[1]: Started Fail2Ban Service. Jun 28 19:29:15 fail2ban20 fail2ban-server[39396]: Server ready

다음 단계에서는 Fail2ban이 작동하는 것을 보여줄 것입니다.

단계 3 — 차단 정책 테스트 (선택 사항)

향후 Fail2ban 서버에 로그인할 필요가 없는 다른 서버에서 두 번째 서버를 금지시켜 규칙을 테스트할 수 있습니다. 두 번째 서버에 로그인한 후 Fail2ban 서버로 SSH 연결을 시도해 보십시오. 존재하지 않는 이름을 사용하여 연결을 시도할 수 있습니다:

  1. ssh blah@your_server

비밀번호 프롬프트에 무작위 문자를 입력하십시오. 이를 몇 번 반복하십시오. 어느 시점에서 Permission denied에서 Connection refused로 받는 오류가 바뀔 것입니다. 이것은 두 번째 서버가 Fail2ban 서버에서 금지되었음을 나타냅니다.

Fail2ban 서버에서 iptables 출력을 확인하여 새 규칙을 볼 수 있습니다. iptables는 서버의 낮은 수준의 포트 및 방화벽 규칙과 상호 작용하기 위한 명령입니다. DigitalOcean의 초기 서버 설정 가이드에 따랐다면 더 높은 수준에서 방화벽 규칙을 관리하기 위해 ufw를 사용할 것입니다. iptables -S를 실행하면 ufw가 이미 생성한 모든 방화벽 규칙을 보여줍니다:

  1. sudo iptables -S
Output
-P INPUT DROP -P FORWARD DROP -P OUTPUT ACCEPT -N f2b-sshd -N ufw-after-forward -N ufw-after-input -N ufw-after-logging-forward -N ufw-after-logging-input -N ufw-after-logging-output -N ufw-after-output -N ufw-before-forward -N ufw-before-input -N ufw-before-logging-forward -N ufw-before-logging-input -N ufw-before-logging-output …

iptables -S의 출력을 grep에 파이프하여 해당 규칙에서 f2b 문자열을 검색하면 fail2ban에 의해 추가된 규칙을 볼 수 있습니다:

  1. sudo iptables -S | grep f2b
Output
-N f2b-sshd -A INPUT -p tcp -m multiport --dports 22 -j f2b-sshd -A f2b-sshd -s 134.209.165.184/32 -j REJECT --reject-with icmp-port-unreachable -A f2b-sshd -j RETURN

Fail2ban에 의해 추가된 REJECT --reject-with icmp-port-unreachable를 포함한 줄은 두 번째 서버의 IP 주소를 반영해야 합니다.

결론

지금은 서비스에 대한 일부 금지 정책을 구성할 수 있어야 합니다. Fail2ban은 인증을 사용하는 모든 종류의 서비스를 보호하는 유용한 방법입니다. fail2ban이 어떻게 작동하는지에 대해 더 알고 싶다면, fail2ban 규칙 및 파일이 작동하는 방법에 대한 자습서를 확인할 수 있습니다.

다른 서비스를 보호하기 위해 fail2ban을 사용하는 방법에 대한 정보는 Ubuntu 14.04에서 Fail2Ban을 사용하여 Nginx 서버를 보호하는 방법Ubuntu 14.04에서 Fail2Ban을 사용하여 Apache 서버를 보호하는 방법을 읽어보세요.

Source:
https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-ubuntu-20-04