남용을 성공적으로 제한하는 수많은 Postfix 지시문이 있습니다.하지만: 제한이 적용된 후 학대자는 다시 연결하여 동일한 테스트를 다시 실패하는 전체 프로세스를 거칩니다. 연결 클라이언트가 적용한 이전 제한 사항과 관련하여 메모리 지속성은 없습니다.
리소스가 많이 소요되는 지시문이 한 번만 적용된 후 이 루프를 단락시키고 블록으로 바로 이동할 수 있는 솔루션이 있습니까? 이상적으로는 IPv4/IPv6 주소를 모두 블랙리스트에 추가하는 기능을 지원하고 싶습니다.
답변1
업데이트:
저는 솔루션에 대한 실질적인 업데이트를 수행하고 IPv6 지원 및 하우스키핑을 추가하여 범죄자가 서버 공격을 중단한 후 IP를 정리하는 "롤링" 차단 목록을 구현했습니다.
소개:
남용자를 차단할 수 있는 Postfix 지시문은 많지만, 이 지시문의 문제점은 이전 결정을 기억하는 지속성이 없다는 것입니다.따라서 학대자는 끝없이 다시 연결할 수 있으며 동일한 테스트를 통해 트래픽이 다시 실패해야 합니다. 따라서 궁극적인 목표는 이러한 끝없는 남용의 고리를 끊고 첫 번째 리소스 집약적 테스트가 실패한 후 문제가 되는 IP를 금지하는 것입니다.
나는솔루션을 오픈소스로 공개했습니다나는 많은 도메인에 대해 많은 계정을 호스팅하는 내 자신의 (다소) 바쁜 메일 서버를 운영하고 있습니다. 간단히 말해서 RegEx를 사용하여 /var/log/maillog
IPv4 및 IPv6 주소 모두에 대해 남용 패턴을 긁어내는 스크립트를 실행하는 SystemD 서비스 및 타이머를 생성합니다. 테스트는 지금까지 남용을 크게 줄이는 데 성공했습니다.
에서 표본 출력 /etc/postfix/access
. 단일 IPv6 주소를 포함하지 않음:
213.230.115.33 REJECT
213.230.75.114 REJECT
185.66.252.78 REJECT
162.243.133.39 REJECT
104.168.159.38 REJECT
78.128.113.109 REJECT
77.40.3.227 REJECT
77.40.3.101 REJECT
61.163.192.88 REJECT
37.0.20.10 REJECT
26.189.237.221 REJECT
[2001:da8:5066:66:eda:41ff:fe1d:b27] REJECT
그런데, IPv6를 이것과 함께 작동시키는 것은 약간 원숭이 같았지만 결국 거기에 도달했습니다 ;-)
블랙리스트 전략:
2.5개월 만에 약 1200개 이상의 IP가 블랙리스트에 올랐습니다.범죄자 IP를 지속적으로 기록한 내 저장소의 이전 반복을 사용합니다. 이 목록을 주기적으로 정리하는 메커니즘이 없으면 확장성 문제가 발생합니다. 나의 새로운 접근 방식은 롤링 차단 목록을 만드는 것입니다. 즉, 새로운 학대자 IP에 대한 메일 로그를 지속적으로 스크랩하고 더 이상 메일 로그에 표시되지 않는 IP를 삭제하는 것입니다.내가 생각할 수 있는 다른 접근 방식은 IP를 제거하는 데 걸리는 임의의 시간을 기반으로 했습니다.
따라서 로그 교체 후 학대자가 새 메일 로그에 나타나지 않으면 블랙리스트에 포함되지 않습니다. 후속 학대 시도를 하는 경우에만 해당됩니다. IP는 순환 전 메일로그 수명 동안만 블랙리스트에 등록됩니다.
암호
내 테스트에서 주석에 표시된 대로 저장소가 수행된다고 말할 수 있습니다. 하지만 어떤 부분은 더 우아할 수 있다는 점은 의심하지 않습니다. 다음은 비즈니스를 수행하고 동료 검토를 위해 제공되는 주요 스크립트입니다.
생각이나 제안 사항이 있으면 이를 듣거나 나에게 끌어오기 요청을 보내는 것이 좋습니다(개선 사항을 테스트한 후에만 요청하십시오). 스크립트는 테스트하기 쉽습니다.그것은 당신을 위해 모든 것을 수행하며 모든 코드는 잘 설명되어 있습니다.- 긴장을 푸는 것도 마찬가지로 쉽습니다.
참고하세요: 이 스크립트는 에서 "access" 맵을 읽는 지시어가 있는 경우에만 효과가 있습니다 main.cf
.또한 Postfix의 제한적 지시어는 왼쪽에서 오른쪽으로 적용됩니다., 따라서 "액세스" 맵을 읽는 지시문은 더 비싼 테스트를 실행하는 지시문에서 제외되어야 합니다.
저장소에는 일부 테스트만 수행하려는 경우 모든 것을 제거하는 스크립트가 포함되어 있습니다.
cat <<'EOF'> /etc/postfix/access-autoBlacklisting.sh
#!/bin/bash
#
# Author/Developer: Terrence Houlahan Linux Engineer F1Linux.com
# Linkedin: https://www.linkedin.com/in/terrencehoulahan
# License: GPL 3.0
# Source: https://github.com/f1linux/postfix-autoBlacklisting.git
# Version: 03.20.00
# OPERATION:
# ----------
# This script PREPENDS offending IP addresses from "/var/log/maillog" to "/etc/postfix/access"
# This ensures restrictive access rules applied before permissive grants.
# Consult README.md file for more granular detail about this script and its operation.
# Stop timer from executing Blacklisting script: Existing blacklist in /etc/postfix/access is enforce enforced while the new blacklist rebuilds
systemctl stop Postfix-AutoBlacklisting.timer
# Purge blacklist: Blacklist recreated each script execution capturing both previous offending IPs as well as newest ones present in logs
sed -i '/REJECT$/d' /etc/postfix/access
# Purge the scratch file:
> /etc/postfix/access-blacklist
### Scrape log for different forms of abuse using different tests to identify abuse IPs and squirt each to same central file:
# Enable/Disable any of below tests according to your requirements. Adding your own is easy if you use my tests which isolate offending IPs as templates.
# TEST 1: Blacklist Zombie hosts from endlessly squirting spam: These are identified by no PTR record being set for them.
# This test will catch both new zombies as well as those already RBLed which should serve to stop them constantly being endlessly checked against the RBL
# IPv4 Test:
# Below commented test was found to not be 100 perecent as accurate as the one using the awk form. Have not investigated why however.
#grep "does not resolve to address" /var/log/maillog | grep -Eo "([0-9]{1,3}[\.]){3}[0-9]{1,3}" | sort -u >> /etc/postfix/access-blacklist
grep "does not resolve to address" /var/log/maillog | awk 'match($0, /([0-9]{1,3}[\.]){3}[0-9]{1,3}/) {print substr($0, RSTART, RLENGTH)}' | sort -u >> /etc/postfix/access-blacklist
# IPv6 Test:
grep "does not resolve to address" /var/log/maillog | grep -Eo "2[0-9a-fA-F]{3}:(([0-9a-fA-F]{1,4}[:]{1,2}){1,6}[0-9a-fA-F]{1,4})" | sort -u | awk '{print "["$1"]"}' >> /etc/postfix/access-blacklist
# TEST 2: Block spammers guessing account names where they know our domain:
# WARNING: this could potentially cause a block where an unintentional misspelling of an mail account name occured.
# Uncomment only if you are OK with accepting such a risk:
# IPv4 Test:
#grep "Recipient address rejected: User unknown in virtual mailbox table" /var/log/maillog | sed -rn 's/.*\[(([0-9]{,3}.){4})\].*/\1/gp' >> /etc/postfix/access-blacklist
# IPv6 Test:
#grep "Recipient address rejected: User unknown in virtual mailbox table" /var/log/maillog | grep -Eo "2[0-9a-fA-F]{3}:(([0-9a-fA-F]{1,4}[:]{1,2}){1,6}[0-9a-fA-F]{1,4})" | sort -u | awk '{print "["$1"]"}' >> /etc/postfix/access-blacklist
# Populate an array with sorted and depuplicated list of offending IPs scraped from maillog using foregoing tests:
readarray arrayIPblacklist < <( cat /etc/postfix/access-blacklist | sort -u -t . -k 1,1n -k 2,2n -k 3,3n -k 4,4n | sed '/^$/d' )
# If "access" is a new empty file then the subsequent "sed" will fail. Any new file will have a zero size so the '-s' test will not equal 'true'.
# So we use negation to test "true" and echo a blank space to file. The subsequent "sed" will now execute.
# If "access" file already has whitelist entry then the 'if' statement does nothing and "sed" which follows executes as expected for a non-empty file:
if [ ! -s /etc/postfix/access ]; then echo "" > /etc/postfix/access; fi
for i in "${arrayIPblacklist[@]}"; do
# Write list of IPS from array to TOP of "access" file to enforce restrictions BEFORE processing whitelisted "OK" addresses:
sed -i "1i $i" /etc/postfix/access
# Append " REJECT" (with a space prepended in front of it) after each of the IPs added to to the "access" file:
sed -i '1s/$/ REJECT/' /etc/postfix/access
done
# Rebuild the /etc/postfix/access Berkeley DB:
postmap /etc/postfix/access
systemctl reload postfix.service
# After cycle completes and IPs written to /etc/postfix/acces we wipe array which repopulates anew upon next script execution:
unset arrayIPblacklist
systemctl start Postfix-AutoBlacklisting.timer
EOF
결론:
값비싼 테스트가 끝없이 반복되는 것을 막기 위해 이전에 차단한 IP에 대한 메모리의 지속성을 유지하는 시스템으로 왔다고 생각합니다. 완벽합니까? 아마도 약간의 연마 작업이 필요할 수 있지만 지금까지의 테스트 결과는 유망해 보입니다.
귀하의 메일 서버가 스패머들에 의해 끝없이 남용되는 것에 지쳤다면, 가능한 한 빨리 메일 서버를 종료할 수 있는 빠르고 쉬운 솔루션이 있습니다: