initial commit
This commit is contained in:
commit
3586c571f3
24 files changed
+887
No files matched your search
@@ -0,0 +1,2 @@
|
||||
.ansible/
|
||||
*.retry
|
||||
@@ -0,0 +1,55 @@
|
||||
# nbops-ansible-router
|
||||
|
||||
Ansible framework for building a Debian 13 BIRD router VM from an initial Debian 12 install.
|
||||
|
||||
The first stage performs the Debian 12 to Debian 13 dist upgrade. Router configuration then installs WireGuard and BIRD, applies forwarding sysctl values, and renders configs from variables.
|
||||
|
||||
## Layout
|
||||
|
||||
- `site.yml` - main entry point.
|
||||
- `inventories/production/hosts.yml` - VM inventory placeholder.
|
||||
- `group_vars/routers.yml` - shared router variables.
|
||||
- `roles/debian_dist_upgrade` - Debian 12 to Debian 13 upgrade workflow.
|
||||
- `roles/bird_router` - WireGuard, sysctl forwarding, CZ.NIC BIRD packages, and BIRD configuration.
|
||||
|
||||
## Usage
|
||||
|
||||
Edit `inventories/production/hosts.yml`, then run:
|
||||
|
||||
```sh
|
||||
ansible-playbook site.yml
|
||||
```
|
||||
|
||||
To run only the OS upgrade stage:
|
||||
|
||||
```sh
|
||||
ansible-playbook site.yml --tags debian_upgrade
|
||||
```
|
||||
|
||||
The upgrade role expects the VM to start on Debian 12/bookworm and upgrades it to Debian 13/trixie.
|
||||
|
||||
## Router Secrets
|
||||
|
||||
WireGuard private keys are read from environment variables by default:
|
||||
|
||||
```sh
|
||||
export WG1_PRIVATEKEY='...'
|
||||
export WG2_PRIVATEKEY='...'
|
||||
ansible-playbook site.yml
|
||||
```
|
||||
|
||||
For production, prefer Ansible Vault group vars instead of committing secrets. Public keys, allowed IPs, BGP peers, package track, and package version are defined in `group_vars/routers.yml`.
|
||||
|
||||
## BIRD Package Track
|
||||
|
||||
The router role configures the CZ.NIC Labs apt repository for BIRD. Defaults:
|
||||
|
||||
- `bird_track: bird2`
|
||||
- `bird_package_version: 2.19.1-cznic.1~trixie`
|
||||
|
||||
To test BIRD 3 later, set:
|
||||
|
||||
```yaml
|
||||
bird_track: bird3
|
||||
bird_package_version: ""
|
||||
```
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
[defaults]
|
||||
inventory = inventories/production/hosts.yml
|
||||
roles_path = roles
|
||||
host_key_checking = True
|
||||
retry_files_enabled = False
|
||||
interpreter_python = auto_silent
|
||||
local_tmp = .ansible/tmp
|
||||
|
||||
[privilege_escalation]
|
||||
become = True
|
||||
become_method = sudo
|
||||
become_ask_pass = False
|
||||
@@ -0,0 +1,151 @@
|
||||
router id 82.215.64.105;
|
||||
|
||||
log syslog all;
|
||||
log "/var/log/bird/bird.log" { debug, trace, remote, warning, error, auth, fatal, bug };
|
||||
#log "/var/log/bird/info-bird.log" { info };
|
||||
|
||||
protocol device { scan time 5; }
|
||||
protocol direct { ipv6; }
|
||||
|
||||
protocol kernel {
|
||||
ipv6 { export none; };
|
||||
# ipv6;
|
||||
scan time 15;
|
||||
# learn;
|
||||
}
|
||||
|
||||
protocol kernel {
|
||||
ipv4;
|
||||
scan time 15;
|
||||
# export filter rt_export;
|
||||
# learn;
|
||||
}
|
||||
|
||||
protocol static announcev6 {
|
||||
ipv6;
|
||||
description "Static v6 Routes";
|
||||
# route 2a12:bec0:6b0::/44 blackhole;
|
||||
route 2a12:bec0:6b1::/48 via 2a12:bec2:b00b::201;
|
||||
# route 2a12:bec0:6b9::/48 via 2a12:bec2:b00b::1f7;
|
||||
# route 2a12:bec0:210:4::/64 via 2a12:bec0:210:4::1; #Pete-tunnel
|
||||
# route 2a12:bec0:218::/48 via 2a12:bec0:210:4::2; #Pete-range
|
||||
|
||||
}
|
||||
|
||||
protocol static announcev4 {
|
||||
ipv4;
|
||||
description "Static v4 Routes";
|
||||
}
|
||||
|
||||
protocol static {
|
||||
ipv6;
|
||||
}
|
||||
|
||||
protocol static {
|
||||
ipv4;
|
||||
}
|
||||
|
||||
filter rt_importv4 {
|
||||
accept;
|
||||
}
|
||||
|
||||
filter rt_importv6 {
|
||||
accept;
|
||||
}
|
||||
|
||||
filter rt_nothanks {
|
||||
|
||||
if (net ~ [ fd00:dead:beef:c0::/80 ]) then
|
||||
reject;
|
||||
if (net ~ [ fd4d:6169:6c69:6f77::/64 ]) then
|
||||
reject;
|
||||
if (net ~ [ fd7a:115c:a1e0::/48 ]) then
|
||||
reject;
|
||||
if (net ~ [ fd8c:c43c:133e::/64 ]) then
|
||||
reject;
|
||||
if (net ~ [ fd8c:c43c:133e:1::/64 ]) then
|
||||
reject;
|
||||
if (net ~ [ fd8c:c43c:133e:2::/64 ]) then
|
||||
reject;
|
||||
if (net ~ [ fd00:1::/64 ]) then
|
||||
reject;
|
||||
if (net ~ [ 2a12:bec2:b00b::/64 ]) then
|
||||
reject;
|
||||
if (net ~ [ ::10.10.10.1/128 ]) then
|
||||
reject;
|
||||
if (net ~ [ 2a12:bec0:210:3::/64 ]) then
|
||||
reject;
|
||||
else
|
||||
accept;
|
||||
}
|
||||
|
||||
filter sbehop {
|
||||
gw = 2a12:bec0:210:3::1;
|
||||
accept;
|
||||
}
|
||||
|
||||
filter brt_importv6 {
|
||||
reject;
|
||||
}
|
||||
|
||||
filter rt_export {
|
||||
if (proto = "announcev4") then
|
||||
accept;
|
||||
if (proto = "announcev6") then
|
||||
accept;
|
||||
# reject_bogon_asns();
|
||||
# reject_v6_bogon_prefixes();
|
||||
# reject_smallv6_prefixes();
|
||||
# reject_long_aspaths();
|
||||
reject;
|
||||
# accept; #export Any Accepted Prefixes
|
||||
}
|
||||
|
||||
#EBGP upstream sessions
|
||||
protocol bgp tgj4 {
|
||||
# debug all;
|
||||
local 172.22.10.2 as 213026;
|
||||
neighbor 172.22.10.1 as 199519;
|
||||
# default bgp_local_pref 20;
|
||||
multihop 255;
|
||||
ipv6 {
|
||||
export limit 30;
|
||||
import filter sbehop;
|
||||
export filter rt_nothanks;
|
||||
graceful restart on;
|
||||
};
|
||||
}
|
||||
|
||||
protocol bgp scaleblade6 {
|
||||
# debug all;
|
||||
local 2a12:bec2:b00b::201 as 213026;
|
||||
neighbor 2a12:bec1::2 as 52041;
|
||||
multihop 255;
|
||||
# default bgp_local_pref 20;
|
||||
ipv6 {
|
||||
export limit 50;
|
||||
import filter rt_importv6;
|
||||
export filter rt_nothanks;
|
||||
graceful restart on;
|
||||
};
|
||||
}
|
||||
|
||||
#IBGP sessions
|
||||
protocol bgp ntbx {
|
||||
local 172.18.72.1 as 213026;
|
||||
neighbor 172.18.72.2 as 213026;
|
||||
multihop 255;
|
||||
ipv6 {
|
||||
import limit 20;
|
||||
# import none;
|
||||
import filter rt_importv6;
|
||||
export filter rt_export;
|
||||
# export none;
|
||||
};
|
||||
# ipv4 {
|
||||
# import limit 20;
|
||||
# import none;
|
||||
# export filter rt_export;
|
||||
## graceful restart on;
|
||||
# };
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
BIRD_RUN_USER=bird
|
||||
BIRD_RUN_GROUP=bird
|
||||
#BIRD_ARGS=
|
||||
@@ -0,0 +1,3 @@
|
||||
net.ipv6.conf.all.forwarding = 1
|
||||
net.ipv6.conf.default.forwarding = 1
|
||||
net.ipv4.ip_forward = 1
|
||||
@@ -0,0 +1,16 @@
|
||||
# Wireguard to pfSense
|
||||
|
||||
[Interface]
|
||||
PrivateKey = ${WG1_PRIVATEKEY}
|
||||
Address = 2a12:bec0:6b1::1/64,172.18.72.1/30
|
||||
ListenPort = 51825
|
||||
MTU = 1430
|
||||
|
||||
PreUp = ip neigh add proxy 82.215.64.187 dev eth0
|
||||
|
||||
PostDown = ip neigh del proxy 82.215.64.187 dev eth0
|
||||
|
||||
[Peer]
|
||||
PublicKey = SsGjCLJBKQFDuxSnVgwua77fvb/ha4KFRiJcCBk7vF0=
|
||||
AllowedIPs = 2a12:bec0:6b1::2/64,2a12:bec0:6b9::/48,172.18.72.0/30,82.215.64.187/32
|
||||
#2a12:bec0:6b9:2::/64,2a12:bec0:6b9:3::/64,2a12:bec0:6b9:10::/64,2a12:bec0:6b9::/48,172.18.72.0/30,82.215.64.187/32
|
||||
@@ -0,0 +1,13 @@
|
||||
# Wireguard to TGJ
|
||||
|
||||
[Interface]
|
||||
PrivateKey = ${WG2_PRIVATEKEY}
|
||||
Address = 2a12:bec0:210:3::2/64,172.22.10.2/30
|
||||
ListenPort = 51820
|
||||
MTU = 1430
|
||||
|
||||
[Peer]
|
||||
PublicKey = 1XaLeqKZimM1cS57dPzTSf/UGW8bThADjf+oBmRF82I=
|
||||
AllowedIPs = 2a12:bec0:21f::2/64,172.22.10.1/30,2a12:bec0:212::/48,2a12:bec0:210::/48,2a12:bec0:214::/48
|
||||
Endpoint = v4.router.colo.tgj.services:51869
|
||||
PersistentKeepalive = 25
|
||||
@@ -0,0 +1,8 @@
|
||||
82.215.64.187 = Virtual Home IP used by Bird
|
||||
82.215.64.105 = BIRD VPS IP
|
||||
82.215.64.169 = VPS IP
|
||||
v4.router.colo.tgj.services:51869 = TGJ WG Remote Node
|
||||
|
||||
82.215.64.187 is cloud-init added to the default interface, this should be removed in wireguard PreUp, or ansible config
|
||||
|
||||
Should use ansible variables for allowedIPs, private / public keys, etc. anything that should not be committed to github should be in group vars or envy
|
||||
@@ -0,0 +1,115 @@
|
||||
---
|
||||
debian_upgrade_target_release: trixie
|
||||
debian_upgrade_target_major_version: "13"
|
||||
debian_upgrade_source_major_version: "12"
|
||||
|
||||
debian_upgrade_reboot_timeout: 1800
|
||||
|
||||
router_external_interface: eth0
|
||||
|
||||
router_virtual_home_ip: 82.215.64.187
|
||||
router_bird_vps_ip: 82.215.64.105
|
||||
router_vps_ip: 82.215.64.169
|
||||
|
||||
router_sysctl:
|
||||
net.ipv6.conf.all.forwarding: 1
|
||||
net.ipv6.conf.default.forwarding: 1
|
||||
net.ipv4.ip_forward: 1
|
||||
|
||||
bird_enable: true
|
||||
bird_track: bird2
|
||||
bird_package_version: 2.19.1-cznic.1~trixie
|
||||
bird_router_id: 82.215.64.105
|
||||
bird_local_as: 213026
|
||||
bird_run_user: bird
|
||||
bird_run_group: bird
|
||||
bird_log_file: /var/log/bird/bird.log
|
||||
bird_sbehop_gateway: 2a12:bec0:210:3::1
|
||||
|
||||
bird_static_routes_v6:
|
||||
- prefix: 2a12:bec0:6b1::/48
|
||||
via: 2a12:bec2:b00b::201
|
||||
|
||||
bird_reject_prefixes_v6:
|
||||
- fd00:dead:beef:c0::/80
|
||||
- fd4d:6169:6c69:6f77::/64
|
||||
- fd7a:115c:a1e0::/48
|
||||
- fd8c:c43c:133e::/64
|
||||
- fd8c:c43c:133e:1::/64
|
||||
- fd8c:c43c:133e:2::/64
|
||||
- fd00:1::/64
|
||||
- 2a12:bec2:b00b::/64
|
||||
- ::10.10.10.1/128
|
||||
- 2a12:bec0:210:3::/64
|
||||
|
||||
bird_bgp_sessions:
|
||||
- name: tgj4
|
||||
local_address: 172.22.10.2
|
||||
local_as: 213026
|
||||
neighbor_address: 172.22.10.1
|
||||
neighbor_as: 199519
|
||||
address_family: ipv6
|
||||
export_limit: 30
|
||||
import_filter: sbehop
|
||||
export_filter: rt_nothanks
|
||||
graceful_restart: true
|
||||
- name: scaleblade6
|
||||
local_address: 2a12:bec2:b00b::201
|
||||
local_as: 213026
|
||||
neighbor_address: 2a12:bec1::2
|
||||
neighbor_as: 52041
|
||||
address_family: ipv6
|
||||
export_limit: 50
|
||||
import_filter: rt_importv6
|
||||
export_filter: rt_nothanks
|
||||
graceful_restart: true
|
||||
- name: ntbx
|
||||
local_address: 172.18.72.1
|
||||
local_as: 213026
|
||||
neighbor_address: 172.18.72.2
|
||||
neighbor_as: 213026
|
||||
address_family: ipv6
|
||||
import_limit: 20
|
||||
import_filter: rt_importv6
|
||||
export_filter: rt_export
|
||||
|
||||
wireguard_enable: true
|
||||
wireguard_interfaces:
|
||||
- name: wg1
|
||||
description: WireGuard to pfSense
|
||||
private_key_env: WG1_PRIVATEKEY
|
||||
address:
|
||||
- 2a12:bec0:6b1::1/64
|
||||
- 172.18.72.1/30
|
||||
listen_port: 51825
|
||||
mtu: 1430
|
||||
pre_up:
|
||||
- "ip addr del 82.215.64.187/32 dev eth0 2>/dev/null || true"
|
||||
- "ip neigh add proxy 82.215.64.187 dev eth0 2>/dev/null || true"
|
||||
post_down:
|
||||
- "ip neigh del proxy 82.215.64.187 dev eth0 2>/dev/null || true"
|
||||
peers:
|
||||
- public_key: SsGjCLJBKQFDuxSnVgwua77fvb/ha4KFRiJcCBk7vF0=
|
||||
allowed_ips:
|
||||
- 2a12:bec0:6b1::2/64
|
||||
- 2a12:bec0:6b9::/48
|
||||
- 172.18.72.0/30
|
||||
- 82.215.64.187/32
|
||||
- name: wg2
|
||||
description: WireGuard to TGJ
|
||||
private_key_env: WG2_PRIVATEKEY
|
||||
address:
|
||||
- 2a12:bec0:210:3::2/64
|
||||
- 172.22.10.2/30
|
||||
listen_port: 51820
|
||||
mtu: 1430
|
||||
peers:
|
||||
- public_key: 1XaLeqKZimM1cS57dPzTSf/UGW8bThADjf+oBmRF82I=
|
||||
allowed_ips:
|
||||
- 2a12:bec0:21f::2/64
|
||||
- 172.22.10.1/30
|
||||
- 2a12:bec0:212::/48
|
||||
- 2a12:bec0:210::/48
|
||||
- 2a12:bec0:214::/48
|
||||
endpoint: v4.router.colo.tgj.services:51869
|
||||
persistent_keepalive: 25
|
||||
@@ -0,0 +1,7 @@
|
||||
all:
|
||||
children:
|
||||
routers:
|
||||
hosts:
|
||||
router-vm:
|
||||
ansible_host: 10.10.10.10
|
||||
ansible_user: debian
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
router_external_interface: eth0
|
||||
|
||||
router_sysctl:
|
||||
net.ipv6.conf.all.forwarding: 1
|
||||
net.ipv6.conf.default.forwarding: 1
|
||||
net.ipv4.ip_forward: 1
|
||||
|
||||
wireguard_enable: true
|
||||
wireguard_package_name: wireguard-tools
|
||||
wireguard_interfaces: []
|
||||
|
||||
bird_enable: true
|
||||
bird_track: bird2
|
||||
bird_package_name: "{{ bird_track }}"
|
||||
bird_package_version: ""
|
||||
bird_cznic_repo_enabled: true
|
||||
bird_cznic_repo_base_url: https://pkg.labs.nic.cz
|
||||
bird_cznic_repo_distribution: "{{ ansible_facts.distribution_release | default('trixie') }}"
|
||||
bird_cznic_key_url: https://pkg.labs.nic.cz/gpg
|
||||
|
||||
bird_config_path: /etc/bird/bird.conf
|
||||
bird_envvars_path: /etc/bird/envvars
|
||||
bird_service_name: bird
|
||||
bird_router_id: 127.0.0.1
|
||||
bird_local_as: 64512
|
||||
bird_run_user: bird
|
||||
bird_run_group: bird
|
||||
bird_log_file: /var/log/bird/bird.log
|
||||
bird_sbehop_gateway: ""
|
||||
bird_static_routes_v6: []
|
||||
bird_static_routes_v4: []
|
||||
bird_reject_prefixes_v6: []
|
||||
bird_bgp_sessions: []
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: Reload sysctl
|
||||
ansible.builtin.command: sysctl --system
|
||||
listen: reload_sysctl
|
||||
changed_when: false
|
||||
|
||||
- name: Restart WireGuard interfaces
|
||||
ansible.builtin.systemd:
|
||||
name: "wg-quick@{{ item.name }}"
|
||||
state: restarted
|
||||
loop: "{{ wireguard_interfaces }}"
|
||||
listen: restart_wireguard_interfaces
|
||||
when: wireguard_enable
|
||||
|
||||
- name: Restart BIRD
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ bird_service_name }}"
|
||||
state: restarted
|
||||
listen: restart_bird
|
||||
when: bird_enable
|
||||
@@ -0,0 +1,131 @@
|
||||
- name: Validate BIRD package track
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- bird_track in ['bird2', 'bird3']
|
||||
fail_msg: "bird_track must be either bird2 or bird3."
|
||||
when: bird_enable
|
||||
|
||||
- name: Install repository prerequisites
|
||||
ansible.builtin.apt:
|
||||
name:
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
- python3-debian
|
||||
state: present
|
||||
update_cache: true
|
||||
when: bird_enable and bird_cznic_repo_enabled
|
||||
|
||||
- name: Configure CZ.NIC Labs BIRD apt repository
|
||||
ansible.builtin.deb822_repository:
|
||||
name: "cznic-labs-{{ bird_track }}"
|
||||
types: deb
|
||||
uris: "{{ bird_cznic_repo_base_url }}/{{ bird_track }}"
|
||||
suites: "{{ bird_cznic_repo_distribution }}"
|
||||
components: main
|
||||
signed_by: "{{ bird_cznic_key_url }}"
|
||||
state: present
|
||||
when: bird_enable and bird_cznic_repo_enabled
|
||||
|
||||
- name: Update package cache after configuring CZ.NIC repository
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
when: bird_enable and bird_cznic_repo_enabled
|
||||
|
||||
- name: Install WireGuard tools
|
||||
ansible.builtin.apt:
|
||||
name: "{{ wireguard_package_name }}"
|
||||
state: present
|
||||
when: wireguard_enable
|
||||
|
||||
- name: Install selected BIRD package
|
||||
ansible.builtin.apt:
|
||||
name: "{{ bird_package_name if bird_package_version | length == 0 else bird_package_name + '=' + bird_package_version }}"
|
||||
state: present
|
||||
when: bird_enable
|
||||
|
||||
- name: Configure router sysctl values
|
||||
ansible.builtin.template:
|
||||
src: router-sysctl.conf.j2
|
||||
dest: /etc/sysctl.d/99-router.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: reload_sysctl
|
||||
|
||||
- name: Ensure WireGuard configuration directory exists
|
||||
ansible.builtin.file:
|
||||
path: /etc/wireguard
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0700"
|
||||
when: wireguard_enable
|
||||
|
||||
- name: Validate WireGuard private keys are provided
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- >-
|
||||
(item.private_key is defined and item.private_key | length > 0)
|
||||
or
|
||||
(item.private_key_env is defined and lookup('ansible.builtin.env', item.private_key_env) | length > 0)
|
||||
fail_msg: "Private key for {{ item.name }} is missing. Set it via Ansible Vault or the matching environment lookup."
|
||||
loop: "{{ wireguard_interfaces }}"
|
||||
no_log: true
|
||||
when: wireguard_enable
|
||||
|
||||
- name: Configure WireGuard interfaces
|
||||
ansible.builtin.template:
|
||||
src: wg.conf.j2
|
||||
dest: "/etc/wireguard/{{ item.name }}.conf"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0600"
|
||||
loop: "{{ wireguard_interfaces }}"
|
||||
no_log: true
|
||||
notify: restart_wireguard_interfaces
|
||||
when: wireguard_enable
|
||||
|
||||
- name: Enable WireGuard interfaces
|
||||
ansible.builtin.systemd:
|
||||
name: "wg-quick@{{ item.name }}"
|
||||
enabled: true
|
||||
state: started
|
||||
loop: "{{ wireguard_interfaces }}"
|
||||
when: wireguard_enable
|
||||
|
||||
- name: Ensure BIRD log directory exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ bird_log_file | dirname }}"
|
||||
state: directory
|
||||
owner: "{{ bird_run_user }}"
|
||||
group: "{{ bird_run_group }}"
|
||||
mode: "0755"
|
||||
when: bird_enable
|
||||
|
||||
- name: Configure BIRD environment
|
||||
ansible.builtin.template:
|
||||
src: bird-envvars.j2
|
||||
dest: "{{ bird_envvars_path }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: restart_bird
|
||||
when: bird_enable
|
||||
|
||||
- name: Configure BIRD
|
||||
ansible.builtin.template:
|
||||
src: bird.conf.j2
|
||||
dest: "{{ bird_config_path }}"
|
||||
owner: root
|
||||
group: "{{ bird_run_group }}"
|
||||
mode: "0640"
|
||||
validate: "bird -p -c %s"
|
||||
notify: restart_bird
|
||||
when: bird_enable
|
||||
|
||||
- name: Enable BIRD service
|
||||
ansible.builtin.systemd:
|
||||
name: "{{ bird_service_name }}"
|
||||
enabled: true
|
||||
state: started
|
||||
when: bird_enable
|
||||
@@ -0,0 +1,3 @@
|
||||
BIRD_RUN_USER={{ bird_run_user }}
|
||||
BIRD_RUN_GROUP={{ bird_run_group }}
|
||||
#BIRD_ARGS=
|
||||
@@ -0,0 +1,109 @@
|
||||
router id {{ bird_router_id }};
|
||||
|
||||
log syslog all;
|
||||
log "{{ bird_log_file }}" { debug, trace, remote, warning, error, auth, fatal, bug };
|
||||
|
||||
protocol device { scan time 5; }
|
||||
protocol direct { ipv6; }
|
||||
|
||||
protocol kernel {
|
||||
ipv6 { export none; };
|
||||
scan time 15;
|
||||
}
|
||||
|
||||
protocol kernel {
|
||||
ipv4;
|
||||
scan time 15;
|
||||
}
|
||||
|
||||
protocol static announcev6 {
|
||||
ipv6;
|
||||
description "Static v6 Routes";
|
||||
{% for route in bird_static_routes_v6 %}
|
||||
{% if route.blackhole | default(false) %}
|
||||
route {{ route.prefix }} blackhole;
|
||||
{% else %}
|
||||
route {{ route.prefix }} via {{ route.via }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
protocol static announcev4 {
|
||||
ipv4;
|
||||
description "Static v4 Routes";
|
||||
{% for route in bird_static_routes_v4 %}
|
||||
{% if route.blackhole | default(false) %}
|
||||
route {{ route.prefix }} blackhole;
|
||||
{% else %}
|
||||
route {{ route.prefix }} via {{ route.via }};
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
}
|
||||
|
||||
protocol static {
|
||||
ipv6;
|
||||
}
|
||||
|
||||
protocol static {
|
||||
ipv4;
|
||||
}
|
||||
|
||||
filter rt_importv4 {
|
||||
accept;
|
||||
}
|
||||
|
||||
filter rt_importv6 {
|
||||
accept;
|
||||
}
|
||||
|
||||
filter rt_nothanks {
|
||||
{% for prefix in bird_reject_prefixes_v6 %}
|
||||
if (net ~ [ {{ prefix }} ]) then reject;
|
||||
{% endfor %}
|
||||
accept;
|
||||
}
|
||||
|
||||
filter sbehop {
|
||||
gw = {{ bird_sbehop_gateway }};
|
||||
accept;
|
||||
}
|
||||
|
||||
filter brt_importv6 {
|
||||
reject;
|
||||
}
|
||||
|
||||
filter rt_export {
|
||||
if (proto = "announcev4") then accept;
|
||||
if (proto = "announcev6") then accept;
|
||||
reject;
|
||||
}
|
||||
|
||||
{% for session in bird_bgp_sessions %}
|
||||
protocol bgp {{ session.name }} {
|
||||
local {{ session.local_address }} as {{ session.local_as }};
|
||||
neighbor {{ session.neighbor_address }} as {{ session.neighbor_as }};
|
||||
multihop {{ session.multihop | default(255) }};
|
||||
{{ session.address_family | default('ipv6') }} {
|
||||
{% if session.import_limit is defined %}
|
||||
import limit {{ session.import_limit }};
|
||||
{% endif %}
|
||||
{% if session.export_limit is defined %}
|
||||
export limit {{ session.export_limit }};
|
||||
{% endif %}
|
||||
{% if session.import_filter is defined %}
|
||||
import filter {{ session.import_filter }};
|
||||
{% else %}
|
||||
import none;
|
||||
{% endif %}
|
||||
{% if session.export_filter is defined %}
|
||||
export filter {{ session.export_filter }};
|
||||
{% else %}
|
||||
export none;
|
||||
{% endif %}
|
||||
{% if session.graceful_restart | default(false) %}
|
||||
graceful restart on;
|
||||
{% endif %}
|
||||
};
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,3 @@
|
||||
{% for key, value in router_sysctl | dictsort %}
|
||||
{{ key }} = {{ value }}
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,39 @@
|
||||
# {{ item.description | default(item.name) }}
|
||||
|
||||
[Interface]
|
||||
{% if item.private_key is defined %}
|
||||
PrivateKey = {{ item.private_key }}
|
||||
{% else %}
|
||||
PrivateKey = {{ lookup('ansible.builtin.env', item.private_key_env) }}
|
||||
{% endif %}
|
||||
Address = {{ item.address | join(',') }}
|
||||
{% if item.listen_port is defined %}
|
||||
ListenPort = {{ item.listen_port }}
|
||||
{% endif %}
|
||||
{% if item.mtu is defined %}
|
||||
MTU = {{ item.mtu }}
|
||||
{% endif %}
|
||||
{% for command in item.pre_up | default([]) %}
|
||||
PreUp = {{ command }}
|
||||
{% endfor %}
|
||||
{% for command in item.post_up | default([]) %}
|
||||
PostUp = {{ command }}
|
||||
{% endfor %}
|
||||
{% for command in item.pre_down | default([]) %}
|
||||
PreDown = {{ command }}
|
||||
{% endfor %}
|
||||
{% for command in item.post_down | default([]) %}
|
||||
PostDown = {{ command }}
|
||||
{% endfor %}
|
||||
{% for peer in item.peers | default([]) %}
|
||||
|
||||
[Peer]
|
||||
PublicKey = {{ peer.public_key }}
|
||||
AllowedIPs = {{ peer.allowed_ips | join(',') }}
|
||||
{% if peer.endpoint is defined %}
|
||||
Endpoint = {{ peer.endpoint }}
|
||||
{% endif %}
|
||||
{% if peer.persistent_keepalive is defined %}
|
||||
PersistentKeepalive = {{ peer.persistent_keepalive }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
debian_upgrade_source_major_version: "12"
|
||||
debian_upgrade_target_major_version: "13"
|
||||
debian_upgrade_target_release: trixie
|
||||
debian_upgrade_reboot_timeout: 1800
|
||||
|
||||
debian_upgrade_sources_list_path: /etc/apt/sources.list
|
||||
debian_upgrade_sources_backup_path: /etc/apt/sources.list.bookworm.bak
|
||||
debian_upgrade_deb822_sources_path: /etc/apt/sources.list.d/debian.sources
|
||||
debian_upgrade_deb822_sources_backup_path: /etc/apt/sources.list.d/debian.sources.bookworm.bak
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: Reboot after Debian dist upgrade
|
||||
ansible.builtin.reboot:
|
||||
msg: Rebooting after Debian dist upgrade
|
||||
reboot_timeout: "{{ debian_upgrade_reboot_timeout }}"
|
||||
listen: reboot_after_debian_dist_upgrade
|
||||
@@ -0,0 +1,118 @@
|
||||
---
|
||||
- name: Validate current host is Debian
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_facts.distribution == "Debian"
|
||||
fail_msg: "This role only supports Debian hosts."
|
||||
|
||||
- name: Validate expected source Debian major version
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_facts.distribution_major_version == debian_upgrade_source_major_version
|
||||
fail_msg: >-
|
||||
Expected Debian {{ debian_upgrade_source_major_version }} before upgrade,
|
||||
found Debian {{ ansible_facts.distribution_major_version }}.
|
||||
success_msg: "Host is Debian {{ debian_upgrade_source_major_version }} and ready for upgrade."
|
||||
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
|
||||
- name: Update package cache on current release
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
cache_valid_time: 3600
|
||||
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
|
||||
- name: Upgrade installed packages before release change
|
||||
ansible.builtin.apt:
|
||||
upgrade: dist
|
||||
autoremove: true
|
||||
autoclean: true
|
||||
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
|
||||
- name: Check for classic apt sources list
|
||||
ansible.builtin.stat:
|
||||
path: "{{ debian_upgrade_sources_list_path }}"
|
||||
register: debian_upgrade_sources_list_stat
|
||||
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
|
||||
- name: Check for deb822 apt sources
|
||||
ansible.builtin.stat:
|
||||
path: "{{ debian_upgrade_deb822_sources_path }}"
|
||||
register: debian_upgrade_deb822_sources_stat
|
||||
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
|
||||
- name: Back up current apt sources
|
||||
ansible.builtin.copy:
|
||||
src: "{{ debian_upgrade_sources_list_path }}"
|
||||
dest: "{{ debian_upgrade_sources_backup_path }}"
|
||||
remote_src: true
|
||||
mode: "0644"
|
||||
force: false
|
||||
when:
|
||||
- ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
- debian_upgrade_sources_list_stat.stat.exists
|
||||
|
||||
- name: Back up current deb822 apt sources
|
||||
ansible.builtin.copy:
|
||||
src: "{{ debian_upgrade_deb822_sources_path }}"
|
||||
dest: "{{ debian_upgrade_deb822_sources_backup_path }}"
|
||||
remote_src: true
|
||||
mode: "0644"
|
||||
force: false
|
||||
when:
|
||||
- ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
- debian_upgrade_deb822_sources_stat.stat.exists
|
||||
|
||||
- name: Configure Debian target release classic apt sources
|
||||
ansible.builtin.template:
|
||||
src: sources.list.j2
|
||||
dest: "{{ debian_upgrade_sources_list_path }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
when:
|
||||
- ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
- debian_upgrade_sources_list_stat.stat.exists or not debian_upgrade_deb822_sources_stat.stat.exists
|
||||
|
||||
- name: Configure Debian target release deb822 apt sources
|
||||
ansible.builtin.template:
|
||||
src: debian.sources.j2
|
||||
dest: "{{ debian_upgrade_deb822_sources_path }}"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
when:
|
||||
- ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
- debian_upgrade_deb822_sources_stat.stat.exists
|
||||
|
||||
- name: Update package cache for target release
|
||||
ansible.builtin.apt:
|
||||
update_cache: true
|
||||
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
|
||||
- name: Perform Debian dist upgrade
|
||||
ansible.builtin.apt:
|
||||
upgrade: dist
|
||||
autoremove: true
|
||||
autoclean: true
|
||||
dpkg_options: force-confdef,force-confold
|
||||
environment:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
APT_LISTCHANGES_FRONTEND: none
|
||||
notify: reboot_after_debian_dist_upgrade
|
||||
when: ansible_facts.distribution_major_version != debian_upgrade_target_major_version
|
||||
|
||||
- name: Flush reboot handler before verification
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- name: Gather facts after possible upgrade
|
||||
ansible.builtin.setup:
|
||||
|
||||
- name: Verify Debian target version
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- ansible_facts.distribution == "Debian"
|
||||
- ansible_facts.distribution_major_version == debian_upgrade_target_major_version
|
||||
fail_msg: >-
|
||||
Debian upgrade did not finish as expected. Found
|
||||
{{ ansible_facts.distribution }} {{ ansible_facts.distribution_major_version }}.
|
||||
success_msg: "Host is running Debian {{ debian_upgrade_target_major_version }}."
|
||||
@@ -0,0 +1,11 @@
|
||||
Types: deb
|
||||
URIs: http://deb.debian.org/debian
|
||||
Suites: {{ debian_upgrade_target_release }} {{ debian_upgrade_target_release }}-updates
|
||||
Components: main contrib non-free non-free-firmware
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||
|
||||
Types: deb
|
||||
URIs: http://security.debian.org/debian-security
|
||||
Suites: {{ debian_upgrade_target_release }}-security
|
||||
Components: main contrib non-free non-free-firmware
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||
@@ -0,0 +1,3 @@
|
||||
deb http://deb.debian.org/debian {{ debian_upgrade_target_release }} main contrib non-free non-free-firmware
|
||||
deb http://deb.debian.org/debian {{ debian_upgrade_target_release }}-updates main contrib non-free non-free-firmware
|
||||
deb http://security.debian.org/debian-security {{ debian_upgrade_target_release }}-security main contrib non-free non-free-firmware
|
||||
Reference in new issue
Block a user