wiki:sysadminiptables

Version 17 (modified by risard, 13 years ago) (diff)

--

Networking Issue

Quick Reference


Overview
Reading iptables
Configuring iptables
Testing Your Config
Necessary Ports - Database Server
Necessary Ports - Open-ils Server
References


Overview

Network security is an important aspect of any distributed database, particularly one in which patron data is kept. Like any computer these days, Linux servers come with a configurable firewall referred to generically as iptables. The following is a description of the ports that need to be opened via iptables for Evergreen to work. Iptables is a very complicated topic that can take you into the darkest depths of packet routing and network configuration. What follows is a simple primer that will allow you to get work done on Evergreen. For more information see References section. The assumption here is a two server (database and oils) configuration. For security reasons, I've changed the ip addresses and host names in the examples below.

NOTE: Our ISP keeps our production servers behind a substantial firewall and coordination with them is essential. Any ports you open via iptables, also need to be opened in their firewall. This is done by contacting support after you've configured iptalbes.


Reading iptables

    sudo iptables -L

or

    sudo iptables -L -n

The latter command will generate exactly the same list as the former except the -n (numbers) switch renders the list of addresses in dot decimal form. Without -n the entries in the list are shown as hostnames. So with with iptables -L you see something like this:

    target     prot opt source        destination
    ACCEPT     tcp  --  larry.isp.ca  curly.isp.ca dpt:ssh
    ACCEPT     tcp  --  moe.isp.ca  curly.isp.ca tcp dpt:ssh
    ACCEPT     tcp  --  larry.isp.ca curly.isp.ca tcp dpt:2301
    ACCEPT     tcp  --  moe.isp.ca  curly.isp.ca tcp dpt:2301

The same output with the -n option:

    target     prot     source               destination
    ACCEPT     tcp  --  10.104.94.4         10.104.100.168     tcp dpt:22
    ACCEPT     tcp  --  10.104.94.8         10.104.100.168     tcp dpt:22
    ACCEPT     tcp  --  10.104.94.4         10.104.100.168     tcp dpt:2301
    ACCEPT     tcp  --  10.104.94.8         10.104.100.168     tcp dpt:2301

NOTE: that the command requires the use of sudo to use.

The output of either command will group the lines above into three sections called "chains". Each chain represents inbound packets (Chain INPUT), outbound packets (Chain OUTPUT) and packets that are to be passed transparently to other machines (Chain FORWARD). The only one you should concern yourself with, and the only one being used on this page or in these examples is Chain INPUT. We're only concerned with being able to accept packets from other machines.

You will also notice several special lines that have "state" listed as their destination, likely with ESTABLISHED, RELATED or something similar. These are special entries and should never be modified by you. In addition, you will see a lot of entries for "dpt:22" or "dpt:ssh". Never change these without consultations from your fellow Conifer admins! These entries allow for ssh access between the various servers and allow you to ssh into the machines. If you remove them, you will not be able to interact remotely with the server anymore! If this happens, you need to call our isp, and have them fix it.

The output is easier to read from right to left. dpt = "destination port" so

    target     prot opt source        destination
    ACCEPT     tcp  --  larry.isp.ca  curly.isp.ca dpt:ssh

reads

"packets destined for the tcp ssh port on curly - that are from larry - should be accepted."


Configuring iptables

In Debian Lenny there are two ways to change iptables. You can edit the tables interactively at the shell using the iptables command and then save them with iptables-save command, or you can edit the file where the tables are stored directly and then apply them.

NOTE: that when you use the iptables command, you're changes are live.

The iptables command

The iptables syntax is as follows:

    sudo iptables -A INPUT -s 10.104.100.167 -d 10.104.100.168 -p tcp -m tcp --dport 8023 -j ACCEPT    

The command above can be broken down as follows:

-A INPUTsays the rule should be appended to Chain INPUT
-s 10.104.100.167the source of the packet is the machine found at 10.104.100.167
-d 10.104.100.168means the destination machine is 10.104.100.168
-p tcpmeans the rule is concerned with the tcp protocol (so a udp packet coming in on port 8023 wouldn't be addressed by this rule)
-m tcpthis means load the rules that match the listed protocol, in this case tcp. Although this isn't strictly necessary since we've specified the protocol with the -p option, it's considered good form to use it, and our ISP does use it, so we should too.
--dport 8023This rule concerns itself with packets destined for port 8023.
-j ACCEPTif a packet matches the rules above, then "jump" to the ACCEPT command, in other words, accept the packet.

If you ran the above command, it would immediately add a rule to the iptables INPUT chain. If you ran iptalbes -L, you'd see your new rule in the list.

If you want to delete a rule simply write it as is, but with a -D at the beginning rather then -A:

   sudo iptables -D INPUT -s 10.104.100.167 -d 10.104.100.168 -p tcp -m tcp --dport 8023 -j ACCEPT

Deletes the rule we used in the example above.

Although the above looks complicated, it should be noted that the only parts you should ever be changing are the -s, -d and --dport options. If you feel the need to change anything else, you should ask your fellow Evergreen Admins about it first!

Once you've edited the rules to your liking, you need to save them to a file. You do this with the following command:

    sudo iptables-save > /<path>/<firewall_file>

This will save your changes to the file listed on the right.

Editing the file

We keep our iptables rules in a configuration file. For the name and location, ask your fellow Evergreen admins. When you open the file, it simply looks like a list of iptable commands, just like the ones you'd type at the command line. You can open the file with:

    sudo vim firewall_file

Once opened, you can just add a line to the file and save it. It's important to remember that the order in which the rules are listed is important. You'll notice that the rules in each chain are listed with the ACCEPT rules before the REJECT rules. If you add an ACCEPT rule after a REJECT rule, it won't get read when the rules are loaded into memory.

Once you've edited the file and saved it, you can apply the changes with:

    iptables-restore < /<path>/<firewall_file>

Testing Your Config

The easiest way to ensure a port is open is to use nmap.

NOTE: although nmap is a valid networking diagnotic tool, it's also a very controversial tool. PLEASE use with discretion!

You can test the status of a port by running the following command from another machine:

    sudo nmap 10.0.0.1 -sS -p 5432 

The command above tests the 5432 port on computer 10.0.0.1. The return is something like:

    Interesting ports on 10.0.0.1:
    PORT     STATE SERVICE
    5432/tcp open  postgresql
    
    Nmap done: 1 IP address (1 host up) scanned in 0.169 seconds

The output above lists the port as STATE: open. This means the iptables rules are working properly. If STATE returns "filered" or "closed", the port isn't open and you need to revisit your iptalbe rules.

NOTE: if the port returns "open" but you still can't get a connection from the service you want (ie port 5432 is open but you still can't get a connection to postgres from another machine) then be sure to check that another service isn't running on the port:

    netstat -an | grep 5432

On a typical machine running a webserver the above command should return a line like:

    tcp        0      0 0.0.0.0:5432      0.0.0.0:*               LISTEN

The important things here are:

  1. The protocol is correct - tcp. If tcp6 is running for example (IPv6) then the connection will not likely work.
  1. The service is listening on the correct ip. If the entry was 127.0.0.1:5432 you wouldn't get a connection because it's only listening to the localhost. 0.0.0.0:5432 or the machine's public IP are acceptable.
  1. The service is listening for connections from where ever you're trying to connect from. In this case it will take a connection from anywhere (0.0.0.0:*). It's important to ensure that the machine isn't listening for a connections from a specific machine (ie. 10.0.0.2:*) or if it is, then it's the machine you're trying to connect from.
  1. The port is actually in the LISTEN state.

If netstat checks out and you still can't connect to the service you think you should be connecting to on that port, check to see if the service is in fact running with;

   ps aux | grep postgresql

In this example, you should see a line like:

    postgres 21296  0.0  0.0 100608  5784 ?        S    May28   0:01 /usr/lib/postgresql/8.3/bin/postgres -D /<path>/main

This will change depending on the service you're running, but will coincide with the command you ran to start the service. (So in the example above, the command to start postgres was obviously: /usr/lib/postgresql/8.3/bin/postgres -D /<path>/main)


References

http://iptables-tutorial.frozentux.net/iptables-tutorial.html http://www.5dollarwhitebox.org/wiki/index.php/Howtos_Basic_IPTables http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch14_:_Linux_Firewalls_Using_iptables


Quick Reference

Commands

# list rules

    sudo iptables -L
    sudo iptables -L -n     

# iptable command syntax

    iptables -A INPUT -s 10.104.100.167 -d 10.104.100.168 -p tcp -m tcp --dport 8023 -j ACCEPT

# save
    
    sudo iptables-save > /<path>/<firewall_file>

# apply

    sudo iptables-restore < /<path>/<firewall_file>    

Necessary Ports - Database Server

    -A INPUT -s <oils_server> -p tcp -m tcp --dport 5432 -j ACCEPT    #connection allowing oils server to access dbase

Necessary Ports - Open-ils Server

    -A INPUT -d 0.0.0.0/0 -p tcp -m tcp --dport 80 -j ACCEPT     #http access to opac
    -A INPUT -d 0.0.0.0/0 -p tcp -m tcp --dport 443 -j ACCEPT    #ssl access to opac
    -A INPUT -d 0.0.0.0/0 -p tcp -m tcp --dport 6001 -j ACCEPT   #SIP
    -A INPUT -d 0.0.0.0/0 -p tcp -m tcp --dport 8080 -j ACCEPT   #SIP
    -A INPUT -d 0.0.0.0/0 -p tcp -m tcp --dport 8023 -j ACCEPT   #SIP
    -A INPUT -d 0.0.0.0/0 -p tcp -m tcp --dport 210 -j ACCEPT    #Z39.50    

# Note, there are other necessary ports but these should only be configured by the ISP