Version 24 (modified by risard, 14 years ago) (diff)


Networking Issues

Quick Reference

Reading iptables
Configuring iptables
Testing Your Config
Special Postgresql Issues

Allowing Remote Connections
Installing JSON::XS

Necessary Ports - Database Server
Necessary Ports - Open-ils Server


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


    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  -- dpt:ssh
    ACCEPT     tcp  -- tcp dpt:ssh
    ACCEPT     tcp  -- tcp dpt:2301
    ACCEPT     tcp  -- tcp dpt:2301

The same output with the -n option:

    target     prot     source               destination
    ACCEPT     tcp  --     tcp dpt:22
    ACCEPT     tcp  --     tcp dpt:22
    ACCEPT     tcp  --     tcp dpt:2301
    ACCEPT     tcp  --     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  -- dpt:ssh


"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 -d -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 source of the packet is the machine found at
-d the destination machine is
-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 -d -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 -sS -p 5432 

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

    Interesting ports on
    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*               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 you wouldn't get a connection because it's only listening to the localhost. 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 (*). It's important to ensure that the machine isn't listening for a connections from a specific machine (ie.*) 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)

Special Postgresql Issues

Allowing Remote Connections

With postgres, you also need to specifically allow remote hosts to access the server.

To begin with, you need to tell postgres to listen for connections from other hosts rather then just the localhost (the default).

As the postgres user, edit postgresql.conf:

    sudo vim /etc/postgresql/8.3/main/postgresql.conf


    #listen_addresses = ‘localhost’


    listen_addresses = ‘<ip address of oils server>’

Next, edit pg_hba.conf:

    sudo vim /etc/postgresql/8.3/main/pg_hba.conf

and in the area marked "Put your actual configuration here," enter the following:

    # Put your actual configuration here
    # ----------------------------------
    # If you want to allow non-local connections, you need to add more
    # "host" records. In that case you will also need to make PostgreSQL listen
    # on a non-local interface via the listen_addresses configuration parameter,
    # or via the -i or -h command line switches.

    host    evergreen       evergreen      md5
connection type in this example, host is used. This means postgres should be looking for a TCP connection (rather then a Unix socket connection for example)
databasethe name evergreen is being used in this example
useragain, in our hypothetical example, evergreen is the username
addressthe ip address or host name of the machine that's allowed to make a connection. In real life, this would be the oils server address
authentication optionsin this case md5 is used, meaning the password is encrypted

After editing and saving both files, you need to restart postgres.

Installing JSON::XS

Again, assuming a two server setup with Open-ils on one and postgres on the other, you need to ensure that the database server can actually communicate with the oils server.

To begin with, you need to install the JSON::XS perl module on the database server. This allows the database server to exchange JSON messages with the oils server.

Make sure you've got a compiler installed first:

    which gcc

If you don't, install one:

    apt-get update
    apt-get install gcc

Next install the mod from CPAN:

    perl -MCPAN -e 'CPAN::Shell→install(“JSON::XS”)'

Accept the defaults.

Once again, you should run on the oils server to update opac and Staff Client files. Do this on the oils server as the opensrf user with oils up and running.


Quick Reference


# list rules

    sudo iptables -L
    sudo iptables -L -n     

# iptable command syntax

    iptables -A INPUT -s -d -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 -p tcp -m tcp --dport 80 -j ACCEPT     #http access to opac
    -A INPUT -d -p tcp -m tcp --dport 443 -j ACCEPT    #ssl access to opac
    -A INPUT -d -p tcp -m tcp --dport xx -j ACCEPT   #SIP
    -A INPUT -d -p tcp -m tcp --dport xx -j ACCEPT   #SIP
    -A INPUT -d -p tcp -m tcp --dport xx -j ACCEPT   #SIP
    -A INPUT -d -p tcp -m tcp --dport xx -j ACCEPT    #Z39.50    

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