--- network_mgmt_zone: "{{ network_zones.mgmt }}" network_internal_zone_names: - lan - guest - infoscreens openwrt_network_external: - name: interface 'citycom' options: device: 'eth1' proto: static ipaddr: "{{ network_zones.cc_hmtsaal.prefix | ansible.utils.ipaddr(network_zones.cc_hmtsaal.offsets[inventory_hostname]) | ansible.utils.ipaddr('address') }}" netmask: "{{ network_zones.cc_hmtsaal.prefix | ansible.utils.ipaddr('netmask') }}" gateway: "{{ network_zones.cc_hmtsaal.gateway }}" dns: "{{ network_zones.cc_hmtsaal.dns }}" accept_ra: 0 openwrt_network_internal: "{{ openwrt_network_internal_yaml | from_yaml }}" openwrt_network_internal_yaml: | {% for zone_name in network_internal_zone_names %} - name: "interface '{{ zone_name }}'" options: device: "eth0.{{ network_zones[zone_name].vlan }}" proto: static ipaddr: "{{ network_zones[zone_name].gateway }}" netmask: "{{ network_zones[zone_name].prefix | ansible.utils.ipaddr('netmask') }}" accept_ra: 0 {% endfor %} openwrt_network_base: - name: globals 'globals' options: ula_prefix: "fc{{ '%02x:%04x:%04x' | format((255 | random(seed=inventory_hostname + '0')), (65535 | random(seed=inventory_hostname + '1')), (65535 | random(seed=inventory_hostname + '2'))) }}::/48" - name: interface 'loopback' options: device: lo proto: static ipaddr: 127.0.0.1 netmask: 255.0.0.0 - name: device options: type: bridge name: "br-mgmt" ports: - "eth0.{{ network_mgmt_zone.vlan }}" - name: interface 'mgmt' options: device: "br-mgmt" proto: static ipaddr: "{{ network_mgmt_zone.prefix | ansible.utils.ipaddr(network_mgmt_zone.offsets[inventory_hostname]) | ansible.utils.ipaddr('address') }}" netmask: "{{ network_mgmt_zone.prefix | ansible.utils.ipaddr('netmask') }}" accept_ra: 0 - name: device options: type: bridge name: "br-mixer" ports: - "eth0.{{ network_zones.mixer.vlan }}" - name: interface 'mixer' options: device: "br-mixer" proto: static ipaddr: "{{ network_zones.mixer.prefix | ansible.utils.ipaddr(network_zones.mixer.offsets[inventory_hostname]) | ansible.utils.ipaddr('address') }}" netmask: "{{ network_zones.mixer.prefix | ansible.utils.ipaddr('netmask') }}" accept_ra: 0 openwrt_dhcp_external: - name: dhcp 'citycom' options: interface: 'citycom' ignore: '1' openwrt_dhcp_internal: "{{ openwrt_dhcp_internal_yaml | from_yaml }}" openwrt_dhcp_internal_yaml: | {% for zone_name in network_internal_zone_names %} - name: "dhcp '{{ zone_name }}'" options: interface: "{{ zone_name }}" {% if 'dhcp' in network_zones[zone_name] %} start: {{ network_zones[zone_name].dhcp.start }} limit: {{ network_zones[zone_name].dhcp.limit }} leasetime: {{ network_zones[zone_name].dhcp.leasetime | default('12h') }} dhcpv6: 'disabled' ra: 'disabled' {% else %} ignore: '1' {% endif %} {% endfor %} openwrt_dhcp_base: - name: dnsmasq options: domainneeded: '1' boguspriv: '0' filterwin2k: '0' localise_queries: '1' rebind_protection: '0' rebind_localhost: '1' local: '/lan/' domain: 'lan' expandhosts: '1' nonegcache: '0' authoritative: '1' readethers: '1' leasefile: '/tmp/dhcp.leases' resolvfile: '/tmp/resolv.conf.auto' localservice: '1' server: "{{ network_zones.cc_hmtsaal.dns }}" addnhosts: - '/etc/hosts.extra' - name: odhcpd 'odhcpd' options: maindhcp: '0' leasefile: '/tmp/hosts/odhcpd' leasetrigger: '/usr/sbin/odhcpd-update' - name: dhcp 'mgmt' options: interface: 'mgmt' ignore: '1' - name: dhcp 'mixer' options: interface: 'mixer' ignore: '1' openwrt_arch: x86 openwrt_target: 64 openwrt_profile: generic openwrt_output_image_suffixes: - "{{ openwrt_profile }}-ext4-combined.img.gz" openwrt_packages_remove: - ppp - ppp-mod-pppoe - kmod-ppp - kmod-pppoe - kmod-pppox - firewall - firewall4 - odhcpd-ipv6only openwrt_packages_add: - nftables - kmod-nft-nat - haveged - htop - ip - less - nano - tcpdump-mini - iperf - iperf3 - mtr - iptraf-ng - sqm-scripts - openvpn-openssl - prometheus-node-exporter-lua - prometheus-node-exporter-lua-netstat - prometheus-node-exporter-lua-openwrt openwrt_mixin: /etc/dropbear/authorized_keys: content: "{{ ssh_keys_root | join('\n') }}\n" /etc/htoprc: file: "{{ global_files_dir }}/common/htoprc" /etc/hosts.extra: content: | {{ network_zones.lan.prefix | ansible.utils.ipaddr(network_zones.lan.offsets['ele-media']) | ansible.utils.ipaddr('address') }} media.elev8.at /etc/hotplug.d/openvpn/10-mgmt: content: | #!/bin/sh [ "$INSTANCE" != "mgmt" ] && exit 0 [ "$ACTION" = "up" ] && ip link set up mtu "$3" dev "$2" master "br-mgmt" exit 0 /etc/openvpn/mgmt-ca-cert.pem: content: "{{ vault_ovpn_ca_cert }}" /etc/openvpn/mgmt-cert.pem: content: "{{ vault_ovpn_certs[inventory_hostname] }}" /etc/openvpn/mgmt-key.pem: content: "{{ vault_ovpn_keys[inventory_hostname] }}" mode: '0400' /etc/hotplug.d/openvpn/10-mixer: content: | #!/bin/sh [ "$INSTANCE" != "mixer" ] && exit 0 [ "$ACTION" = "up" ] && ip link set up mtu "$3" dev "$2" master "br-mixer" exit 0 /etc/openvpn/mixer-ca-cert.pem: content: "{{ vault_ovpn_ca_cert }}" /etc/openvpn/mixer-cert.pem: content: "{{ vault_ovpn_certs[inventory_hostname] }}" /etc/openvpn/mixer-key.pem: content: "{{ vault_ovpn_keys[inventory_hostname] }}" mode: '0400' /etc/rc.d/S21nftables: link: "../init.d/nftables" /etc/rc.d/K89nftables: link: "../init.d/nftables" /etc/init.d/nftables: mode: "0755" content: | #!/bin/sh /etc/rc.common START=21 STOP=89 start() { nft -f /etc/nftables.conf } stop() { nft flush ruleset } /etc/nftables.conf: content: | flush ruleset define nic_citycom = eth1 define ip_citycom = {{ network_zones.cc_hmtsaal.prefix | ansible.utils.ipaddr(network_zones.cc_hmtsaal.offsets[inventory_hostname]) | ansible.utils.ipaddr('address') }} define nic_mgmt = "br-mgmt" define prefix_mgmt = {{ network_mgmt_zone.prefix }} define nic_mixer = "br-mixer" define prefix_mixer = {{ network_zones.mixer.prefix }} {% for zone_name in network_internal_zone_names %} define nic_{{ zone_name }} = eth0.{{ network_zones[zone_name].vlan }} define prefix_{{ zone_name }} = {{ network_zones[zone_name].prefix }} {% endfor %} table inet global { ## INPUT chain input_external { ip protocol icmp accept ip6 nexthdr ipv6-icmp accept tcp dport { {{ ansible_port }} } accept udp dport { 1194, 1195 } accept } chain input_internal { ip protocol icmp accept ip6 nexthdr ipv6-icmp accept tcp dport { {{ ansible_port }}, domain } accept udp dport { bootps, domain, ntp } accept } chain input_mixer { ip protocol icmp accept ip6 nexthdr ipv6-icmp accept tcp dport { domain } accept udp dport { domain, ntp } accept } chain input { type filter hook input priority filter; policy drop; ct state vmap { established: accept, related: accept, invalid: drop } iifname vmap { lo: accept, $nic_mgmt: accept, $nic_mixer: jump input_mixer{% for zone_name in network_internal_zone_names %}, $nic_{{ zone_name }}: jump input_internal {% endfor %}, $nic_citycom: jump input_external } } ## FORWARD chain forward { type filter hook forward priority filter; policy drop; ct state vmap { established: accept, related: accept, invalid: drop } iifname { {{ ['$nic_'] | product(network_internal_zone_names) | map('join') | join(', ') }} } oifname $nic_citycom accept } chain postrouting { type nat hook postrouting priority srcnat; policy accept; ip saddr { {{ ['$prefix_'] | product(network_internal_zone_names) | map('join') | join(', ') }} } oifname $nic_citycom snat to $ip_citycom } } openwrt_uci: system: - name: system options: hostname: '{{ host_name }}' timezone: 'CET-1CEST,M3.5.0,M10.5.0/3' ttylogin: '0' log_size: '64' urandom_seed: '0' - name: timeserver 'ntp' options: enabled: '1' enable_server: '1' server: - '0.at.pool.ntp.org' - '1.at.pool.ntp.org' - '2.at.pool.ntp.org' - '3.at.pool.ntp.org' dropbear: - name: dropbear options: PasswordAuth: 'off' RootPasswordAuth: 'off' Port: '{{ ansible_port }}' uhttpd: - name: uhttpd main options: enabled: '0' prometheus-node-exporter-lua: - name: prometheus-node-exporter-lua 'main' options: listen_interface: 'mgmt' listen_port: '9100' dhcp: "{{ openwrt_dhcp_base + openwrt_dhcp_internal + openwrt_dhcp_external }}" network: "{{ openwrt_network_base + openwrt_network_internal + openwrt_network_external }}" sqm: - name: queue 'citycom' options: enabled: '1' interface: 'eth1' download: '70000' upload: '70000' qdisc: 'cake' script: 'piece_of_cake.qos' qdisc_advanced: '0' ingress_ecn: 'ECN' egress_ecn: 'ECN' qdisc_really_really_advanced: '0' itarget: 'auto' etarget: 'auto' linklayer: 'ethernet' overhead: '44 mpu 84' openvpn: - name: openvpn mgmt options: enabled: '1' port: '1194' proto: 'udp' dev: 'ovpn-mgmt' dev_type: 'tap' server_bridge: 'nogw' keepalive: '10 120' persist_key: '1' persist_tun: '1' user: 'nobody' tls_version_min: '1.3' ca: '/etc/openvpn/mgmt-ca-cert.pem' cert: '/etc/openvpn/mgmt-cert.pem' key: '/etc/openvpn/mgmt-key.pem' dh: 'none' remote_cert_tls: 'client' data_ciphers: - 'CHACHA20-POLY1305' data_ciphers_fallback: 'AES-256-GCM' allow_compression: 'no' - name: openvpn mixer options: enabled: '1' port: '1195' proto: 'udp' dev: 'ovpn-mixer' dev_type: 'tap' server_bridge: 'nogw' keepalive: '10 120' persist_key: '1' persist_tun: '1' user: 'nobody' tls_version_min: '1.3' ca: '/etc/openvpn/mixer-ca-cert.pem' cert: '/etc/openvpn/mixer-cert.pem' key: '/etc/openvpn/mixer-key.pem' dh: 'none' remote_cert_tls: 'client' data_ciphers: - 'CHACHA20-POLY1305' data_ciphers_fallback: 'AES-256-GCM' allow_compression: 'no' prometheus_scrape_endpoint: "{{ network_mgmt_zone.prefix | ansible.utils.ipaddr(network_mgmt_zone.offsets[inventory_hostname]) | ansible.utils.ipaddr('address') }}:9100" prometheus_exporters_default: - openwrt