Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: preg_match(): Unknown modifier '-' in /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php on line 783

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794

Warning: Cannot modify header information - headers already sent by (output started at /home/akl1986/public_html/support/wp-content/plugins/redux-framework/redux-core/inc/extensions/metaboxes/class-redux-extension-metaboxes.php:783) in /home/akl1986/public_html/support/wp-includes/rest-api/class-wp-rest-server.php on line 1794
{"id":2866,"date":"2019-12-27T06:48:05","date_gmt":"2019-12-27T06:48:05","guid":{"rendered":"https:\/\/support.aklwebhost.com\/?post_type=manual_kb&p=2866"},"modified":"2019-12-27T06:51:29","modified_gmt":"2019-12-27T06:51:29","slug":"how-to-secure-freebsd-with-pf-firewall","status":"publish","type":"manual_kb","link":"https:\/\/support.aklwebhost.com\/knowledgebase\/how-to-secure-freebsd-with-pf-firewall\/","title":{"rendered":"How to Secure FreeBSD with PF Firewall"},"content":{"rendered":"

This tutorial will show you how to protect your FreeBSD server using OpenBSD PF firewall. We will assume that you have a clean FreeBSD installation deployed by AKLWEB Host with no users added. We will do some other things beside Firewall configuration which will also harden the security of our FreeBSD server. Before firewall configuration, we will install some packages since the default FreeBSD installation comes with a minimal set of tools and packages (which is correct), to make it easier for us to work.<\/p>\n

The default shell in FreeBSD is\u00a0\/bin\/sh<\/code>. This is a basic shell with no auto-complete functions. We will use something better. We will install\u00a0zsh<\/code>.<\/p>\n

First, install these packages:<\/p>\n

# pkg install zsh gnuls\r\nThe package management tool is not yet installed on your system.\r\nDo you want to fetch and install it now? [y\/N]: y\r\nBootstrapping pkg from pkg+http:\/\/pkg.FreeBSD.org\/freebsd:10:x86:64\/latest, please wait...\r\n...\r\n<\/code><\/pre>\n

GNULS is the\u00a0ls<\/code>\u00a0program from Linux. We just want to have the same\u00a0ls<\/code>\u00a0command in Linux and FreeBSD.<\/p>\n

Add a normal user to the system: (replace john with your username and don’t forget to add user to the wheel group)<\/p>\n

# adduser\r\nUsername: john\r\nFull name: John Doe\r\nUid (Leave empty for default): \r\nLogin group [john]: \r\nLogin group is john. Invite john into other groups? []: wheel\r\nLogin class [default]: \r\nShell (sh csh tcsh zsh rzsh nologin) [sh]: zsh\r\nHome directory [\/home\/john]: \r\nHome directory permissions (Leave empty for default): \r\nUse password-based authentication? [yes]: \r\nUse an empty password? (yes\/no) [no]: \r\nUse a random password? (yes\/no) [no]: \r\nEnter password: \r\nEnter password again: \r\nLock out the account after creation? [no]: \r\nUsername   : john\r\nPassword   : *****\r\nFull Name  : John Doe\r\nUid        : 1001\r\nClass      : \r\nGroups     : john wheel\r\nHome       : \/home\/john\r\nHome Mode  : \r\nShell      : \/usr\/local\/bin\/zsh\r\nLocked     : no\r\nOK? (yes\/no): yes\r\nadduser: INFO: Successfully added (john) to the user database.\r\nAdd another user? (yes\/no): no\r\nGoodbye!\r\n<\/code><\/pre>\n

Create zsh config file:<\/p>\n

# ee \/home\/your-username\/.zshrc\r\n<\/code><\/pre>\n

Copy this to your .zshrc file:<\/p>\n

PS1=\"<%U%m%u>$[%B%1~%b]%(#.#.$) \"\r\n\r\nbindkey -e\r\nalias su='su -m'\r\nalias du='du -h -d0'\r\nalias df='df -h'\r\nalias l=less\r\nalias ll='gnuls --color=always -l'\r\nalias ls='gnuls --color=always'\r\nalias pkg_ver='pkg version -v -l \"<\" | > upgrade'\r\n\r\nexport EDITOR=ee\r\n\r\nautoload -U colors && colors\r\nautoload -U promptinit && promptinit\r\nautoload -U compinit && compinit\r\n\r\n# History settings\r\nSAVEHIST=1000\r\nHISTSIZE=1000\r\nHISTFILE=~\/.history\r\nsetopt histignoredups appendhistory\r\n<\/code><\/pre>\n

Run this command: (replace john with your username)<\/p>\n

chown john:john \/home\/john\/.zshrc\r\n<\/code><\/pre>\n

Now, login to the FreeBSD server with your username and change the default root password:<\/p>\n

<aklwebhost>[~]$ su\r\nPassword:\r\n<aklwebhost>[~]# passwd \r\nChanging local password for root\r\nNew Password:\r\nRetype New Password:\r\n<aklwebhost>[~]# \r\n<\/code><\/pre>\n

We don’t need sendmail. Stop and disable this service:<\/p>\n

<aklwebhost>[~]# \/etc\/rc.d\/sendmail stop\r\nStopping sendmail.\r\nWaiting for PIDS: 7843.\r\nsendmail_submit not running? (check \/var\/run\/sendmail.pid).\r\nStopping sendmail_msp_queue.\r\nWaiting for PIDS: 7846.\r\n<\/code><\/pre>\n

Next, we will change our rc.conf file to look more natural:<\/p>\n

# ee \/etc\/rc.conf\r\n<\/code><\/pre>\n

Change it to look like this:<\/p>\n

#----------- NETWORKING ------------------------------------------------#\r\nhostname=\"ceph.domain1.com\" # replace ceph.domain1.com with your domain\r\nifconfig_vtnet0=\"dhcp\"\r\nstatic_routes=linklocal\r\nroute_linklocal=\"-net 169.254.0.0\/16 -interface vtnet0\"\r\n\r\n#--------- SERVICES BSD LOCAL ----------------------------------------#\r\nsshd_enable=\"YES\"\r\nntpd_enable=\"YES\"\r\n\r\n#pf_enable=\"YES\"\r\n#pf_rules=\"\/etc\/firewall\"\r\n#pf_flags=\"\"\r\n#pflog_enable=\"YES\"              \r\n#pflog_logfile=\"\/var\/log\/pflog\"  \r\n#pflog_flags=\"\"    \r\n\r\nsendmail_enable=\"NONE\"\r\nsendmail_submit_enable=\"NO\"\r\nsendmail_outbound_enable=\"NO\"\r\nsendmail_msp_queue_enable=\"NO\"\r\n<\/code><\/pre>\n

Edit\u00a0\/etc\/hosts<\/code>\u00a0file:<\/p>\n

# ee \/etc\/hosts\r\n<\/code><\/pre>\n

Add your IP address and hostname:<\/p>\n

::1                     localhost localhost.ceph ceph\r\n127.0.0.1               localhost localhost.ceph ceph\r\n108.61.178.110          ceph.domain1.com       ceph\r\n<\/code><\/pre>\n

Set timezone:<\/p>\n

# bsdconfig\r\n<\/code><\/pre>\n

Whenever you can, disable remote access for the root user. Most attacks on SSH will try to access through the root user account. Always connect with your username and then\u00a0su<\/code>\u00a0to root. Only users from the\u00a0wheel<\/code>\u00a0group can\u00a0su<\/code>\u00a0to root. That’s why we added our user to the wheel group.<\/p>\n

Disable root login:<\/p>\n

# ee \/etc\/ssh\/sshd_config\r\n<\/code><\/pre>\n

Uncomment this line:<\/p>\n

PermitRootLogin no\r\n<\/code><\/pre>\n

Reboot:<\/p>\n

# reboot\r\n<\/code><\/pre>\n

After the reboot finishes, you will see a message like this in the AKWLEB Host console:<\/p>\n

time correction of 3600 seconds exceeds sanity limit (1000); set clock manually to\r\ncorrect UTC time.\r\n<\/code><\/pre>\n

That’s why we need to correct the clock manually. Follow these commands, first\u00a0su<\/code>\u00a0to root:<\/p>\n

$ su\r\nPassword:\r\n# ntpdate 0.europe.pool.ntp.org\r\n<\/code><\/pre>\n

Now, we are going to configure the firewall. OpenBSD PF is included in the FreeBSD kernel, so you don’t have to install any packages.<\/p>\n

With\u00a0ee<\/code>\u00a0editor, create file\u00a0\/etc\/firewall<\/code>:<\/p>\n

# ee \/etc\/firewall\r\n<\/code><\/pre>\n

Insert this: (replace any IP addresses with yours)<\/p>\n

#######################################################################\r\nme=\"vtnet0\"                \r\ntable <bruteforcers> persist    \r\ntable <trusted> persist file \"\/etc\/trusted\"\r\nicmp_types = \"echoreq\"          \r\njunk_ports=\"{ 135,137,138,139,445,68,67,3222 }\"\r\njunk_ip=\"224.0.0.0\/4\"           \r\n\r\nset loginterface vtnet0           \r\nscrub on vtnet0 reassemble tcp no-df random-id\r\n\r\n# ---- First rule obligatory \"Pass all on loopback\"\r\npass quick on lo0 all           \r\n\r\n# ---- Block junk logs\r\nblock quick proto { tcp, udp } from any to $junk_ip \r\nblock quick proto { tcp, udp } from any to any port $junk_ports\r\n\r\n# ---- Second rule \"Block all in and pass all out\"\r\nblock in log all                \r\npass out all keep state         \r\n\r\n############### FIREWALL ###############################################\r\n# ---- Allow all traffic from my Home\r\npass quick proto {tcp, udp} from 1.2.3.4 to $me keep state\r\n\r\n# ---- block SMTP out \r\nblock quick proto tcp from $me to any port 25\r\n\r\n# ---- Allow incoming Web traffic\r\npass quick proto tcp from any to $me port { 80, 443 } flags S\/SA keep state\r\n\r\n# ---- Allow my team member SSH access \r\npass quick proto tcp from 1.2.3.5 to $me port ssh flags S\/SA keep state\r\n\r\n# ---- Block bruteforcers\r\nblock log quick from <bruteforcers>\r\n\r\n# ---- Allow SSH from trusted sources, but block bruteforcers\r\npass quick proto tcp from <trusted> to $me port ssh \\\r\nflags S\/SA keep state \\\r\n(max-src-conn 10, max-src-conn-rate 20\/60, \\\r\noverload <bruteforcers> flush global)\r\n\r\n# ---- Allow ICMP \r\npass in inet proto icmp all icmp-type $icmp_types keep state\r\npass out inet proto icmp all icmp-type $icmp_types keep state\r\n<\/code><\/pre>\n

Create\u00a0\/etc\/trusted<\/code>\u00a0file. In this file, we will put IPs that we “trust”.<\/p>\n

# ee \/etc\/trusted\r\n<\/code><\/pre>\n

Add some IP’s:<\/p>\n

# Hosting\r\n1.2.0.0\/16\r\n\r\n# My friends\r\n1.2.4.0\/24\r\n<\/code><\/pre>\n

Now some explanation. Junk ports and junk IPs are just some ports\/IPs that we don’t want to see in logs. We have done this with this rule:<\/p>\n

# ---- Block junk logs\r\nblock quick proto { tcp, udp } from any to $junk_ip \r\nblock quick proto { tcp, udp } from any to any port $junk_ports\r\n<\/code><\/pre>\n

These are just defaults and you don’t have to worry about it:<\/p>\n

icmp_types = \"echoreq\"                                            \r\nset loginterface vtnet0           \r\nscrub on vtnet0 reassemble tcp no-df random-id\r\npass quick on lo0 all\r\nblock in log all                \r\npass out all keep state\r\n<\/code><\/pre>\n

This rule blocks outgoing SMTP traffic from your server (which is the default on AKLWEB Host).<\/p>\n

# ---- block SMTP out \r\nblock quick proto tcp from $me to any port 25\r\n<\/code><\/pre>\n

Except\u00a0bruteforcers<\/code>\u00a0the rest is pretty straight forward.<\/p>\n

# ---- Allow SSH from trusted sources, but block bruteforcers\r\npass quick proto tcp from <trusted> to $me port ssh \\\r\nflags S\/SA keep state \\\r\n(max-src-conn 10, max-src-conn-rate 20\/60, \\\r\noverload <bruteforcers> flush global)\r\n<\/code><\/pre>\n

Bruteforcers just says: Allow from <trusted> IPs to port 22 but only 10 concurrent connections can be made from one source IP. If it’s more than 10, block this IP and put it in table bruteforcers. The same goes for 20\/60 rule. It means a max of 20 connections in 60 seconds.<\/p>\n

Enable firewall:<\/p>\n

# ee \/etc\/rc.conf\r\n<\/code><\/pre>\n

Uncomment these lines:<\/p>\n

pf_enable=\"YES\"\r\npf_rules=\"\/etc\/firewall\"\r\npf_flags=\"\"\r\npflog_enable=\"YES\"\r\npflog_logfile=\"\/var\/log\/pflog\"\r\npflog_flags=\"\"\r\n<\/code><\/pre>\n

Reboot:<\/p>\n

# reboot \r\n<\/code><\/pre>\n

If you have done everything right, then you will be able to login and the firewall will be enabled. You don’t have to reboot every time you change the\u00a0\/etc\/firewall<\/code>\u00a0file. Just do:<\/p>\n

# \/etc\/rc.d\/pf reload\r\n<\/code><\/pre>\n

See who is trying to connect to your server in real-time:<\/p>\n

# tcpdump -n -e -ttt -i pflog0\r\n<\/code><\/pre>\n

Show history:<\/p>\n

# tcpdump -n -e -ttt -r \/var\/log\/pflog\r\n<\/code><\/pre>\n

See if you have someone in bruteforcers table:<\/p>\n

# pfctl -t bruteforcers -T show\r\n<\/code><\/pre>\n

And that’s it. You have successfully implemented PF firewall on FreeBSD server!<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","format":"standard","manualknowledgebasecat":[230],"manual_kb_tag":[437],"_links":{"self":[{"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb\/2866"}],"collection":[{"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb"}],"about":[{"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/types\/manual_kb"}],"author":[{"embeddable":true,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/comments?post=2866"}],"version-history":[{"count":3,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb\/2866\/revisions"}],"predecessor-version":[{"id":2872,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb\/2866\/revisions\/2872"}],"wp:attachment":[{"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/media?parent=2866"}],"wp:term":[{"taxonomy":"manualknowledgebasecat","embeddable":true,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manualknowledgebasecat?post=2866"},{"taxonomy":"manual_kb_tag","embeddable":true,"href":"https:\/\/support.aklwebhost.com\/wp-json\/wp\/v2\/manual_kb_tag?post=2866"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}