# Blocking sites with PF?



## Deleted member 2077 (May 22, 2012)

I recently switched to pf from ipfw and trying to figure out how to block a list of sites from a file?  I tried google, but must be using the wrong keywords.

In ipfw I just had a list of sites: /etc/badguys.txt and had a simple bash script to loop though and do this for each line:


```
ipfw add $id deny ip from any to "$url"
```

Is there a way to do this with pf?

The list changes a lot, so don't want to hardcode it in /etc/pf.conf


----------



## wblock@ (May 22, 2012)

pf(4) has support for persistent tables, at least of IP addresses.  Haven't tried domain names or URLs, but be aware that domain names don't always resolve to the same IP.


----------



## bbzz (May 22, 2012)

Maybe not an answer to your question, but use *squid* proxy/*dansguardian* for content filtering, way more effective than to let firewall do this.


----------



## Deleted member 2077 (May 22, 2012)

bbzz said:
			
		

> Maybe not an answer to your question, but use *squid* proxy/*dansguardian* for content filtering, way more effective than to let firewall do this.



We do have squid and block some sites though that; but we need to block more than websites.  For example, one user got a virus that keeps "calling home" and needed a quick way to just stop all that traffic.  There is nothing valid on that IP that anyone needed, so a way to block all traffic would have been quite useful.


----------



## Deleted member 2077 (May 22, 2012)

wblock@ said:
			
		

> pf(4) has support for persistent tables, at least of IP addresses.  Haven't tried domain names or URLs, but be aware that domain names don't always resolve to the same IP.



Thanks, I've been trying that; but hasn't been working:

/etc/pf.conf

```
table <blockedips> persist file "/etc/pf.blocked.ip.conf"

ext_if="em0"
int_if="em1"
int_net="{ 192.168.17.0/24 }"

set skip on lo
scrub in

nat on $ext_if from $int_net to any -> ($ext_if)

block in
block drop in log (all) quick on $ext_if from <blockedips> to any
block drop out log (all) quick on $ext_if from <blockedips> to any
pass out

pass quick on $int_if no state
antispoof quick for { lo $int_if }

# allow dns queries on local
pass out on $int_if proto udp from any to any port 53 keep state

# ssh
pass in on $ext_if proto tcp to ($ext_if) port ssh
# http
pass in on $ext_if proto tcp to ($ext_if) port http
pass in on $ext_if proto tcp to ($ext_if) port https

#pass out on $ext_if inet proto icmp from any to ($ext_if) icmp-type { unreach,redir,timex }
```

/etc/pf.blocked.ip.conf has one IP address (for testing).

I reloaded rules with */etc/rc.d/pf reload* - but still can get to that IP.  Ping, tcp port 80, are all still accessible.

I also tried adding the block statements to bottom, but same result.  Any ideas?


----------



## wblock@ (May 23, 2012)

Version of FreeBSD may be important, pf(4) varies.

On FreeBSD 8, I have

```
block in quick on $ext_if from <annoyingips> to any
```

The "to" and "from" on your second rule look backwards.


----------



## Deleted member 2077 (May 23, 2012)

It's RELENG_9_0, not sure what version of pf (whatever is the default).

If I change to/from I get a syntax error

```
/etc/pf.conf:21: syntax error
```


----------



## CoTones (May 23, 2012)

Hello, change 


```
block drop out log (all) quick on $ext_if from <blockedips> to any
```

to

```
block drop out log (all) quick on $ext_if from any to <blockedips>
```

Regards,
CoTones


----------



## SirDice (May 23, 2012)

feralape said:
			
		

> We do have squid and block some sites though that; but we need to block more than websites.  For example, one user got a virus that keeps "calling home" and needed a quick way to just stop all that traffic.  There is nothing valid on that IP that anyone needed, so a way to block all traffic would have been quite useful.



Quick solution, block _all_ outgoing traffic. Force everyone through a proxy and only allow the proxy to connect to the internet. Use proper content filtering on the proxy.

Malware tends to contact its command & control servers directly. Same for any spamming, the malware will try to deliver the email directly to the receiving mailservers. For this reason you shouldn't allow any machine direct access to the internet. That way you keep control on what's going in or out your network.


----------



## Deleted member 2077 (May 23, 2012)

CoTones said:
			
		

> Hello, change
> 
> 
> ```
> ...



Thanks!  That worked like a charm.


----------



## Deleted member 2077 (May 23, 2012)

SirDice said:
			
		

> Quick solution, block _all_ outgoing traffic. Force everyone through a proxy and only allow the proxy to connect to the internet.



Depends on the environment, but here that won't be a quick solution as it could be potentially high impact and far reaching..   We would need approvals, testing and all sorts of red tape.  It's a viable long term solution though.


----------



## sidetone (Dec 20, 2015)

update.

pf(4) can block numerical IP addresses, not named IP addresses. hosts.allow is for that.


----------



## User7 (Dec 20, 2015)

> I recently switched to pf from ipfw



What is the reason to switch IPFW to PF?


----------



## sidetone (Dec 20, 2015)

That quote is from a long time ago, and the person is unlikely to respond. I just updated to give this thread an answer for closure.

...
But I use pf because there's more documentation available, it has more features, and it comes from a security oriented operating system. I use it in conjunction with IPFW and one of it's generic configuration. IPF was replaced by PF, so I see it as obsolete specifically for a BSD environment.


----------

