09 February 2012

63. Iptables for LAN with one internet connected gateway; sharing internet connection using iptables

Here I show how to share an internet connection with clients on a LAN. It's based in part on the iptables which firestarter generates when setting up connection sharing -- I think one could probably get away with dropping the INBOUND/OUTBOUND sections for the gateway server.

You will probably find that you need to open more ports, depending on your network services. Hopefully it's obvious from the instructions below how to do that. As always, use what you find below as a starting point and expand and correct it as you fool around with it.

While it's easier to use a gui like gufw or firestarter (see previous post), it's easier to get an absolute overview of your firewall configuration if you define each rule using iptables. It's also not that difficult and with a bit of trial and error you can work it out.

The usual caveats apply -- a good 2/3 of my posts are written as I'm teaching myself, while the remainder describe easy, useful, but not always obvious, things and programmes which makes life easier. This lands in the former category.

--- START HERE ---

My network:
One computer has two cards. eth0 is connected to the outside world, eth1 is connected to a switch making up a LAN. Each client is connected to the switch and has static IP (set in /etc/network/interfaces)

The clients are the easiest, so we'll start with them

Client:
create /etc/firewall-rules.sh (e.g. sudo vim /etc/firewall-rules.sh) and put the following in it:

sudo iptables -F #FLUSH

#INPUT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT #network access
sudo iptables -A INPUT -i lo -j ACCEPT                        #127.0.0.1
sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT -s 192.168.1.0/24 #ssh
sudo iptables -A INPUT -p tcp --dport www -j ACCEPT -s 192.168.1.0/24 #web server
sudo iptables -A INPUT -p tcp --dport nfs -j ACCEPT -s 192.168.1.0/24 #needed for nfs
sudo iptables -A INPUT -p udp --dport nfs -j ACCEPT -s 192.168.1.0/24 #needed for nfs
sudo iptables -A INPUT -p tcp --dport sunrpc -j ACCEPT -s 192.168.1.0/24 #needed for nfs 
sudo iptables -A INPUT -p udp --dport sunrpc -j ACCEPT -s 192.168.1.0/24 #needed for nfs 
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT -s 192.168.1.0/24 #ping
sudo iptables -A INPUT -p udp --dport 60003 -j ACCEPT -s 192.168.1.0/24 #sinfo/d
sudo iptables -A INPUT -m limit --limit 15/minute -j LOG --log-level 7 --log-prefix " Dropped by firewall "
sudo iptables -A INPUT -j DROP                          #drop all else

#OUTPUT
sudo iptables -A OUTPUT -o lo -j ACCEPT #127.0.0.1
sudo iptables -A OUTPUT -j ACCEPT          #all outgoing ok

#FORWARD
sudo iptables -A FORWARD -p icmp --icmp-type 8 -j ACCEPT

#Default behaviour
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP 
sudo iptables -P FORWARD DROP
Next, change ownership and permission

sudo chown root firewall-rules.sh
sudo chmod 700 firewall-rules.sh

Finally, edit /etc/network/interfaces and put
post-up sh /etc/firewall-rules.sh
as the last line. If you use post-up routing rules as well you can put those before or after.

Done!


The Gateway:
We need to allow the local network access to the services of the gateway, such as apt-cache. We also need to pass through traffic to the outside world.

Here's the gateway's /etc/firewall-rules.sh:

sudo iptables -F #FLUSH
# T1 -> eth0 --> inet, eth1 --> LAN (192.168.0/24)

#table nat
sudo iptables -t nat -P PREROUTING ACCEPT
sudo iptables -t nat -P INPUT ACCEPT
sudo iptables -t nat -P OUTPUT ACCEPT
sudo iptables -t nat -P POSTROUTING ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

#table mangle
sudo iptables -t mangle -P PREROUTING ACCEPT
sudo iptables -t mangle -P INPUT ACCEPT
sudo iptables -t mangle -P FORWARD ACCEPT
sudo iptables -t mangle -P OUTPUT ACCEPT
sudo iptables -t mangle -P POSTROUTING ACCEPT 

#main table
sudo iptables -N OUTBOUND
sudo iptables -N INBOUND

#INPUT
sudo iptables -A INPUT -i eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT #allows network access
sudo iptables -A INPUT -i lo -j ACCEPT                                                #127.0.0.1
sudo iptables -A INPUT -i eth1 -p tcp --dport ssh -j ACCEPT -s 192.168.1.0/24 #ssh
sudo iptables -A INPUT -i eth1 -p tcp --dport www -j ACCEPT -s 192.168.1.0/24 #web server
sudo iptables -A INPUT -i eth1 -p tcp --dport nfs -j ACCEPT -s 192.168.1.0/24 #needed for nfs
sudo iptables -A INPUT -i eth1 -p udp --dport nfs -j ACCEPT -s 192.168.1.0/24 #needed for nfs
sudo iptables -A INPUT -i eth1 -p tcp --dport sunrpc -j ACCEPT -s 192.168.1.0/24  #needed for nfs 
sudo iptables -A INPUT -i eth1 -p udp --dport sunrpc -j ACCEPT -s 192.168.1.0/24 #needed for nfs 
sudo iptables -A INPUT -i eth1 -p icmp --icmp-type 8 -j ACCEPT -s 192.168.1.0/24  #ping
sudo iptables -A INPUT -i eth1 -p udp --dport 60003 -j ACCEPT -s 192.168.1.0/24 #sinfo/d
sudo iptables -A INPUT -i eth1 -p tcp --dport 3142 -j ACCEPT -s 192.168.1.0/24             #apt-cache
sudo iptables -A INPUT -i eth1 -d 192.168.1.1 -j INBOUND                                                   #needed for gw -> clients
sudo iptables -A INPUT -i eth0 -s 192.168.1.0/24 -j REJECT 
sudo iptables -A INPUT -m limit --limit 15/minute -j LOG --log-level 7 --log-prefix " Dropped by firewall "
sudo iptables -A INPUT -j DROP                                                       #drop all else


#OUTPUT
sudo iptables -A OUTPUT -o lo -j ACCEPT #localhost 127.0.0.1
sudo iptables -A OUTPUT -o eth0 -j ACCEPT #eth0: all outgoing ok
sudo iptables -A OUTPUT -o eth1 -j ACCEPT                               #eth1: all outgoing ok

#FORWARD
sudo iptables -A FORWARD -p icmp -j ACCEPT 
sudo iptables -A FORWARD -p tcp -s 192.168.1.0/24 -j ACCEPT     #forward everything from local LAN
sudo iptables -A FORWARD -p udp -s 192.168.1.0/24 -j ACCEPT    #forward everything from local LAN
sudo iptables -A FORWARD -i eth0 -j OUTBOUND                           #need both for pass-through
sudo iptables -A FORWARD -i eth1 -j OUTBOUND                           #need both for pass-through


#INBOUND
sudo iptables -A INBOUND -j ACCEPT -m state --state RELATED,ESTABLISHED                              
sudo iptables -A INBOUND -s beryllium -j ACCEPT
sudo iptables -A INBOUND -j ACCEPT -s 192.168.1.0/24

#OUTBOUND
sudo iptables -A OUTBOUND -j ACCEPT

#Default behaviour
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP 
sudo iptables -P FORWARD DROP

And that's about it.

To check that it loaded do

sudo iptables -L -n -v

The -n is because of this.

Keep on checking what goes into /var/log/firewall.log to see whether you should open more ports or use a more generous (or strict) firewall policy.



Edit: the following was the old way of doing it. The downside is that
1. it gets loaded very late in the boot sequence
2. it doesn't reload on sudo service networking restart

I've migrated away from network-manager, but it might require the method below. Use if the first method doesn't load the firewall rules.

edit /etc/rc.local and put 
sh /etc/firewall-rules.sh
as the second-to-last line to make the rules be added on each boot.

Remember the sudo iptables -m limit --limit 15/minute -j LOG --log-level 7 --log-prefix " Dropped by firewall " line? It doesn't actually do anything yet.

Edit /etc/rsyslog.conf and put
kern.=debug /var/log/firewall.log
anywhere. Restart the service:

sudo service rsyslog restart

There's now a firewall.log in your  /var/log dir.



There is one caveat:

IMPORTANT: for some reason receiving large files via sftp in filezilla FROM a client to the gateway gives

Error: Incorrect MAC received on packet
Error: File transfer failed after transferring 32,768 bytes in 1 second
or
Error: Server sent disconnect message
Error: type 2 (protocol error):
Error: "Packet corrupt"
Error: File transfer failed

Transferring large files TO a client works fine from the gateway and is blazingly fast. Transferring files between clients also works fast and securely.

i.e. on a client I can easily receive files from the gateway. On the gateway I can easily put a file on a client. The opposite directions don't work, whether I do it on the client or on the gateway. It seems like there should be an obvious iptables fix. My network cards are rtl-8169 gigabit pci cards and/or intel e1000 pro

NFS works fine for filetransfer (see this post) but I'm working on figuring out the incorrect MAC problem.

I've already tried with
sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Also, even a firewall consisting of nothing but (apart from flush):

sudo iptables -P INPUT ACCEPTsudo iptables -P OUTPUT ACCEPTsudo iptables -P FORWARD ACCEPT

doesn't solve it

Links to this post:
http://www.debian-srbija.iz.rs/p/kako-da.html

62. Sharing a folder between computers using nfs on Debian

A year ago I posted about getting nfs set up for a local network as part of a longer post -- here it is reposted, with minimal changes to make up for the substitution of portmap for rpcbind in debian. Hopefully it'll be clearer. Also, nfs is such a universally useful thing that it should be promoted among a wider audience.

I followed this post to get up and running (scroll down) with nfs. Here's my take on it:

UPDATE: with the first comment below in mind, I changed this post a little bit. The folder /shared on the master node is shared with the client, which mounts it under /home/me/shared, instead of sharing the folder /home/me/shared on the host and mounting it as /home/me/shared on the client. I basically want to drive home the message that you're mounting an NFS share in the same way as any other disk resource -- you can mount it in whatever location you want, regardless of where the folder is found on the host.

Server
On the master node (here: 192.168.1.1 - beryllium) which hosts the shared folder on its harddrive:
sudo apt-get install nfs-kernel-server nfs-common rpcbind

Let's share /shared

Create it
sudo mkdir /shared

Set permissions for 'all' to be read, write and execute
sudo chmod a+wrx /shared

Edit /etc/exports by adding a line to the end of the file
/shared *(rw,sync)



[Note that this (the *) is inherently insecure. You should restrict access to the NFS mounts via your firewall (e.g. using iptables with -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 2049 -j ACCEPT;  -A INPUT -s 192.168.1.0/24 -p udp -m udp --dport 111 -j ACCEPT for a local subnet 192.168.1.1-255).  You can also use 
/shared 192.168.1.0/24(rw,sync)

to restrict it similarly directly via /etc/exports. There are more things that can be done, see e.g. here and here. If you are running a cluster with a separate subnet, this is not a great worry. If you are in a situation where security is important, consider using sshfs instead.]

Make stuff happen:
sudo /etc/init.d/nfs-kernel-server restart
sudo exportfs -a

Client
On each client node:
sudo apt-get install rpcbind nfs-common
mkdir ~/shared

Add the following line to the end of /etc/fstab
beryllium:/shared /home/me/shared nfs   rw   0   0

You can mount in a different location if needed -- server:serverfolder localfolder nfs rw 0 0

To get it up and running immediately instead of waiting for reboot:
sudo mount ~/shared


That's it!

Links to this page:
http://forums.debian.net/viewtopic.php?f=5&t=84889

08 February 2012

61. Keeping time with ntp on debian



Set-up
NTP is used to accurately sync the clock on your computer and keep it current.

Install ntp if you haven't already
sudo apt-get install ntp ntpdate
the configuration file is in /etc/ntp.conf

You can have a look through the ntp.conf file and change the server lines to something closer to home if necessary -- you can find server pools for different regions here: http://www.pool.ntp.org/en/

If your clock is off by too much, syncing won't work, so you might want to do this to sync up the first time:

sudo service ntp stop
sudo ntpdate -u 0.pool.ntp.org

 8 Feb 16:28:42 ntpdate[10484]: step time server 121.0.0.41 offset -648.353916 sec

compare the output of date with e.g http://worldtimeserver.com



Now, start the ntp server again:

sudo service ntp start


Running your own local ntp server for your LAN

The NTP daemon will (presumably) run happily in the background and gradually adjust the time if it's off.
For a sub-LAN  you may want to sync e.g. the gateway to the ntp pool, then sync all the local computers to the gateway in order to cut down on traffic, like so.

Here's my version of that link:
server:
Here's /etc/ntp.conf on my server, which is seen as 192.168.1.1 by the local subnet (connected to inet on eth0 and subnet on eth1) . The last two lines were important to get it to work.

driftfile /var/lib/ntp/ntp.drift
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
server 0.oceania.pool.ntp.org
server 1.oceania.pool.ntp.org
server 2.oceania.pool.ntp.org
server 3.oceania.pool.ntp.org
restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery
restrict 127.0.0.1
restrict ::1
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
broadcast 192.168.1.255
server 127.127.1.0
fudge 127.127.1.0 stratum 10

sudo service ntp restart
and you're good to go

client:
/etc/ntp.conf
driftfile /var/lib/ntp/ntp.drift
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
server 192.168.1.1
restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery
restrict 127.0.0.1
restrict ::1
restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
disable auth
broadcastclient
sudo service ntp restart

Checking if the client is connecting to the server.
me@kookaburra:~$ sudo service ntp stop
Stopping NTP server: ntpd.
me@kookaburra:~$ sudo ntpdate 192.168.1.1
 8 Feb 17:22:35 ntpdate[12846]: adjust time server 192.168.1.1 offset -0.008602 sec
me@kookaburra:~$ sudo service ntp start
Starting NTP server: ntpd.
me@kookaburra:~$ sudo ntpq -p
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 beryllium       LOCAL(0)        11 u    2   64    1    0.189   -7.332   0.000

(beryllium is the name of my 192.168.1.1 server.)