By request: Shorewall on the B3

A collection of tips on howto tweak your Bubba.
Post Reply
Gordon
Posts: 1312
Joined: 10 Aug 2011, 03:18

By request: Shorewall on the B3

Post by Gordon » 24 Feb 2012, 14:48

First a statement: Shorewall is not a firewall - it's a script that uses your input variables to control iptables.

Now we got that sorted out let's start with some safety measurements. Since we're about to do funny stuff with iptables and there's no console on the B3, we will want to be able to revert in case we lock ourselves out. Now the problem with the standard firewall script in the B3 is that at shutdown it will actually save whatever we did wrong and reenable that when booting. That's not what we want, so let's alter the bubba-firewall script first. Take whatever editor you favor (that would be nano for everyone under 60 years old) and open the file /etc/init.d/bubba-firewall. Find and comment out the iptables-save line by placing a hashtag (#) in front of it as shown below:

Code: Select all

        stop|restart|force-reload)
        log_action_begin_msg "Saving firewall"

#       iptables-save > /etc/network/firewall.conf

        log_action_end_msg $?
Next step is to actually go get Shorewall:

Code: Select all

apt-get install shorewall
Debian is somewhat particular in this because if you look at the Shorewall config folder (/etc/shorewall) it's practically empty while a regular install will have some 30 files in there. Opinions may vary, but I think it makes things more complicated (seeing a file name may hint what it will do, but trying to re-"invent" the file name for something you want will prove to be difficult). The install does provide some examples though, which you may find at /usr/share/doc/shorewall/examples. Since we're logically running a two-interface setup, let's go with that example and copy it's contents to /etc/shorewall.

You'll find find six files of interest here:

Zones:

Code: Select all

#ZONE   TYPE    OPTIONS                 IN                      OUT
#                                       OPTIONS                 OPTIONS
fw      firewall
net     ipv4
loc     ipv4
This is perfectly fine for what we want, so don't change it.

Interfaces:

Code: Select all

#ZONE   INTERFACE       BROADCAST       OPTIONS
net     eth0            detect          dhcp,tcpflags,nosmurfs,routefilter,logmartians
loc     eth1            detect          tcpflags,nosmurfs,routefilter,logmartians
If you have a non-WiFi B3 that will be okay, but let's assume not (there are actually some deprecated options listed in this example):

Code: Select all

#ZONE   INTERFACE       BROADCAST       OPTIONS
net     eth0            detect          dhcp
loc     br0             detect          routeback
As you can see I dropped most of the options and added a new one. I kept 'dhcp' because it adds rules for eth0 to receive DHCP messages (this is actually a bad in the standard bubba-firewall); routeback is required to allow traffic between the wired network and the wireless interface.

Policy:

Code: Select all

#SOURCE         DEST            POLICY          LOG LEVEL       LIMIT:BURST

loc             net             ACCEPT
net             all             DROP            info
# THE FOLLOWING POLICY MUST BE LAST
all             all             REJECT          info
Now the object is that we want to start by copying the default Bubba behaviour, so we're definitely going to want to add a policy:

Code: Select all

#SOURCE         DEST            POLICY          LOG LEVEL       LIMIT:BURST

loc             net             ACCEPT
loc             $FW             ACCEPT
net             all             DROP            info
# THE FOLLOWING POLICY MUST BE LAST
all             all             REJECT          info
Note the variable '$FW' - this is an auto-assigned variable that holds whatever name you specified in the 'zones' file for the firewall. The additional line instructs Shorewall to write a "policy" rule that will accept any incoming traffic coming from the 'loc zone' (i.e. the LAN). You may consider it to be equivalent with the standard bubba-firewall rule

Code: Select all

-A INPUT -i br0 -j ACCEPT
I'll continue later....
Last edited by Gordon on 25 Feb 2012, 03:41, edited 1 time in total.

RandomUsername
Posts: 904
Joined: 09 Oct 2009, 18:49

Re: By request: Shorewall on the B3

Post by RandomUsername » 24 Feb 2012, 15:43

lol at the nano comment. I am a fan of nano's simplicity (and am also under 60) but have to wrestle with vi on a daily basis on our HP-UX boxes at work. Grrr. My boss (only a year older than me) likes it though :S

Cheeseboy
Posts: 789
Joined: 08 Apr 2007, 12:16

Re: By request: Shorewall on the B3

Post by Cheeseboy » 24 Feb 2012, 18:12

Hey! I'm only 40, and I like vi... :-)

Ubi
Posts: 1547
Joined: 17 Jul 2007, 09:01

Re: By request: Shorewall on the B3

Post by Ubi » 25 Feb 2012, 03:45

This is really great Gordon, can't wait for the next episode.

Oh and I use JOE as an editor. What does that make me?

6feet5
Posts: 269
Joined: 13 Apr 2007, 17:32
Location: Gnesta, Sweden
Contact:

Re: By request: Shorewall on the B3

Post by 6feet5 » 25 Feb 2012, 04:33

(that would be nano for everyone under 60 years old)
6Wiwith an IQ <ESC>2eldt) ;-)

I'm 40 as well and loving vim, though I have to admit it did take me some time to get used to vim, it took me three attempts to fully switch, but once you have learned enough the reward is a very powerful editor. The good thing is you don't have to learn everything, just a couple of commands will get you far. For anyone interested in learning some more about vim, I really suggest this excellent post on stackoverflow.
Oh and I use JOE as an editor. What does that make me?
average maybe

/Johan

Gordon
Posts: 1312
Joined: 10 Aug 2011, 03:18

Re: By request: Shorewall on the B3

Post by Gordon » 25 Feb 2012, 04:48

Are you guys hijacking my topic? vi is rubbish - it's a 2D rewrite of lineedit which is okay for typewriters, but nobody uses typewriters anymore.

On with the next file and this is an important one. This is because if you shutdown Shorewall it does not actually disable the firewall but sets everything to DROP. Obviously since we have no console on the B3, we need to tell Shorewall that we still want to be able to reach the B3 from the LAN end.

routestopped

Code: Select all

#INTERFACE      HOST(S)                  OPTIONS
br0             -
Optionally you can replace the dash with a valid IP or IP range, but let's keep it simple for now.

The next file holds the masquerading policy - you need to have this set if you ever want to be able to receive a response from the internet (with the settings thusfar you can already send messages on to the internet)
masq

Code: Select all

#INTERFACE              SOURCE          ADDRESS         PROTO   PORT(S) IPSEC   MARK
eth0                    10.0.0.0/8,\
                        169.254.0.0/16,\
                        172.16.0.0/12,\
                        192.168.0.0/16
I have no clue why they put this in the example, but then it is an example and it shows how you could restrict the routestopped allowed range. Essentially there's no harm in leaving it the way it is because it includes every range that you'd normally have on a private network. I'd suggest you either put a dash here (like in the routestopped file) or your actual LAN IP range (e.g. 192.168.1.0/24)


You're actually at a point now that you could start Shorewall and have a full restrictive firewall. The fun starts with the rules file where you put your exceptions. More about that later.

If you like to play with the result so far, you need to change the STARTUP_ENABLED parameter in the files shorewall.conf (did I say six files of interest?) to 'Yes'. To prevent accidentally locking yourself out, make sure that Shorewall will not start at boottime by renaming the script:

Code: Select all

mv /etc/init.d/shorewall /etc/init.d/shorewall.test
Remember that we already changed the bubba-firewall script, so if we do lock ourselves out all that's needed is to reboot the B3 and get the old bubba-firewall back up.

:idea: If you want to test if you can still access SSH, don't kill the session you have but try to start a new one next to it.

Gordon
Posts: 1312
Joined: 10 Aug 2011, 03:18

Re: By request: Shorewall on the B3

Post by Gordon » 27 Feb 2012, 05:56

Let's continue with the rules file and list what the example puts in there

rules

Code: Select all

#ACTION         SOURCE          DEST            PROTO   DEST    SOURCE          ORIGINAL        RATE$
#                                                       PORT    PORT(S)         DEST            LIMI$
#
#       Accept DNS connections from the firewall to the network
#
DNS(ACCEPT)     $FW             net
#
#       Accept SSH connections from the local network for administration
#
SSH(ACCEPT)     loc             $FW
#
#       Allow Ping from the local network
#
Ping(ACCEPT)    loc             $FW

#
# Drop Ping from the "bad" net zone.. and prevent your log from being flooded..
#

Ping(DROP)	net		$FW

ACCEPT          $FW             loc             icmp
ACCEPT          $FW             net             icmp
#
What does this example do? It sais to allow DNS queries from the B3 to the internet (tcp port 53 and udp port 53). It allows us to do SSH and ping to the B3 when we're on the LAN side. It denies ping from the internet, but the B3 can ping to everywhere. This is actually good, so let's start Shorewall and look at the result:

Code: Select all

~:# shorewall start
~:# iptables-save
# Generated by iptables-save v1.4.12.1 on Mon Feb 27 11:34:18 2012
*raw
:PREROUTING ACCEPT [9:612]
:OUTPUT ACCEPT [6:728]
COMMIT
# Completed on Mon Feb 27 11:34:18 2012
# Generated by iptables-save v1.4.12.1 on Mon Feb 27 11:34:18 2012
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:eth0_masq - [0:0]
-A POSTROUTING -o eth0 -j eth0_masq
-A eth0_masq -s 10.0.0.0/8 -j MASQUERADE
-A eth0_masq -s 169.254.0.0/16 -j MASQUERADE
-A eth0_masq -s 172.16.0.0/12 -j MASQUERADE
-A eth0_masq -s 192.168.0.0/16 -j MASQUERADE
COMMIT
# Completed on Mon Feb 27 11:34:18 2012
# Generated by iptables-save v1.4.12.1 on Mon Feb 27 11:34:18 2012
*mangle
:PREROUTING ACCEPT [49:2692]
:INPUT ACCEPT [49:2692]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [46:5192]
:POSTROUTING ACCEPT [46:5192]
:tcfor - [0:0]
:tcin - [0:0]
:tcout - [0:0]
:tcpost - [0:0]
:tcpre - [0:0]
-A PREROUTING -j tcpre
-A INPUT -j tcin
-A FORWARD -j MARK --set-xmark 0x0/0xff
-A FORWARD -j tcfor
-A OUTPUT -j tcout
-A POSTROUTING -j tcpost
COMMIT
# Completed on Mon Feb 27 11:34:18 2012
# Generated by iptables-save v1.4.12.1 on Mon Feb 27 11:34:18 2012
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
:Broadcast - [0:0]
:Drop - [0:0]
:Invalid - [0:0]
:NotSyn - [0:0]
:Reject - [0:0]
:dynamic - [0:0]
:fw2loc - [0:0]
:fw2net - [0:0]
:loc2fw - [0:0]
:loc2net - [0:0]
:loc_frwd - [0:0]
:logdrop - [0:0]
:logreject - [0:0]
:net2fw - [0:0]
:net2loc - [0:0]
:reject - [0:0]
:sfilter - [0:0]
:shorewall - [0:0]
-A INPUT -m conntrack --ctstate INVALID,NEW -j dynamic
-A INPUT -i eth0 -j net2fw
-A INPUT -i br0 -j loc2fw
-A INPUT -i lo -j ACCEPT
-A INPUT -j Reject
-A INPUT -j LOG --log-prefix "Shorewall:INPUT:REJECT:" --log-level 6
-A INPUT -g reject
-A FORWARD -i eth0 -o br0 -j net2loc
-A FORWARD -i br0 -j loc_frwd
-A FORWARD -j Reject
-A FORWARD -j LOG --log-prefix "Shorewall:FORWARD:REJECT:" --log-level 6
-A FORWARD -g reject
-A OUTPUT -o eth0 -j fw2net
-A OUTPUT -o br0 -j fw2loc
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -j Reject
-A OUTPUT -j LOG --log-prefix "Shorewall:OUTPUT:REJECT:" --log-level 6
-A OUTPUT -g reject
-A Broadcast -d 172.18.10.255/32 -j DROP
-A Broadcast -d 172.22.10.255/32 -j DROP
-A Broadcast -d 255.255.255.255/32 -j DROP
-A Broadcast -d 224.0.0.0/4 -j DROP
-A Drop
-A Drop -p tcp -m tcp --dport 113 -m comment --comment Auth -j reject
-A Drop -j Broadcast
-A Drop -p icmp -m icmp --icmp-type 3/4 -m comment --comment "Needed ICMP types" -j ACCEPT
-A Drop -p icmp -m icmp --icmp-type 11 -m comment --comment "Needed ICMP types" -j ACCEPT
-A Drop -j Invalid
-A Drop -p udp -m multiport --dports 135,445 -m comment --comment SMB -j DROP
-A Drop -p udp -m udp --dport 137:139 -m comment --comment SMB -j DROP
-A Drop -p udp -m udp --sport 137 --dport 1024:65535 -m comment --comment SMB -j DROP
-A Drop -p tcp -m multiport --dports 135,139,445 -m comment --comment SMB -j DROP
-A Drop -p udp -m udp --dport 1900 -m comment --comment UPnP -j DROP
-A Drop -p tcp -j NotSyn
-A Drop -p udp -m udp --sport 53 -m comment --comment "Late DNS Replies" -j DROP
-A Invalid -m conntrack --ctstate INVALID -j DROP
-A NotSyn -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -j DROP
-A Reject
-A Reject -p tcp -m tcp --dport 113 -m comment --comment Auth -j reject
-A Reject -j Broadcast
-A Reject -p icmp -m icmp --icmp-type 3/4 -m comment --comment "Needed ICMP types" -j ACCEPT
-A Reject -p icmp -m icmp --icmp-type 11 -m comment --comment "Needed ICMP types" -j ACCEPT
-A Reject -j Invalid
-A Reject -p udp -m multiport --dports 135,445 -m comment --comment SMB -j reject
-A Reject -p udp -m udp --dport 137:139 -m comment --comment SMB -j reject
-A Reject -p udp -m udp --sport 137 --dport 1024:65535 -m comment --comment SMB -j reject
-A Reject -p tcp -m multiport --dports 135,139,445 -m comment --comment SMB -j reject
-A Reject -p udp -m udp --dport 1900 -m comment --comment UPnP -j DROP
-A Reject -p tcp -j NotSyn
-A Reject -p udp -m udp --sport 53 -m comment --comment "Late DNS Replies" -j DROP
-A fw2loc -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A fw2loc -p icmp -j ACCEPT
-A fw2loc -j Reject
-A fw2loc -j LOG --log-prefix "Shorewall:fw2loc:REJECT:" --log-level 6
-A fw2loc -g reject
-A fw2net -p udp -m udp --dport 67:68 -j ACCEPT
-A fw2net -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A fw2net -p udp -m udp --dport 53 -m comment --comment DNS -j ACCEPT
-A fw2net -p tcp -m tcp --dport 53 -m comment --comment DNS -j ACCEPT
-A fw2net -p icmp -j ACCEPT

-A fw2net -j Reject
-A fw2net -j LOG --log-prefix "Shorewall:fw2net:REJECT:" --log-level 6
-A fw2net -g reject
-A loc2fw -m conntrack --ctstate INVALID,NEW -j dynamic
-A loc2fw -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A loc2fw -p tcp -m tcp --dport 22 -m comment --comment SSH -j ACCEPT
-A loc2fw -p icmp -m icmp --icmp-type 8 -m comment --comment Ping -j ACCEPT

-A loc2fw -j ACCEPT
-A loc2net -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A loc2net -j ACCEPT
-A loc_frwd -m conntrack --ctstate INVALID,NEW -j dynamic
-A loc_frwd -o eth0 -j loc2net
-A loc_frwd -o br0 -j ACCEPT
-A logdrop -j DROP
-A logreject -j reject
-A net2fw -m conntrack --ctstate INVALID,NEW -j dynamic
-A net2fw -p udp -m udp --dport 67:68 -j ACCEPT
-A net2fw -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A net2fw -p icmp -m icmp --icmp-type 8 -m comment --comment Ping -j DROP
-A net2fw -j Drop
-A net2fw -j LOG --log-prefix "Shorewall:net2fw:DROP:" --log-level 6
-A net2fw -j DROP
-A net2loc -o eth0 -g sfilter
-A net2loc -m conntrack --ctstate INVALID,NEW -j dynamic
-A net2loc -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A net2loc -j Drop
-A net2loc -j LOG --log-prefix "Shorewall:net2loc:DROP:" --log-level 6
-A net2loc -j DROP
-A reject -d 192.168.1.255/32 -j DROP
-A reject -d 192.168.2.255/32 -j DROP
-A reject -d 255.255.255.255/32 -j DROP
-A reject -s 224.0.0.0/4 -j DROP
-A reject -p igmp -j DROP
-A reject -p tcp -j REJECT --reject-with tcp-reset
-A reject -p udp -j REJECT --reject-with icmp-port-unreachable
-A reject -p icmp -j REJECT --reject-with icmp-host-unreachable
-A reject -j REJECT --reject-with icmp-host-prohibited
-A sfilter -j LOG --log-prefix "Shorewall:sfilter:DROP:" --log-level 6
-A sfilter -j DROP
COMMIT
# Completed on Mon Feb 27 11:34:18 2012
As you can see there's a lot going on, so for readability I colorcoded some of the lines:
Red = The lines from the Shorewall policy file
Green = The lines from the Shorewall rules file
Blue = The options specified in the Shorewall interfaces file

Gordon
Posts: 1312
Joined: 10 Aug 2011, 03:18

Re: By request: Shorewall on the B3

Post by Gordon » 27 Feb 2012, 06:48

Now at this point you may feel somewhat restricted when working on the B3 console, or even in the web interface. In fact the only thing you can do is Ping and resolve internet addresses, meaning you can no longer synchronize time and also not update the B3 software. So now let's implement the standard Bubba firewall:

policy
#SOURCE DEST POLICY LOG LEVEL LIMIT:BURST

loc net ACCEPT
loc $FW ACCEPT

#
# OUTPUT breaks up in two directions, so by setting both of them to ACCEPT
# this essentially translates as ":OUTPUT ACCEPT"
#
$FW loc ACCEPT
$FW net ACCEPT

net all DROP info

# THE FOLLOWING POLICY MUST BE LAST
all all REJECT info
rules
#ACTION SOURCE DEST PROTO DEST SOURCE ORIGINAL RATEUSER/ MARK
# PORT PORT(S) DEST LIMITGROUP
#
# Accept DNS connections from the firewall to the network
#
DNS(ACCEPT) $FW net
#
# Accept SSH connections from the local network for administration
#
SSH(ACCEPT) loc $FW
#
# Allow Ping from the local network
#
Ping(ACCEPT) loc $FW


#
# Allow http, https, ftp,
#
ACCEPT net $FW tcp http
ACCEPT net $FW tcp https
ACCEPT net $FW tcp ftp

#ACCEPT net $FW tcp smtp
#ACCEPT net $FW tcp imaps

#
# Drop Ping from the "bad" net zone.. and prevent your log from being flooded..
#

Ping(DROP) net $FW

ACCEPT $FW loc icmp
ACCEPT $FW net icmp
#
That's it 8)
Last edited by Gordon on 27 Feb 2012, 14:03, edited 1 time in total.

Gordon
Posts: 1312
Joined: 10 Aug 2011, 03:18

Re: By request: Shorewall on the B3

Post by Gordon » 27 Feb 2012, 08:01

Let's go do some smart stuff now. Anyone remember the firewall rewrite thingy Eek discovered not so long ago? While the concept of this rewrite is actually good, it doesn't work for me because I myself cannot attach the B3 directly to the internet. This means that after the rewrite all references to my public IP have been replaced by the private IP that my ISP's router hands out.

So I registered my own domain and I want to see what others see when they access my webserver (i.e. do they see the Bubba page or the page I intent them to see?). If you have a similar setup you can try for yourself to see that this leads to a time-out. The solution is a rule that translates the original destination to the IP that was given to the B3 WAN interface, but if these are both dynamic this can be somewhat of a challenge.

Shorewall provides a params file that we can use for this, so start by putting that file in the shorewall config folder:

Code: Select all

cp  /usr/share/doc/shorewall/default-config/params   /etc/shorewall
Insert the following lines:

Code: Select all

# whatismyip.org is a webservice that returns your public IP
PUBLIC_IP=`wget http://whatismyip.org/ -o /dev/null -O /dev/stdout`

# retrieve the current IP address assigned to eth0
WAN_IP=`ip -o -f inet addr show dev eth0 | sed "s/^.*inet \(.*\?\)\/.*$/\1/"`
Now insert the NAT rule in the rules file:

Code: Select all

DNAT		loc		net:$WAN_IP	-	-	-	$PUBLIC_IP
...and observe the result when you list the nat table after restarting Shorewall:

Code: Select all

~:#iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N dnat
-N eth0_masq
-N loc_dnat
-A PREROUTING -j dnat
-A POSTROUTING -o eth0 -j eth0_masq
-A dnat -i br0 -j loc_dnat
-A eth0_masq -s 10.0.0.0/8 -j MASQUERADE
-A eth0_masq -s 169.254.0.0/16 -j MASQUERADE
-A eth0_masq -s 172.16.0.0/12 -j MASQUERADE
-A eth0_masq -s 192.168.0.0/16 -j MASQUERADE
-A loc_dnat -d 224.224.224.224/32 -j DNAT --to-destination 192.168.2.5
224.224.224.224 is of course not a valid address but you got that, right?

Eek
Posts: 372
Joined: 23 Dec 2007, 03:03
Location: the Netherlands

Re: By request: Shorewall on the B3

Post by Eek » 27 Feb 2012, 13:39

Great stuff Gordon.
cheers
Eek

Post Reply