User Tools

Welcome to the pgipfauth Wiki!

Here at the University of Delaware we were looking for a way to lock-down our campus license server to off-campus IPs. The particular way that we run FlexLM leaves all of the vendor sub-daemons registered on random TCP ports, making a strict and static software firewall setup inaccessible.

Trying to get a large population of end users to install and begin using our VPN from off-campus presented quite a challenge. Since VPN funnels all of the user's traffic through the University via the user's ISP, it also seems excessive to increase the VPN load strictly for the sake of passing a couple of packets to the license server.

In looking for another solution I came across the address pool and “auth” features in IPF. The address pool would allow us to manage a dynamic list of off-campus IPs we've authorized to communicate with the license server. Two drawbacks to using the pool feature would be

  • The address list has the potential to become very large; IPF pools are resident in memory
  • Maintaining the pool (adding/removing IPs) requires rewriting and reloading a configuration file periodically and/or using the ippool CLI; the former means changes take time to propagate to the server, the latter requires locking/sequencing

Both of these properties would be handled quite easily by a transactional database: the address list can be arbitrarily large and the database itself would handle the locking/sequencing. Considering the fact that whatever application we created to allow our end users to authorize specific off-campus IPs would store its data in a database anyway, it would be wonderful to be able to interface IPF to that very same database. That's exactly what the “auth” IPF feature is meant to do: provide a means for a userland program to programmatically block/pass packets!

About pgipfauth...

The IPF firewall software has a little-used feature that allows one to write rules that will attempt to build a packet disposition by passing the packet (headers only or headers and payload) to a program running outside the kernel. The userland program must open the /dev/ipauth device and perform ioctl() calls to wait for a packet and to pass back the disposition. An example program exists in the official IPF source distributions; this program holds lists of authorized IPs in memory. The goal of pgipfauth is to use a Postgres database to hold a persistent, possibly large list of authorized IP addresses and consult that list as needed. Authorizations are cached by pgipfauth to attempt to decrease the number of database queries which must be performed.

Combined with the connection state table of IPF, the typical TCP connection profile is handled quite efficiently:

  1. Initial TCP packet triggers a call to pgipfauth
  2. pgipfauth queries the database with the orginating IP, decides to BLOCK or PASS, caches the IP + disposition
  3. IPF adds the TCP session to its state table
  4. Subsequent packets in TCP session are passed or blocked based solely on the IPF state table

For the lifetime of the cache record added in step 2, the primary difference in the connection profile is that the database is never queried: pgipfauth merely returns the cached disposition.