initial commit

ipv4_link_local
n0emis 4 years ago
commit 2151b8e031
Signed by untrusted user: n0emis
GPG Key ID: 00FAF748B777CF10

@ -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…
Cancel
Save