diff --git a/ansible/config/common.yaml b/ansible/config/common.yaml index 359c196..85eaced 100644 --- a/ansible/config/common.yaml +++ b/ansible/config/common.yaml @@ -1,17 +1,74 @@ asn: 205079 -bgp: - my_as_set: "AS205079:AS-MANS" +bgp: {} +afis: [4, 6] ospf: default_cost: 100 accepted_routes: 4: - - "94.142.240.55/32" # ColoClue shared subnet IP - - "94.142.241.216/31" # ColoClue space + - "94.142.240.55/32" # ColoClue shared subnet IP + - "94.142.241.216/31" # ColoClue space 6: - - "2001:678:10ec::/48+" # AS205079 - - "2a02:a442:ba11::/48" # home - - "2a02:898:0:20::424:1/128" # ColoClue shared subnet IP - - "2a02:898:424::/48+" # ColoClue space + - "2001:678:10ec::/48+" # AS205079 + - "2a02:a442:ba11::/48" # home + - "2a02:898:0:20::424:1/128" # ColoClue shared subnet IP + - "2a02:898:424::/48+" # ColoClue space -afis: [4, 6] +routers: + "rtr1nlams1": + fqdn: rtr1nlams1.as205079.net + ipv4: 94.142.240.55 + ipv6: 2001:678:10ec:2201::1 + wg_ll: "fe80::2050:79:2" + wg_pubkey: "xM7LBgiO6oDFqaUmCSStULYYUjG+XSMcNEefQnvLh3o=" + site_id: "02" + rtr_id: "1" + "rtr1nlape1": + fqdn: rtr1nlape1.as205079.net + ipv4: 194.28.98.155 + ipv6: 2001:678:10ec:3201::1 + wg_ll: "fe80::2050:79:3" + wg_pubkey: "OigyZlXZ72Z07pqcFSZKxm6VG4+h9XylblSvwNQB2Cc=" + site_id: "03" + rtr_id: "1" + "rtr1nlwie1": + fqdn: rtr1nlwie1.as205079.net + pub_ipv4: 86.94.191.237 + ipv4: 10.20.10.23 # router is behind NAT + ipv6: 2001:678:10ec:1201::1 + wg_ll: "fe80::2050:79:1" + wg_pubkey: "lsfXc9anjxMxdkP1vsRvBCR4SKIf8MMYT6kLrQFaq3Y=" + site_id: "01" + rtr_id: "1" + +ixp_map: + bgpexch_amsterdam: + pdb_id: 3822 + ipv6_prefix: 2a0e:8f01:1000:11::/64 + present_on: + - rtr1nlape1 + bgpexch_berlin: + pdb_id: 4842 + ipv6_prefix: 2a0e:8f01:1000:13::/64 + present_on: + - rtr1nlape1 + bgpexch_dusseldorf: + pdb_id: 3844 + ipv6_prefix: 2a0e:8f01:1000:46::/64 + present_on: + - rtr1nlape1 + bgpexch_frankfurt: + pdb_id: 3829 + ipv6_prefix: 2a0e:8f01:1000:24::/64 + present_on: + - rtr1nlape1 + bgpexch_london: + pdb_id: 3821 + ipv6_prefix: 2a0e:8f01:1000:10::/64 + present_on: + - rtr1nlape1 + locix: + pdb_id: 2601 + ipv6_prefix: 2a0c:b641:700::/64 + present_on: + - rtr1nlape1 diff --git a/ansible/config/rtr1.nlams1.as205079.net.yaml b/ansible/config/rtr1.nlams1.as205079.net.yaml index 2cd639e..ae4c628 100644 --- a/ansible/config/rtr1.nlams1.as205079.net.yaml +++ b/ansible/config/rtr1.nlams1.as205079.net.yaml @@ -1,6 +1,4 @@ -location: - code: "NLAMS1" - site_id: "2" +shortname: rtr1nlams1 ipv6: primary: "2001:0678:10ec:2201::1" @@ -18,32 +16,10 @@ routes: - "2001:678:10ec::/48" # My space - "2a02:898:424::/48" # ColoClue space -# dummy_interfaces: {} - -gre: - tunnels: - - name: "INT-RTR1NLAPE1" - remote_endpoint: 194.28.98.155 - local_endpoint: 94.142.240.55 - local_ipv6: 2001:678:10ec:20e::1/64 - ttl: 255 - mtu: 1476 - - name: "INT-RTR1NLWIE1" - remote_endpoint: 86.94.191.237 - local_endpoint: 94.142.240.55 - local_ipv6: 2001:678:10ec:20d::1/64 - ttl: 255 - mtu: 1468 - interfaces: - nic: "loop0" description: "Loopback interface" stub: true - # - nic: "eno1" - # description: "Uplink" - # stub: true - - nic: "INT-RTR1NLAPE1" - - nic: "INT-RTR1NLWIE1" - nic: "vmbr1" description: "NLAMS1 Servers" stub: true @@ -75,10 +51,3 @@ peers: import: "RIPE::AS212855:AS-LUJE" export: "RIPE::AS205079:AS-MANS" peer_ipv6: "2a02:898:0:20::427:1" - - -internal_peers: - - name: "RTR1APE1" - ip: "2001:678:10ec:3201::1" - - name: "RTR1WIE1" - ip: "2001:678:10ec:1201::1" diff --git a/ansible/config/rtr1.nlape1.as205079.net.yaml b/ansible/config/rtr1.nlape1.as205079.net.yaml index f9dae86..ed7acc0 100644 --- a/ansible/config/rtr1.nlape1.as205079.net.yaml +++ b/ansible/config/rtr1.nlape1.as205079.net.yaml @@ -1,6 +1,4 @@ -location: - code: "NLAPE1" - site_id: "3" +shortname: rtr1nlape1 ipv6: primary: "2001:0678:10ec:3201::1" @@ -15,18 +13,6 @@ routes: gre: tunnels: - - name: "INT-RTR1NLWIE1" - remote_endpoint: 86.94.191.237 - local_endpoint: 194.28.98.155 - local_ipv6: 2001:678:10ec:20f:0:0:0:1/112 - ttl: 255 - mtu: 1468 - - name: "INT-RTR1NLAMS1" - remote_endpoint: 94.142.240.55 - local_endpoint: 194.28.98.155 - local_ipv6: 2001:678:10ec:20e::2/64 - ttl: 255 - mtu: 1476 - name: "ROUTE64-AMS1" remote_endpoint: 118.91.187.67 local_endpoint: 194.28.98.155 @@ -92,8 +78,6 @@ interfaces: - nic: "ens19" description: "To Loc-IX" stub: true - - nic: "INT-RTR1NLWIE1" - - nic: "INT-RTR1NLAMS1" rpki: run_routinator: true @@ -123,12 +107,6 @@ transits: # asn: 212895 # peer_ipv6: "2a11:6c7:f00:1be::1" -internal_peers: - - name: "RTR1WIE1" - ip: "2001:678:10ec:1201::1" - - name: "RTR1AMS1" - ip: "2001:678:10ec:2201::1" - peers: # LocIX route servers - name: "locix_rs_1" diff --git a/ansible/config/rtr1.nlwie1.as205079.net.yaml b/ansible/config/rtr1.nlwie1.as205079.net.yaml index dd4a5d6..9d64b9c 100644 --- a/ansible/config/rtr1.nlwie1.as205079.net.yaml +++ b/ansible/config/rtr1.nlwie1.as205079.net.yaml @@ -1,6 +1,4 @@ -location: - code: "NLWIE1" - site_id: "1" +shortname: rtr1nlwie1 ipv6: primary: "2001:0678:10ec:1201::1" @@ -13,21 +11,6 @@ routes: 6: - "2001:678:10ec::/48" -gre: - tunnels: - - name: "INT-RTR1NLAPE1" - remote_endpoint: 194.28.98.155 - local_endpoint: 10.20.10.23 - local_ipv6: 2001:678:10ec:20f:0:0:0:2/112 - ttl: 255 - mtu: 1468 - - name: "INT-RTR1NLAMS1" - remote_endpoint: 94.142.240.55 - local_endpoint: 10.20.10.23 - local_ipv6: 2001:678:10ec:20d::2/64 - ttl: 255 - mtu: 1468 - interfaces: - nic: "loop0" description: "Loopback interface" @@ -37,18 +20,10 @@ interfaces: - nic: "eth1" description: "nlwie1 servers" stub: true - - nic: "INT-RTR1NLAPE1" - - nic: "INT-RTR1NLAMS1" - nic: "wg0" description: "wireguard remote" stub: true -internal_peers: - - name: "RTR1APE1" - ip: "2001:678:10ec:3201::1" - - name: "RTR1AMS1" - ip: "2001:678:10ec:2201::1" - lg: version: 0.1.4 agent: diff --git a/ansible/playbook.yaml b/ansible/playbook.yaml index 6ee77d8..0a3dd14 100644 --- a/ansible/playbook.yaml +++ b/ansible/playbook.yaml @@ -7,8 +7,9 @@ roles: # - base # - sysctl - - dummy-interfaces - - gre + # - dummy-interfaces + - wireguard + # - gre # - routinator - bird2 # - lg-backend diff --git a/ansible/roles/bird2/templates/bird.conf.j2 b/ansible/roles/bird2/templates/bird.conf.j2 index 2ecd560..99a66ea 100644 --- a/ansible/roles/bird2/templates/bird.conf.j2 +++ b/ansible/roles/bird2/templates/bird.conf.j2 @@ -415,6 +415,17 @@ protocol ospf v3 { export none; # do not export anything to ospf, ospf will figure things out itself }; area 0.0.0.0 { + +{% for router in routers if not router == shortname %} + interface "int-{{ router }}" { + cost {{ ospf.default_cost }}; + type pointopoint; + neighbors { + {{ routers[router]['wg_ll'] }}; + }; + }; +{% endfor %} + {% for interface in interfaces %} {% if 'description' in interface %} # desc: {{ interface.description }} @@ -435,6 +446,7 @@ protocol ospf v3 { {% endif %} }; {% endfor %} + }; } @@ -464,13 +476,11 @@ template bgp peer { ### END TEMPLATES ### ### START INTERNAL PEERS ### -{% if internal_peers is defined and internal_peers | length > 0 %} -{% for peer in internal_peers | sort(attribute='name') %} -protocol bgp 'internal_{{ peer.name }}' from internal_peer { - neighbor {{ peer.ip }} as {{ asn }}; +{% for router in routers if not router == shortname %} +protocol bgp 'int_{{ router }}' from internal_peer { + neighbor {{ routers[router]['ipv6'] }} as {{ asn }}; } {% endfor %} -{% endif %} ### END INTERNAL PEERS ### ### START TRANSITS ### diff --git a/ansible/roles/gre/handlers/main.yaml b/ansible/roles/gre/handlers/main.yaml index 3edf0e1..9d9fa25 100644 --- a/ansible/roles/gre/handlers/main.yaml +++ b/ansible/roles/gre/handlers/main.yaml @@ -3,8 +3,3 @@ cmd: "ifreload -a" register: ifreload_result changed_when: ifreload_result.stdout != "" and "Reloading" in ifreload_result.stdout - -- name: "Restart networking" - ansible.builtin.systemd: - name: networking - state: restarted diff --git a/ansible/roles/gre/tasks/main.yaml b/ansible/roles/gre/tasks/main.yaml index cfa460d..2dbe6c3 100644 --- a/ansible/roles/gre/tasks/main.yaml +++ b/ansible/roles/gre/tasks/main.yaml @@ -1,4 +1,12 @@ -- name: "Ensure gre interfaces are present" +# - name: "Ensure internal gre interfaces are present" +# ansible.builtin.template: +# src: internal_gre_interfaces.j2 +# dest: /etc/network/interfaces.d/internal_gre_interfaces +# mode: "0644" +# notify: +# - "Reload networking" + +- name: "Ensure extra gre interfaces are present" ansible.builtin.template: src: gre_interface.j2 dest: /etc/network/interfaces.d/{{ item.name }} diff --git a/ansible/roles/gre/templates/internal_gre_interfaces.j2 b/ansible/roles/gre/templates/internal_gre_interfaces.j2 new file mode 100644 index 0000000..24d03f8 --- /dev/null +++ b/ansible/roles/gre/templates/internal_gre_interfaces.j2 @@ -0,0 +1,11 @@ +{%- for router in routers if not router == shortname %} +auto int-{{ router }} +iface int-{{ router }} inet6 static + pre-up ip tunnel add int-{{ router }} mode gre remote {{ routers[router]['pub_ipv4'] | default(routers[router]['ipv4']) }} local {{ routers[shortname]['ipv4'] }} ttl 255 + pre-up ip addr add {{ routers[shortname]['gre_ll'] }}/64 dev int-{{ router }} + up ip link set dev int-{{ router }} up + # up ip link set int-{{ router }} mtu {{ routers[router]['gre_mtu'] }} + up ip link set dev int-{{ router }} mtu 1468 + post-down ip tunnel del int-{{ router }} + +{% endfor %} diff --git a/ansible/roles/wireguard/handlers/main.yaml b/ansible/roles/wireguard/handlers/main.yaml new file mode 100644 index 0000000..9d9fa25 --- /dev/null +++ b/ansible/roles/wireguard/handlers/main.yaml @@ -0,0 +1,5 @@ +- name: "Reload networking" + ansible.builtin.command: + cmd: "ifreload -a" + register: ifreload_result + changed_when: ifreload_result.stdout != "" and "Reloading" in ifreload_result.stdout diff --git a/ansible/roles/wireguard/tasks/main.yaml b/ansible/roles/wireguard/tasks/main.yaml new file mode 100644 index 0000000..34b643c --- /dev/null +++ b/ansible/roles/wireguard/tasks/main.yaml @@ -0,0 +1,47 @@ +- name: "Ensure wireguard is installed" + ansible.builtin.apt: + update_cache: true + name: + - wireguard + +- name: "Ensure /etc/wireguard directory exists" + ansible.builtin.file: + path: "/etc/wireguard/" + state: directory + owner: root + group: root + mode: '0750' + +- name: "Ensure wireguard private key is present" + ansible.builtin.shell: + cmd: "wg genkey > /etc/wireguard/privatekey" + creates: "/etc/wireguard/privatekey" + +- name: "Ensure proper permissions are set on wireguard private key" + ansible.builtin.file: + path: "/etc/wireguard/privatekey" + mode: '0640' + owner: root + group: systemd-network + +- name: "Ensure wireguard publickey file exists" + ansible.builtin.shell: + cmd: "wg pubkey < /etc/wireguard/privatekey > /etc/wireguard/publickey" + creates: "/etc/wireguard/publickey" + +- name: "Ensure internal wireguard interfaces are present" + ansible.builtin.template: + src: internal-wg-interface.j2 + dest: /etc/wireguard/int-{{ item }}.conf + mode: "0640" + loop: "{{ routers.keys() | list }}" + when: item != shortname + register: if_changed + +- name: "Restart wg-quick units for changed interfaces" + ansible.builtin.systemd: + name: "wg-quick@int-{{ item.item }}" + state: restarted + enabled: true + loop: "{{ if_changed.results | selectattr('changed') | list }}" + when: if_changed is defined and if_changed.results | length > 0 diff --git a/ansible/roles/wireguard/templates/internal-wg-interface.j2 b/ansible/roles/wireguard/templates/internal-wg-interface.j2 new file mode 100644 index 0000000..a0e62f9 --- /dev/null +++ b/ansible/roles/wireguard/templates/internal-wg-interface.j2 @@ -0,0 +1,12 @@ +[Interface] +ListenPort = 52{{ routers[item]['site_id'] }}{{ routers[item]['rtr_id'] }} +Address = {{ routers[shortname]['wg_ll'] }}/64 +Table = off +MTU = 1500 # We fragment packets, this is intentional +PostUp = wg set %i private-key /etc/wireguard/privatekey + +[Peer] +PublicKey = {{ routers[item]['wg_pubkey'] }} +Endpoint = {{ routers[item]['pub_ipv4'] | default(routers[item]['ipv4'] )}}:52{{ routers[shortname]['site_id']}}{{ routers[shortname]['rtr_id']}} +AllowedIPs = ::/0 +PersistentKeepalive = 30 diff --git a/docs/roadmap.md b/docs/roadmap.md new file mode 100644 index 0000000..89101f7 --- /dev/null +++ b/docs/roadmap.md @@ -0,0 +1,43 @@ +# Roadmap for AS205079 + +- [ ] Self-service peering portal + - [x] PeeringDB DB sync +- [ ] Bandwidth monitoring/ flow logging + - [ ] Pmacct deployment + - [ ] Akvorado deployment + - [ ] SNMP? +- [ ] Better automation + - [ ] Rewrite Bird2 config + - [ ] Simpler ansible config +- [ ] Looking glass +- [ ] Authoritative DNS + - [ ] PowerDNS deployment + - [ ] nsedit deployment + - [ ] Migrate domains +- [ ] NTP server +- [ ] Web server +- [ ] Looking glass + - [x] Write LG v1 +- [ ] Improve security + - [x] Proxmox firewall + - [ ] VM firewall + - nftables or iptables? + - statefull or stateless + - [ ] Move away from gre? + - Key auth? + - Wireguard? +- [ ] Backups +- [ ] Replace home firewall + - Host HAProxy elsewhere? + - Move away from L4 LB? +- [ ] RDS server +- [ ] Anycast important services + - [ ] OSPF anycast + - [ ] Web server + - [ ] Auth DNS +- [ ] Find ifupdown2 alternative? + - Solve issues with ifupdown2 +- [ ] FastNetMon deployment + - [ ] Alerting + - [ ] Dropping traffic from source-ip + - [ ] Blackholing at transit