Support custom allowed_ips field for services
Like allowed_prefixes, but for single IP addresses. Currently used just for DHCP server to allow (only) packets from relays.
This commit is contained in:
parent
01a27e45ce
commit
036f7c8b74
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import ipaddress
|
||||
import os
|
||||
import pynetbox
|
||||
|
||||
|
@ -38,12 +39,21 @@ class FilterModule(object):
|
|||
|
||||
def allowed_prefixes(self, service):
|
||||
'''Return a list of allowed IP prefixes for the given service'''
|
||||
# Depending on how service was obtained, actual data might be nested under custom_fields.
|
||||
if 'custom_fields' in service:
|
||||
service = service['custom_fields']
|
||||
|
||||
def ip2str(address, single=False):
|
||||
if single: # 1.2.3.4/24 → 1.2.3.4
|
||||
address = ipaddress.ip_interface(address).ip
|
||||
return str(ipaddress.ip_interface(address))
|
||||
|
||||
if ips := service.get('allowed_ips'):
|
||||
yield from (ip2str(ip['address'], single=True) for ip in ips)
|
||||
if prefixes := service.get('allowed_prefixes'):
|
||||
yield from self.nb.ipam.prefixes.filter(id=[prefix['id'] for prefix in prefixes])
|
||||
yield from (ip2str(e.prefix) for e in self.nb.ipam.prefixes.filter(id=[prefix['id'] for prefix in prefixes]))
|
||||
if vlans := service.get('allowed_vlans'):
|
||||
yield from self.nb.ipam.prefixes.filter(vlan_id=[vlan['id'] for vlan in vlans])
|
||||
yield from (ip2str(e.prefix) for e in self.nb.ipam.prefixes.filter(vlan_id=[vlan['id'] for vlan in vlans]))
|
||||
if clusters := service.get('allowed_clusters'):
|
||||
for device in self.nb.dcim.devices.filter(cluster_id=[cluster['id'] for cluster in clusters]):
|
||||
yield from self.nb.ipam.ip_addresses.filter(role='loopback', device_id=device.id)
|
||||
yield from (ip2str(e.address) for e in self.nb.ipam.ip_addresses.filter(role='loopback', device_id=device.id))
|
||||
|
|
|
@ -4,18 +4,16 @@ table inet filter {
|
|||
|
||||
{% for service in services %}
|
||||
{% set prefixes = service | allowed_prefixes %}
|
||||
{% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map('string') %}
|
||||
{% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map('string') %}
|
||||
{% set ports = service.ports | compact_numlist %}
|
||||
{% if 'name' in service %}
|
||||
# service {{ service.name }}
|
||||
{% endif %}
|
||||
{% if prefixes4 or prefixes6 %}
|
||||
{% if prefixes4 %}
|
||||
ip saddr { {{ prefixes4 | join(', ') }} } {{ service.protocol.value }} dport { {{ ports }} } accept
|
||||
{% if prefixes %}
|
||||
{% if prefixes | ipv4 %}
|
||||
ip saddr { {{ prefixes | ipv4 | join(', ') }} } {{ service.protocol.value }} dport { {{ ports }} } accept
|
||||
{% endif %}
|
||||
{% if prefixes6 %}
|
||||
ip6 saddr { {{ prefixes6 | join(', ') }} } {{ service.protocol.value }} dport { {{ ports }} } accept
|
||||
{% if prefixes | ipv6 %}
|
||||
ip6 saddr { {{ prefixes | ipv6 | join(', ') }} } {{ service.protocol.value }} dport { {{ ports }} } accept
|
||||
{% endif %}
|
||||
{% else %}
|
||||
tcp dport { {{ ports }} } accept
|
||||
|
|
|
@ -56,15 +56,13 @@ table inet filter {
|
|||
|
||||
{% for service in cluster_services %}
|
||||
{% set prefixes = service | allowed_prefixes %}
|
||||
{% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map('string') %}
|
||||
{% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map('string') %}
|
||||
{% set ports = service.ports | compact_numlist %}
|
||||
# service {{ service.name }}
|
||||
{% if prefixes4 %}
|
||||
ip saddr { {{ prefixes4 | join(', ') }} } tcp dport { {{ ports }} } accept
|
||||
{% if prefixes | ipv4 %}
|
||||
ip saddr { {{ prefixes | ipv4 | join(', ') }} } tcp dport { {{ ports }} } accept
|
||||
{% endif %}
|
||||
{% if prefixes6 %}
|
||||
ip6 saddr { {{ prefixes6 | join(', ') }} } tcp dport { {{ ports }} } accept
|
||||
{% if prefixes | ipv6 %}
|
||||
ip6 saddr { {{ prefixes | ipv6 | join(', ') }} } tcp dport { {{ ports }} } accept
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
|
|
|
@ -10,14 +10,12 @@ IN ACCEPT -source {{ nodes | map('device_address') | flatten | selectattr('famil
|
|||
IN ACCEPT -source {{ nodes | map('device_address') | flatten | selectattr('family.value', '==', 6) | map(attribute='address') | join(',') }} # my cluster
|
||||
{% for service in cluster_services %}
|
||||
{% set prefixes = service | allowed_prefixes %}
|
||||
{% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map('string') %}
|
||||
{% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map('string') %}
|
||||
{% set ports = service.ports | compact_numlist(range_delimiter=':') %}
|
||||
{% if prefixes4 %}
|
||||
IN ACCEPT -source {{ prefixes4 | join(',') }} -p {{ service.protocol.value }} -dport {{ ports }} # {{ service.name }}
|
||||
{% if prefixes | ipv4 %}
|
||||
IN ACCEPT -source {{ prefixes | ipv4 | join(',') }} -p {{ service.protocol.value }} -dport {{ ports }} # {{ service.name }}
|
||||
{% endif %}
|
||||
{% if prefixes6 %}
|
||||
IN ACCEPT -source {{ prefixes6 | join(',') }} -p {{ service.protocol.value }} -dport {{ ports }} # {{ service.name }}
|
||||
{% if prefixes | ipv6 %}
|
||||
IN ACCEPT -source {{ prefixes | ipv6 | join(',') }} -p {{ service.protocol.value }} -dport {{ ports }} # {{ service.name }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
|
|
Loading…
Reference in a new issue