|
aoakley.com
Throttled WiFi Hotspot and PPTP VPN Howto
How To Create a Throttled Public WiFi Hotspot
with Secure VPN Override using Fedora Core 2
Originally created Mon 8 Nov 2004 by Andrew Oakley.
Last updated Fri 12 Feb 2010 10:04 by Andrew Oakley.
Contents
Summary
Aims
Requirements
Assumptions
Preparation
DHCP
DNS
IPTables
Microsoft MPPE (VPN Encryption)
PPTPD (VPN)
TC (Throttling)
WiFi Access Point
Captive Portal Page
Summary
At home, I have created a Linux-based public WiFi hotspot that anyone, including my neighbours and the general public, can use to browse the web. Their access is throttled down, using traffic shaping, and limited to web pages and SSH only (ports 22, 80 and 443 only). Meanwhile, I can use a Virtual Private Network to bypass these restrictions and use my connection at full speed with all ports on my Microsoft Windows WiFi laptop.
Although originally created under Fedora Core 2, the system now runs on the current Ubuntu LTS release. Almost all the setup is the same.
Top
Aims
- Create a public WiFi hotspot with DHCP and NAT Masquerade based around Linux.
- Limit the hotspot to certain ports.
- Limit the speed to a desired level.
- Create a PPTP VPN compatible with Microsoft Windows so that myself and other authorised users can get unlimited, all ports, full speed access.
Top
Requirements
- A PC with two network cards running Red Hat Linux Fedora Core 2 (you can use any similar Linux distro, but this document is written with RHL FC2 in mind). This is your Linux server.
- A Wireless Access Point.
- An Internet router such as an ADSL router, Cable router or an ISDN router, configured to provide NAT on an internal Private LAN (eg. 192.168.0.0/24).
- An account with an unmetered ISP.
- Two lengths of straight-through Cat5 network cable and one length of crossover network cable. (One of the straight-through cables is for testing only and is not permanently required).
- For testing only, a seperate PC with a wireless network card, a Cat5 network card, and PPTP VPN software, such as a Windows 2000 or Windows XP laptop.
Top
Assumptions
- 192.168.0.0/24 is your internal Private LAN that the general public is NOT permitted access to.
- 192.168.7.0/24 is going to be your external public subnet that the general public IS permitted access to
- 192.168.0.254 is the address of your Internet router.
- Your Internet router is already providing a firewalled NAT on 192.168.0.0/24. You are not using your Linux server for NAT on this subnet.
- 192.168.0.253 and 192.168.7.253 are the addresses of your Linux server, each subnet is on a seperate network card.
- Your test PC/laptop is set to use DHCP ("Obtain an IP address automatically", "Obtain DNS server addresses automatically").
Top
Preparation
- Check that the wireless access point works. Configure the access point in infrastructure mode to allow unlimited access with no encryption and connect it direct to the Internet router. Check that it works on your test machine then disconnect the access point from the router immediately.
- [GOTCHA] You have disconnected your wireless access point, haven't you? It was only a quick test. Make sure it is disconnected now, otherwise everyone will be leeching your bandwidth and getting onto your internal network.
- Check that you can see the Internet from your Linux server on the 192.168.0.0/24 subnet.
- Become root on your Linux server.
Top
DHCP
Here we're setting up the public subnet (192.168.7.0/24) so that we can obtain an IP address, gateway and DNS servers through DHCP.
- Configure DHCPD for the public subnet. Edit /etc/dhcpd.conf like this:
ddns-update-style interim;
ignore client-updates;
# eth1 LAN
subnet 192.168.7.0 netmask 255.255.255.0 {
option routers 192.168.7.253;
option subnet-mask 255.255.255.0;
option domain-name-servers 192.168.7.253;
range dynamic-bootp 192.168.7.17 192.168.7.191;
default-lease-time 21600;
max-lease-time 86400;
}
- Start DHCPD.
service dhcpd start
[GOTCHA] You also have to edit chkconfig to ensure that DHCPD stays enabled after reboots.
chkconfig --level 35 dhcpd on
- Now check that DHCP is working. Ensure your test PC/laptop is set to use DHCP ("Obtain an IP address automatically", "Obtain DNS server addresses automatically"), then connect it to your Public LAN (192.168.7.0/24) network card using the cross-over cable. Check that you can ping 192.168.7.253 (from your test PC/laptop to your Linux server).
Top
DNS
Enable named to act as a DNS nameserver on the Private LAN.
Top
IPTables
Configure iptables to act as both a firewall against the Public LAN, and to do a NAT IP masquerade for Public LAN users.
- Edit /etc/sysconfig/iptables thusly:
# eth1 is HOT (unencrypted public wifi hotspot)
# eth0 is LAN (private LAN & internet)
# ppp0 is VPN (PPTP virtual private network)
##################################################
# NAT
# This bit does the IP masquerading
*nat
# Kick off by accepting everything at this stage
# Anything unpleasant will be filtered out in the
# filter section anyway.
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
# Allow forwarding from HOT to LAN
# eg. from 192.168.7.x clients to external websites
-A POSTROUTING -o eth0 -j MASQUERADE
-A POSTROUTING -s 192.168.0.0/24 -j MASQUERADE
COMMIT
##################################################
# FILTER
# This is where you add port rules
*filter
# Firstly, block all access
# We will open up access, but only to the things we want, later
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
# Accept everything from known safe networks; LAN, VPN and lo
-A INPUT -i ppp0 -s 0/0 -d 0/0 -j ACCEPT
-A INPUT -i eth0 -s 0/0 -d 0/0 -j ACCEPT
-A INPUT -i lo -s 0/0 -d 0/0 -j ACCEPT
# Drop access from HOT to internal LAN subnet
-A INPUT -i eth1 -d 192.168.0.0/24 -j DROP
-A FORWARD -i eth1 -d 192.168.0.0/24 -j DROP
# Accept restricted set of ports from HOT
# Echo
-A INPUT -i eth1 -p icmp --icmp-type echo-request -j ACCEPT
# SSH
-A INPUT -i eth1 -p tcp --dport 22 -j ACCEPT
# PPTP/VPN
-A INPUT -i eth1 -p tcp --dport 1723 -j ACCEPT
# DNS
-A INPUT -i eth1 -p tcp --dport 53 -j ACCEPT
-A INPUT -i eth1 -p udp --dport 53 -j ACCEPT
# HTTP
-A INPUT -i eth1 -p tcp --dport 80 -j ACCEPT
-A INPUT -i eth1 -p tcp --dport 443 -j ACCEPT
# Accept NAT related packets
-A FORWARD -i eth0 -j ACCEPT
-A FORWARD -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# Accept NAT from VPN (PPP0), unrestricted
-A FORWARD -i ppp0 -o eth0 -j ACCEPT
# Return packets
-A INPUT -i ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# Accept NAT from HOT, restricted to certain ports
# Echo
-A FORWARD -i eth1 -o eth0 -p icmp --icmp-type echo-request -j ACCEPT
# SSH
-A FORWARD -i eth1 -o eth0 -p tcp --dport 22 -j ACCEPT
# DNS
-A FORWARD -i eth1 -o eth0 -p tcp --dport 53 -j ACCEPT
-A FORWARD -i eth1 -o eth0 -p udp --dport 53 -j ACCEPT
# HTTP
-A FORWARD -i eth1 -o eth0 -p tcp --dport 80 -j ACCEPT
-A FORWARD -i eth1 -o eth0 -p tcp --dport 443 -j ACCEPT
# Return packets
-A INPUT -i eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT
COMMIT
- [GOTCHA] Enable IP Forwarding on your Linux server. Otherwise NAT doesn't work through iptables.
echo 1 > /proc/sys/net/ipv4/ip_forward
- [GOTCHA] You also have to edit /etc/sysconfig/network to ensure that this stays enabled after reboots.
FORWARD_IPV4 = YES
- Now start the firewall. If iptables is already running, you can use service iptables restart to restart it. If it isn't running, do:
service iptables start
- [GOTCHA] Again, you also have to edit chkconfig to ensure that iptables stays enabled after reboots.
chkconfig --level 35 iptables on
- Now use your test PC/laptop, which should still be connected using the cross-over cable to the 192.168.7.0/24 subnet, to check that NAT is working. Try pinging www.bbc.co.uk . It should ping now. Next, try browsing the web from your test PC/laptop. You should see that HTTP and HTTPS requests work fine, but FTP etc. does not. Also you should be able to SSH into the Linux server on 192.168.7.253.
Top
Microsoft MPPE (VPN Encryption)
[GOTCHA] I recommend we add Microsoft Point-To-Point Encryption (MPPE), which doesn't ship as standard in Red Hat Linux Fedora Core 2. If we don't do this, the VPN connection will be rejected by default on Windows machines, and traffic to and from your private subnet will be unencrypted (this could be very bad, especially if you had shared drives, folders or printers). If you're not using MS Windows machines on your VPN, you may skip this step.
That's the Microsoft encryption out of the way, so if you skipped it because you're not using MS Windows machines, you need to start paying attention again now.
Top
PPTPD (VPN)
Now we create the PPTP VPN. Our goal here is to allow authenticated VPN users on WiFi to access a full range of Internet services at full speed, unencumbered by the firewall and speed limits of the WiFi Public LAN, and in addition, to allow VPN users access to the Private LAN.
- Configure PPTPD. the VPN daemon. Start by editing /etc/pptpd.conf :
localip 192.168.0.251
remoteip 192.168.0.193-248
- Short and sweet. Now to configure the PPP options for PPTPD. Edit /etc/ppp/options.pptpd
name pptpd
lock
mtu 1490
mru 1490
proxyarp
auth
require-chap
# Comment out these two require-mppe lines if you are not
# using MS VPN clients.
require-mppe
require-mppe-stateless
-chap
-chapms
+chapms-v2
ipcp-accept-local
ipcp-accept-remote
lcp-echo-failure 30
lcp-echo-interval 5
mppe-128
#mppe-40 # Both 40 and 128 bits bite eachother
mppe-stateless
# ms-wins 192.168.0.253
ms-dns 192.168.0.254
netmask 255.255.255.0
- It is time to allocate a username and password for the VPN. Edit /etc/ppp/chap-secrets with [GOTCHA] your desired username and password. In this example, the username is toddington and the password is teddington. I recommend you use something completely different, and difficult to guess.
# Secrets for authentication using CHAP
# client server secret IP addresses
toddington pptpd teddington
- Then start the PPTPD service.
service start pptpd
- [GOTCHA] You also have to edit chkconfig to ensure that pptpd stays enabled after reboots.
chkconfig --level 35 pptpd on
- Now use your test PC/laptop to check that the VPN works. Create a new VPN network connection to 192.168.7.253 . The default Microsoft Windows settings should work fine. Use the username and password you specified in /etc/ppp/chap-secrets . You should be assigned an IP address inside your Private LAN (192.168.0.0/24) and you should be able to do things you can't from the Public LAN such as FTP, use RealPlayer, BitTorrent etc.
Top
TC (Throttling)
The hotspot and VPN are now fully functional, the only thing that remains is to throttle the bandwidth available to the hotspot, without throttling the VPN.
- Create a script to initialise the traffic control. Create /root/tc/tc-init as follows:
#!/bin/sh
# Traffic shaping for WiFi hotspot
#
# Throttles web/DNS/SSH access but allows unlimited VPN
# Also requires iptables to firewall out unwanted ports.
#
# Adapted from http://www.wlug.org.nz/TrafficShaping
DEV=eth1
IP=192.168.7.253
# Change LINERATE to reflect your total available bandwidth
LINERATE=1mbit
# Change LOWRATE to your desired restricted public bandwidth
LOWRATE=16kbps
# Where the tc executable is.
TC=/sbin/tc
if ! test -x $TC; then
echo Cant find $TC, aborting
exit 1
fi
$TC qdisc del dev $DEV root
$TC qdisc add dev $DEV root handle 1: cbq avpkt 1000 bandwidth $LINERATE
$TC class add dev $DEV parent 1: classid 1:1 cbq rate $LOWRATE \
allot 1500 prio 5 bounded isolated
# Throttled traffic - class 1:1
# Non-local SSH (22), HTTP (80/443), DNS (53) & DHCP (67)
$TC filter add dev $DEV parent 1: protocol ip prio 16 u32 \
match ip sport 22 0xFFFF flowid 1:1
$TC filter add dev $DEV parent 1: protocol ip prio 16 u32 \
match ip sport 53 0xFFFF flowid 1:1
$TC filter add dev $DEV parent 1: protocol ip prio 16 u32 \
match ip sport 67 0xFFFF flowid 1:1
$TC filter add dev $DEV parent 1: protocol ip prio 16 u32 \
match ip sport 80 0xFFFF flowid 1:1
$TC filter add dev $DEV parent 1: protocol ip prio 16 u32 \
match ip sport 443 0xFFFF flowid 1:1
# Prioritise queues using sfq perturb
$TC qdisc add dev $DEV parent 1:1 sfq perturb 60
# Display Traffic Shaping details
echo "---- qdisc parameters Ingress ----------"
$TC qdisc ls dev $DEV
echo "---- Class parameters Ingress ----------"
$TC class ls dev $DEV
echo "---- filter parameters Ingress ----------"
$TC filter ls dev $DEV
- Ensure tc-init is executable:
chmod 750 /root/tc/tc-init
- Now start TC with:
/root/tc/tc-init
- [GOTCHA] Ensure that tc-init is run automatically after a reboot, by adding the following line to the bottom of /etc/rc.d/rc.local :
/root/tc/tc-init
- Time for another test. Log out of the VPN on your test PC/laptop and browse the web using the 192.68.7.0/24 subnet. Try downloading a large file over HTTP. You should see that the bandwidth is restricted to 16kbyte/sec (128kbit/sec, or whatever you specified).
- Now log in to the VPN on your test PC/laptop and try the download again on the VPN'ed 192.168.0.0/24 subnet. This time you should see that the bandwidth is no longer restricted. Try a different HTTP download to prove that it wasn't cached.
Top
WiFi Access Point
Finally, it is time to place the WiFi access point on the 192.168.7.0/24 subnet.
- Connect your WiFi access point back to the Private LAN and log into it.
- Change the access point's configuration so that it expects to sit on the Public LAN (192.168.7.0/24). There will obviously be a tense moment when the access point switches subnets, and you can no longer see it on the Private LAN.
- Remove your test PC/laptop from the cross-over cable attached to the Public LAN network card on your Linux server.
- Place your WiFi access point at the end of the cross-over cable attached to the Public LAN network card on your Linux server.
- The moment of truth. Fire up the WiFi card on your test PC/laptop and check that the public hotspot works. Remember, you are expecting an address on the Public LAN (192.168.7.0/24) with throttled web/SSH access only.
- Next, log into your VPN on the test PC/laptop and check that you can access all Internet services with no bandwidth throttling.
- Congratulations, you have created a safe, secure, throttled WiFi hotspot with your own private VPN override. Now publicise your hotspot with WiFi Hotspot directories and WarChalking.
Top
Captive Portal Web Page
I also added a "captive portal" page which redirects first-time web browsing visitors to an informational page. Unlike most other captive portals, this one deliberately does not require a log-in. My solution is yet to be fine-tuned, but in the mean time you can read about my first attempt in this uk.comp.os.linux posting.
Unfortunately this captive portal was abandoned, since without requiring authentication, it would be displayed once only to the first HTTP request originating from the client. Usually this first request was the operating system polling for updates, or an anti-virus polling for updates, so the user never saw it.
Top
Public Domain - Andrew Oakley - 2004-11-08
Top -
More Computing Articles -
Article Index -
aoakley.com
| |