Showing posts with label sharing internet connection. Show all posts
Showing posts with label sharing internet connection. Show all posts

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

17 January 2012

50. Sharing an internet connection over a network switch on debian

What it does: One computer has two network cards. One card is used to connect to the internet, the other one is connected to a switch making up a local network. Two more computers are connected to the switch. They all share the internet connection of the first computer. All computers on the local network can ssh into each other.

I have to register the MAC address of each computer which I want to connect to the network at work. The reason probably has more to do with cost than security.

I do not use /etc/network/interfaces in this example
Instead we're only using Network Manager, but from the CLI.

The sharing is enabled using Firestarter. You can probably figure out how to use it yourself without reading this rather lengthy post, but I'll leave it all up here in case you want to know the exact configuration.

Since I use apt-cache to cut down on network traffic (http://verahill.blogspot.com/2012/01/debian-testing-64-wheezy-apt-cache.html) I don't feel too bad about surreptitiously putting a few additional units online.

This is my network:

internet ----- eth0 -Beryllium - eth2 --- switch----( eth0-tantalum, eth0-boron)

Or in words --  I have three computers. One, Beryllium, has two network cards, eth0 and eth1. eth0 is connected to the internet (dhcp). eth1 is connected to a gigabit switch (essentially a dumb router -- no dhcp). Two more computers are connect to the same switch -- Tantalum (eth0) and Boron (eth0). Tantalum has local ip address 192.168.1.102 and Boron has ip address 192.168.1.101.

I do have an additional ethernet card on Beryllium, eth1, which we will ignore.

This way of sharing an internet connection relies on firestarter, which has one problem -- it won't (easily) allow two network cards on the same local network i.e. if eth0 is connected to the internet and you want both eth1 and eth2 on the same local network, firestarter won't help you.

I also need to be able to ssh from any computer on the local network to any other computer on the local network. This method allows for that. Same goes for apt-cache and mpich.

To satisfy my paranoia I've replaced a lot of the more incriminating numbers with X's.


Firestarter:
Firestarter is a firewall -- you'd typically use it to restrict traffic, not enable it. But iptables -- the true firewall and traffic shaper of linux -- is a powerful and slightly odd beast, and firestarter provides a gui-friendly way of editing some aspects of it.

Install firestarter on your internet connected computer (here, beryllium):
sudo apt-get install firestarter

Start it:
sudo firestarter

Chances are it will ask you questions about internet connected network device -- which is eth0 -- and local network connected device -- here it's eth2. Also, check Enable internet connection sharing. If it doesn't ask you, go to Edit, Preferences and select Firewall -- Network Settings.

In my case I've set it up for static ip. I would suspect it to be fairly easy to set up dhcp as well.

I don't know how to put TWO network cards from the same computer on the same local network.

In the main firestarter windows, under policy, you might want to add the IP addresses of the computers on the local network under 'Allow connections from host' -- but that depends on your needs. I prefer to expose all ports in order to deal with mpich.

You may also want to edit what services are allowed. Firestarter is fairly simple to use.


Configuration: Beryllium
eth0 is connected to the internet, and is assigned an IP address by the university using dhcp.
eth2 is connect to the switch and I've manually set the IP address to 192.168.1.1 in network manager. You can edit the file (see below) directly.

The gateway for eth2 is set to 192.168.1.1. Subnet mask is 255.255.255.0 which shows up as 24 in the configuration file below (i.e. 192.168.1.1;24;192.168.1.2 would mean IP 192.168.1.1, subnet 255.255.255.0 and gateway 192.168.1.2)

sudo cat /etc/NetworkManager/system-connections/eth0
[802-3-ethernet]
duplex=full
mac-address=XX:XX:XX:XX:XX:XX
[connection]
id=eth0
uuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
type=802-3-ethernet
timestamp=1326324509
[ipv6]
method=auto
[ipv4]
method=auto


sudo cat /etc/NetworkManager/system-connections/eth2
[802-3-ethernet]
duplex=full
mac-address=XX:XX:XX:XX:XX:XX
[connection]
id=eth2
uuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
type=802-3-ethernet
timestamp=1326690564
[ipv6]
method=auto
[ipv4]
method=manual
addresses1=192.168.1.1;24;192.168.1.1;

Configuration: Tantalum
sudo cat /etc/NetworkManager/system-connections/eth0

[802-3-ethernet]
duplex=full
mac-address=XX:XX:XX:XX:XX:XX
[connection]
id=lan
uuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
type=802-3-ethernet
timestamp=1326152420
[ipv6]
method=auto
[ipv4]
method=manual
dns=XXX.XXX.1.99;
addresses1=192.168.1.102;24;192.168.1.1;


Configuration: Boron
sudo cat /etc/NetworkManager/system-connections/eth0

[802-3-ethernet]
duplex=full
mac-address=XX:XX:XX:XX:XX:XX
[connection]
id=lan
uuid=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
type=802-3-ethernet
timestamp=1326152420
[ipv6]
method=auto
[ipv4]
method=manual
dns=XXX.XXX.1.99;
addresses1=192.168.1.101;24;192.168.1.1;

Quick word on apt-cache:
If you follow this guide: http://verahill.blogspot.com/2012/01/debian-testing-64-wheezy-apt-cache.html
and you're running your apt-cache server on 192.168.1.1 in the example above, change your /etc/apt/sources.list so that
deb http://192.168.1.2:3142/ftp.au.debian.org/debian/ testing main contrib non-free
becomes
deb http://192.168.1.2:3142/ftp.au.debian.org/debian/ testing main contrib non-free