roles/dch-gw: Configure the filter table

The *filter* table is responsible for deciding which packets will be
accepted and which will be rejected. It has three chains, which classify
packets according to whether they are destined for the local machine
(input), passing through this machine (forward) or originating from the
local machine (output).

The *dch-gw* role now configures all three chains in this table. For
now, it defines basic rules, mostly based on TCP/UDP destination port:

* Traffic destined for a service hosted by the local machine (DNS, DHCP,
  SSH), is allowed if it does not come from the Internet
* Traffic passing through the machine is allowed if:
  * It is passing between internal networks
  * It is destined for a host on the FireMon network (VPN)
  * It was NATed to in internal host (marked 323)
  * It is destined for the Internet
* Only DHCP, HTTP, and DNS are allowed to originate from the local
machine

This configuration requires an `internet_iface` variable, which
indicates the name of the network interface connected to the Internet
directly.
jenkins-master
Dustin 2018-03-28 23:32:21 -05:00
parent da5da95894
commit a0a4b91faf
10 changed files with 172 additions and 5 deletions

View File

@ -40,6 +40,11 @@ dch_networks:
router_iface: vlan254
firemon_networks:
- 192.168.0.0/16
- 172.28.33.0/24
nat_port_forwards:
- protocol: tcp
port: http
@ -62,3 +67,33 @@ nat_port_forwards:
- protocol: udp
port: ipsec-nat-t
destination: 172.31.0.2
allow_incoming:
- protocol: udp
port: domain
- protocol: tcp
port: domain
- protocol: udp
port: bootps
- protocol: tcp
port: ssh
allow_outgoing:
- protocol: udp
port: ntp
- protocol: udp
port: dhcpv6-server
- protocol: udp
port: bootps
- protocol: tcp
port: https
- protocol: tcp
port: http
- protocol: udp
port: domain
- protocol: tcp
port: domain
trace_dropped: true

View File

@ -1,6 +1,8 @@
internet_iface: enp4s0
network:
ignore_interfaces:
- enp4s0
- '{{ internet_iface }}'
interfaces:
- ifname: enp1s0
enabled: true
@ -66,7 +68,7 @@ dhcpcd_ntp_servers: false
dhcpcd_noipv4: true
dhcpcd_noipv6rs: true
dhcpcd_interfaces:
- name: enp4s0
- name: '{{ internet_iface }}'
description: Internet
config:
- ipv4

View File

@ -1 +1,3 @@
nat_port_forwards: []
allow_incoming: []
trace_dropped: false

View File

@ -0,0 +1,7 @@
#! /usr/sbin/nft -f
table inet filter {
chain input { type filter hook input priority 0; }
chain forward { type filter hook forward priority 0; }
chain output { type filter hook output priority 0; }
}

View File

@ -31,6 +31,33 @@
sysctl_file=/etc/sysctl.d/ip-forwarding.conf
state=present
- name: ensure inet filter rules are configured
copy:
src=inet-filter.nft
dest=/etc/nftables/ruleset.d/10_inet-filter.nft
mode=0644
notify: reload nftables
- name: ensure basic rules are defined
template:
src={{ item }}.nft.j2
dest=/etc/nftables/ruleset.d/20_{{ item }}.nft
mode=0644
with_items:
- incoming
- forward
- outgoing
notify: reload nftables
- name: ensure final reject rules are defined
template:
src=reject.nft.j2
dest=/etc/nftables/ruleset.d/90_{{ item }}-reject.nft
mode=0644
with_items:
- input
- forward
- output
notify: reload nftables
- name: ensure ipv4 nat rules are configured
copy:
src=ipv4-nat.nft

View File

@ -0,0 +1,23 @@
{#- vim: set sw=4 ts=4 sts=4 et : #}
table inet filter {
set firemon {
type ipv4_addr
flags interval
elements = {
{% for prefix in firemon_networks %}
{{ prefix }},
{% endfor %}
}
}
chain forward {
ct state established,related accept
iifname {{ dch_networks.guest.router_iface }} oif != {{ internet_iface }} drop
iif != {{ internet_iface }} oifname {{ dch_networks.guest.router_iface }} drop
iif != {{ internet_iface }} oif != {{ internet_iface }} counter accept
ip daddr @firemon counter accept
mark 323 counter accept
tcp dport smtp counter reject with icmpx type host-unreachable
oif {{ internet_iface }} accept
}
}

View File

@ -0,0 +1,34 @@
{#- vim: set sw=4 ts=4 sts=4 et : #}
table inet filter {
set allow_tcp_in {
type inet_service
flags interval
elements = {
{% for item in allow_incoming if item.protocol|d('tcp') == 'tcp' %}
{{ item.port }},
{% endfor %}
}
}
set allow_udp_in {
type inet_service
flags interval
elements = {
{% for item in allow_incoming if item.protocol|d('tcp') == 'udp' %}
{{ item.port }},
{% endfor %}
}
}
chain input {
ct state established,related accept
iif lo accept
ip6 nexthdr ipv6-icmp accept
ip protocol icmp accept
udp sport dhcpv6-server counter accept
iif != {{ internet_iface }} tcp dport @allow_tcp_in ct state new counter accept
iif != {{ internet_iface }} udp dport @allow_udp_in ct state new counter accept
iif {{ internet_iface }} drop
pkttype != host drop
}
}

View File

@ -0,0 +1,31 @@
{#- vim: set sw=4 ts=4 sts=4 et : #}
table inet filter {
set allow_tcp_out {
type inet_service
flags interval
elements = {
{% for item in allow_outgoing if item.protocol|d('tcp') == 'tcp' %}
{{ item.port }},
{% endfor %}
}
}
set allow_udp_out {
type inet_service
flags interval
elements = {
{% for item in allow_outgoing if item.protocol|d('tcp') == 'udp' %}
{{ item.port }},
{% endfor %}
}
}
chain output {
ct state established,related accept
oif lo accept
ip6 nexthdr ipv6-icmp accept
ip protocol icmp accept
tcp dport @allow_tcp_out ct state new counter accept
udp dport @allow_udp_out ct state new counter accept
}
}

View File

@ -33,13 +33,13 @@ table ip nat {
}
chain prerouting {
ip daddr $outside_address dnat tcp dport map @tcp_forward
ip daddr $outside_address dnat udp dport map @udp_forward
ip daddr $outside_address meta mark set 323 dnat tcp dport map @tcp_forward
ip daddr $outside_address meta mark set 323 dnat udp dport map @udp_forward
}
chain postrouting {
{% for item in nat_port_forwards %}
ip saddr @inside_networks ip daddr {{ item.destination }} {{ item.protocol|d('tcp') }} dport {{ item.port }} masquerade
ip saddr @inside_networks ip daddr {{ item.destination }} {{ item.protocol|d('tcp') }} dport {{ item.port }} meta mark set 323 masquerade
{% endfor %}
}
}

View File

@ -0,0 +1,6 @@
{#- vim: set sw=4 ts=4 sts=4 et : #}
table inet filter {
chain {{ item }} {
{% if trace_dropped %}nftrace set 1 {% endif %}counter reject with icmpx type host-unreachable
}
}