Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firewall refresh #118

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions files/etc/iptables.d/001-CHAINS
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@
ip46tables -N input
ip46tables -N bat-input
ip46tables -N mesh-input
ip46tables -N uplink-input
ip46tables -N icvpn-input
ip46tables -N peering-input
ip46tables -N wan-input

# Default Forward Chains

ip46tables -N forward
ip46tables -N bat-forward
ip46tables -N mesh-forward
ip46tables -N wan-forward
ip46tables -N fwd-in
ip46tables -N mesh-fwd-in
ip46tables -N mesh-fwd-out
ip46tables -N uplink-fwd-in
ip46tables -N uplink-fwd-out
ip46tables -N icvpn-fwd-in
ip46tables -N icvpn-fwd-out
ip46tables -N peering-fwd-in
ip46tables -N peering-fwd-out

# Helper Chains

Expand Down
4 changes: 2 additions & 2 deletions files/etc/iptables.d/050-FORWARD-PreProcessing
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ ip4tables -A FORWARD -p icmp -j ACCEPT
ip6tables -A FORWARD -p icmpv6 -j ACCEPT

# udp specific connection tracking
ip46tables -A FORWARD -p udp -m conntrack --ctstate NEW -j forward
ip46tables -A FORWARD -p udp -m conntrack --ctstate NEW -j fwd-in
ip4tables -A FORWARD -p udp -j REJECT --reject-with icmp-port-unreachable
ip6tables -A FORWARD -p udp -j REJECT --reject-with icmp6-port-unreachable

# tcp specific connection tracking
ip46tables -A FORWARD -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j forward
ip46tables -A FORWARD -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j fwd-in
ip46tables -A FORWARD -p tcp -j REJECT --reject-with tcp-reset
13 changes: 9 additions & 4 deletions files/etc/iptables.d/900-FORWARD-drop
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Drop all packages which are not ACCEPTed to this point
ip46tables -A FORWARD -j DROP
ip46tables -A forward -j DROP
ip46tables -A bat-forward -j DROP
ip46tables -A mesh-forward -j DROP
ip46tables -A wan-forward -j DROP
ip46tables -A fwd-in -j DROP
ip46tables -A mesh-fwd-in -j DROP
ip46tables -A mesh-fwd-out -j DROP
ip46tables -A uplink-fwd-in -j DROP
ip46tables -A uplink-fwd-out -j DROP
ip46tables -A icvpn-fwd-in -j DROP
ip46tables -A icvpn-fwd-out -j DROP
ip46tables -A peering-fwd-in -j DROP
ip46tables -A peering-fwd-out -j DROP
4 changes: 0 additions & 4 deletions manifests/batman-adv.pp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,4 @@
scriptname => "batman-visible-gateway-count",
sudo => true;
}

ffnord::firewall::device { "bat-${mesh_code}":
chain => "bat"
}
}
10 changes: 5 additions & 5 deletions manifests/bridge.pp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@
];
} ->
ffnord::firewall::device { "br-${mesh_code}":
chain => "mesh"
} ->
ffnord::firewall::forward { "br-${mesh_code}":
chain => "mesh"
}
zone => "mesh",
zone_forward_ipv4 => ['mesh','icvpn'],
zone_forward_ipv6 => ['mesh','icvpn'],
forward_conntrack => false
}
}
145 changes: 104 additions & 41 deletions manifests/firewall.pp
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,27 @@
*
* We simple define the firewall rules by putting them into ordered files.
* This way we can place new rules at any position into the chains.
* The predefined ruleset first resets the Xtables rulesets and
* handles connection tracking, jumping the packages into seperated
* chains or directly drop them.
* Packages accepted for further processing are then be sorted into
* zone specific chaines.
*
* We have two zones in this setup: mesh and wan
* Each with a forward and a input chain: mesh-forward, mesh-input, ...
* The general processing idea is to define a zone for each device handled
* and define which zones are allowed to forward traffic trough this device.
* According to the device definition forwarding packages may be handled
* by connection tracking. Traffic from a zone is then processed
* through a zone forward chain and pre-filtered before passed to the
* destination device chain.
*
* We have four zones in this setup: mesh, uplink, icvpn, peering.
* Each with a forward input, forward output and a input chain, e.g:
* mesh-fwd-in, mesh-fwd-out and mesh-input.
*
* The order of execution is matched to meaning by the following list:
*
* 000 RESET all the rules
* 050 Preprocessing
* 025 Pre conntrack forward handling
* 050 Connection Tracking
* 100 Zone selection
* 500+ Service/Port acceptance
* 800 Forwarding acceptance
* 700 Zone-Device forwarding handling
* 850 Forwarding acceptance
* 900 Drop the rest
* 900+ Mangle/Postrouting handling
*
Expand Down Expand Up @@ -140,7 +145,9 @@
}

ffnord::firewall::device { $wan_devices:
chain => 'wan';
zone => 'wan',
inter_zone_forward => false,
forward_conntrack => true;
}
}

Expand All @@ -165,57 +172,113 @@
<% if @ports.length > 0 -%>
<% @ports.each do |port| -%>
<% if @rate_limit -%>
rate_limit46 \"<%=@name%>\" <%=@rate_limit_seconds%> <%=@rate_limit_hitcount%> -A <%=chain%>-input -p <%=proto%> -m <%=proto%> --dport <%=port%><% if @source -%> -s <%=source%>
rate_limit46 \"<%=@name%>\" <%=@rate_limit_seconds%> <%=@rate_limit_hitcount%> -A <%=chain%>-input -p <%=proto%> -m <%=proto%> --dport <%=port%><% if @source -%> -s <%=@source%>
<% end %>
<% end -%>
ip46tables -A <%=chain%>-input -p <%=proto%> -m <%=proto%> --dport <%=port%><% if @source -%> -s <%=source%><% end -%> -j ACCEPT -m comment --comment '<%=@name%>'
ip46tables -A <%=chain%>-input -p <%=proto%> -m <%=proto%> --dport <%=port%><% if @source -%> -s <%=@source%><% end -%> -j ACCEPT -m comment --comment '<%=@name%>'
<% end -%>
<% else %>
ip46tables -A <%=chain%>-input -p <%=proto%><% if @source -%> -s <%=source%><% end -%> -j ACCEPT -m comment --comment '<%=@name%>'
ip46tables -A <%=chain%>-input -p <%=proto%><% if @source -%> -s <%=@source%><% end -%> -j ACCEPT -m comment --comment '<%=@name%>'
<% end -%>
<% end -%>
<% end -%>
");
}
}

# Process packages from devices into the chains
# Process packages from devices
define ffnord::firewall::device (
$chain = "mesh" # Possible values are "mesh","wan"
$zone = "mesh", # Possible values are "mesh","wan","uplink","icvpn"
$zone_forward_ipv4 = [], # which zones are allowed to forward ipv4 traffic through this device
$zone_forward_ipv6 = [], # which zones are allowed to forward ipv6 traffic through this device
$inter_zone_forward = true,
$forward_conntrack, # shall forwarded traffic be handled by connection tracking
) {

include ffnord::firewall
include ffnord::firewall

file { "/etc/iptables.d/100-device-${name}":
ensure => file,
owner => "root",
group => "root",
mode => "0644",
content => inline_template("# Process packages from device <%=@name%>
ip46tables -A input -i <%=@name%> -j <%=@chain%>-input
ip46tables -A forward -i <%=@name%> -j <%=@chain%>-forward
# 002 - Define device specific chain, for forwarded output.
# ZONE-fwd-INTERFACENAME-out
if size($zone_forward_ipv4) + size($zone_forward_ipv6) > 0 or $inter_zone_forward {
file { "/etc/iptables.d/002-device-chains-${name}":
ensure => file,
owner => "root",
group => "root",
mode => "0644",
content => inline_template("# Allow zone forwarding for device <%=@name%>
ip46tables -N <%=@zone%>-fwd-<%=@name%>-out
"),
require => [File['/etc/iptables.d/']];
}
}
require => [File['/etc/iptables.d/']];
}
}

# Allow device for mesh forwarding
define ffnord::firewall::forward (
$chain = "mesh" # Possible values are "mesh","wan"
) {
# 025 - When traffic should not be handled by connection tracking we have to jump
# it directly to the fwd-in chain, for further processing.
if ! $forward_conntrack {
file { "/etc/iptables.d/025-forward-device-${name}":
ensure => "file",
owner => "root",
group => "root",
mode => "0644",
content => inline_template("# Jump packages to the forward-in chain before conntrack
ip46tables -A FORWARD -i <%=@name%> -j fwd-in
")
}
}

# 100 - Jump packages to zone chains.
file { "/etc/iptables.d/100-device-${name}":
ensure => file,
owner => "root",
group => "root",
mode => "0644",
# instead of the chain-fwd-out we shall jump to chain-fwd-in and check for e.g. source
content => inline_template("# Process packages from device <%=@name%>
ip46tables -A input -i <%=@name%> -j <%=@zone%>-input
<% if @inter_zone_forward -%>
# Inter-Zone-Traffic is allowed for this device.
ip46tables -A fwd-in -i <%=@name%> -j <%=@zone%>-fwd-<%=@name%>-out
<% end -%>
"),
require => [File['/etc/iptables.d/']];
}

include ffnord::firewall
file { "/etc/iptables.d/800-${chain}-forward-ACCEPT-${name}":
ensure => absent;
}

file { "/etc/iptables.d/800-${chain}-forward-ACCEPT-${name}":
ensure => file,
owner => "root",
group => "root",
mode => "0644",
content => inline_template("# Process packages from device <%=@name%>
ip46tables -A mesh-forward -o <%=@name%> -j ACCEPT
# 700 - Accepting packages from other zones, for the device specific output chain.
if size($zone_forward_ipv4) + size($zone_forward_ipv6) > 0 or $inter_zone_forward {
file { "/etc/iptables.d/700-forward-transfer-${name}":
ensure => file,
owner => "root",
group => "root",
mode => "0644",
content => inline_template("# Process packages to device <%=@name%>
<% @zone_forward_ipv4.each do |zone_ipv4| -%>
ip4tables -A <%=zone_ipv4%>-fwd-in -o <%=@name%> -j <%=@zone%>-fwd-<%=@name%>-out
<% end -%>
<% @zone_forward_ipv6.each do |zone_ipv6| -%>
ip4tables -A <%=zone_ipv6%>-fwd-in -o <%=@name%> -j <%=@zone%>-fwd-<%=@name%>-out
<% end -%>
"),
require => [File['/etc/iptables.d/']];
}
require => [File['/etc/iptables.d/']];
}
}

# 850 - Accept all remaining packages on the device specific output chain.
if size($zone_forward_ipv4) + size($zone_forward_ipv6) > 0 or $inter_zone_forward {
file { "/etc/iptables.d/850-${chain}-forward-ACCEPT-${name}":
ensure => file,
owner => "root",
group => "root",
mode => "0644",
content => inline_template("# Finally accept all remaining forward packages for <%=@name%>
ip46tables -A <%=@zone%>-fwd-<%=@name%>-out -j ACCEPT
"),
require => [File['/etc/iptables.d/']];
}
}
}

define ffnord::firewall::set_value(
Expand Down
9 changes: 4 additions & 5 deletions manifests/tinc.pp
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,10 @@
}

ffnord::firewall::device { "icvpn":
chain => 'mesh'
}

ffnord::firewall::forward { "icvpn":
chain => 'mesh'
zone => 'icvpn',
zone_forward_ipv4 => ['mesh'],
zone_forward_ipv6 => ['mesh'],
forward_conntrack => False,
}

ffnord::firewall::service { "tincd":
Expand Down
7 changes: 5 additions & 2 deletions manifests/uplink.pp
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,11 @@
]
}

ffnord::firewall::forward { "uplink-${name}":
chain => 'mesh'
ffnord::firewall::device { "uplink-${name}":
zone => 'uplink',
zone_forward_ipv4 => ['mesh'],
zone_forward_ipv6 => [''],
forward_conntrack => True;
}

ffnord::firewall::service { "gre-${name}":
Expand Down
6 changes: 4 additions & 2 deletions manifests/vpn.pp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@

ffnord::monitor::vnstat::device { 'tun-anonvpn': }

ffnord::firewall::forward { 'tun-anonvpn':
chain => 'mesh'
ffnord::firewall::device { "tun-anonvpn":
zone => uplink,
zone_forward_ipv4 => ['mesh'],
forward_conntrack => True,
}

# Define Firewall rule for masquerade
Expand Down