Automatically create wireguard and ibgp mesh between nodes #1

Merged
mans merged 3 commits from new-automation into main 2025-11-09 13:31:40 +00:00
13 changed files with 214 additions and 103 deletions

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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:

View File

@@ -7,8 +7,9 @@
roles:
# - base
# - sysctl
- dummy-interfaces
- gre
# - dummy-interfaces
- wireguard
# - gre
# - routinator
- bird2
# - lg-backend

View File

@@ -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 ###

View File

@@ -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

View File

@@ -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 }}

View File

@@ -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 %}

View File

@@ -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

View File

@@ -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

View File

@@ -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

43
docs/roadmap.md Normal file
View File

@@ -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