Skip to content

Instantly share code, notes, and snippets.

@Strykar
Last active July 13, 2023 19:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Strykar/f190bcc36778e1119d70b15eace0bafe to your computer and use it in GitHub Desktop.
Save Strykar/f190bcc36778e1119d70b15eace0bafe to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import sys
import dns.resolver
def resolve_ips(domain, resolver):
ips = []
try:
ips += [str(rdata) for rdata in resolver.resolve(domain, 'A')]
except (dns.resolver.NoAnswer, dns.resolver.Timeout):
pass
try:
ips += [str(rdata) for rdata in resolver.resolve(domain, 'AAAA')]
except (dns.resolver.NoAnswer, dns.resolver.Timeout):
pass
return ips
# Resolving hostnames to IP addresses using 8.8.8.8 DNS server
resolver1 = dns.resolver.Resolver()
resolver1.nameservers = ['8.8.8.8']
resolver1.timeout = 27.5
resolver1.lifetime = 27.5
INGEST_IPS = resolve_ips('ingest.multiorch.com', resolver1)
V1_IPS = resolve_ips('i5.4v1.in', resolver1)
# If resolution was unsuccessful, try with 1.1.1.1 DNS server
if not INGEST_IPS or not V1_IPS:
resolver2 = dns.resolver.Resolver()
resolver2.nameservers = ['1.1.1.1']
resolver2.timeout = 27.5
resolver2.lifetime = 27.5
if not INGEST_IPS:
INGEST_IPS = resolve_ips('ingest.multiorch.com', resolver2)
if not V1_IPS:
V1_IPS = resolve_ips('i5.4v1.in', resolver2)
# Check if IP is from ingest.multiorch.com or i5.4v1.in
if sys.argv[1] in INGEST_IPS + V1_IPS:
sys.exit(0)
# If IP was not from the allowed hosts, return 1
sys.exit(1)
@Strykar
Copy link
Author

Strykar commented Jul 13, 2023

13:31 --> Strykar (~wakka@signald/Strykar) has joined #fail2ban
13:31 -- Channel #fail2ban: 29 nicks (0 ops, 0 voiced, 29 regular)
13:32 -- Channel created on Sat, 22 May 2021 23:35:38
19:10 <Strykar> "ignoreip" resolves dns names with multiple IPs correctly right? https://www.fail2ban.org/wiki/index.php/Whitelist says "ignoreip" can be an IP address, a CIDR mask or a DNS host.
19:33 <sebres> Strykar: yes, just note that in new versions of f2b this dns-resolve caching those host->IPs for 5 minutes
19:36 <sebres> ... so if DNS is changing, f2b would get it at last in 5 minutes (+ N minutes by DNS servers by its TTL)
20:08 <Strykar> sebres: that sounds reasonable, can I force it to use external DNS, his hostname resolves to over 30 IPs and its failing on some machines probably because it wants to do it over TCP
20:13 <sebres> Strykar: only fail2ban? unfortunately no - it uses default python resolver (so basically system resolver)... but you can use ignorecommand instead (together with ignorecache), see https://github.com/fail2ban/fail2ban/issues/2013#issuecomment-426940189 for example
20:22 <Strykar> sebres: so as long as my ignorecommand script outputs a space separated list of IPs I can combine it with ignorecache to force using an external resolves? As easy as: dig +short my.host.com @8.8.8.8 | tr '\n' ' '
20:30 <sebres> no ignorecommand must return exit code 0 for ignore, or 1 otherwise (like in example `"<ip>" = "10.0.0.1"` would ignore 10.0.0.1 and ban other)... so you have to check in the script the IP belongs to resolved list or not
20:31 <sebres> ... and ignorecache simply cashes result for a key (IP in example) and doesn't call it 5 minutes long
20:32 <sebres> see man jail.conf(5) for details - https://manpages.debian.org/experimental/fail2ban/jail.conf.5.en.html#ignorecommand
21:10 <Strykar> sebres: I think I got it now: 1) ignorecache = key="<ip>", max-count=50, max-time=5m  2) ignorecommand = /home/strykar/.bin/f2b_ignore.sh "<ip>" #Returns 0 for IPs that should not be banned
21:12 <sebres> xctly
21:12 <Strykar> this is better than just being able to use a specified DNS, thank you!!
21:12 <sebres> yw
22:51 <Strykar> Here's the python script I came up with in case its useful to anyone else, works for both IPv4 and IPv6 addresses and hostnames - https://gist.github.com/Strykar/f190bcc36778e1119d70b15eace0bafe
22:57 <sebres> Strykar: looks nice, just... since it uses external resolver, the question of timeout is not really cleared in script
22:58 <sebres> here is an example how it can look with a timeout - https://github.com/fail2ban/fail2ban/blob/48c91dfb6bd8478968c226d0c6ca965bdce2768d/config/filter.d/ignorecommands/apache-fakegooglebot#L24
22:59 <sebres> ... since fail2ban has 60 seconds for ignorecommand, see related issue https://github.com/fail2ban/fail2ban/issues/2951
23:04 <sebres> although the problem with timeout in #2951 is similar, but the command uses reverse lookup (to identify googlebot) and because "real" googlebots must be normally resolved fast, so the solution with 55 secs (that causes a positive case) is justified there
23:13 <Strykar> sebres: added timeouts and the ability to use a second nameserver if resolution fails at first - https://bpa.st/4YKRE
23:16 <sebres> +1, just 55 must be whole timeout (in your case it still can fail, since in 60 seconds fail2ban will stop the command, and second resolver will have max 5 seconds to resolve)
23:18 <Strykar> ah, so set resolver1.timeout = 27.5  resolver1.lifetime = 27.5
23:18 <sebres> yup
23:19 <Strykar> cheers!
23:28 <sebres> Strykar: what you can do additionally, if resolving will not be cached internally, to cache INGEST_IPS and V1_IPS in some local file/sqlite-db (for few minutes)
23:30 <sebres> also note that you don't need IP_RANGES, since it can be added by ignoreip and always wins against ignorecommand (so don't need to invoke it at all if ignored there)
23:34 <Strykar> oh wait, I can use ignoreip AND ignorecommand and they will match one after the other?
23:37 <sebres> yes, rtfm :) - https://manpages.debian.org/experimental/fail2ban/jail.conf.5.en.html#ignorecommand
23:37 <sebres> The option affects additionally to ignoreself and ignoreip and will be first executed if both don't hit.
00:39 <Strykar> I had, this could be clearer IMO "The option affects additionally to ignoreself and ignoreip and will be first executed if both don't hit."  Something like "This option operates alongside the ignoreself and ignoreip options. It is executed first, only if neither ignoreself nor ignoreip match the criteria."
00:39 <Strykar> I had read that, it didn't register, which is my fault 
00:42 <sebres> np, you can also provide a PR for that man with improved wording
00:45 <sebres> https://github.com/fail2ban/fail2ban/edit/master/man/jail.conf.5#L249

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment