Compare commits
	
		
			2 commits
		
	
	
		
			a3dd4eba65
			...
			036f7c8b74
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 036f7c8b74 | |||
| 01a27e45ce | 
					 8 changed files with 101 additions and 23 deletions
				
			
		| 
						 | 
				
			
			@ -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 %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,32 @@
 | 
			
		|||
  package:
 | 
			
		||||
    name:
 | 
			
		||||
    - dnsmasq
 | 
			
		||||
    - bind-tools
 | 
			
		||||
    - krb5
 | 
			
		||||
    - py3-pexpect
 | 
			
		||||
 | 
			
		||||
- name: Configure kerberos
 | 
			
		||||
  template:
 | 
			
		||||
    dest: /etc/krb5.conf
 | 
			
		||||
    src: krb5.conf.j2
 | 
			
		||||
 | 
			
		||||
- name: Init kerberos keytab
 | 
			
		||||
  expect:
 | 
			
		||||
    command: ktutil
 | 
			
		||||
    responses:
 | 
			
		||||
      '.*:':
 | 
			
		||||
      - 'add_entry -password -p {{ password.ldap_user }} -k 1 -e aes256-cts-hmac-sha1-96'
 | 
			
		||||
      - '{{ password.ldap_pass }}'
 | 
			
		||||
      - 'write_kt /etc/krb5.keytab'
 | 
			
		||||
      - 'exit'
 | 
			
		||||
  args:
 | 
			
		||||
    creates: /etc/krb5.keytab
 | 
			
		||||
 | 
			
		||||
- name: Copy DNS updater script
 | 
			
		||||
  template:
 | 
			
		||||
    dest: "/usr/local/bin/dns-update"
 | 
			
		||||
    src: "dns-update.j2"
 | 
			
		||||
    mode: 0700
 | 
			
		||||
 | 
			
		||||
- name: Configure dnsmasq
 | 
			
		||||
  template:
 | 
			
		||||
| 
						 | 
				
			
			@ -12,5 +38,4 @@
 | 
			
		|||
  - 10-ranges.conf
 | 
			
		||||
  notify: restart dnsmasq
 | 
			
		||||
 | 
			
		||||
# TODO DNS update
 | 
			
		||||
# TODO netboot config
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,3 +9,5 @@ dhcp-proxy
 | 
			
		|||
 | 
			
		||||
dhcp-option = option:dns-server,{{ dns | join(',') }}
 | 
			
		||||
dhcp-option = option:ntp-server,{{ ntp | join(',') }}
 | 
			
		||||
 | 
			
		||||
dhcp-script = /usr/local/bin/dns-update
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										29
									
								
								roles/dnsmasq/templates/dns-update.j2
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								roles/dnsmasq/templates/dns-update.j2
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
domain={{ domain }}
 | 
			
		||||
ldap_user={{ password.ldap_user }}
 | 
			
		||||
ttl=3600
 | 
			
		||||
 | 
			
		||||
address="${3}"
 | 
			
		||||
 | 
			
		||||
case "${1}" in
 | 
			
		||||
add)
 | 
			
		||||
	host="${4}"
 | 
			
		||||
	kinit -k "${ldap_user}"
 | 
			
		||||
	nsupdate -g <<EOF
 | 
			
		||||
update add ${host}.${domain} ${ttl} A ${address}
 | 
			
		||||
send
 | 
			
		||||
EOF
 | 
			
		||||
	;;
 | 
			
		||||
old)
 | 
			
		||||
	if [ -n "${DNSMASQ_OLD_HOSTNAME}" -a -n "${DNSMASQ_SUPPLIED_HOSTNAME}" ] ; then
 | 
			
		||||
		kinit -k "${ldap_user}"
 | 
			
		||||
		nsupdate -g <<EOF
 | 
			
		||||
update del ${DNSMASQ_OLD_HOSTNAME}.${domain}
 | 
			
		||||
update add ${DNSMASQ_SUPPLIED_HOSTNAME}.${domain} ${ttl} A ${address}
 | 
			
		||||
send
 | 
			
		||||
EOF
 | 
			
		||||
	fi
 | 
			
		||||
	;;
 | 
			
		||||
# TODO del, probably
 | 
			
		||||
esac
 | 
			
		||||
							
								
								
									
										18
									
								
								roles/dnsmasq/templates/krb5.conf.j2
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								roles/dnsmasq/templates/krb5.conf.j2
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
[libdefaults]
 | 
			
		||||
dns_lookup_realm = false
 | 
			
		||||
ticket_lifetime = 24h
 | 
			
		||||
renew_lifetime = 7d
 | 
			
		||||
#forwardable = true
 | 
			
		||||
rdns = false
 | 
			
		||||
default_realm = {{ domain | upper }}
 | 
			
		||||
 | 
			
		||||
[realms]
 | 
			
		||||
{{ domain | upper }} = {
 | 
			
		||||
{% for server in dns %}
 | 
			
		||||
  kdc = {{ server }}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
[domain_realm]
 | 
			
		||||
.{{ domain }} = {{ domain | upper }}
 | 
			
		||||
{{ domain }} = {{ domain | upper }}
 | 
			
		||||
| 
						 | 
				
			
			@ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue