PF - User Shell for Authenticating Gateways (authpf)
Introduction
The authpf(8) utility is a user shell for authenticating gateways. An authenticating gateway is just like a regular network gateway (also known as a router) except that users must first authenticate themselves to it before their traffic is allowed to pass through. When a user's shell is set to/usr/sbin/authpf and he or she logs
in using SSH, authpf will make the necessary changes to the active
pf(4) ruleset so that the user's
traffic is passed through the filter and/or translated using NAT/redirection.
Once the user logs out, or the session is disconnected, authpf will remove
any rules loaded for the user and kill any stateful connections the user has
open.
Because of this, the ability of the user to pass traffic through the gateway
only exists while the user keeps the SSH session open.
A user's rules are loaded into a unique anchor
point by authpf.
The anchor is named by combining the username and the authpf process-id
in the username(PID) format.
Each user's anchor is stored within the authpf anchor which is
in turn anchored to the main ruleset.
The fully qualified anchor path then becomes:
main_ruleset/authpf/username(PID)The rules that authpf loads can be configured on a per-user or global basis.
Example uses of authpf include:
- Requiring users to authenticate before allowing internet access.
- Granting certain users, such as administrators, access to restricted parts of the network.
- Allowing only known users to access the rest of the network or internet from a wireless network segment.
- Allowing workers from home or on the road access to resources on the company network. Users outside the office can not only open access to the company network, but can also be redirected to particular resources (their own desktops, for example) based on the usernames they use to authenticate.
- In a setting such as a library or other place with public internet terminals, PF may be configured to allow limited internet access to guest users. Registered users can then be provided with complete access.
Configuration
The basic steps needed to configure authpf are outlined here. For a complete description of authpf configuration, please refer to the man page.Enabling authpf
The authpf utility will not run if the/etc/authpf/authpf.conf
config file is not present.
The file may be empty, but, unless it is present, authpf will exit immediately
after a user authenticates successfully.
The following configuration directives can be placed in
authpf.conf:
anchor=name- Use the specified anchornameinstead ofauthpftable=name- Use the specified tablenameinstead ofauthpf_users
Linking authpf into the Main Ruleset
To link authpf into the main ruleset, use ananchor rule:
anchor "authpf/*"Wherever the
anchor rule is placed within the ruleset is where PF
will branch off from the main ruleset to evaluate the authpf rules.
Configuring Loaded Rules
The authpf rules can be loaded from one of these two files:/etc/authpf/users/$USER/authpf.rules/etc/authpf/authpf.rules
$USER (which is replaced with the user's username) logs in.
The per-user rule configuration is used when a specific user, such as an
administrator, requires a set of rules that is different than the default set.
The second file contains the default rules which are loaded for any users that
don't have their own authpf.rules file.
If the user-specific file exists, it will override the default file.
At least one of the files must exist or authpf will not run.
Rules have the same syntax as any other PF ruleset, with the exception that authpf allows for the use of two predefined macros:
$user_ip- the IP address of the logged in user$user_id- the username of the logged in user
$user_ip macro to only permit
traffic through the gateway from the authenticated user's computer.
In addition to the $user_ip macro, authpf will make use of the
authpf_users table (if it exists) for storing the IP addresses
of all authenticated users.
Be sure to define the table before using it:
table <authpf_users> persist pass in on egress proto tcp from <authpf_users> to port smtpThis table should only be used in rules that are meant to apply to all authenticated users.
Access Control Lists
Specific users can be prevented from accessing authpf by creating a file in the/etc/authpf/banned directory that matches the username.
The contents of this file will be displayed to the users before authpf
disconnects them.
This provides a handy way to notify the users of why they're disallowed
access and who to contact to have it restored.
Conversely, it's also possible to only grant access to specific users by
placing usernames in the /etc/authpf/authpf.allow file.
If the file does not exist, or if "*" is entered into it,
authpf will permit access to any users who successfully log in via SSH
as long as they are not explicitly banned.
If authpf is unable to determine whether a username is allowed or denied, it
will print a brief message and then disconnect the user.
A file in /etc/authpf/banned always overrides an entry in
/etc/authpf/authpf.allow.
Displaying a Login Message
Whenever a user successfully authenticates to authpf, a greeting is printed which indicates that the user is authenticated.Hello charlie. You are authenticated from host "198.51.100.10"This message can be supplemented by putting a custom message in
/etc/authpf/authpf.message.
The contents of this file will be displayed after the default welcome message.
Assigning authpf as a User's Shell
In order for authpf to work, it must be assigned as the user's login shell. When the user successfully authenticates to sshd(8), authpf will be executed as the user's shell. It will then check if the user is allowed to use authpf, load the rules from the appropriate file, etc.There are a couple ways of assigning authpf as a user's shell:
- Manually for each user using chsh(1), vipw(8), useradd(8), usermod(8), etc.
- By assigning users to a login class and changing the class's
shelloption in login.conf(5).
Creating an authpf Login Class
When using authpf on a system that has regular user accounts and authpf user accounts, it can be beneficial to use a separate login class for the authpf users. This allows for certain changes to be made to those accounts on a global basis, and also allows different policies to be placed on regular accounts and authpf accounts. Some examples of what policies can be set:- shell - Specify a user's login shell.
This can be used to force a user's shell to
authpfregardless of the entry in the passwd(5) database. - welcome - Specify which motd(5) file to display when a user logs in. This is useful for displaying messages that are relevant only to authpf users.
Login classes are created in the login.conf(5) file. OpenBSD comes with an authpf login class defined as:
authpf:\
:welcome=/etc/motd.authpf:\
:shell=/usr/sbin/authpf:\
:tc=default:
Users are assigned to a login class by editing the class field
of the user's passwd(5) database entry.
One way to do this is with the
chsh(1) command.
Seeing Who is Logged In
Once a user has successfully logged in and authpf has adjusted the PF rules, authpf changes its process title to indicate the username and IP address of the logged in user:# ps -ax | grep authpf 23664 p0 Is+ 0:00.11 -authpf: charlie@192.168.1.3 (authpf)Here the user
charlie is logged in from the machine 192.168.1.3.
By sending a SIGTERM signal to the authpf process, the user can be forcefully
logged out.
Any rules loaded for the user will be removed and any stateful connections
the user has open will be killed.
# kill -TERM 23664
Example
The authpf tool is being used on an OpenBSD gateway to authenticate users of a wireless network that is part of a larger campus network. Authenticated users will be permitted to SSH out, browse the web, and access the campus DNS servers, assuming they're not on the banned list.
The /etc/authpf/authpf.rules file contains the following rules:
wifi_if = "wi0"
pass in quick on $wifi_if \
proto tcp from $user_ip to any port { ssh, http, https }
The administrative user charlie needs to be able to access the
campus SMTP and POP3 servers in addition to surfing the web and using SSH.
The following rules are set up in
/etc/authpf/users/charlie/authpf.rules:
wifi_if = "wi0"
smtp_server = "10.0.1.50"
pop3_server = "10.0.1.51"
pass in quick on $wifi_if \
proto tcp from $user_ip to $smtp_server port smtp
pass in quick on $wifi_if \
proto tcp from $user_ip to $pop3_server port pop3
pass in quick on $wifi_if \
proto tcp from $user_ip to port { ssh, http, https }
The main /etc/pf.conf ruleset is set up as follows:
wifi_if = "wi0"
ext_if = "fxp0"
dns_servers = "{ 10.0.1.56, 10.0.2.56 }"
table <authpf_users> persist
block drop all
pass out quick on $ext_if \
inet proto { tcp, udp, icmp } from { $wifi_if:network, $ext_if }
pass in quick on $wifi_if \
inet proto tcp from $wifi_if:network to $wifi_if port ssh
pass in quick on $wifi_if \
inet proto { tcp, udp } from <authpf_users> to $dns_servers port domain
anchor "authpf/*" in on $wifi_if
The ruleset is very simple and does the following:
- Block everything (default deny)
- Pass outgoing TCP, UDP and ICMP traffic on the external interface from the wireless network and from the gateway itself
- Pass incoming SSH traffic from the wireless network destined for the gateway itself (This rule is necessary to permit users to log in.)
- Pass incoming DNS requests from all authenticated authpf users to the campus DNS servers
- Create the anchor point "authpf" for incoming traffic on the wireless interface
quick keyword is used throughout so that PF doesn't have to
evaluate each named ruleset when a new connection passes through the gateway.