Solved Improve rules for a web server (newbie about pf)

Hello,

pf in FreeBSD is not my strongest side, is there anything I should improve (or anything missing) in our pf setup for a basic web server with low traffic?

Thank you very much,

Code:
ext_if="vmx0"
me="11.22.33.44"
good_tcp_ports="{ 33333,443,80,8080,25,22222 }"

set skip on lo0

block in all
block out all

table <blockedips> persist file "/usr/local/etc/pf.blocked.ip.conf"
block drop in log (all) quick on $ext_if from <blockedips> to any

pass in quick on $ext_if inet proto tcp from any to $me port $good_tcp_ports

pass in on $ext_if proto tcp from any to $me port 22222 flags S/SA synproxy state
pass in on $ext_if proto tcp from any to $me port > 40000 keep state
pass out keep state

pass in quick on $ext_if inet proto udp from any port 53 to $me
pass in on $ext_if inet proto icmp all icmp-type echoreq keep state
pass out quick on $ext_if inet proto { tcp, udp, icmp } from $me to any
 
Here's my ruleset for home use, set to block incoming traffic.

I use one rule to Deny all traffic where you have 2, block in all and block out all. Your pass out rule should keep and modulate state. I use other options like scrub and antispoof you might want to adopt:

Code:
### Macro name for external interface
ext_if = "em0"
netbios_tcp = "{ 22, 23, 25, 80, 110, 111, 123, 512, 513, 514, 515, 6000, 6010 }"
netbios_udp = "{ 123, 512, 513, 514, 515, 5353, 6000, 6010 }"

### Reassemble fragmented packets
scrub in on $ext_if all fragment reassemble

### Default deny everything
block log all

### Pass loopback
set skip on lo0

### Block spooks
antispoof for lo0
antispoof for $ext_if inet
block in from no-route to any
block in from urpf-failed to any
block in quick on $ext_if from any to 255.255.255.255
block in quick log on $ext_if from { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 255.255.255.255/32 } to any

### Block all IPv6
block in quick inet6 all
block out quick inet6 all

### Block to and from port 0
block quick proto { tcp, udp } from any port = 0 to any
block quick proto { tcp, udp } from any to any port = 0

### Block specific ports
block in quick log on $ext_if proto tcp from any to any port $netbios_tcp
block in quick log on $ext_if proto udp from any to any port $netbios_udp

### Keep and modulate state of outbound tcp, udp and icmp traffic
pass out on $ext_if proto { tcp, udp, icmp } from any to any modulate state
 
If pf isn't for you then why not use one of the other two firewalls? Remember: security is a process, not a product to turn on it off, and a basic understanding of your firewall is part of that process.
 
Code:
pass in quick on $ext_if inet proto tcp from any to $me port $good_tcp_ports
Don't use $me, use something like this instead:
Code:
pass in quick on $ext_if inet proto tcp from any to ($ext_if) port $good_tcp_ports
That ($ext_if) will get translated to the address of the interface. Should your IP address change then you don't have to modify your firewall.

Code:
good_tcp_ports="{ 33333,443,80,8080,25,22222 }"
What exactly do you plan on running on 33333 and 22222? And don't open port 25 incoming unless you fully understand how to protect your mail server against attacks. It will get scanned, and it will get abused within a couple of minutes of being open to the internet.

Code:
pass in quick on $ext_if inet proto udp from any port 53 to $me
Unless you run an authoritative DNS server don't allow incoming DNS requests. If you don't know what an authoritative DNS is then don't allow any incoming DNS requests. Same as with port 25, it will be found and it will get abused as a DDoS amplifier. You do want to allow outgoing DNS requests or your machine won't be able to resolve anything. DNS works on both UDP and TCP nowadays.

Code:
pass in on $ext_if proto tcp from any to $me port > 40000 keep state
Why this?

Code:
pass in on $ext_if proto tcp from any to $me port 22222 flags S/SA synproxy state
This is already covered by the $good_tcp_ports rule. Don't create multiple rules that do the same thing, it'll just make things confusing.
 
SirDice Thank you for your exhaustive answer.

Good point about the IP address variable, going to change that.

The port number 33333 and 22222 is actually just made up fake numbers for the real FTP and SSH port numbers.

When I saw that there was an answer from this forum, I actually had a Putty session open, running # tail -f /var/log/maillog I don't remember why port 25 is (was) open, as we never receives any mail, just sends. It's dead silent now ;) Good to know about port 53 as well, removing that line.

As for the following line, I think we needed that one to be able to use FTPS through our router, I'm not sure right now.

Code:
pass in on $ext_if proto tcp from any to $me port > 40000 keep state

The same applies for the following line:

Code:
pass in on $ext_if proto tcp from any to $me port 22222 flags S/SA synproxy state

I don't have the right knowledge about the two last lines, as we got help with this for some time ago.
 
I think we needed that one to be able to use FTPS through our router, I'm not sure right now.
Use SFTP instead. That one works over SSH port and doesn't require any other ports. Works just the same as a regular FTP but encrypted. FTPS is FTP over SSL, which should also work and shouldn't need any additional ports either. Plain old FTP does but you really shouldn't be using that any more.

I don't have the right knowledge about the two last lines, as we got help with this for some time ago.
Code:
pass in on $ext_if inet proto icmp all icmp-type echoreq keep state
Allows incoming ICMP Echo requests. More commonly known as ping(8). Note that the Windows 'ping' utility uses UDP, not ICMP to ping.
 
And don't open port 25 incoming unless you fully understand how to protect your mail server against attacks. It will get scanned, and it will get abused within a couple of minutes of being open to the internet.
It sure will. I, or one of the Agents of Chaos, will be running security/proxycheck or security/nmap to check for open TCP and UDP port 25 and your IP# will appear in the proxy list of vulnerable machines. Soon Agents will be using your IP# port 25 with net/proxychains to do our work and it looks like you are doing it.

Deterministic Chaos at our command...

Your last line on the ruleset should look like this:
Code:
### Keep and modulate state of outbound tcp, udp and icmp traffic
pass out on $ext_if proto { tcp, udp, icmp } from any to any modulate state
 
It sure will. I, or one of the Agents of Chaos, will be running security/proxycheck or security/nmap to check for open TCP and UDP port 25 and your IP# will appear in the proxy list of vulnerable machines. Soon Agents will be using your IP# port 25 with net/proxychains to do our work and it looks like you are doing it.

Deterministic Chaos at our command...

Your last line on the ruleset should look like this:
Code:
### Keep and modulate state of outbound tcp, udp and icmp traffic
pass out on $ext_if proto { tcp, udp, icmp } from any to any modulate state
Thanks for your input Trihexagonal - I really appreciate it, going to check the last in our config soon enough :)
 
Use SFTP instead. That one works over SSH port and doesn't require any other ports. Works just the same as a regular FTP but encrypted. FTPS is FTP over SSL, which should also work and shouldn't need any additional ports either. Plain old FTP does but you really shouldn't be using that any more.


Code:
pass in on $ext_if inet proto icmp all icmp-type echoreq keep state
Allows incoming ICMP Echo requests. More commonly known as ping(8). Note that the Windows 'ping' utility uses UDP, not ICMP to ping.
Thanks again SirDice - I really appreciate you guys taking your time answering 🙏:)
 
Back
Top