Debian 11에서 Fail2Ban으로 SSH 보호하는 방법

소개

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

네트워크에 노출된 어떤 서비스든 이와 같은 방식으로 잠재적인 대상이 될 수 있습니다. 널리 사용되는 서버에서 실행 중인 SSH 서비스의 로그를 검토하면 사용자 및 봇에 의한 반복적이고 체계적인 로그인 시도가 종종 보입니다. 비록 SSH 키를 사용하여 비밀번호 인증을 비활성화하는 것과 같은 SSH 서비스의 일부 최적화를 통해 이러한 공격이 성공할 가능성을 거의 제로에 가깝게 줄일 수 있지만, 이는 여전히 소량의 계속되는 위협이 될 수 있습니다.

대규모 생산 배포에서 이러한 책임을 완전히 허용할 수 없는 경우, 보통 와이어가드(WireGuard)와 같은 VPN을 SSH 서비스 앞에 구현하여 외부 인터넷에서 기본 SSH 포트 22에 직접 연결할 수 없도록 추가 소프트웨어 추상화나 게이트웨이 없이는 불가능하게 합니다. 이러한 VPN 솔루션은 널리 신뢰받지만 복잡성을 추가하고 일부 자동화 또는 다른 작은 소프트웨어 후크를 망가뜨릴 수 있습니다.

전체 VPN 설정에 앞서 또는 추가로 Fail2ban이라는 도구를 구현할 수 있습니다. Fail2ban은 특정 IP를 일정 횟수의 로그인 시도 실패 후에 방화벽 구성을 자동으로 변경하여 브루트 포스 공격을 상당히 완화할 수 있습니다. 이를 통해 서버가 당신의 개입 없이 이러한 접근 시도에 대한 자체 보호를 강화할 수 있습니다.

이 안내서에서는 Debian 11 서버에 Fail2ban을 설치하고 사용하는 방법을 살펴볼 것입니다.

전제 조건

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

  • Debian 11 서버 및 sudo 권한이 있는 비 루트 사용자. 이러한 권한을 갖는 사용자를 설정하는 방법에 대해 더 알아보려면 Debian 11 초기 서버 설정 가이드를 참조하세요.

  • 선택적으로, 의도적으로 금지된 상태를 테스트할 첫 번째 서버에 연결할 수 있는 두 번째 서버가 필요합니다.

단계 1 — Fail2ban 설치하기

Fail2ban은 Debian의 소프트웨어 저장소에 있습니다. 패키지 목록을 업데이트하고 Fail2ban을 설치하기 위해 다음 명령을 루트가 아닌 사용자로 실행하세요:

  1. sudo apt update
  2. sudo apt install fail2ban

Fail2ban은 설치된 후에 자동으로 백그라운드 서비스를 설정합니다. 상태를 확인하려면 systemctl 명령을 사용할 수 있습니다:

  1. systemctl status fail2ban.service
Output
● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled Active: active (running) since Tue 2022-06-28 16:23:14 UTC; 17s ago Docs: man:fail2ban(1) Process: 1942 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS Main PID: 1943 (fail2ban-server) Tasks: 5 (limit: 1132) Memory: 15.8M CPU: 280ms CGroup: /system.slice/fail2ban.service └─1943 /usr/bin/python3 /usr/bin/fail2ban-server -xf start

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.local 파일 또는 jail.d/customisation.local에서 사용자 정의를 제공하십시오. # 예를 들어 모든 감옥에 대한 기본 금지 시간을 변경하고 # ssh-iptables 감옥을 활성화하려면 (.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 보고서 및 관련 로그 라인을 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 이메일 보내기 및 관련 로그 라인을 destemail로 보내기
#를 포함합니다.
action_xarf = %(action_)s
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]

# CloudFlare에서 IP 금지 및 whois 보고서 및 관련 로그 라인을 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은 모든 위의 동작을 수행하고 추가로 클라우드플레어 API에 사용자 계정과 연관된 가해자를 금지하기 위해 업데이트를 보냅니다.

개별 감옥 설정

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

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

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

기본적으로 SSH 서비스는 활성화되어 있고, 다른 모든 서비스는 비활성화되어 있습니다.
.
여기에 설정된 다른 일부 설정은 로그에서 인증 실패를 나타내는지 여부를 결정하는 filter 및 해당 서비스의 로그가 위치한 곳을 알려주는 logpath입니다.

filter 값은 실제로 /etc/fail2ban/filter.d 디렉토리에 위치한 파일에 대한 참조이며, 그 파일의 .conf 확장자가 제거됩니다. 이러한 파일에는 로그의 한 줄이 인증 실패 시도인지를 결정하는 정규 표현식이 들어 있습니다(텍스트 구문 분석의 일반적인 약칭). 이 가이드에서는 이러한 파일을 깊이 있게 다루지 않겠습니다. 이 파일들은 꽤 복잡하며 미리 정의된 설정이 적절한 줄과 일치합니다.

그러나 해당 디렉토리를 살펴보면 어떤 종류의 필터가 있는지 확인할 수 있습니다:

  1. ls /etc/fail2ban/filter.d

사용 중인 서비스와 관련된 것 같은 파일을 본다면 텍스트 편집기로 열어보아야 합니다. 대부분의 파일은 꽤 잘 주석이 달려 있으며 적어도 스크립트가 어떤 종류의 조건을 지켜야 하는지 알 수 있습니다. 이러한 필터 대부분은 원하는 경우 jail.local 파일에서 활성화할 수 있는 적절한(비활성화된) 섹션을 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
. . .

파일 편집을 완료하면 저장하고 닫으십시오. 변경 사항이 있으면 systemctl을 사용하여 Fail2ban 서비스를 다시 시작할 수 있습니다:

  1. sudo systemctl restart fail2ban

다음 단계에서 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

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

결론

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

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

Source:
https://www.digitalocean.com/community/tutorials/how-to-protect-ssh-with-fail2ban-on-debian-11