mirror of https://github.com/fail2ban/fail2ban
don't add subnets to local addresses of `ignoreself` from network interfaces, use only IPs instead (subnets may be too heavy and not wanted, todo: make it configurable later)
parent
cb8674e68a
commit
582436aadf
|
@ -669,13 +669,28 @@ IPAddr.IP6_4COMPAT = IPAddr("::ffff:0:0", 96)
|
||||||
|
|
||||||
class IPAddrSet(set):
|
class IPAddrSet(set):
|
||||||
|
|
||||||
|
hasSubNet = False
|
||||||
|
|
||||||
|
def __init__(self, ips=[]):
|
||||||
|
ips2 = set()
|
||||||
|
for ip in ips:
|
||||||
|
if not isinstance(ip, IPAddr): ip = IPAddr(ip)
|
||||||
|
ips2.add(ip)
|
||||||
|
self.hasSubNet |= not ip.isSingle
|
||||||
|
set.__init__(self, ips2)
|
||||||
|
|
||||||
|
def add(self, ip):
|
||||||
|
if not isinstance(ip, IPAddr): ip = IPAddr(ip)
|
||||||
|
self.hasSubNet |= not ip.isSingle
|
||||||
|
set.add(self, ip)
|
||||||
|
|
||||||
def __contains__(self, ip):
|
def __contains__(self, ip):
|
||||||
if not isinstance(ip, IPAddr): ip = IPAddr(ip)
|
if not isinstance(ip, IPAddr): ip = IPAddr(ip)
|
||||||
# IP can be found directly or IP is in each subnet:
|
# IP can be found directly or IP is in each subnet:
|
||||||
return set.__contains__(self, ip) or any(n.contains(ip) for n in self)
|
return set.__contains__(self, ip) or (self.hasSubNet and any(n.contains(ip) for n in self))
|
||||||
|
|
||||||
|
|
||||||
def _NetworkInterfacesAddrs():
|
def _NetworkInterfacesAddrs(withMask=False):
|
||||||
|
|
||||||
# Closure implementing lazy load modules and libc and define _NetworkInterfacesAddrs on demand:
|
# Closure implementing lazy load modules and libc and define _NetworkInterfacesAddrs on demand:
|
||||||
# Currently tested on Linux only (TODO: implement for MacOS, Solaris, etc)
|
# Currently tested on Linux only (TODO: implement for MacOS, Solaris, etc)
|
||||||
|
@ -735,12 +750,13 @@ def _NetworkInterfacesAddrs():
|
||||||
break
|
break
|
||||||
ifa = ifa.ifa_next.contents
|
ifa = ifa.ifa_next.contents
|
||||||
|
|
||||||
def getfamaddr(ifa):
|
def getfamaddr(ifa, withMask=False):
|
||||||
sa = ifa.ifa_addr.contents
|
sa = ifa.ifa_addr.contents
|
||||||
fam = sa.sa_family
|
fam = sa.sa_family
|
||||||
if fam == socket.AF_INET:
|
if fam == socket.AF_INET:
|
||||||
sa = cast(pointer(sa), POINTER(struct_sockaddr_in)).contents
|
sa = cast(pointer(sa), POINTER(struct_sockaddr_in)).contents
|
||||||
addr = socket.inet_ntop(fam, sa.sin_addr)
|
addr = socket.inet_ntop(fam, sa.sin_addr)
|
||||||
|
if withMask:
|
||||||
nm = ifa.ifa_netmask.contents
|
nm = ifa.ifa_netmask.contents
|
||||||
if nm is not None and nm.sa_family == socket.AF_INET:
|
if nm is not None and nm.sa_family == socket.AF_INET:
|
||||||
nm = cast(pointer(nm), POINTER(struct_sockaddr_in)).contents
|
nm = cast(pointer(nm), POINTER(struct_sockaddr_in)).contents
|
||||||
|
@ -749,6 +765,7 @@ def _NetworkInterfacesAddrs():
|
||||||
elif fam == socket.AF_INET6:
|
elif fam == socket.AF_INET6:
|
||||||
sa = cast(pointer(sa), POINTER(struct_sockaddr_in6)).contents
|
sa = cast(pointer(sa), POINTER(struct_sockaddr_in6)).contents
|
||||||
addr = socket.inet_ntop(fam, sa.sin6_addr)
|
addr = socket.inet_ntop(fam, sa.sin6_addr)
|
||||||
|
if withMask:
|
||||||
nm = ifa.ifa_netmask.contents
|
nm = ifa.ifa_netmask.contents
|
||||||
if nm is not None and nm.sa_family == socket.AF_INET6:
|
if nm is not None and nm.sa_family == socket.AF_INET6:
|
||||||
nm = cast(pointer(nm), POINTER(struct_sockaddr_in6)).contents
|
nm = cast(pointer(nm), POINTER(struct_sockaddr_in6)).contents
|
||||||
|
@ -756,7 +773,7 @@ def _NetworkInterfacesAddrs():
|
||||||
return IPAddr(addr)
|
return IPAddr(addr)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _NetworkInterfacesAddrs():
|
def _NetworkInterfacesAddrs(withMask=False):
|
||||||
ifap = POINTER(struct_ifaddrs)()
|
ifap = POINTER(struct_ifaddrs)()
|
||||||
result = libc.getifaddrs(pointer(ifap))
|
result = libc.getifaddrs(pointer(ifap))
|
||||||
if result != 0:
|
if result != 0:
|
||||||
|
@ -765,7 +782,7 @@ def _NetworkInterfacesAddrs():
|
||||||
try:
|
try:
|
||||||
for ifa in ifap_iter(ifap):
|
for ifa in ifap_iter(ifap):
|
||||||
name = ifa.ifa_name.decode("UTF-8")
|
name = ifa.ifa_name.decode("UTF-8")
|
||||||
addr = getfamaddr(ifa)
|
addr = getfamaddr(ifa, withMask)
|
||||||
if addr:
|
if addr:
|
||||||
yield name, addr
|
yield name, addr
|
||||||
finally:
|
finally:
|
||||||
|
@ -777,6 +794,6 @@ def _NetworkInterfacesAddrs():
|
||||||
raise _init_error
|
raise _init_error
|
||||||
|
|
||||||
DNSUtils._NetworkInterfacesAddrs = staticmethod(_NetworkInterfacesAddrs);
|
DNSUtils._NetworkInterfacesAddrs = staticmethod(_NetworkInterfacesAddrs);
|
||||||
return _NetworkInterfacesAddrs()
|
return _NetworkInterfacesAddrs(withMask)
|
||||||
|
|
||||||
DNSUtils._NetworkInterfacesAddrs = staticmethod(_NetworkInterfacesAddrs);
|
DNSUtils._NetworkInterfacesAddrs = staticmethod(_NetworkInterfacesAddrs);
|
||||||
|
|
|
@ -2334,8 +2334,9 @@ class DNSUtilsNetworkTests(unittest.TestCase):
|
||||||
ip1 = IPAddr('2606:2800:220:1:248:1893:25c8:1946'); ip2 = IPAddr('2606:2800:220:1:248:1893:25c8:1946'); self.assertEqual(id(ip1), id(ip2))
|
ip1 = IPAddr('2606:2800:220:1:248:1893:25c8:1946'); ip2 = IPAddr('2606:2800:220:1:248:1893:25c8:1946'); self.assertEqual(id(ip1), id(ip2))
|
||||||
|
|
||||||
def test_NetworkInterfacesAddrs(self):
|
def test_NetworkInterfacesAddrs(self):
|
||||||
|
for withMask in (False, True):
|
||||||
try:
|
try:
|
||||||
ips = IPAddrSet([a for ni, a in DNSUtils._NetworkInterfacesAddrs()])
|
ips = IPAddrSet([a for ni, a in DNSUtils._NetworkInterfacesAddrs(withMask)])
|
||||||
ip = IPAddr('127.0.0.1')
|
ip = IPAddr('127.0.0.1')
|
||||||
self.assertEqual(ip in ips, any(ip in n for n in ips))
|
self.assertEqual(ip in ips, any(ip in n for n in ips))
|
||||||
ip = IPAddr('::1')
|
ip = IPAddr('::1')
|
||||||
|
|
Loading…
Reference in New Issue