Guarding Your Wireless Network with authpf

Security professionals tend to agree that even though WEP encryption offers little protection, it’s just barely enough to signal to would-be attackers that you do not intend to let all and sundry use your network resources. Using WPA increases security somewhat, at the cost of some complexity.

The configurations we built so far in this chapter are functional. Both the WEP and WPA configurations will let all reasonably configured wireless clients connect, and that may be a problem in itself, since that configuration does not have any real support built in for letting you decide who uses your network.

As mentioned earlier, MAC address filtering is not really a solid defense against attackers because it’s just too easy to change a MAC address. The OpenBSD developers chose a radically different approach to this problem when they introduced authpf in OpenBSD version 3.1. Instead of tying access to a hardware identifier such as the network card’s MAC address, they decided that the robust and highly flexible user authentication mechanisms already in place were more appropriate for the task. The user shell authpf lets the system load PF rules on a per-user basis, effectively deciding which user gets to do what.

To use authpf, you create users with the authpf program as their shell. In order to get network access, the user logs in to the gateway using SSH. Once the user successfully completes SSH authentication, authpf loads the rules you have defined for the user or the relevant class of users.

These rules, which apply to the IP address the user logged in from, stay loaded and in force for as long as the user stays logged in via the SSH connection. Once the SSH session is terminated, the rules are unloaded, and in most scenarios, all non-SSH traffic from the user’s IP address is denied. With a reasonable setup, only traffic originated by authenticated users will be let through.

Note

On OpenBSD, authpf is one of the login classes offered by default, as you will notice the next time you create a user with adduser.

For systems where the authpf login class is not available by default, you may need to add the following lines to your /etc/login.conf file:

authpf:
        :welcome=/etc/motd.authpf:
        :shell=/usr/sbin/authpf:
        :tc=default:

The next couple of sections contain a few examples that may or may not fit your situation directly, but that I hope will give you ideas you can use.

A Basic Authenticating Gateway

Setting up an authenticating gateway with authpf involves creating and maintaining a few files besides your basic pf.conf. The main addition is authpf.rules. The other files are fairly static entities that you will not be spending much time on once they have been created.

Start by creating an empty /etc/authpf/authpf.conf file. This file needs to be there in order for authpf to work, but it doesn’t actually need any content, so creating an empty file with touch is appropriate.

The other relevant bits of /etc/pf.conf follow. First, here are the interface macros:

ext_if = "re0"
int_if = "ath0"

In addition, if you define a table called <authpf_users>, authpf will add the IP addresses of authenticated users to the table:

table <authpf_users> persist

If you need to run NAT, the rules that take care of the translation could just as easily go in authpf.rules, but keeping them in the pf.conf file does not hurt in a simple setup like this:

pass out on $ext_if from $localnet nat-to ($ext_if)

Here’s pre-OpenBSD 4.7 syntax:

nat on $ext_if from $localnet to any -> ($ext_if)

Next, we create the authpf anchor, where rules from authpf.rules are loaded once the user authenticates:

anchor "authpf/*"

For pre-OpenBSD 4.7 authpf versions, several anchors were required, so the corresponding section would be as follows:

nat-anchor "authpf/*"
rdr-anchor "authpf/*"
binat-anchor "authpf/*"
anchor "authpf/*"

This brings us to the end of the required parts of a pf.conf file for an authpf setup.

For the filtering part, we start with the block all default, and then add the pass rules we need. The only essential item at this point is to let SSH traffic pass on the internal network:

pass quick on $int_if inet proto { tcp, udp } to $int_if port ssh

From here on out, it really is up to you. Do you want to let your clients have name resolution before they authenticate? If so, put the pass rules for the TCP and UDP service domain in your pf.conf file, too.

For a relatively simple and egalitarian setup, you could include the rest of our baseline rule set, changing the pass rules to allow traffic from the addresses in the <authpf_users> table, rather than any address in your local network:

pass quick inet proto { tcp, udp } from <authpf_users> to port $udp_services
pass inet proto tcp from <authpf_users> to port $client_out

For a more differentiated setup, you could put the rest of your rule set in /etc/authpf/authpf.rules or per-user rules in customized authpf.rules files in each user’s directory under /etc/authpf/users/. If your users generally need some protection, your general /etc/authpf/authpf.rules could have content like this:

client_out = "{ ssh, domain, pop3, auth, nntp, http, https }"
udp_services = "{ domain, ntp }"
pass quick inet proto { tcp, udp } from $user_ip to port $udp_services
pass inet proto tcp from $user_ip to port $client_out

The macro user_ip is built into authpf and expands to the IP address from which the user authenticated. These rules will apply to any user who completes authentication at your gateway.

A nice and relatively easy addition to implement is special-case rules for users with different requirements than your general user population. If an authpf.rules file exists in the user’s directory under /etc/authpf/users/, the rules in that file will be loaded for the user. This means that your naïve user Peter who only needs to surf the Web and have access to a service that runs on a high port on a specific machine could get what he needs with a /etc/authpf/users/peter/authpf.rules file like this:

client_out = "{ domain, http, https }"
pass inet from $user_ip to 192.168.103.84 port 9000
pass quick inet proto { tcp, udp } from $user_ip to port $client_out

On the other hand, Peter’s colleague Christina runs OpenBSD and generally knows what she is doing, even if she sometimes generates traffic to and from odd ports. You could give her free rein by putting this in /etc/authpf/users/christina/authpf.rules:

pass from $user_ip os = "OpenBSD" to any

This means Christina can do pretty much anything she likes over TCP as long as she authenticates from her OpenBSD machines.

Wide Open but Actually Shut

In some settings, it makes sense to set up your network to be open and unencrypted at the link level, while enforcing some restrictions via authpf. The next example is very similar to Wi-Fi zones you may encounter in airports or other public spaces, where anyone can associate to the access points and get an IP address, but any attempt at accessing the Web will be redirected to one specific web page until the user has cleared some sort of authentication.[23]

This pf.conf file is again built on our baseline, with two important additions to the basic authpf setup: a macro and a redirection.

ext_if = "re0"
int_if = "ath0"
auth_web="192.168.27.20"
dhcp_services = "{ bootps, bootpc }" # DHCP server + client
table <authpf_users> persist
pass in quick on $int_if proto tcp from ! <authpf_users> to port http rdr-to $auth_web
match out on $ext_if from $int_if:network nat-to ($ext_if)
anchor "authpf/*"
block all
pass quick on $int_if inet proto { tcp, udp } to $int_if port $dhcp_services
pass quick inet proto { tcp, udp } from $int_if:network to any port domain
pass quick on $int_if inet proto { tcp, udp } to $int_if port ssh

For older authpf versions, use this file instead:

ext_if = "re0"
int_if = "ath0"
auth_web="192.168.27.20"
dhcp_services = "{ bootps, bootpc }" # DHCP server + client
table <authpf_users> persist
rdr pass on $int_if proto tcp from ! <authpf_users> to any port http -> $auth_web
nat on $ext_if from $localnet to any -> ($ext_if)
nat-anchor "authpf/*"
rdr-anchor "authpf/*"
binat-anchor "authpf/*"
anchor "authpf/*"
block all
pass quick on $int_if inet proto { tcp, udp } to $int_if port $dhcp_services
pass quick inet proto { tcp, udp } from $int_if:network to port domain
pass quick on $int_if inet proto { tcp, udp } to $int_if port ssh

The auth_web macro and the redirection make sure all web traffic from addresses that are not in the <authpf_users> table leads all nonauthenticated users to a specific address. At that address, you set up a web server that serves up whatever you need. This could range from a single page with instructions on who to contact in order to get access to the network all the way up to a system that accepts credit cards and handles user creation.

Note that in this setup, name resolution will work, but all surfing attempts will end up at the auth_web address. Once the users clear authentication, you can add general rules or user-specific ones to the authpf.rules files as appropriate for your situation.



[23] Thanks to Vegard Engen for the idea and showing me his configuration, which is preserved here in spirit, if not all details.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.7.131