최근에 내 Minecraft 서버에서 스팸을 경험했는데, 일종의 포트 스캐너나 다른 봇에서 오는 것으로 의심됩니다. 지금까지는 그것이 무엇이든 실제적인 위협을 가하지는 않지만, 후회하는 것보다 안전한 것이 낫다고 생각합니다. fail2ban
3회 이상 연결 시도에 실패한 IP에 대해 차단을 설정하려고 했습니다 . Reddit에서 동일한 도구를 사용하여 성공을 거둔 다른 사람들을 보았기 때문에 한번 시도해 볼까 생각했습니다.
그러나 나는 약간 붙어 있습니다. Fail2ban 서비스를 시작하려고 할 때마다 다음 오류와 함께 실패합니다.
ERROR Failed during configuration: Have not found any log file for minecraft jail
ERROR Async configuration of server failed
logpath
Google 검색에 따르면 이는 일반적으로 이 "minecraft"에 대한 해당 파일의 구성 옵션이 jail.conf
유효하지 않은 경로를 참조하거나 존재하지 않는 파일을 가리키기 때문인 것으로 나타났습니다. 몇 번이고 확인해보니 제가 지정한 경로가 실제로 존재하는 것을 확인할 수 있어서 뭔가 다른 것 아닌가 하는 생각이 듭니다.
구성 파일을 통해 "minecraft" 장치를 비활성화하고, failure2ban systemd 서비스를 시작하고, "minecraft" 장치를 다시 활성화하고, 명령을 사용하여 fall2ban 서버를 다시 로드하면 fail2ban-client
다음 오류가 발생합니다.
[root@fedora ~]# fail2ban-client reload
2023-06-30 21:37:28,314 fail2ban [4565]: ERROR NOK: (13, 'Permission denied')
[Errno 13] Permission denied: '/path/omitted.log'
흠, 알았어... 권한이 나쁜 것 아닐까? 권한이 방해가 되지 않도록 하기 위해 /tmp
다음 권한이 있는 디렉터리에서 사용할 임시 테스트 파일을 만들었습니다.
[root@fedora ~]# ll -d /tmp
drwxrwxrwt. 29 root root 640 Jun 30 22:10 /tmp
[root@fedora ~]# ll /tmp/testing.log
-rwxrwxrwx. 1 root root 0 Jun 30 21:29 /tmp/testing.log
위에서 다시 로드 프로세스를 반복하면 주사위가 표시되지 않습니다. 내가 무엇을 놓치고 있나요? 누구든지 내가 시도해볼 아이디어가 있나요? 어떤 도움이라도 대단히 감사하겠습니다! 더 자세한 정보가 필요하면 알려주시기 바랍니다.
다음은 위의 다시 로드 프로세스를 수행한 후 (DEBUG 로깅이 활성화된) Fail2ban 서버의 로그 출력입니다.
[root@fedora ~]# tail -n 50 /var/log/fail2ban.log
<output removed for brevity>
2023-06-30 21:37:28,186 fail2ban.server [4553]: INFO Start Fail2ban v1.0.2
2023-06-30 21:37:28,187 fail2ban.server [4553]: INFO Changed logging target to /var/log/fail2ban.log for Fail2ban v1.0.2
2023-06-30 21:37:28,187 fail2ban.ipdns [4553]: DEBUG IPv6 is auto
2023-06-30 21:37:28,187 fail2ban.jail [4553]: INFO Creating new jail 'minecraft'
2023-06-30 21:37:28,311 fail2ban.jail [4553]: DEBUG Backend 'pyinotify' failed to initialize due to No module named 'pyinotify'
2023-06-30 21:37:28,312 fail2ban.jail [4553]: DEBUG Backend 'gamin' failed to initialize due to No module named 'gamin'
2023-06-30 21:37:28,312 fail2ban.jail [4553]: INFO Jail 'minecraft' uses poller {}
2023-06-30 21:37:28,312 fail2ban.filter [4553]: DEBUG Setting usedns = warn for FilterPoll(Jail('minecraft'))
2023-06-30 21:37:28,312 fail2ban.filter [4553]: DEBUG Created FilterPoll(Jail('minecraft'))
2023-06-30 21:37:28,312 fail2ban.filterpoll [4553]: DEBUG Created FilterPoll
2023-06-30 21:37:28,312 fail2ban.jail [4553]: INFO Initiated 'polling' backend
2023-06-30 21:37:28,312 fail2ban.filter [4553]: DEBUG Setting usedns = warn for FilterPoll(Jail('minecraft'))
2023-06-30 21:37:28,312 fail2ban.server [4553]: DEBUG failregex: '\\(\\/<HOST>\\:'
2023-06-30 21:37:28,313 fail2ban.filter [4553]: INFO maxRetry: 3
2023-06-30 21:37:28,313 fail2ban.filter [4553]: INFO findtime: 86400
2023-06-30 21:37:28,313 fail2ban.actions [4553]: INFO banTime: 2592000
2023-06-30 21:37:28,313 fail2ban.filter [4553]: INFO encoding: UTF-8
2023-06-30 21:37:28,313 fail2ban.server [4553]: INFO Reload finished.
2023-06-30 21:37:28,313 fail2ban.transmitter [4553]: ERROR Command ['reload', '--all', [], [['set', 'syslogsocket', 'auto'], ['set', 'loglevel', 'DEBUG'], ['set', 'logtarget', '/var/log/fail2ban.log'], ['set', 'allowipv6', 'auto'], ['set', 'dbfile', '/var/lib/fail2ban/fail2ban.sqlite3'], ['set', 'dbmaxmatches', 10], ['set', 'dbpurgeage', '1d'], ['add', 'minecraft', 'auto'], ['set', 'minecraft', 'usedns', 'warn'], ['set', 'minecraft', 'addfailregex', '\\(\\/<HOST>\\:'], ['set', 'minecraft', 'maxretry', 3], ['set', 'minecraft', 'maxmatches', 3], ['set', 'minecraft', 'findtime', '1d'], ['set', 'minecraft', 'bantime', '30d'], ['set', 'minecraft', 'ignorecommand', ''], ['set', 'minecraft', 'logencoding', 'auto'], ['set', 'minecraft', 'addlogpath', '/tmp/testing.log', 'head'], ['set', 'minecraft', 'addaction', 'firewallcmd-rich-rules'], ['multi-set', 'minecraft', 'action', 'firewallcmd-rich-rules', [['actionstart', ''], ['actionstop', ''], ['actioncheck', ''], ['actionban', 'ports="0:65535"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --add-rich-rule="rule family=\'<family>\' source address=\'<ip>\' port port=\'$p\' protocol=\'tcp\' reject type=\'<rejecttype>\'"; done'], ['actionunban', 'ports="0:65535"; for p in $(echo $ports | tr ", " " "); do firewall-cmd --remove-rich-rule="rule family=\'<family>\' source address=\'<ip>\' port port=\'$p\' protocol=\'tcp\' reject type=\'<rejecttype>\'"; done'], ['port', '0:65535'], ['protocol', 'tcp'], ['chain', '<known/chain>'], ['name', 'minecraft'], ['actname', 'firewallcmd-rich-rules'], ['family', 'ipv4'], ['zone', 'public'], ['service', 'ssh'], ['rejecttype', 'icmp-port-unreachable'], ['blocktype', 'REJECT --reject-with <rejecttype>'], ['rich-blocktype', "reject type='<rejecttype>'"], ['family?family=inet6', 'ipv6'], ['rejecttype?family=inet6', 'icmp6-port-unreachable']]], ['start', 'minecraft']]] has failed. Received PermissionError(13, 'Permission denied')
Traceback (most recent call last):
File "/usr/lib/python3.11/site-packages/fail2ban/server/transmitter.py", line 58, in proceed
ret = self.__commandHandler(command)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/fail2ban/server/transmitter.py", line 109, in __commandHandler
self.__commandHandler(cmd)
File "/usr/lib/python3.11/site-packages/fail2ban/server/transmitter.py", line 89, in __commandHandler
return self.__commandSet(command[1:])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/fail2ban/server/transmitter.py", line 258, in __commandSet
self.__server.addLogPath(name, value, tail)
File "/usr/lib/python3.11/site-packages/fail2ban/server/server.py", line 382, in addLogPath
filter_.addLogPath(fileName, tail)
File "/usr/lib/python3.11/site-packages/fail2ban/server/filter.py", line 1006, in addLogPath
log = FileContainer(path, self.getLogEncoding(), tail)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/fail2ban/server/filter.py", line 1327, in __init__
handler = open(filename, 'rb')
^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied: '/tmp/testing.log'
답변1
링크를 공유해 주신 @roaima에게 감사드립니다.CentOS 7에 fall2ban 설치, 이 문제를 해결하는 길로 인도했습니다.
간단히 말해서:
문제는 SELinux에 있습니다. 이를 비활성화하거나 액세스 제어 정책을 변경하거나 로그 파일이 저장되는 위치를 변경하는 것이 이 문제를 해결하는 유일한 방법입니다.
해결책:
SELinux 문제에 대한 빠르고 더러운 수정 및/또는 확인은 SELinux의 시행 정책을 "강제" 대신 "허용"으로 설정하는 것입니다. 제공된 설명에 따르면이 Red Hat 도움말 문서, SELinux의 시행 정책을 "권한"으로 설정하면 모든 액세스 제어 정책의 시행이 효과적으로 비활성화됩니다. 따라서 SELinux 액세스 정책이 프로세스가 로그 파일에 액세스할 수 없는 이유인 경우 fail2ban-server
이를 비활성화하면 SELinux가 문제인지 여부를 알 수 있습니다. 이는 다음과 유사한 작업을 수행하여 수행할 수 있습니다.
[root@kaleb-desktop ~]# sestatus | grep "Current mode"
Current mode: enforcing
[root@kaleb-desktop ~]# setenforce 0
[root@kaleb-desktop ~]# sestatus | grep "Current mode"
Current mode: permissive
[root@kaleb-desktop ~]#
이제 나와 비슷한 상황에 처해 있고 위의 작업을 수행하면 갑자기 fail2ban
원하는 로그 파일에 액세스할 수 있게 된다면 운이 좋은 것입니다. 그렇지 않다면 불행하게도 다른 문제가 있을 수 있습니다. SELinux를 유지하고 싶지 않다면 위의 방법으로 충분하다고 생각합니다. 그러나 반드시 SELinux를 완전히 제거하고 싶지는 않습니다.
시스템 감사 로그를 자세히 살펴보면 SELinux가 실제로 문제에 대한 보다 영구적인 솔루션을 제공한다는 것을 알 수 있습니다. 실행하면 sealert -l "*"
(Fedora 38 시스템에 수동으로 설치해야 함) 다음과 같은 결과가 출력됩니다.
SELinux is preventing fail2ban-server from open access on the file /tmp/testing.log.
***** Plugin catchall (100. confidence) suggests **************************
If you believe that fail2ban-server should be allowed open access on the testing.log file by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'fail2ban-server' --raw | audit2allow -M my-fail2banserver
# semodule -X 300 -i my-fail2banserver.pp
출력에 명시된 대로 권장되는 솔루션은 기존 정책 위에 적용할 수 있는 로컬 정책 모듈을 만드는 것입니다. 그러나 @roaima가 공유한 허용된 솔루션에서 지적했듯이 이 정책은 향후 패키지 업데이트에 의해 재정의될 수 있습니다 selinux-policy
.
따라서 최종적이고 가장 영구적인 해결 방법은 기존 SELinux 액세스 제어 정책을 만족하는 디렉터리로 로그를 이동하는 것입니다. 내 경우에는 /var/log
SELinux가 만족스러워 보이는 하위 디렉터리 로 로그를 이동할 수 있었습니다 . YMMV.
journalctl -lfu fail2ban
또한 내 시스템의 출력이 @roaima가 공유한 링크의 출력을 반영하지 않는다는 점도 언급하고 싶었습니다 . 이 질문은 8년 전에 요청되었으므로 문서화 방법에 있어 많은 변화가 있었을 수 있으므로 이에 유의하시기 바랍니다.
장황하게 말해서 미안하지만, 이전에 이해하지 못했던 것을 탐구하고 반대편에서 더 나은 이해를 할 수 있는 기회를 주셔서 감사합니다. 이 설명이 비슷한 상황에 있는 다른 사람들에게도 도움이 되기를 바랍니다!