Add IPv6 support to bridges

This commit is contained in:
Wojciech Kozlowski 2023-07-27 23:07:45 +02:00
parent f944dae2fe
commit 18ee9c7a24
8 changed files with 82 additions and 47 deletions

View File

@ -1,2 +1,3 @@
---
vpn_bridge_local_only_daddr: []
vpn_bridge_local_only_inet_daddr: []
vpn_bridge_local_only_inet6_daddr: []

View File

@ -0,0 +1,4 @@
#!/usr/bin/env -S nft -f
flush table ip6 br0_ipv6
delete table ip6 br0_ipv6

View File

@ -6,29 +6,36 @@ argument_specs:
interface:
type: "str"
required: true
local_network:
local_inet_network:
type: "str"
required: false
local_inet6_network:
type: "str"
required: false
vpn_bridge_dnat:
type: "list"
elements: "dict"
required: true
vpn_bridge_address:
vpn_bridge_inet_address:
type: "str"
required: true
vpn_bridge_broadcast:
vpn_bridge_inet6_prefixlen:
type: "str"
required: true
vpn_bridge_prefixlen:
vpn_bridge_inet_subnet:
type: "str"
required: true
vpn_bridge_subnet:
vpn_bridge_inet6_subnet:
type: "str"
required: true
vpn_bridge_routing_table:
type: "int"
required: false
vpn_bridge_local_only_daddr:
vpn_bridge_local_only_inet_daddr:
type: "list"
elements: "str"
required: true
vpn_bridge_local_only_inet6_daddr:
type: "list"
elements: "str"
required: true

View File

@ -1,17 +1,14 @@
---
- name: "post-up nftables inet script"
- name: "post-up nftables scripts"
ansible.builtin.template:
src: "./post-up-br0-inet.nft"
dest: "/usr/local/sbin/post-up-br0-inet.nft"
src: "./{{ item }}"
dest: "/usr/local/sbin/{{ item }}"
mode: 0755
register: vpn_bridge_post_up_br0_inet_nft
- name: "post-up nftables ipv4 script"
ansible.builtin.template:
src: "./post-up-br0-ipv4.nft"
dest: "/usr/local/sbin/post-up-br0-ipv4.nft"
mode: 0755
register: vpn_bridge_post_up_br0_ipv4_nft
loop:
- "post-up-br0-inet.nft"
- "post-up-br0-ipv4.nft"
- "post-up-br0-ipv6.nft"
register: vpn_bridge_post_up_nft
- name: "configure interface"
ansible.builtin.template:
@ -35,18 +32,15 @@
ifup br0
fi
when:
vpn_bridge_post_up_br0_inet_nft.changed or
vpn_bridge_post_up_br0_ipv4_nft.changed or
vpn_bridge_post_up_nft.changed or
vpn_bridge_intf.changed
- name: "pre-down nftables inet script"
- name: "pre-down nftables scripts"
ansible.builtin.copy:
src: "./pre-down-br0-inet.nft"
dest: "/usr/local/sbin/pre-down-br0-inet.nft"
mode: 0755
- name: "pre-down nftables ipv4 script"
ansible.builtin.copy:
src: "./pre-down-br0-ipv4.nft"
dest: "/usr/local/sbin/pre-down-br0-ipv4.nft"
src: "./{{ item }}"
dest: "/usr/local/sbin/{{ item }}"
mode: 0755
loop:
- "pre-down-br0-inet.nft"
- "pre-down-br0-ipv4.nft"
- "pre-down-br0-ipv6.nft"

View File

@ -4,15 +4,21 @@ iface br0 inet static
post-up /usr/local/sbin/post-up-$IFACE-inet.nft
post-up /usr/local/sbin/post-up-$IFACE-ipv4.nft
post-up /usr/local/sbin/post-up-$IFACE-ipv6.nft
{% if vpn_bridge_routing_table is defined %}
post-up ip rule add dev $IFACE table {{ vpn_bridge_routing_table }}
post-up ip rule add dev $IFACE to {{ local_network }} table main priority 1
post-up ip rule add dev $IFACE to {{ local_inet_network }} table main priority 1
post-up ip -6 rule add dev $IFACE table {{ vpn_bridge_routing_table }}
post-up ip -6 rule add dev $IFACE to {{ local_inet6_network }} table main priority 1
{% endif %}
{% if vpn_bridge_routing_table is defined %}
pre-down ip rule del dev $IFACE to {{ local_network }} table main priority 1
pre-down ip -6 rule del dev $IFACE to {{ local_inet6_network }} table main priority 1
pre-down ip -6 rule del dev $IFACE table {{ vpn_bridge_routing_table }}
pre-down ip rule del dev $IFACE to {{ local_inet_network }} table main priority 1
pre-down ip rule del dev $IFACE table {{ vpn_bridge_routing_table }}
{% endif %}
pre-down /usr/local/sbin/pre-down-$IFACE-ipv6.nft
pre-down /usr/local/sbin/pre-down-$IFACE-ipv4.nft
pre-down /usr/local/sbin/pre-down-$IFACE-inet.nft
@ -21,6 +27,8 @@ iface br0 inet static
bridge_fd 0
bridge_ports none
address {{ vpn_bridge_address }}
broadcast {{ vpn_bridge_broadcast }}
netmask {{ vpn_bridge_prefixlen }}
address {{ vpn_bridge_inet_address }}/{{ vpn_bridge_inet_prefixlen }}
iface br0 inet6 static
address {{ vpn_bridge_inet6_address }}/{{ vpn_bridge_inet6_prefixlen }}
dad-attempts 0

View File

@ -1,5 +1,8 @@
#!/usr/bin/env -S nft -f
table inet br0_inet {
chain postrouting {
type nat hook postrouting priority 100;
iif br0 oif { {{ [ansible_default_ipv4.interface, ansible_default_ipv6.interface] | unique | join(", ") }} } masquerade;
}
}

View File

@ -4,27 +4,21 @@ table ip br0_ipv4 {
chain prerouting {
type nat hook prerouting priority -100;
{% for forward in vpn_bridge_dnat %}
iif {{ ansible_default_ipv4.interface }} tcp dport { {{ forward.ports | join(", ") }} } dnat to {{ forward.address }};
iif {{ ansible_default_ipv4.interface }} tcp dport { {{ forward.ports | join(", ") }} } dnat to {{ forward.inet_address }};
{% endfor %}
}
chain forward {
type filter hook forward priority 0;
{% if local_inet_network is defined %}
{% if local_network is defined %}
ct state established,related accept;
iif br0 ip daddr {{ local_network }} drop;
iif br0 ip daddr {{ local_inet_network }} drop;
{% endif %}
{% if vpn_bridge_local_only_daddr %}
{% if vpn_bridge_local_only_inet_daddr %}
# Drop all external traffic for these addresses.
ip saddr != {{ vpn_bridge_subnet }} ip daddr { {{ vpn_bridge_local_only_daddr | join(", ") }} } drop;
ip saddr != {{ vpn_bridge_inet_subnet }} ip daddr { {{ vpn_bridge_local_only_inet_daddr | join(", ") }} } drop;
{% endif %}
}
chain postrouting {
type nat hook postrouting priority 100;
iif br0 oif {{ ansible_default_ipv4.interface }} masquerade;
}
}

View File

@ -0,0 +1,24 @@
#!/usr/bin/env -S nft -f
table ip6 br0_ipv6 {
chain prerouting {
type nat hook prerouting priority -100;
{% for forward in vpn_bridge_dnat %}
iif {{ ansible_default_ipv6.interface }} tcp dport { {{ forward.ports | join(", ") }} } dnat to {{ forward.inet6_address }};
{% endfor %}
}
chain forward {
type filter hook forward priority 0;
{% if local_inet6_network is defined %}
ct state established,related accept;
iif br0 ip6 daddr {{ local_inet6_network }} drop;
{% endif %}
{% if vpn_bridge_local_only_inet6_daddr %}
# Drop all external traffic for these addresses.
ip6 saddr != {{ vpn_bridge_inet6_subnet }} ip6 daddr { {{ vpn_bridge_local_only_inet6_daddr | join(", ") }} } drop;
{% endif %}
}
}