Jump to content
Shogun

PF Sample Config

Recommended Posts

Update April 2020

 

I have modified the rules to allow ipv6 connections, and added some comments.

 

Hello,
 

As I had just posted the file without any explanation of it, which is not really useful unless you are already familiar with pf, I have added a little tutorial.

This is a sample pf.conf file that you can use as a base to create your own for your Metin2 FreeBSDserver. As you can see it was originally made by Tim and I have used it ever since on my server.
 

If you host your website in a different IP address than your game server, it's a good idea to add it's IP to the trusted_hosts table (you can remove the dummy address that I placed there safely). Any host that you want to have "free access", that is, skip firewall rules, should be added there. IP addresses must be separated by commas.

 

Only the ports that you specify under service_ports and game_ports will be open. service_ports should generally include your SSH port, and 80 if you are running a web server.

 

We also apply packet scrubbing and a limit on the number of connections, both measures helpful against certain types of attacks.
 
Although this configuration allows UDP for ServerCheck to work, it is a good idea to completely block UDP, although you may need to change the login screen if you use a standard login so it doesn't show your channels as offline.
 

# pf config by Shogun on 4th April 2020
# This is a minimalistic configuration with basic rate limiting

# Change the value to reflect your public interface. You can see this with ifconfig.

ext_if="igb0"

# A custom list with ports used for services (ssh, http, https) - we can also name them as per /etc/services
# instead of using numbers. The commented out line would do the same as the previous one.

service_ports="{ 22, 80, 443 }"
#service_ports="{ ssh, http, https }"

# Another custom list with ports used by Metin2 (these numbers are just an example, replace with all your
# auth and game ports. db does not need to be publicly accessible)

game_ports="{ 11002, 13001, 13002, 13003, 13004, 13099 }"

# IP addresses that should override the firewall rules, such as your web server.
# If you have many IP addresses to whitelist, you can keep them in a text file instead, one IP per line.
# Unless you have a static IP, it's not a good idea to place your own IP address here.

table <trusted_hosts> const { 83.122.73.44, 8.8.8.8 }
# table <trusted_hosts> persist file "/var/db/trusted_hosts"

table <abusive_hosts> persist

# we drop blocked packets instead of returning them, as that would make us vulnerable to a RST flood
# (flooding your own outbound connection responding to blocked packets)
set block-policy drop
# Set the interface we want to log
set loginterface $ext_if
# Do not process localhost connections
set skip on lo
# Sanitize packets
scrub on $ext_if reassemble no-df random-id

# Drop spoofed packets
antispoof for { $ext_if } inet

block log in

pass in quick from <trusted_hosts>
block in quick from <abusive_hosts>

# Allow ping in
pass in inet proto icmp all icmp-type echoreq

# Allow connecting to our service and game ports as defined at the beginning of the file.
# IP adresses with excessive connections will be blocked and placed in abusive_hosts table.
# We are allowing only TCP connections on service ports, whereas we allow UDP and TCP for Metin2.
# UDP is a potential risk for DDoS attacks and Metin2 only uses UDP to verify channel state
# in the login screen, so you can safely block it by changing "{tcp,udp}" to just "tcp".

# If you want the packets dropped instead of banning the IP, remove the ", overload <abusive_hosts> flush" part.
# If you want offender IPs blocked in every port and not just the one they flooded, add "global" after flush 

# Please note that by itself, this offers very limited protection against all but the most basic and primitive
# attacks. Don't expect this script to protect you from crafty attackers.

pass in on $ext_if proto tcp to any port $service_ports flags S/SA keep state 
        (max-src-conn 64, max-src-conn-rate 32/5, overload <abusive_hosts> flush)
pass in on $ext_if proto {tcp,udp} to any port $game_ports flags S/SA keep state 
        (max-src-conn 64, max-src-conn-rate 32/5, overload <abusive_hosts> flush)

# Same for ipv6
pass in on $ext_if inet6 proto tcp to any port $service_ports flags S/SA keep state 
        (max-src-conn 64, max-src-conn-rate 32/5, overload <abusive_hosts> flush)
pass in on $ext_if inet6 proto {tcp,udp} to any port $game_ports flags S/SA keep state 
        (max-src-conn 64, max-src-conn-rate 32/5, overload <abusive_hosts> flush)

# Let outbound connections through. Keep state means that the connection doesn't need to be
# processed again by the firewall every time there is a packet sent back and forth. Note
# that UDP does not keep state and is not affected by this setting.

pass out all keep state
pass out on $ext_if all modulate state

 

 

Edited by Shogun (see edit history)
  • Love 9

Share this post


Link to post

I have added a little explanation of the file on the first post. Here's also a

 

PF Quickstart Guide
 
To enable pf on your server, you can follow these steps after you have saved the pf.conf file. Be careful not to lock yourself out with wrong firewall rules, it's a good idea to add your own IP address to trusted_hosts if you are unsure of your changes.

kldload pf
pfctl -f /etc/pf.conf

If everything is correct it should display this:

No ALTQ support in kernel
ALTQ related functions disabled

To load pf on every boot add this line to /etc/rc.conf:

pf_enable="YES"

Managing the IP ban list

 

To show all banned IPs:

pfctl -t abusive_hosts -T show

To ban an IP:

pfctl -t abusive_hosts -T add 8.8.8.8

To unban an IP:

pfctl -t abusive_hosts -T delete 8.8.8.8

To unban all IPs:

pfctl -t abusive_hosts -T flush
  • Love 2

Share this post


Link to post

And the port 15000 ?

 

Port 15000 should never be publicly open! Only the game cores need to connect to it, not your users. In fact it's a security risk as anybody can create an auth server which connects to your db core and login any account they want on your server.

Share this post


Link to post

And the port 15000 ?

 

I like to block the P2P ports and port 15000 from outside access

Share this post


Link to post

 

pass in on $ext_if proto {tcp,udp} to any port $game_ports flags S/SA keep state

        (max-src-conn 30, max-src-conn-rate 15/5, overload <abusive_hosts> flush)

i think to know that the rule had to be like this

pass in on $ext_if proto {tcp,udp} to any port $game_ports flags S/SA keep state 
        (source-track rule, max-src-conn 30, max-src-conn-rate 15/5, overload <abusive_hosts> flush)

I'm not completly sure, but i think "max-src-conn" and "conn-rate" can't take affect without sourcetrackrule

Share this post


Link to post

According to this

 

"Both of these options automatically invoke the source-track rule option and are incompatible with source-track global."

  • Love 1

Share this post


Link to post

So i have a question. How can i approach this task. I want to reject all conections wich are for more than 3 seconds synchronizing? Or these connections which are lagging for more than 15sec?

Share this post


Link to post

So i have a question. How can i approach this task. I want to reject all conections wich are for more than 3 seconds synchronizing? Or these connections which are lagging for more than 15sec?

 

I don't think that's even possible.

  • Love 1

Share this post


Link to post

At line 4 you write: ext_if="eth0"

If I do "ifconfig", there's nothing with eth0 so I have to change?

 

Regards

Share this post


Link to post

You have to change to whatever the name of the public interface is:

 

For example here my public interface is called re0

 

208106ff93.png

 

 

  • Love 1

Share this post


Link to post

Only the specified ports are open, the rest is blocked.

Share this post


Link to post

Where and what do I have to book now in the PF register so that the port 15000 is blocked and only localhost can access it security fix?

Share this post


Link to post

You have to change to whatever the name of the public interface is:

 

For example here my public interface is called re0

 

208106ff93.png

 

Juan, You are showing your servers ip address.

Share this post


Link to post

And what's the point in attacking a test server...

  • Love 1

Share this post


Link to post

A new sample config for a FreeBSD server running nginx with cloudflare and teamspeak.

 

If you want to use the bruteforce protection feature, install the sshguard-pf package (/usr/ports/security/sshguard-pf)

ext_if="igb0"
service_ports="{ 22,80,443,10011,30033 }"
udp_ports="{ 9987 }"
table <trusted_hosts> persist file "/var/db/trusted_hosts"
table <abusive_hosts> persist
table <sshguard> persist
icmp_types = "{ echoreq, unreach }"

set block-policy drop
set loginterface $ext_if
set optimization aggressive
set limit { frags 32000, states 64000 }
set skip on lo

scrub on $ext_if all random-id min-ttl 64 max-mss 1440 set-tos reliability reassemble tcp fragment reassemble

antispoof quick for { lo0 $ext_if }

block in

block in quick on $ext_if proto tcp from <sshguard> to any port 22 label "ssh bruteforce"

pass out all keep state
pass out on $ext_if all modulate state

pass in quick from <trusted_hosts>
block in quick from <abusive_hosts>

pass inet proto icmp all icmp-type $icmp_types keep state

pass in on $ext_if proto tcp to any port $service_ports flags S/SA synproxy state 
        (max-src-conn 50, max-src-conn-rate 25/5, overload <abusive_hosts> flush global)

pass in on $ext_if proto udp to any port $udp_ports keep state (max-src-states 5, max-src-conn-rate 5/5, overload <abusive_hosts> flush)

In /var/db/trusted_hosts, Cloudflare:

199.27.128.0/21
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/12
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32
  • Love 2

Share this post


Link to post

 

A new sample config for a FreeBSD server running nginx with cloudflare and teamspeak.

 

If you want to use the bruteforce protection feature, install the sshguard-pf package (/usr/ports/security/sshguard-pf)

ext_if="igb0"
service_ports="{ 22,80,443,10011,30033 }"
udp_ports="{ 9987 }"
table <trusted_hosts> persist file "/var/db/trusted_hosts"
table <abusive_hosts> persist
table <sshguard> persist
icmp_types = "{ echoreq, unreach }"

set block-policy drop
set loginterface $ext_if
set optimization aggressive
set limit { frags 32000, states 64000 }
set skip on lo

scrub on $ext_if all random-id min-ttl 64 max-mss 1440 set-tos reliability reassemble tcp fragment reassemble

antispoof quick for { lo0 $ext_if }

block in

block in quick on $ext_if proto tcp from <sshguard> to any port 22 label "ssh bruteforce"

pass out all keep state
pass out on $ext_if all modulate state

pass in quick from <trusted_hosts>
block in quick from <abusive_hosts>

pass inet proto icmp all icmp-type $icmp_types keep state

pass in on $ext_if proto tcp to any port $service_ports flags S/SA synproxy state 
        (max-src-conn 50, max-src-conn-rate 25/5, overload <abusive_hosts> flush global)

pass in on $ext_if proto udp to any port $udp_ports keep state (max-src-states 5, max-src-conn-rate 5/5, overload <abusive_hosts> flush)

In /var/db/trusted_hosts, Cloudflare:

199.27.128.0/21
173.245.48.0/20
103.21.244.0/22
103.22.200.0/22
103.31.4.0/22
141.101.64.0/18
108.162.192.0/18
190.93.240.0/20
188.114.96.0/20
197.234.240.0/22
198.41.128.0/17
162.158.0.0/15
104.16.0.0/12
2400:cb00::/32
2606:4700::/32
2803:f800::/32
2405:b500::/32
2405:8100::/32

Thanks fot this :D

  • Love 1

Share this post


Link to post

You are welcome let me know if you have any question.

 

The configuration is made by MartPwnS and me based on the original one by Tim which you can find in the first post.

Share this post


Link to post

For me,don`t work I copy and paste your config and : No ALTQ support in kernel ALTQ related functions disabled /etc/pf.conf:41: syntax error pfctl: Syntax error in config file: pf rules not loaded The problems is at : Rate limits, trial and error pass in on $ext_if proto tcp to any port $service_ports flags S/SA keep state (max-src-conn 30, max-src-conn-rate 15/5, overload flush) pass in on $ext_if proto {tcp,udp} to any port $game_ports flags S/SA keep state (max-src-conn 30, max-src-conn-rate 15/5, overload flush)

Share this post


Link to post

The original config (and the modified one too!) uses states to keep track of open connections. The state table however, is by default limited to 10000 entries (FreeBSD 10.1 amd64), which could lead to problems during medium-/large-scale attacks, since new connections will be dropped once the table is full.

 

I usually use the following memory pool limits for PF:

set limit { states 100000, frags 20000, src-nodes 100000, table-entries 200000 }

Raising the table-entries limit is also a good idea if you have dynamically filled tables of "bad hosts", same goes for src-nodes.

 

It's also recommended to have a few whitelisted static IPs, whose traffic is passed unconditionally and stateless.

e.g.:

table <ovh> const { 213.186.33.13, 213.186.50.100 }

pass in quick on $ext_if from <ovh> to any no state
  • Love 4

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.