Move firewall_master role to servers repo
This commit is contained in:
		
							parent
							
								
									ff1abcb508
								
							
						
					
					
						commit
						48b987180a
					
				
					 19 changed files with 0 additions and 430 deletions
				
			
		| 
						 | 
				
			
			@ -1,54 +0,0 @@
 | 
			
		|||
- name: Enable community package repo
 | 
			
		||||
  lineinfile:
 | 
			
		||||
    path: /etc/apk/repositories
 | 
			
		||||
    regexp: '^# *(http.*/v[^/]*/community)'
 | 
			
		||||
    line: '\1'
 | 
			
		||||
    backrefs: yes
 | 
			
		||||
 | 
			
		||||
- name: Install packages
 | 
			
		||||
  package:
 | 
			
		||||
    name: bind-tools,certbot,krb5,py3-pexpect
 | 
			
		||||
 | 
			
		||||
- name: Configure kerberos
 | 
			
		||||
  template:
 | 
			
		||||
    dest: /etc/krb5.conf
 | 
			
		||||
    src: krb5.conf.j2
 | 
			
		||||
 | 
			
		||||
- name: Copy DNS updater scripts for certbot
 | 
			
		||||
  template:
 | 
			
		||||
    dest: "/usr/local/bin/{{ item }}"
 | 
			
		||||
    src: "{{ item }}.j2"
 | 
			
		||||
    mode: 0700
 | 
			
		||||
  with_items:
 | 
			
		||||
    - certbot-auth
 | 
			
		||||
    - certbot-cleanup
 | 
			
		||||
 | 
			
		||||
- name: Init kerberos keytab
 | 
			
		||||
  expect:
 | 
			
		||||
    command: ktutil
 | 
			
		||||
    responses:
 | 
			
		||||
      '.*:':
 | 
			
		||||
        - 'add_entry -password -p {{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="ldap_user") }} -k 1 -e aes256-cts-hmac-sha1-96'
 | 
			
		||||
        - '{{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="ldap_pass") }}'
 | 
			
		||||
        - 'write_kt /etc/krb5.keytab'
 | 
			
		||||
        - 'exit'
 | 
			
		||||
  args:
 | 
			
		||||
    creates: /etc/krb5.keytab
 | 
			
		||||
 | 
			
		||||
- name: Create LE account
 | 
			
		||||
  command:
 | 
			
		||||
    cmd: certbot register --agree-tos --register-unsafely-without-email
 | 
			
		||||
    creates: /etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory/*/meta.json
 | 
			
		||||
 | 
			
		||||
- name: Create LE certificate
 | 
			
		||||
  command:
 | 
			
		||||
    cmd: certbot certonly --quiet --manual --preferred-challenges=dns --manual-auth-hook certbot-auth --manual-cleanup-hook certbot-cleanup -d {{ fqdn }}
 | 
			
		||||
    creates: "/etc/letsencrypt/renewal/{{ fqdn }}.conf"
 | 
			
		||||
 | 
			
		||||
- name: Enable certbot renewal
 | 
			
		||||
  cron:
 | 
			
		||||
    name: "certbot renew"
 | 
			
		||||
    job: "certbot renew --quiet"
 | 
			
		||||
    user: root
 | 
			
		||||
    hour: "2,14"
 | 
			
		||||
    minute: "38"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,13 +0,0 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
dns={{ dns[0] }}
 | 
			
		||||
ldap_user={{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="ldap_user") }}
 | 
			
		||||
ttl=10
 | 
			
		||||
 | 
			
		||||
kinit -k -t /etc/krb5.keytab "${ldap_user}"
 | 
			
		||||
nsupdate -g <<EOF
 | 
			
		||||
server ${dns}
 | 
			
		||||
update add _acme-challenge.${CERTBOT_DOMAIN} ${ttl} TXT ${CERTBOT_VALIDATION}
 | 
			
		||||
send
 | 
			
		||||
EOF
 | 
			
		||||
sleep $(( ttl + 5 ))
 | 
			
		||||
| 
						 | 
				
			
			@ -1,11 +0,0 @@
 | 
			
		|||
#!/bin/sh
 | 
			
		||||
 | 
			
		||||
dns={{ dns[0] }}
 | 
			
		||||
ldap_user={{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="ldap_user") }}
 | 
			
		||||
 | 
			
		||||
kinit -k -t /etc/krb5.keytab "${ldap_user}"
 | 
			
		||||
nsupdate -g <<EOF
 | 
			
		||||
server ${dns}
 | 
			
		||||
update delete _acme-challenge.${CERTBOT_DOMAIN} TXT
 | 
			
		||||
send
 | 
			
		||||
EOF
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +0,0 @@
 | 
			
		|||
[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]
 | 
			
		||||
.fri1.uni-lj.si = {{ domain | upper }}
 | 
			
		||||
fri1.uni-lj.si = {{ domain | upper }}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,16 +0,0 @@
 | 
			
		|||
table inet filter {
 | 
			
		||||
    set fri {
 | 
			
		||||
        typeof ip saddr; flags interval
 | 
			
		||||
        elements = { 10.32.0.0/14, 192.168.0.0/16, 141.255.211.0/24, 193.2.76.0/24 }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set fri/6 {
 | 
			
		||||
        typeof ip6 saddr; flags interval
 | 
			
		||||
        elements = { 2001:1470:fffd::/48 }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    chain input {
 | 
			
		||||
        ip saddr @fri tcp dport { ssh, http, https } accept
 | 
			
		||||
        ip6 saddr @fri/6 tcp dport { ssh, http, https } accept
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,16 +0,0 @@
 | 
			
		|||
[uwsgi]
 | 
			
		||||
uid = friwall
 | 
			
		||||
gid = friwall
 | 
			
		||||
 | 
			
		||||
socket = /run/friwall.socket
 | 
			
		||||
chown-socket = friwall:nginx
 | 
			
		||||
chmod-socket = 660
 | 
			
		||||
 | 
			
		||||
plugin = python3
 | 
			
		||||
chdir = /srv/friwall/app
 | 
			
		||||
mount = /=wsgi:app
 | 
			
		||||
env = PYTHONUSERBASE=/srv/friwall/.local
 | 
			
		||||
env = HOME=/srv/friwall
 | 
			
		||||
 | 
			
		||||
# Microsoft OIDC endpoint sends some fat‐ass headers.
 | 
			
		||||
buffer-size = 16384
 | 
			
		||||
| 
						 | 
				
			
			@ -1,18 +0,0 @@
 | 
			
		|||
#!/sbin/openrc-run
 | 
			
		||||
 | 
			
		||||
command="/srv/friwall/app/$RC_SVCNAME"
 | 
			
		||||
command_background="yes"
 | 
			
		||||
command_user="friwall"
 | 
			
		||||
command_group="nogroup"
 | 
			
		||||
directory="/srv/friwall"
 | 
			
		||||
pidfile="/run/$RC_SVCNAME.pid"
 | 
			
		||||
 | 
			
		||||
depend() {
 | 
			
		||||
	need net
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
stop() {
 | 
			
		||||
	ebegin "Stopping $RC_SVCNAME"
 | 
			
		||||
	pkill -INT -g $(cat "$pidfile") && rm -f "$pidfile"
 | 
			
		||||
	eend $?
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,2 +0,0 @@
 | 
			
		|||
[uwsgi]
 | 
			
		||||
emperor = /etc/uwsgi/conf.d
 | 
			
		||||
| 
						 | 
				
			
			@ -1,39 +0,0 @@
 | 
			
		|||
- name: restart interfaces
 | 
			
		||||
  shell: ifdown --force --auto && ifup --auto
 | 
			
		||||
  when: "'handler' not in ansible_skip_tags"
 | 
			
		||||
 | 
			
		||||
- name: reload nftables
 | 
			
		||||
  service:
 | 
			
		||||
    name: nftables
 | 
			
		||||
    state: reloaded
 | 
			
		||||
  when: "'handler' not in ansible_skip_tags"
 | 
			
		||||
 | 
			
		||||
- name: reload nginx
 | 
			
		||||
  service:
 | 
			
		||||
    name: nginx
 | 
			
		||||
    state: reloaded
 | 
			
		||||
  when: "'handler' not in ansible_skip_tags"
 | 
			
		||||
 | 
			
		||||
- name: restart nginx
 | 
			
		||||
  service:
 | 
			
		||||
    name: nginx
 | 
			
		||||
    state: restarted
 | 
			
		||||
  when: "'handler' not in ansible_skip_tags"
 | 
			
		||||
 | 
			
		||||
- name: restart pusher
 | 
			
		||||
  service:
 | 
			
		||||
    name: pusher
 | 
			
		||||
    state: restarted
 | 
			
		||||
  when: "'handler' not in ansible_skip_tags"
 | 
			
		||||
 | 
			
		||||
- name: reload uwsgi
 | 
			
		||||
  service:
 | 
			
		||||
    name: uwsgi
 | 
			
		||||
    state: reloaded
 | 
			
		||||
  when: "'handler' not in ansible_skip_tags"
 | 
			
		||||
 | 
			
		||||
- name: restart uwsgi
 | 
			
		||||
  service:
 | 
			
		||||
    name: uwsgi
 | 
			
		||||
    state: restarted
 | 
			
		||||
  when: "'handler' not in ansible_skip_tags"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,9 +0,0 @@
 | 
			
		|||
- name: Install mail server
 | 
			
		||||
  package:
 | 
			
		||||
    name: opensmtpd
 | 
			
		||||
 | 
			
		||||
- name: Enable mail server
 | 
			
		||||
  service:
 | 
			
		||||
    name: smtpd
 | 
			
		||||
    enabled: yes
 | 
			
		||||
    state: started
 | 
			
		||||
| 
						 | 
				
			
			@ -1,42 +0,0 @@
 | 
			
		|||
- name: Set up network interfaces
 | 
			
		||||
  template:
 | 
			
		||||
    dest: /etc/network/interfaces
 | 
			
		||||
    src: interfaces.j2
 | 
			
		||||
    mode: 0644
 | 
			
		||||
  notify: restart interfaces
 | 
			
		||||
 | 
			
		||||
- name: Install nftables
 | 
			
		||||
  package:
 | 
			
		||||
    name: nftables
 | 
			
		||||
 | 
			
		||||
- name: Accept connections from FRI addresses
 | 
			
		||||
  copy:
 | 
			
		||||
    dest: /etc/nftables.d/
 | 
			
		||||
    src: accept-fri.nft
 | 
			
		||||
  notify: reload nftables
 | 
			
		||||
 | 
			
		||||
- name: Enable nftables
 | 
			
		||||
  service:
 | 
			
		||||
    name: nftables
 | 
			
		||||
    enabled: yes
 | 
			
		||||
    state: started
 | 
			
		||||
 | 
			
		||||
- name: Install qemu guest agent
 | 
			
		||||
  package:
 | 
			
		||||
    name: qemu-guest-agent
 | 
			
		||||
 | 
			
		||||
- name: Enable qemu guest agent
 | 
			
		||||
  service:
 | 
			
		||||
    name: qemu-guest-agent
 | 
			
		||||
    enabled: yes
 | 
			
		||||
    runlevel: boot
 | 
			
		||||
    state: started
 | 
			
		||||
 | 
			
		||||
- name: Set up mail server
 | 
			
		||||
  import_tasks: mail.yml
 | 
			
		||||
 | 
			
		||||
- name: Set up friwall user
 | 
			
		||||
  import_tasks: user.yml
 | 
			
		||||
 | 
			
		||||
- name: Set up web UI
 | 
			
		||||
  import_tasks: web.yml
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
- name: Create friwall group
 | 
			
		||||
  group:
 | 
			
		||||
    name: friwall
 | 
			
		||||
    system: yes
 | 
			
		||||
 | 
			
		||||
- name: Create friwall user
 | 
			
		||||
  user:
 | 
			
		||||
    name: friwall
 | 
			
		||||
    system: yes
 | 
			
		||||
    home: /srv/friwall
 | 
			
		||||
    shell: /sbin/nologin
 | 
			
		||||
    generate_ssh_key: yes
 | 
			
		||||
    ssh_key_comment: "{{ inventory_hostname }}"
 | 
			
		||||
    ssh_key_type: ed25519
 | 
			
		||||
| 
						 | 
				
			
			@ -1,110 +0,0 @@
 | 
			
		|||
---
 | 
			
		||||
- name: Install packages
 | 
			
		||||
  package:
 | 
			
		||||
    name: git,inotify-tools,nginx,py3-pip,procps-ng,rsync,uwsgi,uwsgi-python3,wireguard-tools
 | 
			
		||||
 | 
			
		||||
- name: Clone web files
 | 
			
		||||
  become: yes
 | 
			
		||||
  become_user: friwall
 | 
			
		||||
  become_method: su
 | 
			
		||||
  become_flags: "-s /bin/sh"
 | 
			
		||||
  git:
 | 
			
		||||
    repo: '{{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="friwall_repo") }}'
 | 
			
		||||
    dest: /srv/friwall/app
 | 
			
		||||
    force: yes
 | 
			
		||||
  notify: reload uwsgi
 | 
			
		||||
 | 
			
		||||
- name: Install requirements
 | 
			
		||||
  become: yes
 | 
			
		||||
  become_user: friwall
 | 
			
		||||
  become_method: su
 | 
			
		||||
  become_flags: '-s /bin/sh'
 | 
			
		||||
  pip:
 | 
			
		||||
    requirements: /srv/friwall/app/requirements.txt
 | 
			
		||||
    extra_args: --user --break-system-packages
 | 
			
		||||
 | 
			
		||||
- name: Configure base settings
 | 
			
		||||
  template:
 | 
			
		||||
    dest: "/srv/friwall/{{ item }}"
 | 
			
		||||
    src: "{{ item }}.j2"
 | 
			
		||||
    owner: friwall
 | 
			
		||||
    group: friwall
 | 
			
		||||
    mode: 0600
 | 
			
		||||
    force: no
 | 
			
		||||
  loop:
 | 
			
		||||
    - nodes.json
 | 
			
		||||
    - settings.json
 | 
			
		||||
  notify: restart uwsgi
 | 
			
		||||
 | 
			
		||||
- name: Configure list of networks
 | 
			
		||||
  template:
 | 
			
		||||
    dest: "/srv/friwall/networks.json"
 | 
			
		||||
    src: "networks.json.j2"
 | 
			
		||||
    owner: friwall
 | 
			
		||||
    group: friwall
 | 
			
		||||
    mode: 0600
 | 
			
		||||
 | 
			
		||||
- name: Configure uwsgi
 | 
			
		||||
  copy:
 | 
			
		||||
    dest: /etc/uwsgi/
 | 
			
		||||
    src: uwsgi.ini
 | 
			
		||||
  notify: restart uwsgi
 | 
			
		||||
 | 
			
		||||
- name: Configure uwsgi instance
 | 
			
		||||
  copy:
 | 
			
		||||
    dest: /etc/uwsgi/conf.d/
 | 
			
		||||
    src: friwall.ini
 | 
			
		||||
    owner: friwall
 | 
			
		||||
    group: friwall
 | 
			
		||||
 | 
			
		||||
- name: Enable uwsgi
 | 
			
		||||
  service:
 | 
			
		||||
    name: uwsgi
 | 
			
		||||
    enabled: yes
 | 
			
		||||
    state: started
 | 
			
		||||
 | 
			
		||||
- name: Configure nginx instance
 | 
			
		||||
  template:
 | 
			
		||||
    dest: /etc/nginx/http.d/friwall.conf
 | 
			
		||||
    src: nginx.conf.j2
 | 
			
		||||
  notify: reload nginx
 | 
			
		||||
 | 
			
		||||
- name: Run nginx in default VRF
 | 
			
		||||
  lineinfile:
 | 
			
		||||
    path: /etc/conf.d/nginx
 | 
			
		||||
    line: "vrf=\"default\""
 | 
			
		||||
  notify: restart nginx
 | 
			
		||||
 | 
			
		||||
- name: Enable nginx
 | 
			
		||||
  service:
 | 
			
		||||
    name: nginx
 | 
			
		||||
    enabled: yes
 | 
			
		||||
    state: started
 | 
			
		||||
 | 
			
		||||
- name: Install config pusher initscript
 | 
			
		||||
  copy:
 | 
			
		||||
    dest: /etc/init.d/pusher
 | 
			
		||||
    src: pusher.initd
 | 
			
		||||
    mode: 0755
 | 
			
		||||
  notify: restart pusher
 | 
			
		||||
 | 
			
		||||
- name: Enable config pusher service
 | 
			
		||||
  service:
 | 
			
		||||
    name: pusher
 | 
			
		||||
    enabled: true
 | 
			
		||||
    state: started
 | 
			
		||||
 | 
			
		||||
- name: Regenerate config daily
 | 
			
		||||
  cron:
 | 
			
		||||
    name: "regenerate config"
 | 
			
		||||
    job: "cd ~/app ; FLASK_APP=web python3 -m flask generate"
 | 
			
		||||
    user: friwall
 | 
			
		||||
    hour: "3"
 | 
			
		||||
    minute: "33"
 | 
			
		||||
 | 
			
		||||
- name: Try (re-)pushing config periodically
 | 
			
		||||
  cron:
 | 
			
		||||
    name: "push config"
 | 
			
		||||
    job: "cd ~/app ; FLASK_APP=web python3 -m flask push"
 | 
			
		||||
    user: friwall
 | 
			
		||||
    minute: "*/15"
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +0,0 @@
 | 
			
		|||
auto lo
 | 
			
		||||
iface lo inet loopback
 | 
			
		||||
 | 
			
		||||
{% for iface in interfaces %}
 | 
			
		||||
auto {{ iface.name }}
 | 
			
		||||
iface {{ iface.name }} inet static
 | 
			
		||||
{% for address in iface.ip_addresses %}
 | 
			
		||||
    address {{ address.address }}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
{% if iface.custom_fields.gateway %}
 | 
			
		||||
    gateway {{ iface.custom_fields.gateway.address | ipaddr('address') }}
 | 
			
		||||
{% endif %}
 | 
			
		||||
 | 
			
		||||
{% endfor %}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +0,0 @@
 | 
			
		|||
{
 | 
			
		||||
{% for vlan, addrs in vrf_prefixes | groupby('vlan.vid') %}
 | 
			
		||||
  "{{ addrs[0].vlan.name }}": {
 | 
			
		||||
    "ip": {{ addrs | selectattr('family.value', '==', 4) | map(attribute='prefix') | to_json }},
 | 
			
		||||
    "ip6": {{ addrs | selectattr('family.value', '==', 6) | map(attribute='prefix') | to_json }}
 | 
			
		||||
  }{% if not loop.last %},{% endif +%}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,21 +0,0 @@
 | 
			
		|||
server {
 | 
			
		||||
	listen 80;
 | 
			
		||||
	listen [::]:80;
 | 
			
		||||
	server_name {{ fqdn }};
 | 
			
		||||
 | 
			
		||||
	return 301 https://$host$request_uri;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
server {
 | 
			
		||||
	listen 443 ssl;
 | 
			
		||||
	listen [::]:443 ssl;
 | 
			
		||||
	server_name {{ fqdn }};
 | 
			
		||||
 | 
			
		||||
	ssl_certificate /etc/letsencrypt/live/{{ fqdn }}/fullchain.pem;
 | 
			
		||||
	ssl_certificate_key /etc/letsencrypt/live/{{ fqdn }}/privkey.pem;
 | 
			
		||||
 | 
			
		||||
	location / {
 | 
			
		||||
		uwsgi_pass unix:/run/friwall.socket;
 | 
			
		||||
		include uwsgi_params;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
{% set nodes = query('netbox.netbox.nb_lookup', 'devices', raw_data=true)
 | 
			
		||||
    | selectattr('config_context') | selectattr('config_context', 'contains', 'master')
 | 
			
		||||
    | selectattr('config_context.master', '==', inventory_hostname)
 | 
			
		||||
    | map(attribute='name') -%}
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
{% for node in nodes %}
 | 
			
		||||
  "{{ hostvars[node].interfaces | selectattr('name', '==', 'lo') | map(attribute='ip_addresses') | first | selectattr('role') | selectattr('role.value', '==', 'loopback') | map(attribute='address') | ipv4 | first | ipaddr('address') }}": -1{{ '' if loop.last else ',' }} {# TODO help my eyes the goggles do nothing +#}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,10 +0,0 @@
 | 
			
		|||
{
 | 
			
		||||
  "ldap_host": "{{ domain }}",
 | 
			
		||||
  "ldap_user": "{{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="ldap_user") }}",
 | 
			
		||||
  "ldap_pass": "{{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="ldap_pass") }}",
 | 
			
		||||
  "ldap_base_dn": "{{ ldap_base_dn }}",
 | 
			
		||||
  "oidc_server": "{{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="oidc_server") }}",
 | 
			
		||||
  "oidc_client_id": "{{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="oidc_client_id") }}",
 | 
			
		||||
  "oidc_client_secret": "{{ lookup("passwordstore", "vm/"~inventory_hostname, subkey="oidc_client_secret") }}",
 | 
			
		||||
  "wg_net": "{{ wg_net }}"
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -26,8 +26,3 @@
 | 
			
		|||
- hosts: fw-*
 | 
			
		||||
  roles:
 | 
			
		||||
    - firewall
 | 
			
		||||
 | 
			
		||||
- hosts: zid
 | 
			
		||||
  roles:
 | 
			
		||||
    - certbot_dns
 | 
			
		||||
    - firewall_master
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue