Friday, March 5, 2010

How to setup a linux VM to act as a router

Objective: To become more familiar with Linux distros and to configure a linux machine to work as a router using DHCP, DNS, and IPTables doing NAT.

Materials:
  • Computer with two network interfaces (I will be using a MacBook laptop)
  • Virtualbox or Vmware (optional: I will be using Virtualbox for this tutorial)
  • Linux distro of your choice (I will be using Ubuntu Server 8.10)
  • At least one other machine to test your internal interface (I will be using a Dell D600 with Ubuntu Desktop installed)

Requirements:
Part 1 –
  1. Setup your linux machine with two network interfaces: eth0 and eth1. Interface eth0 will be your external (WAN) interface and eth1 will be your internal (LAN) interface.
  2. Configure eth0 to use dhcp
  3. Configure eth1 to use static settings with the following specs:
  4. IP address: 10.1.1.1
  5. Subnet Mask: 255.255.255.0

Part 2 –
  1. Install DHCP:
  2. Run this service on eth1 only.
  3. Set your IP address range between 10.1.1.100 and 10.1.1.200 with subnet mask 255.255.255.0
  4. Have your test machine always use IP 10.1.1.5
  5. Install DNS:
  6. Set the host name it347 to ping 10.1.1.5

Part 3 –
  1. Use iptables to forward all traffic from eth1 to eth0 so internet access is available to your internal network (this is the part that makes your machine a router and not just a switch)

Procedure:
Part 1 –
  1. First you will need to install your OS and make sure it is setup with two network interfaces. To do this with Virtualbox and Ubuntu Server 8.10 on a Macbook follow these steps:
  2. Download and Install Virtualbox
  3. Download Ubuntu Server 8.10 iso file
  4. In Virtualbox click on the ‘New’ button
  5. Follow the steps to make a new machine (I used the following settings):
  6. Name: it347router
  7. Operating System: Linux
  8. Version: Ubuntu
  9. Base Memory Size: 192 MB
  10. Boot Hard Disk: checked
  11. Create new hard disk
  12. Dynamically expanding storage
  13. Size: 8.00 GB
  14. Now your machine is created and you need to configure the other settings
  15. Under ‘Details’ click on ‘Network’
  16. Set Adapter 1 ‘Attached to’ to ‘NAT’ (this is necessary for my machine to get DHCP while using campus wireless; if you don’t have public wireless restrictions you can try setting this to ‘Bridged’ and then set ‘Name’ to ‘en1: AirPort’ but make sure you know what you’re doing first)
  17. Set Adapter 2 to ‘Enable Network Adapter’ and set ‘Attached to’ to ‘Bridged Adapter’ and 'Name’ to ‘en0: Ethernet’
  18. Click ‘OK’
  19. Now click on ‘Storage’
  20. Click on the disc that says ‘Empty’
  21. Pull up the Virtual Media Manager by clicking on the folder icon next to ‘CD/DVD Device’
  22. Click ‘Add’ and browse to your iso file
  23. Click ‘Select’
  24. Click ‘OK’
  25. Now you can start your machine and install Ubuntu Server. This will take a while. Just follow the steps and make sure you remember the username and password you give it.
  26. You should now be running Ubuntu Server in Virtualbox with two network adapters. To verify you have two adapters in the VM use the command ifconfig -a and if you see both eth0 and eth1 then you are good. If you don’t then you did something wrong or skipped a step, most likely you forgot to add the extra adapter to the vm settings.
  27. Next you need to configure the interfaces
  28. Open the interfaces configuration by typing the command sudo nano /etc/networking/interfaces
  29. Setup your configuration to look like the file seen in “/etc/network/interfaces” in Appendix A
  30. Restart your network settings by typing the command sudo /etc/init.d/networking restart
  31. Verify that eth1 is now using the IP 10.1.1.1 and that eth0 is getting an address through DHCP by checking ifconfig
  32. Verify that your internet works: ping google.com
  33. That’s it! Move on to part 2

Part 2 –
  1. Install DHCP
  2. First make sure your packages are up to date: sudo apt-get update
  3. Install dhcp3-server: sudo apt-get install dhcp3-server
  4. Say yes to all the questions
  5. Configure DHCP
  6. Define the interface to use DHCP
  7. Type the command sudo nano /etc/default/dhcp3-server and make a line that says INTERFACES=”eth1” (See “/etc/default/dhcp3-server” in Appendix B)
  8. Now edit the dhcp configuration to use your settings
  9. Type the command sudo nano /etc/dhcp3/dhcpd.conf and edit the file to look like “/etc/dhcp3/dhcpd.conf” seen in Appendix B. For the it347 host hardware-ethernet you will need to use the MAC address of your test laptop’s ethernet
  10. Restart your DHCP server: sudo /etc/init.d/dhcp3-server restart
  11. If it fails it is most likely due to syntax errors and it should tell you on the command line where and what the error is. If not, you can check the syslog: cat /var/log/syslog | grep dhcp
  12. Install DNS
  13. Install bind9: sudo apt-get install bind9 and say yes to everything
  14. Configure DNS
  15. Stop DNS: sudo /etc/init.d/bind9 stop
  16. Change your named.conf.local to look like the file “/etc/bind/named.conf.local” seen in Appendix B
  17. This will be adding two zones, one for your domain and one for the reverse lookup for your subnet
  18. Create a zones directory to store your db files: sudo mkdir /etc/bind/zones
  19. Create the first db file: sudo nano /etc/bind/zones/db.sanpaco.org and make it look like “/etc/bind/zones/db.sanpaco.org” seen in Appendix B
  20. Create the reverse lookup db file: sudo nano /etc/bind/zones/db.1.1.10 and make it look like “/etc/bind/zones/db.1.1.10” seen in Appendix B
  21. Start DNS up again: sudo /etc/init.d/bind9 start
  22. If it starts up then check the syslog to make sure no errors were thrown: cat /var/log/syslog | grep bind The server might start fine but not tell you about syntax errors in your db files
  23. Optional: if you would like to specify a secondary DNS to use for anything not found in your DNS, you can specify which server to use in the named.conf.options file. Just look for the section with forwarders and uncomment it and change the 0.0.0.0 address to the address of the alternate DNS lookup server
  24. Test your settings
  25. Plug the test laptop into the Macbook Ethernet port.
  26. Your test laptop should be getting an IP address in the range specified, most likely it will be getting 10.1.1.101
  27. Try pinging your test laptop from the Macbook server: ping it347
  28. You should be getting a response, if not then something is not configured correctly. Do troubleshooting and cry your eyes out until you figure it out.
  29. That’s it! Move on to part 3.

Part 3 –
  1. First you need to allow IP forwarding: sudo nano /proc/sys/net/ipv4/ip_forward change the 0 to a 1 and save
  2. Configure IPTables
  3. sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
  4. sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
  5. sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
  6. Test that the settings are working by trying to ping from an internal computer (your test laptop)
  7. If it works, change your kernel settings to allow ip forwarding automatically on boot: sudo nano /etc/sysctl.conf and change the line that says net.ipv4.ip_forward = 0 to net.ipv4.ip_forward = 1
  8. Setup your iptables to automatically apply these rules on startup
  9. Save the rules to a file: ‘sudo iptables-save > /etc/iptables.natrules’ (you might need to log in as root for this to work, if so just do ‘sudo -s’ and then ‘exit’ when you are done)
  10. Now edit your interfaces file to look like “/etc/network/interfaces” in Appendix C
  11. The only change is the pre-up line which applies the stored rules on bootup
  12. Reboot your server and test again to make sure everything is still working and the NAT rules persisted.
  13. sudo iptables –L
  14. sudo iptables –t nat -L
  15. That’s it! You are done!

Personal troubleshooting and issues:
Part 1 –
For the first section of this project I ran into mostly problems due to certain limitations of Virtualbox. It turns out that when you move a Virtualbox machine, the interfaces change numbers. Originally I was working around this by editing my interfaces file and stuff everytime I move the machine but this was getting quite cumbersome. A related problem I was having was that the eth0 was not getting internet from the main system. I finally fixed this by adding the network adapters as bridged adapters. This brought up another issue which I ran into in part 3 and I will discuss it when I get to it.

I learned some interesting stuff about networking in linux with this project like using the interfaces file for adapter settings and how to restart networking (ipconfig release and renew in windows)

Part 2 –
This was easily the hardest section of the project. Getting DHCP to work was relatively simple. Originally I had started doing the project on Debian and I was getting an error when I tried installing dhcp3-server saying it required lenny3 but was finding lenny4 instead. After a lot of troubleshooting I found the command sudo apt-get autoclean and then sudo apt-get update to completely flush all the packages and renew them. This fixed the error and I was able to install DHCP

After I initially got DHCP working, I had to make changes throughout in order to reflect some of my DNS settings. I had to add the zones to DHCP. I also learned that it is usually safest to just use IP addresses in the config files.

The DNS portion was much more difficult. I tried all kinds of things to get my DNS working but couldn’t get it. I had gotten to a point where I just didn’t have any idea what or where the error was because bind was starting ok. This was when I learned about syslog. Syslog is my friend. It was giving me an error about an end of line and I found that if I added root.mydomain.com. after the ns.mydomain.com. in the first line of the db file that fixed the error. I also had a few lines out of order in the actual db settings and was able to get them right. You have to put the ‘@ IN NS’ line first and then the ‘@ IN A’ line. Also you can’t point two different names to the same IP address. If you want two names for the same IP you use one for the A line and then you put a CNAME to the other name. The last problem I had with DNS which finally got things working was that I was not putting the full path to my db file in the named.conf.local file. I thought that since the db file was in the same directory that it would be able to find it.

Part 3 –
I had two pretty simply problems with this part. First was getting the iptables to persist on a reboot. I was able to find an explanation online that told how to do a pre-up in the interfaces file which would restore the rules before bringing the interface up on boot. The second problem I had was actually because of BYU’s wireless. I got everything working originally at my house, using my own wireless connection for my eth0 connection. It was passing DHCP to my virtual machine just fine and I even used my test laptop to surf the internet for a while. But when I came in the next day to pass off, suddenly it was not working anymore. I checked and found that eth0 was no longer getting DHCP. My Macbook was getting an ip from BYU-Guest and BYU-Secure and even IT-Wireless G but when I did networking restart on the VM it would get to ‘eth0 DHCPDISCOVER’ and timeout. I was able to fix the problem by changing the Virtualbox settings for the Network adapter. I changed it from bridged to NAT. My VM now gets DHCP using NAT while on campus. Obviously I have to authenticate on the Mac side first for the internet to actually work.

Conclusion:
This was a very helpful lab for me. I learned a lot more about linux than I knew before and feel more comfortable being able to use it in the future. I also learned a lot about configuring DHCP and DNS and how to use the network features in linux. I have already repeated many of the steps of this lab multiple times and feel confident that I could do so at anytime. I also feel confident that I will be using this knowledge in my own personal networking and also professionally later on. I look forward to learning more about other features and how to configure them as well, and while I didn’t finish the extra credit in time for points, I’m still going to work on them because of the practical value they both provide beyond simply getting extra credit.


APPENDICES

Appendix A (files from part 1)

/etc/network/interfaces:
There is one change to be made in this file which will be seen in Appendix C.

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet static
address 10.1.1.1
netmask 255.255.255.0
dns-nameservers 10.1.1.1

Appendix B (files from part 2)

/etc/default/dhcp3-server:
# Defaults for dhcp initscript
# sourced by /etc/init.d/dhcp
# installed at /etc/default/dhcp3-server by the maintainer scripts

#
# This is a POSIX shell fragment
#

# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
# Separate multiple interfaces with spaces, e.g. "eth0 eth1".
INTERFACES="eth1"


/etc/dhcp3/dhcpd.conf:
There are a bunch of lines in the file that are commented out and give descriptions of how to configure DHCP. I have left these out and only included the lines uncommented.

ddns-update-style interim;

# option definitions common to all supported networks...
option domain-name "sanpaco.org";
option domain-name-servers 10.1.1.1;

default-lease-time 600;
max-lease-time 7200;

subnet 10.1.1.0 netmask 255.255.255.0 {
range 10.1.1.100 10.1.1.200;
option subnet-mask 255.255.255.0;
option routers 10.1.1.1;
option domain-name "sanpaco.org";
option domain-name-servers 10.1.1.1;
option broadcast-address 10.1.1.255;

zone 1.1.10.in-addr.arpa. {
primary ns.sanpaco.org;
}

zone sanpaco.org. {
primary ns.sanpaco.org;
}

host it347 {
hardware ethernet 00:0b:db:05:1d:5a;
fixed-address 10.1.1.5;
}
}


/etc/bind/named.conf.local:
//
// Do any local configuration here
//

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

zone "sanpaco.org" {
type master;
file "/etc/bind/zones/db.sanpaco.org";
};

zone "1.1.10.in-addr.arpa" {
type master;
file "/etc/bind/zones/db.1.1.10";
};


/etc/bind/zones/db.sanpaco.org:
$TTL 604800
@ IN SOA ns.sanpaco.org. root.sanpaco.org. (
2010030301
7200
120
2419200
604800 )
;
@ IN NS ns.sanpaco.org.
@ IN A 10.1.1.1
ns IN A 10.1.1.1
it347 IN A 10.1.1.5



/etc/bind/zones/db.1.1.10:
$TTL 3D
@ IN SOA sanpaco.org. root.sanpaco.org. (
2010030301
3600
300
172800
43200 )
;
@ IN NS ns.sanpaco.org.
@ IN PTR sanpaco.org.
5 IN PTR it347.sanpaco.org.



Appendix C (files from part 3)

/etc/iptables.natrules:
# Generated by iptables-save v1.4.0 on Thu Mar 4 00:32:08 2010
*nat
:PREROUTING ACCEPT [2:156]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
# Completed on Thu Mar 4 00:32:08 2010
# Generated by iptables-save v1.4.0 on Thu Mar 4 00:32:08 2010
*filter
:INPUT ACCEPT [104:12355]
:FORWARD ACCEPT [25:1738]
:OUTPUT ACCEPT [90:7662]
-A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i eth0 -j ACCEPT
COMMIT
# Completed on Thu Mar 4 00:32:08 2010


/etc/sysctl.conf:
All that is changed from the default here is the line net.ipv4.ip_forward=1 was uncommented

#
# /etc/sysctl.conf - Configuration file for setting system variables
# See /etc/sysctl.d/ for additional system variables.
# See sysctl.conf (5) for information.
#

#kernel.domainname = example.com

# Uncomment the following to stop low-level messages on console
#kernel.printk = 4 4 1 7

##############################################################3
# Functions previously found in netbase
#

# Uncomment the next two lines to enable Spoof protection (reverse-path filter)
# Turn on Source Address Verification in all interfaces to
# prevent some spoofing attacks
#net.ipv4.conf.default.rp_filter=1
#net.ipv4.conf.all.rp_filter=1

# Uncomment the next line to enable TCP/IP SYN cookies
# This disables TCP Window Scaling (http://lkml.org/lkml/2008/2/5/167),
# and is not recommended.
#net.ipv4.tcp_syncookies=1

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

# Uncomment the next line to enable packet forwarding for IPv6
#net.ipv6.conf.all.forwarding=1


###################################################################
# Additional settings - these settings can improve the network
# security of the host and prevent against some network attacks
# including spoofing attacks and man in the middle attacks through
# redirection. Some network environments, however, require that these
# settings are disabled so review and enable them as needed.
#
# Ignore ICMP broadcasts
#net.ipv4.icmp_echo_ignore_broadcasts = 1
#
# Ignore bogus ICMP errors
#net.ipv4.icmp_ignore_bogus_error_responses = 1
#
# Do not accept ICMP redirects (prevent MITM attacks)
#net.ipv4.conf.all.accept_redirects = 0
#net.ipv6.conf.all.accept_redirects = 0
# _or_
# Accept ICMP redirects only for gateways listed in our default
# gateway list (enabled by default)
# net.ipv4.conf.all.secure_redirects = 1
#
# Do not send ICMP redirects (we are not a router)
#net.ipv4.conf.all.send_redirects = 0
#
# Do not accept IP source route packets (we are not a router)
#net.ipv4.conf.all.accept_source_route = 0
#net.ipv6.conf.all.accept_source_route = 0
#
# Log Martian Packets
#net.ipv4.conf.all.log_martians = 1
#
# The contents of /proc//maps and smaps files are only visible to
# readers that are allowed to ptrace() the process
# sys.kernel.maps_protect = 1

/etc/network/interfaces:
Again only one change here. The line pre-up iptables-restore < /etc/iptables.natrules was added.

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp
pre-up iptables-restore < /etc/iptables.natrules auto eth1 iface eth1 inet static address 10.1.1.1 netmask 255.255.255.0 dns-nameservers 10.1.1.1