Compare commits

..

No commits in common. "29598ef4bb4d1398d4fa47e68ea84257f2a8e627" and "6a9a4142ce411008864945a32c07b34ac9406b5f" have entirely different histories.

13 changed files with 49 additions and 70 deletions

View file

@ -7,7 +7,6 @@ class FilterModule(object):
'''Various utilities for manipulating NetBox data''' '''Various utilities for manipulating NetBox data'''
def __init__(self): def __init__(self):
if 'NETBOX_API' in os.environ and 'NETBOX_TOKEN' in os.environ:
self.nb = pynetbox.api(os.getenv('NETBOX_API'), os.getenv('NETBOX_TOKEN')) self.nb = pynetbox.api(os.getenv('NETBOX_API'), os.getenv('NETBOX_TOKEN'))
def filters(self): def filters(self):
@ -38,12 +37,11 @@ class FilterModule(object):
def allowed_prefixes(self, service): def allowed_prefixes(self, service):
'''Return a list of allowed IP prefixes for the given service''' '''Return a list of allowed IP prefixes for the given service'''
if 'custom_fields' in service: service_data = self.nb.ipam.services.get(service['id']).custom_fields
service = service['custom_fields'] if service_data['allowed_prefixes']:
if prefixes := service.get('allowed_prefixes'): yield from self.nb.ipam.prefixes.filter(id=[prefix['id'] for prefix in service_data['allowed_prefixes']])
yield from self.nb.ipam.prefixes.filter(id=[prefix['id'] for prefix in prefixes]) if service_data['allowed_vlans']:
if vlans := service.get('allowed_vlans'): yield from self.nb.ipam.prefixes.filter(vlan_id=[vlan['id'] for vlan in service_data['allowed_vlans']])
yield from self.nb.ipam.prefixes.filter(vlan_id=[vlan['id'] for vlan in vlans]) if service_data['allowed_clusters']:
if clusters := service.get('allowed_clusters'): for device in self.nb.dcim.devices.filter(cluster_id=[cluster['id'] for cluster in service_data['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 self.nb.ipam.ip_addresses.filter(role='loopback', device_id=device.id)

View file

@ -1,8 +0,0 @@
#!/bin/sh
upgrade() {
echo "Starting upgrade on $(date)"
apk upgrade --update
}
upgrade >> /var/log/unattended-upgrade.log

View file

@ -1,3 +0,0 @@
/var/log/unattended-upgrade.log {
missingok
}

View file

@ -22,7 +22,6 @@
name: name:
- git - git
- iproute2 - iproute2
- logrotate
- nftables - nftables
- procps - procps
- rsync - rsync
@ -65,15 +64,3 @@
name: qemu-guest-agent name: qemu-guest-agent
enabled: yes enabled: yes
state: started state: started
- name: Install automatic upgrade script
copy:
dest: /etc/periodic/weekly/
src: unattended-upgrade
mode: 0755
- name: Configure log rotation for automatic upgrades
copy:
dest: /etc/logrotate.d/unattended-upgrade
src: unattended-upgrade.logrotate
mode: 0644

View file

@ -7,9 +7,7 @@ table inet filter {
{% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map('string') %} {% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map('string') %}
{% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map('string') %} {% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map('string') %}
{% set ports = service.ports | compact_numlist %} {% set ports = service.ports | compact_numlist %}
{% if 'name' in service %}
# service {{ service.name }} # service {{ service.name }}
{% endif %}
{% if prefixes4 or prefixes6 %} {% if prefixes4 or prefixes6 %}
{% if prefixes4 %} {% if prefixes4 %}
ip saddr { {{ prefixes4 | join(', ') }} } tcp dport { {{ ports }} } accept ip saddr { {{ prefixes4 | join(', ') }} } tcp dport { {{ ports }} } accept

View file

@ -54,7 +54,7 @@ table inet filter {
ip saddr @allowed accept # TODO remove exceptions ip saddr @allowed accept # TODO remove exceptions
ip6 saddr @allowed/6 accept # TODO remove exceptions ip6 saddr @allowed/6 accept # TODO remove exceptions
{% for service in cluster_services %} {% for service in cluster.custom_fields.services %}
{% set prefixes = service | allowed_prefixes %} {% set prefixes = service | allowed_prefixes %}
{% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map('string') %} {% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map('string') %}
{% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map('string') %} {% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map('string') %}

View file

@ -1,10 +1,11 @@
{% for fqdn in fqdns %}
server { server {
listen 443 ssl http2; listen 443 ssl http2;
listen [::]:443 ssl http2; listen [::]:443 ssl http2;
server_name {{ dns_name }}; server_name {{ fqdn }};
ssl_certificate /etc/letsencrypt/live/{{ dns_name }}/fullchain.pem; ssl_certificate /etc/letsencrypt/live/{{ fqdn }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ dns_name }}/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/{{ fqdn }}/privkey.pem;
client_max_body_size 100M; client_max_body_size 100M;
@ -34,3 +35,5 @@ server {
fastcgi_pass unix:/run/php-fpm.socket; fastcgi_pass unix:/run/php-fpm.socket;
} }
} }
{% endfor %}

View file

@ -1,21 +1,18 @@
# Make expensive lookups to NetBox once for later reference by any host. # Make expensive lookups to NetBox once for later reference by any host.
- when: lookup("env", "NETBOX_API") != "" - name: Lookup networks and prefixes
block:
- name: Lookup networks and prefixes
set_fact: set_fact:
vlans: '{{ query("netbox.netbox.nb_lookup", "vlans", api_filter="group=new-net", raw_data=true) vlans: '{{ query("netbox.netbox.nb_lookup", "vlans", api_filter="group=new-net", raw_data=true)
| sort(attribute="vid") }}' | sort(attribute="vid") }}'
prefixes: '{{ query("netbox.netbox.nb_lookup", "prefixes", raw_data=true) prefixes: '{{ query("netbox.netbox.nb_lookup", "prefixes", raw_data=true)
| sort(attribute="prefix") | sort(attribute="family.value") }}' | sort(attribute="prefix") | sort(attribute="family.value") }}'
- when: 'cluster is defined' - name: Get my cluster and all nodes in it
block:
- name: Get my cluster and all nodes in it
set_fact: set_fact:
cluster: '{{ query("netbox.netbox.nb_lookup", "clusters", raw_data=true, api_filter="name="+cluster) | first }}' cluster: '{{ query("netbox.netbox.nb_lookup", "clusters", raw_data=true, api_filter="name="+cluster) | first }}'
nodes: '{{ groups["cluster_"+cluster] | map("extract", hostvars) | rejectattr("is_virtual") }}' nodes: '{{ groups["cluster_"+cluster] | map("extract", hostvars) | rejectattr("is_virtual") }}'
when: cluster
- name: Get cluster services - name: Get my domain names if any
set_fact: set_fact:
cluster_services: '{{ (cluster_services|default([])) + query("netbox.netbox.nb_lookup", "services", raw_data=true, api_filter="id="+item) }}' fqdns: '{{ interfaces | map(attribute="ip_addresses") | flatten
loop: '{{ cluster.custom_fields.services | map(attribute="id") | map("string") }}' | map(attribute="dns_name") | reject("==", "") | sort | unique }}'

View file

@ -1,9 +1,10 @@
{% for fqdn in fqdns %}
server { server {
server_name {{ dns_name }}; server_name {{ fqdn }};
listen [::]:443 ssl ipv6only=off; listen [::]:443 ssl ipv6only=off;
ssl_certificate /etc/letsencrypt/live/{{ dns_name }}/fullchain.pem; ssl_certificate /etc/letsencrypt/live/{{ fqdn }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ dns_name }}/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/{{ fqdn }}/privkey.pem;
location / { location / {
proxy_pass http://unix:/var/lib/forgejo/socket; proxy_pass http://unix:/var/lib/forgejo/socket;
@ -18,3 +19,5 @@ server {
client_max_body_size 512M; client_max_body_size 512M;
} }
} }
{% endfor %}

View file

@ -49,7 +49,7 @@
line: '{{ item.line }}' line: '{{ item.line }}'
loop: loop:
- key: '^ALLOWED_HOSTS = ' - key: '^ALLOWED_HOSTS = '
line: "ALLOWED_HOSTS = ['{{ dns_name }}']" line: "ALLOWED_HOSTS = [{{ fqdns | map('regex_replace', '^(.*)$', '\"\\1\"') | join(', ') }}]"
- key: 'USER.*PostgreSQL username' - key: 'USER.*PostgreSQL username'
line: " 'USER': '{{ user }}', # PostgreSQL username" line: " 'USER': '{{ user }}', # PostgreSQL username"
# XXX unnecessary? # XXX unnecessary?

View file

@ -1,9 +1,10 @@
{% for fqdn in fqdns %}
server { server {
server_name {{ dns_name }}; server_name {{ fqdn }};
listen [::]:443 ssl ipv6only=off; listen [::]:443 ssl ipv6only=off;
ssl_certificate /etc/letsencrypt/live/{{ dns_name }}/fullchain.pem; ssl_certificate /etc/letsencrypt/live/{{ fqdn }}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/{{ dns_name }}/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/{{ fqdn }}/privkey.pem;
client_max_body_size 100m; client_max_body_size 100m;
@ -18,3 +19,5 @@ server {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
} }
} }
{% endfor %}

View file

@ -26,8 +26,9 @@
- name: Get LE certificate - name: Get LE certificate
command: command:
cmd: certbot certonly --non-interactive --agree-tos --register-unsafely-without-email --webroot --webroot-path /srv/http -d {{ dns_name }} cmd: certbot certonly --non-interactive --agree-tos --register-unsafely-without-email --webroot --webroot-path /srv/http -d {{ item }}
creates: '/etc/letsencrypt/renewal/{{ dns_name }}.conf' creates: '/etc/letsencrypt/renewal/{{ item }}.conf'
loop: '{{ fqdns }}'
- name: Enable certbot renewal - name: Enable certbot renewal
cron: cron:

View file

@ -8,16 +8,16 @@ IN Ping(ACCEPT) -log nolog # don’t be rude
IN SSH(ACCEPT) -i mgmt # for ansible etc. IN SSH(ACCEPT) -i mgmt # for ansible etc.
IN ACCEPT -source {{ nodes | map('device_address') | flatten | selectattr('family.value', '==', 4) | map(attribute='address') | join(',') }} # my cluster IN ACCEPT -source {{ nodes | map('device_address') | flatten | selectattr('family.value', '==', 4) | map(attribute='address') | join(',') }} # my cluster
IN ACCEPT -source {{ nodes | map('device_address') | flatten | selectattr('family.value', '==', 6) | map(attribute='address') | join(',') }} # my cluster IN ACCEPT -source {{ nodes | map('device_address') | flatten | selectattr('family.value', '==', 6) | map(attribute='address') | join(',') }} # my cluster
{% for service in cluster_services %} {% for service in cluster.custom_fields.services %}
{% set prefixes = service | allowed_prefixes %} {% set prefixes = service | allowed_prefixes %}
{% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map('string') %} {% set prefixes4 = prefixes | selectattr('family.value', '==', 4) | map('string') %}
{% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map('string') %} {% set prefixes6 = prefixes | selectattr('family.value', '==', 6) | map('string') %}
{% set ports = service.ports | compact_numlist(range_delimiter=':') %} {% set ports = service.ports | compact_numlist(range_delimiter=':') %}
{% if prefixes4 %} {% if prefixes4 %}
IN ACCEPT -source {{ prefixes4 | join(',') }} -p {{ service.protocol.value }} -dport {{ ports }} # {{ service.name }} IN ACCEPT -source {{ prefixes4 | join(',') }} -p {{ service.protocol }} -dport {{ ports }} # {{ service.name }}
{% endif %} {% endif %}
{% if prefixes6 %} {% if prefixes6 %}
IN ACCEPT -source {{ prefixes6 | join(',') }} -p {{ service.protocol.value }} -dport {{ ports }} # {{ service.name }} IN ACCEPT -source {{ prefixes6 | join(',') }} -p {{ service.protocol }} -dport {{ ports }} # {{ service.name }}
{% endif %} {% endif %}
{% endfor %} {% endfor %}