Filtering bogon ranges from exiting WAN

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



So I've been working on building my own router using iptables and
iproute2 as a bit of a research project to get to know these things
better.

I've written about it here (mostly so I have something to refer to)
and so others can try it out:

http://wiki.alpinelinux.org/wiki/Linux_Router_with_VPN_on_a_Raspberry_Pi

I realized that I was not filtering bogon ranges, that were exiting
out my router's WAN port. These things are obviously forbidden in
some way on the general internet I wanted to filter them before
that happens.

I'd looked at this guide:

http://blog.ls20.com/securing-your-server-using-ipset-and-dynamic-blocklists/

I'm not using the full fullbogons-ipv4.txt range, but rather the
smaller one which consists of reserved ranges.

https://files.pfsense.org/lists/bogon-bn-nonagg.txt
https://en.wikipedia.org/wiki/Reserved_IP_addresses

The method is to use ipset to load the list, and add it to it's own
filter chain and then block all but the actual ranges that exist on
my network.

First of all I imported the list and can see it was correctly loaded:

# ipset list
Name: bogon-bn-nonagg
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 8976
References: 4
Members:
172.16.0.0/12
192.168.0.0/16
192.0.2.0/24
224.0.0.0/4
240.0.0.0/4
10.0.0.0/8
127.0.0.0/8
198.18.0.0/15
198.51.100.0/24
100.64.0.0/10
192.0.0.0/24
169.254.0.0/16
203.0.113.0/24
0.0.0.0/8


Then created the chain:

# Create Bogon Chain
:IP4BOGONS - [0:0]

# Allow localhost
-A INPUT ! -i lo -j IP4BOGONS


Made the exceptions:

# Except connection between modem and router
-A IP4BOGONS -s 192.168.0.0/30 -j RETURN

# Except hosts on regular link to ISP
-A IP4BOGONS -s 192.168.1.0/24 -j RETURN

# Except hosts on link to VPN
-A IP4BOGONS -s 192.168.2.0/24 -j RETURN

# Except hosts on LAN only subnet
-A IP4BOGONS -s 192.168.3.0/24 -j RETURN

# Except VPN interface
-A IP4BOGONS -s 172.16.32.0/20 -j RETURN

Block all remaining bogons whether in source or destination:

# Block bogons with source matching list
-A IP4BOGONS -m set --match-set bogon-bn-nonagg src -j DROP

# Block bogons with destination matching list
-A IP4BOGONS -m set --match-set bogon-bn-nonagg dst -j DROP

Unfortunately the problem still seems to be if I ping 192.168.5.1
for example it still is routed out to my ISP and filtered by their
router.

My full rules are below for completeness:

#########################################################################
# Advanced routing rule set
# Uses 192.168.1.0 via ISP
#      192.168.2.0 via VPN
#      192.168.3.0 via LAN
#
# Packets to/from 192.168.1.0/24 are marked with 0x1 and routed to ISP
# Packets to/from 192.168.2.0/24 are marked with 0x2 and routed to VPN
# Packets to/from 192.168.3.0/24 are marked with 0x3 and routed to LAN
#
#########################################################################

#
# Mangle Table
# This is the place where our markings happen, whether they be 0x1 or 0x2
#
*mangle

# Set default policies for table
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

# Restore CONNMARK to the MARK (If one doesn't exist then no mark is set)
-A PREROUTING -j CONNMARK --restore-mark --nfmask 0xffffffff --ctmask 0xffffffff

# If packet MARK is 3, then it means there is already a connection mark
#-A PREROUTING -s 192.168.3.0/24 -m mark --mark 0x3 -j ACCEPT

# Check packets coming from 192.168.3.0/24 are 0x3
#-A PREROUTING -s 192.168.3.0/24 -j MARK --set-xmark 0x3/0xffffffff

# If packet MARK is 2, then it means there is already a connection mark and the original packet came in on VPN
-A PREROUTING -s 192.168.2.0/24 -m mark --mark 0x2 -j ACCEPT

# Check exception (this is a server which when accessed on a 192.168.2.0/24 address will go out the ISP table) are 0x1
#-A PREROUTING -s 192.168.2.0/24 -d <IP_OF_EXCEPTED_SERVER>/32 -m mark --mark 0x1 -j ACCEPT

# Check packets coming from 192.168.2.0/24 are 0x2
-A PREROUTING -s 192.168.2.0/24 -j MARK --set-xmark 0x2/0xffffffff

# If packet MARK is 1, then it means there is already a connection mark and the original packet came in on ISP
-A PREROUTING -s 192.168.1.0/24 -m mark --mark 0x1 -j ACCEPT

# Check packets coming from 192.168.1.0/24 are 0x1
-A PREROUTING -s 192.168.1.0/24 -j MARK --set-xmark 0x1/0xffffffff

# Mark exception (this is a server which when accessed on a 192.168.2.0/24 address will go out the ISP table) as 0x1
#-A PREROUTING -s 192.168.2.0/24 -d <IP_OF_EXCEPTED_SERVER>/32 -j MARK --set-xmark 0x1/0xffffffff

# Save MARK to CONNMARK (remember iproute can't see CONNMARKs)
-A PREROUTING -j CONNMARK --save-mark --nfmask 0xffffffff --ctmask 0xffffffff
COMMIT

#
# Filter Table
# This is where we decide to ACCEPT, DROP or REJECT things
#
*filter

# Set default policies for table
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]

# Create rule chain per input interface for forwarding packets
:FWD_ETH0 - [0:0]
:FWD_ETH1 - [0:0]
:FWD_PPP0 - [0:0]
:FWD_TUN0 - [0:0]

# Create rule chain per input interface for input packets (for host itself)
:IN_ETH0 - [0:0]
:IN_ETH1 - [0:0]
:IN_PPP0 - [0:0]
:IN_TUN0 - [0:0]

# Create Bogon Chain
:IP4BOGONS - [0:0]

# Allow localhost
-A INPUT ! -i lo -j IP4BOGONS

# Pass input packet to corresponding rule chain
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -j IN_ETH0
-A INPUT -i eth1 -j IN_ETH1
-A INPUT -i ppp0 -j IN_PPP0
-A INPUT -i tun0 -j IN_TUN0

# Log packets that are dropped in INPUT chain
-A INPUT -j LOG --log-prefix "DROPPED INPUT: "

# Track forwarded packets
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Pass forwarded packet to corresponding rule chain
-A FORWARD -i eth0 -j FWD_ETH0
-A FORWARD -i eth1 -j FWD_ETH1
-A FORWARD -i ppp0 -j FWD_PPP0
-A FORWARD -i tun0 -j FWD_TUN0

# Log packets that are dropped in FORWARD chain
-A FORWARD -j LOG --log-prefix "DROPPED FORWARD: "

# Forward traffic to ISP
-A FWD_ETH0 -s 192.168.1.0/24 -j ACCEPT

# Forward traffic to VPN
-A FWD_ETH0 -s 192.168.2.0/24 -j ACCEPT

# Forward traffic to LAN
-A FWD_ETH0 -s 192.168.3.0/24 -j ACCEPT

# Allow excepted server to be FORWARD to ppp0
#-A FWD_ETH0 -s 192.168.2.0/24 -d <IP_OF_EXCEPTED_SERVER>/32 -o ppp0 -j ACCEPT

# Forward SSH packets from network to modem
-A FWD_ETH1 -s 192.168.0.0/30 -d 192.168.1.0/24 -p tcp -m tcp --sport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A FWD_ETH1 -s 192.168.0.0/30 -d 192.168.2.0/24 -p tcp -m tcp --sport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# SSH to Router
-A IN_ETH0 -s 192.168.1.0/24 -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A IN_ETH0 -s 192.168.2.0/24 -p tcp -m tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# DNS to Router
-A IN_ETH0 -s 192.168.1.0/24 -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
-A IN_ETH0 -s 192.168.2.0/24 -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT

# FreeRadius Client (eg a UniFi AP)
-A IN_ETH0 -s 192.168.1.0/24 -p tcp -m tcp --dport 1812 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A IN_ETH0 -s 192.168.1.0/24 -p udp -m udp --dport 1812 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# Ubiquiti UAP Device Discovery Broadcast
-A IN_ETH0 -s 192.168.1.0/24 -p udp -m udp --dport 10001 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# NTP to Router
-A IN_ETH0 -s 192.168.1.0/24 -p udp -m udp --dport 123 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A IN_ETH0 -s 192.168.2.0/24 -p udp -m udp --dport 123 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# Accept traffic to router on both subnets
-A IN_ETH0 -s 192.168.1.0/24 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
-A IN_ETH0 -s 192.168.2.0/24 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# Allow excepted server to be INPUT to eth0 from LAN
#-A IN_ETH0 -s 192.168.2.0/24 -d <IP_OF_EXCEPTED_SERVER>/32 -o ppp0 -j ACCEPT

# SSH To Modem from Router
-A IN_ETH1 -s 192.168.0.0/30 -d 192.168.0.0/30 -p tcp -m tcp --sport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

# Accept incoming tracked PPP0 connection
-A IN_PPP0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Accept incoming tracked TUN0 connection
-A IN_TUN0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Except connection between modem and router
-A IP4BOGONS -s 192.168.0.0/30 -j RETURN

# Except hosts on regular link to ISP
-A IP4BOGONS -s 192.168.1.0/24 -j RETURN

# Except hosts on link to VPN
-A IP4BOGONS -s 192.168.2.0/24 -j RETURN

# Except hosts on LAN only subnet
-A IP4BOGONS -s 192.168.3.0/24 -j RETURN

# Except VPN interface
-A IP4BOGONS -s 172.16.32.0/20 -j RETURN

# Block bogons with source matching list
-A IP4BOGONS -m set --match-set bogon-bn-nonagg src -j DROP

# Block bogons with destination matching list
-A IP4BOGONS -m set --match-set bogon-bn-nonagg dst -j DROP

COMMIT

#
# NAT Table
# This is where translation of packets happens and "forwarding" of ports
# to specific hosts.
#
*nat

# Set default policies for table
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

# Port forwarding for Bittorrent
-A PREROUTING -i tun0 -p tcp -m tcp --dport 6881:6889 -j DNAT --to-destination 192.168.2.20
-A PREROUTING -i tun0 -p udp -m udp --dport 6881:6889 -j DNAT --to-destination 192.168.2.20

# Allows hosts of the network to use the VPN tunnel
-A POSTROUTING -o tun0 -j MASQUERADE

# Allows hosts of the network to use the PPP tunnel
-A POSTROUTING -o ppp0 -j MASQUERADE
COMMIT


The the exception chains are certainly working as indicated by the
counters. However it seems chain 8-9 (the two DROP chains) don't
seem to work at all.

If I put the exceptions below those two match-sets then it certainly
denies me access to the router as expected, so I know ipset is
working.

I tried using ACCEPT instead of RETURN but that didn't help me
either.

# iptables --line-numbers -nv -L INPUT; iptables -nv -L IP4BOGONS
Chain INPUT (policy DROP 1 packets, 40 bytes)
num   pkts bytes target     prot opt in     out     source               destination
1     3456  953K IP4BOGONS  all  --  !lo    *       0.0.0.0/0            0.0.0.0/0
2      123 21379 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
3        0     0 IN_ETH0    all  --  eth0   *       0.0.0.0/0            0.0.0.0/0
4        0     0 IN_ETH1    all  --  eth1   *       0.0.0.0/0            0.0.0.0/0
5      959  750K IN_PPP0    all  --  ppp0   *       0.0.0.0/0            0.0.0.0/0
6        0     0 IN_TUN0    all  --  tun0   *       0.0.0.0/0            0.0.0.0/0
7        1    40 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4 prefix "DROPPED INPUT: "
8        0     0 DROP       all  --  eth0   *       0.0.0.0/0            0.0.0.0/0            match-set bogon-bn-nonagg src
9        0     0 DROP       all  --  eth0   *       0.0.0.0/0            0.0.0.0/0            match-set bogon-bn-nonagg dst
Chain IP4BOGONS (1 references)
 pkts bytes target     prot opt in     out     source               destination
   44  5933 ACCEPT     all  --  *      *       192.168.0.0/30       0.0.0.0/0
   61  8733 ACCEPT     all  --  *      *       192.168.1.0/24       0.0.0.0/0
 2336  159K ACCEPT     all  --  *      *       192.168.2.0/24       0.0.0.0/0
    0     0 ACCEPT     all  --  *      *       192.168.3.0/24       0.0.0.0/0
   62 29160 ACCEPT     all  --  *      *       172.16.32.0/20       0.0.0.0/0

-------------------------------------------------------------------------------

--
To unsubscribe from this list: send the line "unsubscribe netfilter" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Netem]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux