Firewall with bridged interfaces and captive portal

Christopher Cowart ccowart at
Wed Dec 10 11:20:17 PST 2008

Olivier Nicole wrote:
>>> I need to implement a firewall with bridged interfaces that offers
>>> captive portal (authentication before opening the traffic).
>> We are using a combination of squid+ipfw. Although we are NATing the
>> users, that really just introduces needless complexity that could be
>> avoided with a bridging solution.
>> Our web-app/captive portal/authentication program is written in-house;
>> it's very tightly integrated with several existing pieces of
>> infrastructure. I don't know if there are any solutions that will work
>> out-of-the-box.
>> I can get you more technical details if this is a direction you'd be
>> interested in moving.
> Long time ago I have been toying with ipf (for the genral firewall)
> and NoCat+ipfw for the captive portal.
> But that did not work too well, so any technical information will be
> appreciated :)
> My long term vision is a quite integrated thing, where users that read
> their email and authenticate to POP3/IMAP would be granted the access
> without the need to authenticate to the web portal.


Sorry it's taken a while to get back to you on this.

You're going to want to get squid up and running as a transparent proxy.
You will probably want to write a redirect script [1]. Mine checks
against a small set of always-authorized URLs that squid is allowed to
proxy for; any other HTTP request will receive a redirect:

  printf "302:%s%s\n" "${default_url}" "$suffix"

The URL points to the webserver running on the aux-router (as we call
it). The www user has passwordless sudo rules that allow the web code to
call scripts for adding and removing a client to and from ipfw tables [2].

You're also going to need to get ipfw to play with bridging. For this,
you'll need to `sysctl -w` [3].

The portion of your ruleset is going to look something like this:
$cmd allow all from $TABLE_AUTH to any bridged
$cmd allow all from any to $TABLE_AUTH bridged
$cmd fwd,3128 tcp from $MY_SUBNET to any http bridged
$cmd deny all from any to any bridged

NB: you may need IPFIREWALL_FORWARD enabled to get full use of the fwd

You'll also probably need to poke holes for or deal with DNS, any remote
webserver your authentication process may require access to, etc.

Also note, I haven't actually done this with bridging, so your mileage
my vary. I found 2 tools to be invaluable when working on this project:

1) tcpdump (use -i for interface, and watch the traffic in order to
   profile exactly what you need to allow, fwd, etc.).
2) ipfw logging. I found that on any deny rule, especially when
   troubleshooting, I'd do something like:

   $cmd deny log logamount 0 all from any to any bridged

   Or, just as useful, but you can stick anywhere in the middle without
   affecting packet flow:

   $cmd count log logamount 0 all from any to any bridged
   NB: AFAIK, requires kernel option IPFIREWALL_VERBOSE

I might be able to give you some more pointers if you get stumped, but I
hope this helps you get well on your way.

[2] ipfw(8) /LOOKUP TABLES
[3] ipfw(8) /PACKET FLOW

Chris Cowart
Network Technical Lead
Network & Infrastructure Services, RSSP-IT
UC Berkeley
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
Url :

More information about the freebsd-questions mailing list