Solved pf and freebsd-update

I'm trying to get freebsd-update to run with a simple pf(4) firewall config.

Here it is:

web_services = "{ 80, 443 }"

ext_if = "xn0"

block all

pass out log on $ext_if proto tcp to any port $web_services

The last line appears to be faulty, as freebsd-update does not connect when it is active, but works with-

pass out all
 
It would normally be necessary to allow outbound DNS queries to resolve the addresses of the FreeBSD update servers, unless you have them listed in your hosts(5) file.
Try adding the line:
Code:
pass out on $ext_if proto { udp,  tcp } to any port 53
 
Unless you want to do a super tightly locked down system you usually want to allow everything on lo0 with this option:

Code:
set skip on lo0
 
It would normally be necessary to allow outbound DNS queries to resolve the addresses of the FreeBSD update servers, unless you have them listed in your hosts(5) file.
Try adding the line:
Code:
pass out on $ext_if proto { udp,  tcp } to any port 53

Thanks - allowing 53 out did the trick. :beer::)

Unless you want to do a super tightly locked down system you usually want to allow everything on lo0 with this option:

Code:
set skip on lo0

Also thanks - I have that in there already but omitted it in my post for simplicity.
 
Great! If you want a tighter configuration, you could use a table for the IP addresses of the FreeBSD update servers so that connections are only permitted to them rather than to any server. You could write a script that runs periodically to refresh that list of IP addresses. Also, instead of calling freebsd-update(8) directly, you could write a script that changes the firewall rules to permit the connections (in PF, an anchor would be perfect for such a task) you need, runs freebsd-update(8) and then changes the firewall rules back. Though I would also say that if you really need such a tight configuration you might want to consider whether being connected to the Internet is such a good idea :)
 
Great! If you want a tighter configuration, you could use a table for the IP addresses of the FreeBSD update servers so that connections are only permitted to them rather than to any server. You could write a script that runs periodically to refresh that list of IP addresses. Also, instead of calling freebsd-update(8) directly, you could write a script that changes the firewall rules to permit the connections (in PF, an anchor would be perfect for such a task) you need, runs freebsd-update(8) and then changes the firewall rules back. Though I would also say that if you really need such a tight configuration you might want to consider whether being connected to the Internet is such a good idea :)

That's all great advice, thanks. Was wondering what I should put in a script to get the IP addresses of the update servers? And do their IPs ever change?
 
I'm pretty sure you can throw hostnames at pfctl(8) for rules and tables and let it do the DNS lookup. When I did this myself I remember the subtlety to doing this on startup is that PF comes up before name resolution. I ended up writing my own rc(8) script that ran later in the boot process to populate the table of IP addresses, with something similar being called from periodic(8).

All that said, you probably don't want to be doing automated unattended updates in case something goes wrong. If the IPs rarely change you could stick them into hosts(5), list them explicitly in pf.conf(5) and then just update the manually if something goes awry. That would also mean that you don't need to worry about allowing/disallowing DNS traffic at the appropriate time. I have seen many otherwise tight firewall configurations let down by the ability to connect to anywhere outbound on port 53. But again... if you are that concerned about this system, perhaps having it physically connected to the Internet is not the thing to do.
 
If you have multiple FreeBSD hosts that need updating I can highly recommend using a caching proxy for it. That way only the proxy machine needs access to the internet. The added bonus is also that only the first update needs to be downloaded from the internet, the next machine will get its updates from the proxy cache.
 
Back
Top