forked from ansible_roles/dn42
initial commit
commit
2151b8e031
@ -0,0 +1,27 @@
|
||||
dn42_wg_private_key: "foobar2342"
|
||||
|
||||
dn42_local_subnet_v4: "172.17.0.1/28"
|
||||
dn42_local_subnet_v6: "fe80::1/56"
|
||||
dn42_local_v4: "172.17.0.1"
|
||||
dn42_local_v6: "fe80::1"
|
||||
dn42_local_as: "424242424243"
|
||||
|
||||
dn42_enable_roa: yes
|
||||
dn42_roa_v4_source: "https://dn42.burble.com/roa/dn42_roa_bird2_4.conf"
|
||||
dn42_roa_v4_location: "/etc/bird/roa_dn42.conf"
|
||||
dn42_roa_v6_source: "https://dn42.burble.com/roa/dn42_roa_bird2_6.conf"
|
||||
dn42_roa_v6_location: "/etc/bird/roa_dn42_v6.conf"
|
||||
|
||||
dn42_roa_cronjob: "curl -sfSLR -o{{ dn42_roa_v4_location }} -z{{ dn42_roa_v4_location }} {{ dn42_roa_v4_source }} && curl -sfSLR -o{{ dn42_roa_v6_location }} -z{{ dn42_roa_v6_location }} {{ dn42_roa_v6_source }} && birdc configure"
|
||||
|
||||
dn42_peers:
|
||||
- name: "neighbour"
|
||||
as: "4242424242"
|
||||
v6: "fe80::42:1"
|
||||
if:
|
||||
v6: fe80::42:42:1
|
||||
wg:
|
||||
port: 42424
|
||||
endpoint: "example.com:2342"
|
||||
pubkey: "peers_public_key"
|
||||
privkey: "your_private_key"
|
@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: reload bird
|
||||
service:
|
||||
name: "bird"
|
||||
state: reloaded
|
||||
|
||||
- name: restart networking
|
||||
service:
|
||||
name: "networking"
|
||||
state: restarted
|
@ -0,0 +1,10 @@
|
||||
---
|
||||
- name: Add birds packaging Key
|
||||
apt_key:
|
||||
url: "http://bird.network.cz/debian/apt.gpg"
|
||||
state: present
|
||||
|
||||
- name: Ensure bird repos are present
|
||||
apt_repository:
|
||||
repo: "deb https://bird.network.cz/debian/ {{ ansible_distribution_release }} main"
|
||||
update_cache: yes
|
@ -0,0 +1,29 @@
|
||||
---
|
||||
#- import_tasks: bird-repos.yml
|
||||
- name: Install bird2
|
||||
apt:
|
||||
name: "bird2"
|
||||
state: present
|
||||
|
||||
- name: Copy bird config-file
|
||||
template:
|
||||
dest: /etc/bird/bird.conf
|
||||
src: "bird2/bird.conf.j2"
|
||||
notify: reload bird
|
||||
|
||||
- name: Ensure birds peer foler exists
|
||||
file:
|
||||
path: "/etc/bird/peers"
|
||||
state: directory
|
||||
owner: "bird"
|
||||
group: "bird"
|
||||
|
||||
- name: Copy birds peer config-files
|
||||
template:
|
||||
dest: "/etc/bird/peers/{{ peer.name }}.conf"
|
||||
src: "bird2/peer.conf.j2"
|
||||
loop: "{{ dn42_peers }}"
|
||||
loop_control:
|
||||
loop_var: "peer"
|
||||
notify: reload bird
|
||||
|
@ -0,0 +1,30 @@
|
||||
---
|
||||
- import_tasks: sysctl.yml
|
||||
- import_tasks: bird2.yml
|
||||
- include_tasks: wireguard.yml
|
||||
loop: "{{ dn42_peers }}"
|
||||
loop_control:
|
||||
loop_var: "peer"
|
||||
|
||||
- name: Download ROA-Tables
|
||||
shell: "{{ dn42_roa_cronjob }}"
|
||||
args:
|
||||
creates: "{{ dn42_roa_v6_location }}"
|
||||
when: "dn42_enable_roa"
|
||||
|
||||
- name: Install ROA-Cron-Job
|
||||
cron:
|
||||
name: Download ROA-Tables
|
||||
minute: "*/15"
|
||||
job: "{{ dn42_roa_cronjob }}"
|
||||
when: "dn42_enable_roa"
|
||||
|
||||
- name: Configure Local IPs on loopback-interface
|
||||
interfaces_file:
|
||||
iface: "lo"
|
||||
option: "up"
|
||||
value:
|
||||
- "ip a add {{ dn42_local_v4 }}/32 dev lo"
|
||||
- "ip a add {{ dn42_local_v6 }}/128 dev lo"
|
||||
state: present
|
||||
notify: restart networking
|
@ -0,0 +1,25 @@
|
||||
---
|
||||
- name: Ensure forwarding of ipv4-packets is allowed
|
||||
sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: '1'
|
||||
state: present
|
||||
|
||||
- name: Ensure forwarding of ipv6-packets is allowed
|
||||
sysctl:
|
||||
name: net.ipv6.conf.all.forwarding
|
||||
value: '1'
|
||||
state: present
|
||||
|
||||
- name: Ensure reverse path filtering is disabled for v4
|
||||
sysctl:
|
||||
name: net.ipv4.conf.all.rp_filter
|
||||
value: '0'
|
||||
state: present
|
||||
|
||||
- name: Ensure default reverse path filtering is disabled for v4
|
||||
sysctl:
|
||||
name: net.ipv4.conf.all.rp_filter
|
||||
value: '0'
|
||||
state: present
|
||||
|
@ -0,0 +1,23 @@
|
||||
|
||||
- name: Install wg-quick@{{ peer.if.name | default("dn42_" + peer.name) }} config
|
||||
template:
|
||||
dest: "/etc/wireguard/{{ peer.if.name | default('dn42_' + peer.name) }}.conf"
|
||||
src: "wg-quick.j2"
|
||||
when: "peer.wg is defined"
|
||||
register: "configuration"
|
||||
|
||||
- name: Enable wg-quick@{{ peer.if.name | default("dn42_" + peer.name) }} service
|
||||
service:
|
||||
name: "wg-quick@{{ peer.if.name | default('dn42_' + peer.name) }}"
|
||||
enabled: yes
|
||||
|
||||
- name: Restart wg-quick@{{ peer.if.name | default('dn42_' + peer.name) }}
|
||||
service:
|
||||
name: "wg-quick@{{ peer.if.name | default('dn42_' + peer.name) }}"
|
||||
state: restarted
|
||||
when: "configuration is changed"
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,75 @@
|
||||
# Device status
|
||||
protocol device {
|
||||
scan time 10; # recheck every 10 seconds
|
||||
}
|
||||
|
||||
protocol static {
|
||||
# Static routes to announce your own range(s) in dn42
|
||||
route {{ dn42_local_subnet_v4 }} reject;
|
||||
import all;
|
||||
export none;
|
||||
};
|
||||
|
||||
# local configuration
|
||||
######################
|
||||
|
||||
# keeping router specific in a seperate file,
|
||||
# so this configuration can be reused on multiple routers in your network
|
||||
include "/etc/bird/local4.conf";
|
||||
|
||||
# filter helpers
|
||||
#################
|
||||
|
||||
##include "/etc/bird/filter4.conf";
|
||||
|
||||
# Kernel routing tables
|
||||
########################
|
||||
|
||||
/*
|
||||
krt_prefsrc defines the source address for outgoing connections.
|
||||
On Linux, this causes the "src" attribute of a route to be set.
|
||||
|
||||
Without this option outgoing connections would use the peering IP which
|
||||
would cause packet loss if some peering disconnects but the interface
|
||||
is still available. (The route would still exist and thus route through
|
||||
the TUN/TAP interface but the VPN daemon would simply drop the packet.)
|
||||
*/
|
||||
protocol kernel {
|
||||
scan time 20;
|
||||
import none;
|
||||
export filter {
|
||||
if source = RTS_STATIC then reject;
|
||||
krt_prefsrc = OWNIP;
|
||||
accept;
|
||||
};
|
||||
};
|
||||
# DN42
|
||||
#######
|
||||
|
||||
template bgp dnpeers {
|
||||
local as OWNAS;
|
||||
# metric is the number of hops between us and the peer
|
||||
path metric 1;
|
||||
# this lines allows debugging filter rules
|
||||
# filtered routes can be looked up in birdc using the "show route filtered" command
|
||||
import keep filtered;
|
||||
import filter {
|
||||
# accept every subnet, except our own advertised subnet
|
||||
# filtering is important, because some guys try to advertise routes like 0.0.0.0
|
||||
if is_valid_network() && !is_self_net() then {
|
||||
accept;
|
||||
}
|
||||
reject;
|
||||
};
|
||||
export filter {
|
||||
# here we export the whole net
|
||||
if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then {
|
||||
accept;
|
||||
}
|
||||
reject;
|
||||
};
|
||||
import limit 1000 action block;
|
||||
#source address OWNIP;
|
||||
};
|
||||
|
||||
include "/etc/bird/peers4/*";
|
@ -0,0 +1,66 @@
|
||||
protocol device {
|
||||
scan time 10;
|
||||
}
|
||||
|
||||
# local configuration
|
||||
######################
|
||||
|
||||
include "/etc/bird/local6.conf";
|
||||
|
||||
# filter helpers
|
||||
#################
|
||||
|
||||
##include "/etc/bird/filter6.conf";
|
||||
|
||||
# Kernel routing tables
|
||||
########################
|
||||
|
||||
|
||||
/*
|
||||
krt_prefsrc defines the source address for outgoing connections.
|
||||
On Linux, this causes the "src" attribute of a route to be set.
|
||||
|
||||
Without this option outgoing connections would use the peering IP which
|
||||
would cause packet loss if some peering disconnects but the interface
|
||||
is still available. (The route would still exist and thus route through
|
||||
the TUN/TAP interface but the VPN daemon would simply drop the packet.)
|
||||
*/
|
||||
protocol kernel {
|
||||
scan time 20;
|
||||
import none;
|
||||
export filter {
|
||||
if source = RTS_STATIC then reject;
|
||||
krt_prefsrc = OWNIP;
|
||||
accept;
|
||||
};
|
||||
}
|
||||
|
||||
# static routes
|
||||
################
|
||||
|
||||
protocol static {
|
||||
route {{ dn42_local_subnet_v6 }} reject;
|
||||
import all;
|
||||
export none;
|
||||
}
|
||||
|
||||
template bgp dnpeers {
|
||||
local as OWNAS;
|
||||
path metric 1;
|
||||
import keep filtered;
|
||||
import filter {
|
||||
if is_valid_network() && !is_self_net() then {
|
||||
accept;
|
||||
}
|
||||
reject;
|
||||
};
|
||||
export filter {
|
||||
if is_valid_network() && source ~ [RTS_STATIC, RTS_BGP] then {
|
||||
accept;
|
||||
}
|
||||
reject;
|
||||
};
|
||||
import limit 1000 action block;
|
||||
}
|
||||
|
||||
include "/etc/bird/peers6/*";
|
@ -0,0 +1,23 @@
|
||||
# should be a unique identifier, <GATEWAY_IP> is what most people use.
|
||||
router id {{ dn42_local_v4 }};
|
||||
|
||||
define OWNAS = {{ dn42_local_as }};
|
||||
define OWNIP = {{ dn42_local_v4 }};
|
||||
|
||||
function is_self_net() {
|
||||
return net ~ [{{ dn42_local_subnet_v4 }}+];
|
||||
}
|
||||
|
||||
function is_valid_network() {
|
||||
return net ~ [
|
||||
172.20.0.0/14{21,29}, # dn42
|
||||
172.20.0.0/24{28,32}, # dn42 Anycast
|
||||
172.21.0.0/24{28,32}, # dn42 Anycast
|
||||
172.22.0.0/24{28,32}, # dn42 Anycast
|
||||
172.23.0.0/24{28,32}, # dn42 Anycast
|
||||
172.31.0.0/16+, # ChaosVPN
|
||||
10.100.0.0/14+, # ChaosVPN
|
||||
10.127.0.0/16{16,32}, # neonetwork
|
||||
10.0.0.0/8{15,24} # Freifunk.net
|
||||
];
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
# should be a unique identifier, use same id as for ipv4
|
||||
router id {{ dn42_local_v6 }};
|
||||
|
||||
define OWNAS = {{ dn42_local_as }};
|
||||
define OWNIP = {{ dn42_local_v6 }};
|
||||
|
||||
function is_self_net() {
|
||||
return net ~ [{{ dn42_local_subnet_v6 }}+];
|
||||
}
|
||||
|
||||
function is_valid_network() {
|
||||
return net ~ [
|
||||
fd00::/8{44,64} # ULA address space as per RFC 4193
|
||||
];
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
protocol bgp {{ peer.name }} from dnpeers {
|
||||
neighbor {{ peer.v4 }} as {{ peer.as }};
|
||||
};
|
@ -0,0 +1,8 @@
|
||||
protocol bgp {{ peer.name }} from dnpeers {
|
||||
{% if not peer.linklocal|default(False) %}
|
||||
neighbor {{ peer.v6 }} as {{ peer.as }};
|
||||
{% else %}
|
||||
# if you use link-local ipv6 addresses for peering using the following
|
||||
neighbor {{ peer.v6 }} % '{{ peer.if }}' as {{ peer.as }};
|
||||
{% endif %}
|
||||
};
|
@ -0,0 +1,155 @@
|
||||
################################################
|
||||
# Variable header #
|
||||
################################################
|
||||
|
||||
define OWNAS = {{ dn42_local_as }};
|
||||
define OWNIP = {{ dn42_local_v4 }};
|
||||
define OWNIPv6 = {{ dn42_local_v6 }};
|
||||
define OWNNET = {{ dn42_local_subnet_v4 }};
|
||||
define OWNNETv6 = {{ dn42_local_subnet_v6 }};
|
||||
define OWNNETSET = [{{ dn42_local_subnet_v4 }}+];
|
||||
define OWNNETSETv6 = [{{ dn42_local_subnet_v6 }}+];
|
||||
|
||||
################################################
|
||||
# Header end #
|
||||
################################################
|
||||
|
||||
router id OWNIP;
|
||||
|
||||
protocol device {
|
||||
scan time 10;
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility functions
|
||||
*/
|
||||
|
||||
function is_self_net() {
|
||||
return net ~ OWNNETSET;
|
||||
}
|
||||
|
||||
function is_self_net_v6() {
|
||||
return net ~ OWNNETSETv6;
|
||||
}
|
||||
|
||||
function is_valid_network() {
|
||||
return net ~ [
|
||||
172.20.0.0/14{21,29}, # dn42
|
||||
172.20.0.0/24{28,32}, # dn42 Anycast
|
||||
172.21.0.0/24{28,32}, # dn42 Anycast
|
||||
172.22.0.0/24{28,32}, # dn42 Anycast
|
||||
172.23.0.0/24{28,32}, # dn42 Anycast
|
||||
172.31.0.0/16+, # ChaosVPN
|
||||
10.100.0.0/14+, # ChaosVPN
|
||||
10.127.0.0/16{16,32}, # neonetwork
|
||||
10.0.0.0/8{15,24} # Freifunk.net
|
||||
];
|
||||
}
|
||||
|
||||
{% if dn42_enable_roa %}
|
||||
roa4 table dn42_roa;
|
||||
roa6 table dn42_roa_v6;
|
||||
|
||||
protocol static {
|
||||
roa4 { table dn42_roa; };
|
||||
include "{{ dn42_roa_v4_location }}";
|
||||
};
|
||||
|
||||
protocol static {
|
||||
roa6 { table dn42_roa_v6; };
|
||||
include "{{ dn42_roa_v6_location }}";
|
||||
};
|
||||
{% endif %}
|
||||
|
||||
function is_valid_network_v6() {
|
||||
return net ~ [
|
||||
fd00::/8{44,64} # ULA address space as per RFC 4193
|
||||
];
|
||||
}
|
||||
|
||||
protocol kernel {
|
||||
scan time 20;
|
||||
|
||||
ipv6 {
|
||||
import none;
|
||||
export filter {
|
||||
if source = RTS_STATIC then reject;
|
||||
krt_prefsrc = OWNIPv6;
|
||||
accept;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
protocol kernel {
|
||||
scan time 20;
|
||||
|
||||
ipv4 {
|
||||
import none;
|
||||
export filter {
|
||||
if source = RTS_STATIC then reject;
|
||||
krt_prefsrc = OWNIP;
|
||||
accept;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
protocol static {
|
||||
route OWNNET reject;
|
||||
|
||||
ipv4 {
|
||||
import all;
|
||||
export none;
|
||||
};
|
||||
}
|
||||
|
||||
protocol static {
|
||||
route OWNNETv6 reject;
|
||||
|
||||
ipv6 {
|
||||
import all;
|
||||
export none;
|
||||
};
|
||||
}
|
||||
|
||||
template bgp dnpeers {
|
||||
local as OWNAS;
|
||||
path metric 1;
|
||||
|
||||
ipv4 {
|
||||
import filter {
|
||||
if is_valid_network() && !is_self_net() then {
|
||||
{% if dn42_enable_roa %}
|
||||
if (roa_check(dn42_roa, net, bgp_path.last) != ROA_VALID) then {
|
||||
print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
|
||||
reject;
|
||||
} else accept;
|
||||
{% else %}
|
||||
accept;
|
||||
{% endif %}
|
||||
} else reject;
|
||||
};
|
||||
|
||||
export filter { if is_valid_network() then accept; else reject; };
|
||||
import limit 1000 action block;
|
||||
};
|
||||
|
||||
ipv6 {
|
||||
import filter {
|
||||
if is_valid_network_v6() && !is_self_net_v6() then {
|
||||
{% if dn42_enable_roa %}
|
||||
if (roa_check(dn42_roa_v6, net, bgp_path.last) != ROA_VALID) then {
|
||||
print "[dn42] ROA check failed for ", net, " ASN ", bgp_path.last;
|
||||
reject;
|
||||
} else accept;
|
||||
{% else %}
|
||||
accept;
|
||||
{% endif %}
|
||||
} else reject;
|
||||
};
|
||||
export filter { if is_valid_network_v6() then accept; else reject; };
|
||||
import limit 1000 action block;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
include "/etc/bird/peers/*";
|
@ -0,0 +1,12 @@
|
||||
{% if peer.v4 is defined%}
|
||||
protocol bgp {{ peer.name }} from dnpeers {
|
||||
neighbor {{ peer.v4 }} as {{ peer.as }};
|
||||
};
|
||||
{% endif %}
|
||||
|
||||
{% if peer.v6 is defined%}
|
||||
protocol bgp {{ peer.name }}_v6 from dnpeers {
|
||||
# if you use link-local ipv6 addresses for peering using the following
|
||||
neighbor {{ peer.v6 }}%{{ peer.if.name | default('dn42_' + peer.name) }} as {{ peer.as }};
|
||||
};
|
||||
{% endif %}
|
@ -0,0 +1,15 @@
|
||||
[Interface]
|
||||
PrivateKey = {{ peer.wg.privkey | default(dn42_wg_private_key) }}
|
||||
Address = {{ peer.if.v4 | default(dn42_local_v4) }}/32, {{ peer.if.v6 | default(dn42_local_v6) }}/128
|
||||
PostUp = {% if peer.v4 is defined %}/sbin/ip addr del dev {{ peer.if.name | default("dn42_" + peer.name) }} {{ peer.if.v4 | default(dn42_local_v4) }}/32 && /sbin/ip addr add dev {{ peer.if.name | default("dn42_" + peer.name) }} {{ peer.if.v4 | default(dn42_local_v4) }}/32 peer {{ peer.v4 }}/32 &&/ {% endif %}{% if peer.v6 is defined %}/sbin/ip addr del dev {{ peer.if.name | default("dn42_" + peer.name) }} {{ peer.if.v6 | default(dn42_local_v6) }}/128 && /sbin/ip addr add dev {{ peer.if.name | default("dn42_" + peer.name) }} {{ peer.if.v6 | default(dn42_local_v6) }}/128 peer {{ peer.v6 }}/128{% endif %}
|
||||
|
||||
Table = off
|
||||
ListenPort = {{ peer.wg.port }}
|
||||
|
||||
[Peer]
|
||||
Endpoint = {{ peer.wg.endpoint }}
|
||||
PublicKey = {{ peer.wg.pubkey }}
|
||||
AllowedIPs = 172.16.0.0/12
|
||||
AllowedIPs = 10.0.0.0/8
|
||||
AllowedIPs = fd00::/8
|
||||
AllowedIPs = fe80::/10
|
Loading…
Reference in New Issue