# Best way to do country bans using a FreeBSD firewall?



## Anon (Oct 4, 2011)

I want to ban about 50 countries.


----------



## graudeejs (Oct 4, 2011)

If you want to ban Latvia... you can
`$ fetch -q -m -o /path/to/latvian_ips [url]http://www.nic.lv/local.net[/url]`
To get Latvian IP's

Probably you can do something similar for other countries

After that is' matter of loading IP's to firewall table and adding proper rule


----------



## Anon (Oct 4, 2011)

graudeejs said:
			
		

> If you want to ban Latvia... you can
> `$ fetch -q -m -o /path/to/latvian_ips [url]http://www.nic.lv/local.net[/url]`
> To get Latvian IP's
> 
> ...



Could you show me the proper rules to add in ipfw? For example, what would I input if I want to block these IP's:
http://www.ipdeny.com/ipblocks/data/countries/aw.zone


----------



## graudeejs (Oct 4, 2011)

It's in manual (ipfw(8))


----------



## Anon (Oct 4, 2011)

graudeejs said:
			
		

> It's in manual (ipfw(8))



I need to add hundreds of lines, I am going to use IPF though.

Any generators?


----------



## DutchDaemon (Oct 4, 2011)

Use pf, so you can put IP ranges in files and load them as tables.


----------



## Anon (Oct 4, 2011)

DutchDaemon said:
			
		

> Use pf, so you can put IP ranges in files and load them as tables.



Hey DutchDaemon, do you have any good PF tutorials for a newbie on FreeBSD 8.1?


----------



## Crest (Oct 4, 2011)

IPFW supports IPv4 only tables see ipfw. And their is an (untested) patch for IPv6 tables.


----------



## DutchDaemon (Oct 4, 2011)

ipfw does not load tables from _files_, so you have to script additions and deletions, one by one. That's a major PITA. You can load an altered list of IPs in pf like this:

[cmd=]/sbin/pfctl -t annoying-hosts -Tr -f /tmp/annoying-hosts[/cmd]

pf.conf(5)

Tutorials/FAQs: http://www.bsdly.net/~peter/pf.html / http://www.openbsd.org/faq/pf/ / http://www.benzedrine.cx/pf.html


----------



## Anon (Oct 4, 2011)

DutchDaemon said:
			
		

> ipfw does not load tables from _files_, so you have to script additions and deletions, one by one. That's a major PITA. You can load an altered list of IPs in pf like this:
> 
> [cmd=]/sbin/pfctl -t annoying-hosts -Tr -f /tmp/annoying-hosts[/cmd]
> 
> ...



Oh cool, /sbin/pfctl seems to be already installed, awesome.

Thanks again DutchDaemon.


----------



## DutchDaemon (Oct 4, 2011)

pf, ipf and ipfw are all part of the FreeBSD base system.. Note that pfctl is not some magical, stand-alone program. It is a tool to manipulate the pf packet filter, together with the pf.conf ruleset. There are hundreds of examples on the web and on these forums.


----------



## Anon (Oct 5, 2011)

Hey DutchDaemon I'm trying to find a script to add stuff in this format:
http://www.ipdeny.com/ipblocks/data/countries/au.zone

Any ideas?


----------



## DutchDaemon (Oct 5, 2011)

I gave you the command that will do just that; just download the URL to a local file with e.g. fetch(1) and load it as a pf table. It understands CIDR notation. Don't think of 'scripts' right now, just learn how to use pf, how to write a pf.conf, and how to use pfctl.


----------



## Anon (Oct 5, 2011)

DutchDaemon said:
			
		

> I gave you the command that will do just that; just download the URL to a local file with e.g. fetch(1) and load it as a pf table. It understands CIDR notation. Don't think of 'scripts' right now, just learn how to use pf, how to write a pf.conf, and how to use pfctl.



Alrighty, reading through your tutorials right now, thanks again.

This is how you start it as I understand?

```
/etc/rc.d/pf start
```


----------



## DutchDaemon (Oct 5, 2011)

As you will read [...] one normally starts it from rc.conf(5), in order to boot it with the system. Seriously though: read the documentation, because everything you could ask is in there sooner or later, and there are dozens of topics on it in here.


----------



## Anon (Oct 5, 2011)

This config:

```
table <cn-block> persist file "/usr/local/www/cn.zone"
block in log quick on $ext_if from <cn-block> to any
block out log quick on $ext_if from any to <cn-block>
```

Gives me back:

```
# /etc/rc.d/pf start
Enabling pfNo ALTQ support in kernel
ALTQ related functions disabled
/etc/pf.conf:2: macro 'ext_if' not defined
/etc/pf.conf:2: syntax error
/etc/pf.conf:3: macro 'ext_if' not defined
pfctl: Syntax error in config file: pf rules not loaded
No ALTQ support in kernel
ALTQ related functions disabled
.
```


----------



## Anon (Oct 5, 2011)

Do you guys think this is working now?

```
# pfctl -d ; pfctl -e -f /etc/pf.conf
No ALTQ support in kernel
ALTQ related functions disabled
pfctl: pf not enabled
No ALTQ support in kernel
ALTQ related functions disabled
pf enabled
# pfctl -s all
No ALTQ support in kernel
ALTQ related functions disabled
FILTER RULES:
block drop in log quick on sis0 from <cn-block> to any
block drop out log quick on sis0 from any to <cn-block>

INFO:
Status: Enabled for 0 days 00:00:12           Debug: Urgent

State Table                          Total             Rate
  current entries                        0               
  searches                            2228          185.7/s
  inserts                                0            0.0/s
  removals                               0            0.0/s
Counters
  match                               2228          185.7/s
  bad-offset                             0            0.0/s
  fragment                               0            0.0/s
  short                                  0            0.0/s
  normalize                              0            0.0/s
  memory                                 0            0.0/s
  bad-timestamp                          0            0.0/s
  congestion                             0            0.0/s
  ip-option                              0            0.0/s
  proto-cksum                            0            0.0/s
  state-mismatch                         0            0.0/s
  state-insert                           0            0.0/s
  state-limit                            0            0.0/s
  src-limit                              0            0.0/s
  synproxy                               0            0.0/s

TIMEOUTS:
tcp.first                   120s
tcp.opening                  30s
tcp.established           86400s
tcp.closing                 900s
tcp.finwait                  45s
tcp.closed                   90s
tcp.tsdiff                   30s
udp.first                    60s
udp.single                   30s
udp.multiple                 60s
icmp.first                   20s
icmp.error                   10s
other.first                  60s
other.single                 30s
other.multiple               60s
frag                         30s
interval                     10s
adaptive.start             6000 states
adaptive.end              12000 states
src.track                     0s

LIMITS:
states        hard limit    10000
src-nodes     hard limit    10000
frags         hard limit     5000
tables        hard limit     1000
table-entries hard limit   100000

TABLES:
cn-block

OS FINGERPRINTS:
696 fingerprints loaded
```


----------



## wblock@ (Oct 5, 2011)

The Handbook has a section on PF, along with a link to the PF FAQ.

Wholesale blocking of countries by IP address may not be effective at whatever you're trying to achieve.


----------



## Anon (Oct 5, 2011)

It doesn't seem to work.

I think I might have the wrong name on this:   _### macro name for external interface._

How do I find out my "macro name for external interface", please?


----------



## Anon (Oct 5, 2011)

wblock@ said:
			
		

> The Handbook has a section on PF, along with a link to the PF FAQ.
> 
> Wholesale blocking of countries by IP address may not be effective at whatever you're trying to achieve.



Well, what I'm trying to achieve is blocking certain countries from posting on my site.


----------



## Anon (Oct 5, 2011)

Everytime I do _pfctl -s all_

The State Table total increases. I'm guessing this is normal?


----------



## Anon (Oct 5, 2011)

Okay, when I use proxies of the countries I blocked either two things happen:
They load forever or they 503.

This is... normal? This is what I want, right?


----------



## Anon (Oct 5, 2011)

Could I please get an explanation to what this stuff means?


```
State Table                          Total             Rate
  current entries                       21              
  searches                           23269           23.4/s
  inserts                              289            0.3/s
  removals                             268            0.3/s
Counters
  match                               3941            4.0/s
  bad-offset                             0            0.0/s
  fragment                               0            0.0/s
  short                                  0            0.0/s
  normalize                              0            0.0/s
  memory                                 0            0.0/s
  bad-timestamp                          0            0.0/s
  congestion                             0            0.0/s
  ip-option                              0            0.0/s
  proto-cksum                            0            0.0/s
  state-mismatch                         0            0.0/s
  state-insert                           0            0.0/s
  state-limit                            0            0.0/s
  src-limit                              0            0.0/s
  synproxy                             705            0.7/s
```


----------



## graudeejs (Oct 5, 2011)

`$ grep -v -e '^#' '/path/to/ip/list' | xargs -n 1 ipfw -q table $TABLE_NUMBER add`


----------



## Anon (Oct 5, 2011)

graudeejs said:
			
		

> `$ grep -v -e '^#' '/path/to/ip/list' | xargs -n 1 ipfw -q table $TABLE_NUMBER add`



Thanks again graudeejs, but I think I got it.

Unfortunately my site loads at half a second slower now, is this normal?


----------



## Kai (Sep 9, 2016)

All, I know this is a 5 year old thread and this is some serious necromancy reviving it. But I was recently looking for quick and easy ways to do this myself and this thread is the #1 google hit. Inspired by the thread and a boring Sat night I went away and wrote a perl script that will do exactly this "Block bad countries based on lists of IPs blocks pulled from ipdeny.com" which can be run manually or as a cron job. And because I'm a masochist I made it work for IPFW, PF, for freebsd and iptables for linux. As well as ipset because iptables sucks on it's own. Only major consideration is changing the perl location in the first line of the script for linux.

Tested on FreeBSD 10.3 with pf and ipfw and Ubuntu 16 wth iptables.  

I've thrown it up here and adding this in case anyone else ends up here and wants a quick easy dirty way to do this. Project is on github here : https://github.com/KaiLoi/update-fw-BC

Enjoy


----------



## Murph (Sep 9, 2016)

Just be aware that perfect geolocation of IP is actually impossible.  I.e. 100% of the data sets out there have errors in them.  The errors come from things like a multi-national enterprise or ISP who has, for example, admins in Germany who manage the numbers, but deploys them all round Europe.  They have essentially no real obligation to publish even per-country-accurate current information in whois databases, as long as the contact info is valid and they are not camping on unreasonably large chunks of space.

I've even seen extreme examples of (not hijacked, as far as I could tell) California-registered net blocks being used in China.  My personal IPv4 netblock, with accurate whois, routinely geolocates as the wrong country.  An old work CIDR always geolocated as the wrong country (apart from the subset of users actually at that location), as it was a single whois entry for the whole of Europe (but various national ISP connections from a global private WAN).

You can just about reliably geolocate to one of: North America, South America, Europe, Africa, Asia-Pacific.  (I've missed one out there, I'm sure, it's the top level NICs)  Even those are not 100% due to some legacy allocations from the InterNIC days.


----------



## sidetone (Sep 9, 2016)

Blocking St.Petersburg and N. Korea would do plenty by itself, until they start using proxies.


----------



## obsigna (Sep 9, 2016)

North Korea is easy, you even won't need a table for blocking. They got assigned only one IPv4 block: 175.45.176.0/22. Kim got apprx. 1000 friends with world access, the rest of the country is completely free -- at least free of internet distortion, and they may freely focus on the essence of life.


----------



## Kai (Sep 12, 2016)

Murph  Yea, that's always true, but this script has seriously decimated the hacking attempts against my server. My IDS has gone from raising alerts every 5 min for probe attempts to NONE in the the last 4 days. Not one. I'm blocking most of the the "top 10 hacking countries" (other than the US) listed here http://www.govtech.com/security/204318661.html with Ukraine added.

Nothing is perfect (as it says in the readme of the script). But a lot of internet and online security is about making yourself "less of a target than that guy over there". And so much of modern intrusion and hacking is based out of automated scripts running from one of these countries scouring the net for vulnerable hosts.

If someone is targeting you specifically then there is generally little you can do. But for the "random scans catching my 0-day exposed daemon, until I can get it patched" I cannot recommend blocking the worst sources enough.

Just my 2c worth and why I wrote this.


----------



## Murph (Sep 12, 2016)

Kai Yup, I do actually have some limited per-country stuff in my PF rules. I send certain countries and ISPs into a SMTP blacklist tarpit (particular countries/ISPs that I believe will not ever have any legitimate email to send to my servers).  I don't bother with it for any other services right now, preferring dynamic blacklisting through PF's rate limits, fail2ban, and similar; plus occasional manual blacklisting of specific netblocks here and there.

I just feel it's worth making sure that anyone reading does understand that the data always has errors, and that the design of IP and management of the address allocations makes perfect geolocation impossible; so it must be used with appropriate caution / knowledge, and the risk/consequences of both false positives and false negatives needs to be understood.  My guess would be that accuracy is probably better than 90% of NIC-registry CIDR netblocks, but that up to (maybe) 10% has the potential to create pain for someone if they were not expecting it.


----------



## Kai (Sep 13, 2016)

That's fair. For me, I had so many attempts going on that it made my Intrusion detection systems just total white noise. This has brought it down to a level where, when any of the systems decides to email me with a "this is suspicious" it's usually now worth having a quick looks at. And also I'm more likely to be alerted to a new attack vector or probe that would have been lost in the noise previously. I also use a combo of things like OSSEC, fail2ban etc. as well as regular patching and updates. The script really just throws a big old blanket over the whole thing that keeps most people looking under it to see what's there.


----------

