Adding extra security to wireless networks with AuthPF
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
By Kristijan at 2007-04-13 19:24
Introduction
Operating System: NetBSD (Any OS (OpenBSD/FreeBSD) which supports PF and AuthPF can be used) Prior Knowlede: Basic Linux/BSD understanding / Basic concept of networking / Basic concept behind DHCP & DNS.
Whilst I work in the I.T field, I am no expert on network security, firewalls etc...This how-to is just documentation of the day to day stuff I enjoy dabbling in.
The formatting in the forums makes it a bit difficult to read, so if you prefer, there is a version on my website - http://www.kristijan.org/?q=node/499
Current & New Network Setup
This how-to is a follow on from the DHCP DNS & Firewall with NetBSD tutorial I wrote back in October 2006 which you can find here (http://kristijan.org/?q=node/58). Sections of this how-to will reference back to the older how-to, but this will be noted. The aim of this how-to is to add the wireless AP into my wired network, but restrict direct access to services, othewr LAN nodes and the Internet until authentication is granted.
Prior to following this guide, I recommend reading the following two links:
The access point will be physically connected to my gateway (krusty) via ethernet.
Gateway interfaces:
sip0 - 10.0.0.0/8 - ADSL modem bridge</li>
fxp0 - 192.168.0.0/24 - Wired LAN</li>
fxp1 - 192.168.1.0 - Wireless LAN</li>
I’ve assigned the wireless AP an IP address of 192.168.1.2. All wireless nodes will hang off of the 192.168.1.0/24 network, whilst all my physical nodes will hang off of the 192.168.0.0/24 network. The reason for this is so later on, I can easily create firewall rules to cater for each type of node.
The breakdown of this file was explained in the first tutorial, so I won’t go into the detail here.
We also need to let the DHCP daemon know the new interface to listen on. You can do this by editing the /etc/rc.conf file.
Code:
dhcpd_flags="-q fxp0 fxp1"
**Note: - fxp0 and fxp1 are the interfaces on my NetBSD gateway. They may differ on yours.
To take on the new changes, DHCPD needs to be restarted. Since /etc/rc.conf is read at boot time, it’s best you restart the gateway so that the new interface (fxp1) is now listening for requests.
Setting up DNS
BIND also needs to be aware of the new subnet range, and also how to deal with the dynamic updates which come from DHCP.
Below is the full /etc/named.conf with the changes in bold.
Code:
# Server Settings
controls {
inet 127.0.0.1 allow { localhost; } keys { rndc-key; };
};
include "/etc/rndc.key";
options {
version "Bind";
directory "/etc/namedb";
allow-query { lan; };
listen-on { lan; };
};
acl lan {
127.0.0.1;
192.168.0/24;
192.168.1/24;
};
# Zone Information
zone "." {
type hint;
file "root.cache";
};
zone "localhost" {
type master;
file "localhost";
};
zone "127.IN-ADDR.ARPA" {
type master;
file "127";
};
zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int" {
type master;
file "loopback.v6";
};
zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa" {
type master;
file "loopback.v6";
};
zone "0.168.192.in-addr.arpa" {
type master;
file "0.168.192";
allow-update { key rndc-key; };
};
zone "in.kristijan.org" {
type master;
file "in.kristijan.org";
allow-update { key rndc-key; };
};
zone "1.168.192.in-addr.arpa" {
type master;
file "1.168.192";
allow-update { key rndc-key; };
};
The breakdown of this file was explained in the first tutorial, so I won’t go into the detail here.
/etc/namedb/1.168.192
A new zone file is needed to cater for the 192.168.1.0/24 network.
There is only a single entry for the time being, as wlan.in.kristijan.org is the only node that we know of. The rest of this file will be populated via DHCP when new wireless nodes enter the network.
This line now needs to be added into the 0.168.192 file as we are now dealing with multiple subnets. The same line is present in the 1.168.192 files.
/etc/namedb/in.kristijan.org
Code:
$ORIGIN .
$TTL 3600 ; 1 hour
in.kristijan.org IN SOA krusty.in.kristijan.org. kristijanmilos.gmail.com. (
51 ; serial
3600 ; refresh (1 hour)
3600 ; retry (1 hour)
3600 ; expire (1 hour)
3600 ; minimum (1 hour)
)
NS krusty.in.kristijan.org.
$ORIGIN in.kristijan.org.
bart A 192.168.0.1
homer A 192.168.0.2
krusty A 192.168.0.10
A 192.168.1.1
lisa A 192.168.0.3
wlan A 192.168.1.2
xbox A 192.168.0.4
The same needs to be done for the in.kristijan.org file.
To take on these new changes, you need to restart BIND.
Code:
/etc/rc.d/named restart
Once BIND has been restarted, you can check /var/log/messages for any errors, and to ensure all the zone files are correctly loaded. Below is the output from my /var/log/messages log file of BIND starting up.
Code:
Apr 11 21:56:45 krusty named[213]: starting BIND 9.3.0
Apr 11 21:56:45 krusty named[213]: found 1 CPU, using 1 worker thread
Apr 11 21:56:45 krusty named[213]: loading configuration from '/etc/named.conf'
Apr 11 21:56:45 krusty named[213]: listening on IPv4 interface fxp0, 192.168.0.10#53
Apr 11 21:56:45 krusty named[213]: listening on IPv4 interface fxp1, 192.168.1.1#53
Apr 11 21:56:45 krusty named[213]: listening on IPv4 interface lo0, 127.0.0.1#53
Apr 11 21:56:46 krusty named[213]: command channel listening on 127.0.0.1#953
Apr 11 21:56:46 krusty named[213]: zone 127.IN-ADDR.ARPA/IN: loaded serial 1
Apr 11 21:56:46 krusty named[213]: zone 0.168.192.in-addr.arpa/IN: loaded serial 30
Apr 11 21:56:46 krusty named[213]: zone 1.168.192.in-addr.arpa/IN: loaded serial 28
Apr 11 21:56:46 krusty named[213]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: loaded serial 1
Apr 11 21:56:46 krusty named[213]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int/IN: loaded serial 1
Apr 11 21:56:46 krusty named[213]: zone localhost/IN: loaded serial 1
Apr 11 21:56:46 krusty named[213]: zone in.kristijan.org/IN: loaded serial 51
Apr 11 21:56:46 krusty named[213]: running
Apr 11 21:56:46 krusty named[213]: zone localhost/IN: sending notifies (serial 1)
Apr 11 21:56:46 krusty named[213]: zone 127.IN-ADDR.ARPA/IN: sending notifies (serial 1)
Apr 11 21:56:46 krusty named[213]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.int/IN: sending notifies (serial 1
)
Apr 11 21:56:46 krusty named[213]: zone 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa/IN: sending notifies (serial
1)
Apr 11 21:56:46 krusty named[213]: client 127.0.0.1#65534: received notify for zone 'localhost'
Apr 11 21:56:46 krusty named[213]: client 127.0.0.1#65534: received notify for zone '127.IN-ADDR.ARPA'
Apr 11 21:56:46 krusty named[213]: client 127.0.0.1#65534: received notify for zone '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
.0.0.0.ip6.int'
Apr 11 21:56:46 krusty named[213]: client 127.0.0.1#65534: received notify for zone '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0
.0.0.0.ip6.arpa'
AuthPF and /etc/pf.conf
The objective here is to have my NetBSD gateway running as an authenticating gateway for all wireless nodes. When a new wireless node connects to the AP, it receives an address from DHCP, and the only traffic allowed in through the interface is DNS, and SSH to the gateway only.
Once authenticated, the wireless node is allowed full access to the network and the internet. Any user that is not authenticated, and attempts to browse www traffic, will be redirected to my Apache webserver and shown an “Authentication Required” message.
Setting up AuthPF
First thing that needs to be done is to create a user account which will be used for wireless nodes to authenticate against the gateway, assign it's shell to authpf and set its password.
**Note: - /usr/sbin/authpf is where the shell resides on NetBSD, this may differ on your distribution.
AuthPF requires the authpf.conf file to be present in /etc/authpf directory, even if the file is empty and authpf.rules is the file which will contain our specific rules. NetBSD also keeps track of authenticated IP addresses in /var/authpf. The directory doesn’t exist, so it needs to be created.
Let go ahead and create all the necessary files and directories.
This file contains the rules that will be loaded once the user authenticates.
Code:
wi_if = "fxp1"
pass in quick on $wi_if from $user_ip to any keep state
What this rules does, is allow traffic travelling into the fxp1 interface from the IP addresses of the authenticated user to any destination. $user_ip is a macro which is provided by AuthPF, which contains the IP addresses of the authenticated user.
/etc/pf.conf
We now need to edit the current PF rule set, to accommodate for our changes.
Below is the full /etc/pf.conf with the changes in bold. This is my entire pf.conf file, so it contains other rules which are not related to this tutorial.
Code:
##########
# Macros #
##########
ext_if="ppp0"
int_if="fxp0"
wi_if="fxp1"
adsl_if="sip0"
homer="192.168.0.2"
krusty="192.168.1.1"
auth_web="192.168.0.10"
routable="{ 192.168.0.0/24, 192.168.1.0/24 }"
nonroutable="{ 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, 0.0.0.0/8, 240.0.0.0/4 }"
###########
# Options #
###########
set block-policy drop
set loginterface $ext_if
#########
# Scrub #
#########
scrub no-df random-id fragment reassemble
##########
# Tables #
##########
table <authpf_users> persist
###########
# NAT/RDR #
###########
nat on $ext_if from $routable to any -> ($ext_if)
nat on $adsl_if from $routable to any -> ($adsl_if)
# Azureus
rdr on $ext_if proto tcp from any to any port 61980 -> $homer port 61980
rdr on $ext_if proto udp from any to any port 61980 -> $homer port 61980
# WWW redirect for non-AuthPF users
rdr on $wi_if proto tcp from ! <authpf_users> to any port 80 -> $auth_web
################
# Filter Rules #
################
pass out quick keep state
pass quick on lo0
# Azureus
pass in quick on $ext_if proto tcp from any to any port 61980 flags S/SA keep state
pass in quick on $ext_if proto udp from any to any port 61980
# SSH
pass in quick on $ext_if proto tcp from any to any port 22 flags S/SA keep state
# Non routable
block drop in quick on $ext_if from $nonroutable to any
block drop out quick on $ext_if from any to $nonroutable
# DNS, SSH & WWW-redirect for wireless so user can AuthPF
pass in quick on $wi_if proto udp from 192.168.1.0/24 to any port 53
pass in quick on $wi_if proto tcp from 192.168.1.0/24 to $krusty port 22 flags S/SA keep state
pass in quick on $wi_if proto tcp from ! <authpf_users> to any port 80 flags S/SA keep state
# AuthPF anchor
anchor "authpf/*"
# Drop All
block in quick on $wi_if
block in quick on $ext_if
Breakdown of the changes.
Macros
wi_if="fxp1" - The new NIC in the gateway</li>
krusty="192.168.1.1" - Krusty IP address</li>
auth_web="192.168.0.10" - IP address of Apache webserver</li>
routable="{ 192.168.0.0/24, 192.168.1.0/24 }" - Added in the new subnet range</li>
Tables
table <authpf_users> persist - Creates the authpf_users table, which all authenticated users will go into
NAT/RDR
rdr on $wi_if proto tcp from ! <authpf_users> to any port 80 -> $auth_web - Redirects all port 80 (www) traffic from users who are not in the authpf_users table, to my Apache webserver
Filter Rules
pass in quick on $wi_if proto udp from 192.168.1.0/24 to any port 53 - Allows DNS queries through from users on the 192.168.1.0/24 network
pass in quick on $wi_if proto tcp from 192.168.1.0/24 to $krusty port 22 flags S/SA keep state - Allows SSH only to the gateway from users on the 192.168.1.0/24 network
pass in quick on $wi_if proto tcp from ! <authpf_users> to any port 80 flags S/SA keep state - Allows WWW requests to be redirected from non-authenticated users
anchor "authpf/*" - Where the AuthPF rules will be placed from the authenticated user
block in quick on $wi_if - Block in all other traffic from the 192.168.1.0/24 network
Now with all the changes in place, you can reload the current pf.conf file.
Code:
pfctl –f /etc/pf.conf
Testing the setup
To test the new setup, you are going to need a wireless device capable of obtaining an address via DHCP. A laptop would be the most common device in this situation.
To debug the entire process, you may want to tail the /var/log/messages file to watch things as they happen.
Code:
tail –f /var/log/messages
Set the laptop’s wireless adapter to obtain an address via DHCP, and re-authenticate to the access point. At this point you should be able to do the following:
Obtain an address from DHCP within the 192.168.1.10 – 192.168.1.30 range
Resolve DNS queries
Any web browser requests will be redirected to the Apache server
Apart from SSH into the gateway (krusty), all other traffic (e.g. PING, SSH to other machines, WWW over the Internet) will be dropped
From the laptop, SSH into krusty with the authgw user id.
Once authenticated, you should now be able to do the following:
Browse any pages over the Internet
SSH into any other nodes
PING any local nodes and Internet addresses
As soon as you loose or terminate the SSH session as the authenticated user, the rules will be dropped from the PF filter and you should have restricted access till you re-authenticate.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.