<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>firewall &#8211; Blog of Kliment Andreev &#8211; A place so I won&#039;t forget things</title>
	<atom:link href="https://blog.andreev.it/tag/firewall/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.andreev.it</link>
	<description></description>
	<lastBuildDate>Sat, 31 Oct 2020 14:04:20 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	
	<item>
		<title>Windows, CentOS, FreeBSD: ssh, RDP &#8211; Bypass your corporate firewall</title>
		<link>https://blog.andreev.it/2018/03/125-ssh-rdp-bypass-your-corporate-firewall/</link>
					<comments>https://blog.andreev.it/2018/03/125-ssh-rdp-bypass-your-corporate-firewall/#comments</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Fri, 23 Mar 2018 17:04:18 +0000</pubDate>
				<category><![CDATA[CentOS]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[bypass]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[freebsd]]></category>
		<guid isPermaLink="false">http://blog.iandreev.com/?p=3765</guid>

					<description><![CDATA[If you are behind a firewall and want to access some resources over SSH&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>If you are behind a firewall and want to access some resources over SSH or RDP, most likely you won&#8217;t be able to do that. It&#8217;s because most of the corporate firewalls allow only ports 80 and 443 outbound. But you can still bypass that by tunneling everything over port 443. You will need a software called shellinabox to tunnel SSH over 443 and RDP gateway to tunnel the RDP traffic over 443. I&#8217;ll present the shellinabox solution for both CentOS 7 and FreeBSD 11. Both of these servers will be sitting somewhere in the cloud or behind your home firewall. The only requirement is to have port 443 opened and accessible on Internet. You might have a public IP or your home firewall will forward the traffic to 443, it doesn&#8217;t matter. Another option for connecting to any port is to use putty and a Linux/FreeBSD instance. I&#8217;ll describe that option last.</p>
<h1>CentOS 7</h1>
<p>shellinabox doesn&#8217;t come up with the default packages, so you have to install the EPEL release first. </p>
<pre class="brush: bash; title: ; notranslate">
yum install epel-release
yum install shellinabox
systemctl enable shellinaboxd
</pre>
<p>Edit the configuration file for shellinabox which is <strong>/etc/sysconfig/shellinaboxd</strong>. Make sure it looks like this. </p>
<pre class="brush: bash; title: ; notranslate">
# Shell in a box daemon configuration
# For details see shellinaboxd man page
# Basic options
USER=shellinabox
GROUP=shellinabox
CERTDIR=/var/lib/shellinabox
PORT=4200
OPTS=&quot;--css white-on-black.css -t -s /:SSH:localhost&quot;
#OPTS=&quot;--css color.css -t -s /:SSH:localhost&quot;
</pre>
<p>shellinabox runs on port 4200 by default. You can change it to run on 443, but you have to run as root. A better solution is to install Apache and use the mod_proxy so the Apache will listen on 443 and forward the traffic to 4200. </p>
<pre class="brush: bash; title: ; notranslate">
yum install httpd mod_ssl
systemctl enable httpd
</pre>
<p>Create the configuration file for the Apache server. In my case, I&#8217;ll access the SSH over HTTPS as sshtest.iandreev.com. Change the config below to suit your needs. </p>
<pre class="brush: bash; title: ; notranslate">
cd /etc/httpd/conf.d
touch httpd-vhosts.conf
</pre>
<p>Edit httpd-vhosts.conf and paste the following. </p>
<pre class="brush: bash; title: ; notranslate">
&lt;VirtualHost *:443&gt;
    SSLEngine On
    SSLCertificateFile /etc/pki/tls/certs/sshtest.iandreev.com.crt
    ServerAdmin klimenta@iandreev.com
    ServerName sshtest.iandreev.com
    ErrorLog &quot;/var/log/httpd/sshtest.iandreev.com-error_log&quot;
    CustomLog &quot;/var/log/httpd/sshtest.iandreev.com-access_log&quot; combined
    ProxyRequests On
    ProxyPreserveHost On
    &lt;Proxy *&gt;
        AuthUserFile /var/www/sshtest.iandreev.com/.htpasswd
        AuthName EnterPassword
        AuthType Basic
        require user ssh.admin
        Order deny,allow
        Allow from all
    &lt;/Proxy&gt;
    ProxyPass / http://localhost:4200/
    ProxyPassReverse / http://localhost:4200/
&lt;/VirtualHost&gt;
</pre>
<p>HTTPS requires a certificate, we&#8217;ll create a fake one. If you have a valid certificate, just put it under <strong>/etc/pki/tls/certs</strong> as <strong>sshtest.iandreev.com.crt</strong>.</p>
<pre class="brush: bash; title: ; notranslate">
cd /etc/pki/tls/certs
./make-dummy-cert sshtest.iandreev.com.crt
</pre>
<p>shellinabox when started will give you a SSH prompt so you can login to your server. A more secure solution is to protect the access even more with a username and password. Anytime you access your server, you&#8217;ll get prompted with a username and password and then you&#8217;ll get prompted with your SSH credentials.</p>
<pre class="brush: bash; title: ; notranslate">
cd /var/www
mkdir sshtest.iandreev.com
cd sshtest.iandreev.com
htpasswd -c .htpasswd ssh.admin
cd ..
chown -R apache:apache sshtest.iandreev.com
</pre>
<p>I&#8217;ve created a user called ssh.admin and the commands above will ask you for a password.<br />
Now, it&#8217;s time to start shellinabox.</p>
<pre class="brush: bash; title: ; notranslate">
systemctl start httpd
systemctl start shellinaboxd
</pre>
<p>On a laptop behind your comporate firewall, go to https://sshtest.yourdomain.com and you should get prompted for ssh.admin&#8217;s password. Once you pass that you&#8217;ll see the login prompt in your browser. From here you can SSH to any server that has port 22 opened.<br />
shellinabox comes with two styles. If you see above in it&#8217;s config, we provided these two lines.</p>
<pre class="brush: bash; title: ; notranslate">
OPTS=&quot;--css white-on-black.css -t -s /:SSH:localhost&quot;
#OPTS=&quot;--css color.css -t -s /:SSH:localhost&quot;
</pre>
<p>If you prefer black on white background, uncomment the last line, save the config file and restart shellinabox.<br />
Depending on your CentOS install, you might have firewall and SElinux enabled. If these are not configured, shellinabox won&#8217;t work. For the firewall, you&#8217;ll have to allow port 443 inbound. </p>
<pre class="brush: bash; title: ; notranslate">
firewall-cmd --add-service=https --permanent
firewall-cmd --reload
</pre>
<p>For SElinux, you&#8217;ll have to allow Apache to make outbound connections.</p>
<pre class="brush: bash; title: ; notranslate">
/usr/sbin/setsebool -P httpd_can_network_connect 1
</pre>
<p>At the end, it will look like this.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-01.png"><img fetchpriority="high" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-01.png" alt="" width="698" height="281" class="aligncenter size-full wp-image-8195" /></a><br />
&#8230;and this.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-02.png"><img decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-02.png" alt="" width="475" height="219" class="aligncenter size-full wp-image-8196" /></a></p>
<h1>FreeBSD 11</h1>
<p>We have to install Apache and shellinabox first. </p>
<pre class="brush: bash; title: ; notranslate">
pkg install shellinabox apache24
</pre>
<p>Make sure they start on boot. Add these two lines in <strong>/etc/rc.d</strong></p>
<pre class="brush: bash; title: ; notranslate">
apache24_enable=&quot;YES&quot;
shellinaboxd_enable=&quot;YES&quot;
shellinaboxd_flags=&quot;--disable-ssl --css=/usr/local/www/sshtest.iandreev.com/style.css&quot;
</pre>
<p>Go to the Apache config directory and edit the config file <strong>/usr/local/etc/apache24/httpd.conf</strong>. Make sure these lines are uncommented. </p>
<pre class="brush: bash; title: ; notranslate">
Include etc/apache24/extra/httpd-vhosts.conf
LoadModule authn_socache_module libexec/apache24/mod_authn_socache.so
LoadModule socache_shmcb_module libexec/apache24/mod_socache_shmcb.so
LoadModule ssl_module libexec/apache24/mod_ssl.so
Include etc/apache24/extra/httpd-ssl.conf
LoadModule proxy_module libexec/apache24/mod_proxy.so
LoadModule proxy_http_module libexec/apache24/mod_proxy_http.so
ServerName www.example.com:80
</pre>
<p>Go to <strong>/usr/local/etc/apache24/extra</strong> folder and make sure you have the definitiopn for the virtual host there. Change it to suit your needs. </p>
<pre class="brush: bash; title: ; notranslate">
&lt;VirtualHost *:443&gt;
    SSLEngine On
    SSLCertificateFile /usr/local/share/certs/sshtest.iandreev.com.crt
    SSLCertificateKeyFile /usr/local/share/certs/sshtest.iandreev.com.key
    ServerAdmin klimenta@iandreev.com
    ServerName sshtest.iandreev.com
    ErrorLog &quot;/var/log/sshtest.iandreev.com-error_log&quot;
    CustomLog &quot;/var/log/sshtest.iandreev.com-access_log&quot; combined
    ProxyRequests On
    ProxyPreserveHost On
    &lt;Proxy *&gt;
        AuthUserFile /usr/local/www/sshtest.iandreev.com/.htpasswd
        AuthName EnterPassword
        AuthType Basic
        require user ssh.admin
        Order deny,allow
        Allow from all
    &lt;/Proxy&gt;
    ProxyPass / http://localhost:4200/
    ProxyPassReverse / http://localhost:4200/
&lt;/VirtualHost&gt;
</pre>
<p>In the same directory, edit <strong>httpd-ssl.conf</strong> file and make sure it looks like this.</p>
<pre class="brush: bash; title: ; notranslate">
SSLRandomSeed startup file:/dev/urandom 512
Listen 443
SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLProxyCipherSuite HIGH:MEDIUM:!MD5:!RC4
SSLHonorCipherOrder on
SSLProtocol all -SSLv3
SSLProxyProtocol all -SSLv3
SSLPassPhraseDialog  builtin
SSLSessionCache        &quot;shmcb:/var/run/ssl_scache(512000)&quot;
SSLSessionCacheTimeout  300
</pre>
<p>We&#8217;ll protect shellinabox with extra username (ssh.admin) and password. </p>
<pre class="brush: bash; title: ; notranslate">
cd /usr/local/www
mkdir sshtest.iandreev.com
cd sshtest.iandreev.com
htpasswd -c .htpasswd ssh.admin
</pre>
<p>We&#8217;ll need a certificate for the HTTPS site. Use your own or create a fake one. Hit ENTER for everything prompted. It&#8217;s a fake certificate.</p>
<pre class="brush: bash; title: ; notranslate">
cd /usr/local/share/certs
openssl genrsa -out sshtest.iandreev.com.key 2048
openssl req -new -key sshtest.iandreev.com.key -out sshtest.iandreev.com.csr
openssl x509 -req -days 3650 -in sshtest.iandreev.com.csr -signkey sshtest.iandreev.com.key -out sshtest.iandreev.com.crt
</pre>
<p>Unlike CentOS, FreeBSD shellinabox doesn&#8217;t come up with CSS files for the color, so we can use these two. Copy these files under <strong>/usr/local/www/sshtest.iandreev.com</strong> as <strong>blackonwhite.css</strong> and <strong>whiteonblack.css</strong>.<br />
This is <strong>blackonwhite.css</strong>. Click to expand. </p>
<pre class="brush: css; collapse: true; light: false; title: ; toolbar: true; notranslate">
#vt100 .ansiDefR {
  color:            #ffffff;
}

#vt100 .bgAnsiDefR {
  background-color: #123450;
}

#vt100 #scrollable.inverted .ansiDefR {
  color:            #000000;
}

#vt100 #scrollable.inverted .bgAnsiDefR {
  background-color: #ffffff;
}

#vt100 .ansiDefR {
  color:            #ffdfd0;
}

#vt100 .bgAnsiDefR {
  background-color: #010203;
}

#vt100 #scrollable.inverted .ansiDefR {
  color:            #002030;
}

#vt100 #scrollable.inverted .bgAnsiDefR {
  background-color: #1f1fff;
}
</pre>
<p>This is <strong>whiteonblack.css</strong>. Click to expand.</p>
<pre class="brush: css; collapse: true; light: false; title: ; toolbar: true; notranslate">
#vt100 #cursor.bright {
  background-color: white;
  color:            black;
}

#vt100 #cursor.dim {
  background-color: black;
  opacity:          0.2;
  -moz-opacity:     0.2;
  filter:           alpha(opacity=20);
}

#vt100 #scrollable {
  color:            #ffffff;
  background-color: #000000;
}

#vt100 #scrollable.inverted {
  color:            #000000;
  background-color: #ffffff;
}

#vt100 .ansiDef {
  color:            #ffffff;
}

#vt100 .ansiDefR {
  color:            #000000;
}

#vt100 .bgAnsiDef {
  background-color: #000000;
}

#vt100 .bgAnsiDefR {
  background-color: #ffffff;
}

#vt100 #scrollable.inverted .ansiDef {
  color:            #000000;
}

#vt100 #scrollable.inverted .ansiDefR {
  color:            #ffffff;
}

#vt100 #scrollable.inverted .bgAnsiDef {
  background-color: #ffffff;
}

#vt100 #scrollable.inverted .bgAnsiDefR {
  background-color: #000000;
}
</pre>
<p>Copy one of them to be your style. Anytime you change the style, restart shellinabox.</p>
<pre class="brush: bash; title: ; notranslate">
cd /usr/local/www/sshtest.iandreev.com
cp blackonwhite.css style.css
cd ..
chown -R www:www sshtest.iandreev.com
</pre>
<p>Finally, start Apache and shellinabox. </p>
<pre class="brush: bash; title: ; notranslate">
service shellinaboxd start
service apache24 start
</pre>
<p>Access your server from a laptop behind your corporate firewall as https://sshtest.domain.com.</p>
<h1>Windows 2016</h1>
<p>You will need a Windows 2016 server with a public IP and port 443 allowed or you can use a Windows server behind your home network as long as port 443 is allowed. In order to bypass the RDP restriction, we&#8217;ll tunnel the RDP traffic over HTTPS using Remote Desktop Gateway.<br />
From the Server Manager, go to Add Roles and Features. Select <strong>Remote Desktop Services</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-03.png"><img decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-03.png" alt="" width="790" height="556" class="aligncenter size-full wp-image-8197" /></a><br />
Click <strong>Next </strong>2-3 times and then select <strong>Remote Desktop Gateway</strong>. Click Next again and accept all the defaults. Windows will install some other components for you.<br />
Once everything is installed, from the Server Manager&#8217;s menu click on <strong>Tools</strong>, <strong>Remote Desktop Services</strong> and then <strong>Remote Desktop Gateway Manager</strong>.<br />
Click on the server name and in the middle pane you&#8217;ll see what you have to do.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-04.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-04.png" alt="" width="972" height="456" class="aligncenter size-full wp-image-8198" /></a><br />
Click on the first link, <strong>View or modify certificate properties</strong>. Choose to create a fake certificate or you can import your own. It has to be in p12 format, not PEM.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-05.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-05.png" alt="" width="499" height="590" class="aligncenter size-full wp-image-8199" /></a><br />
If you decide to go with a fake certificate, enter the FQDN of the server, e.g sshtest.iandreev.com. You will have to make sure that sshtest.iandreev.com resolves to the public IP of the Windows box or if you have an internal server in your home lab, then the external IP of your cable/DSL modem. Then just click on the button <strong>Create and Import Certificate</strong>, enter the FQDN sshtest.iandreev.com and then click <strong>OK </strong>when prompted. Click <strong>Apply </strong>and <strong>OK </strong>to go back.<br />
At this point, you might want to create a user or a group that you can allow access to the Gateway.<br />
I created a user called RDP. Back in the RD Gateway Manager, select <strong>Policies </strong>under the server name, right-click on it and choose <strong>Create New Authorization Policies</strong>. Choose the option to create both RD CAP and RD RAP policies. Here is what I did in the wizard config.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-06.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-06.png" alt="" width="958" height="600" class="aligncenter size-full wp-image-8200" /></a><br />
I choose BUILTIN\Users to be able to use the Gateway. The generic user RDP that I created is by default a member of the users group.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-07.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-07.png" alt="" width="952" height="598" class="aligncenter size-full wp-image-8201" /></a><br />
Select the default <strong>Enable device redirection for all client devices</strong>.<br />
Check both checkmarks for <strong>Idle Timeout</strong> and <strong>Session Timeout</strong>. This is optional, but it&#8217;s good to have.<br />
Click Next and then create the <strong>Resource Authorization Policy</strong>.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-08.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-08.png" alt="" width="957" height="598" class="aligncenter size-full wp-image-8202" /></a><br />
Accept the same group (<strong>BUILTIN\Users</strong>).<br />
Choose the option at the bottom, <strong>Allow users to connect to any network resource (computer)</strong>.<br />
Choose the first option, <strong>Allow connections only to port 3389</strong>.<br />
Click <strong>Next </strong>and <strong>Finish</strong>.<br />
So, how do you use this solution now? Easy&#8230;<br />
All you have to do is go to your corporate laptop and create a new RDP connection. Under the General tab enter the IP address of the Windows box that you want to reach. This is the box that listens on 3389 and that you are not able to reach directly. Mind that the Windows server that we just built is a gateway, so the Windows RD Gateway server should be able to talk to the destination server over 3389 and your corporate laptop will talk to Windows RD Gateway server over 443.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-09.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-09.png" alt="" width="542" height="580" class="aligncenter size-full wp-image-8203" /></a><br />
Click on the <strong>Advanced </strong>tab and then the <strong>Settings </strong>button. Select to <strong>Use these RD Gateway server settings</strong> and enter the FQDN (sshtest.iandreev.com) of the RD Gateway server that we just built.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-10.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-10.png" alt="" width="539" height="535" class="aligncenter size-full wp-image-8204" /></a><br />
Once you are done, click <strong>Connect </strong>and you should get prompted to enter the credentials for the RD Gateway (in my case the username and password for the RDP user) and then you&#8217;ll have to enter the username and password for the destination server.<br />
NOTE: Make sure you use .\rdp for the username, not rdp. You can also get an error saying that the identity of the RD Gateway can&#8217;t be verified. This is most likely if you messed up the certificate and it doesn&#8217;t match the hostname. In that case, the RDP client will allow you to view the certificate. Then copy it to a file and import it on the local machine under the Trusted Root Cert Authorities. </p>
<h1>Tunnel over putty</h1>
<p>Let&#8217;s say that your corporate firewall allows only port 443 outbound. In this case, we&#8217;ll build a Linux/BSD server with a public IP and change the SSH listener port from 22 to 443. For this, edit <strong>sshd_config</strong> under <strong>/etc/ssh/sshd_config</strong> or <strong>/usr/local/etc/ssh/sshd_config</strong>. Look for the directive <strong>Port 22</strong> and change it to <strong>Port 443</strong>. Restart the ssh service.<br />
On your client machine behind the corporate firewall, open putty and under Session enter the public IP of your Linux/BSD server and port 443 so it looks like this.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-11.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-11.png" alt="" width="453" height="197" class="aligncenter size-full wp-image-8205" /></a><br />
Now, expand the <strong>Connection </strong>on the left side, then <strong>SSH </strong>and select <strong>Tunnels</strong>. For the <strong>source port</strong> enter 3390 and for the <strong>destination </strong>enter the IP of your Windows box where you want to connect.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2018/03/P102-12.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2018/03/P102-12.png" alt="" width="448" height="200" class="aligncenter size-full wp-image-8206" /></a><br />
Finally, save this session, open it and login to the Linux server to establish the tunnel. You should be able to run the RDP client (mstsc) and RDP to 127.0.0.1:3390. </p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2018/03/125-ssh-rdp-bypass-your-corporate-firewall/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>FreeBSD: pf firewall on FreeBSD 10</title>
		<link>https://blog.andreev.it/2014/06/freebsd-10-and-pf-firewall/</link>
					<comments>https://blog.andreev.it/2014/06/freebsd-10-and-pf-firewall/#comments</comments>
		
		<dc:creator><![CDATA[Kliment Andreev]]></dc:creator>
		<pubDate>Fri, 06 Jun 2014 14:01:23 +0000</pubDate>
				<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[firewall]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[pf]]></category>
		<guid isPermaLink="false">http://blog.iandreev.com/?p=1353</guid>

					<description><![CDATA[In this post I&#8217;ll describe how to install FreeBSD pf firewall. The focus is&#8230;]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>In this post I&#8217;ll describe how to install FreeBSD pf firewall. The focus is on a simple VPS server that I have in the cloud running a web and mail server. In order to enable <strong>pf</strong>, edit <em>/etc/rc.conf</em> and add the following lines. This will enable the <strong>pf</strong> firewall and it will allow traffic logging. </p>
<pre class="brush: bash; title: ; notranslate">
pf_enable=&quot;YES&quot;
pflog_enable=&quot;YES&quot;
</pre>
<p>The default ruleset is in the file <em>/etc/pf.conf</em>. On some installations, there is a sample file <em>/etc/pf.conf.sample</em> and there are some examples under <em>/usr/share/examples/pf/</em>. Here are some basic commands, for more consult the official <a href="http://www.openbsd.org/faq/pf/" target="_blank" rel="noopener noreferrer">pf guide</a> or the FreeBSD <a href="http://www.freebsd.org/doc/handbook/firewalls-pf.html" target="_blank" rel="noopener noreferrer">page</a> for it. </p>
<pre class="brush: bash; title: ; notranslate">
pfctl -e # Enables the firewall
pfctl -d # Disables the firewall
pfctl -f /etc/pf.conf # Loads the config. The changes are applied immediately.
pfctl -nf /etc/pf.conf # Tests the config, but the changes are not applied. t
pfctl -sr # Show the current ruleset
pfctl -ss # Show the current state table
pfctl -si # Show filter stats and counters
pfctl -sa # Show EVERYTHING it can show
</pre>
<p>Note: If you make a change in <strong>pf.conf</strong>, disabling/enabling the firewall won&#8217;t make any changes to the rules. You have to load the rules with <strong>pfctl -f /etc/pf.conf</strong> in order to make changes. The easiest way is to do:</p>
<pre class="brush: bash; title: ; notranslate">
pfctl -F all -f /etc/pf.conf
</pre>
<p>Here is my <strong>/etc/pf.conf</strong> config with explanation of what each line does. </p>
<pre class="brush: bash; title: ; notranslate">
# pf config - K.Andreev 20140604
# This is the external interface. I don't have an internal one. Get the name with ifconfig -a.
ext_if = &quot;vtnet0&quot;
# This command tells pf to do the logging on the external interface
set loginterface $ext_if
# Bypass any packet filtering on the localhost interface.
# If you skip this line, you won't be able to telnet localhost anyport
# Which means any web application that uses smtp/pop, sql, imap won't work
set skip on lo
# This is how you create tables. In this case the name of the table is bruteforce.
table &lt;bruteforce&gt; persist
# These are the TCP ports that I will allow to be accessible from inside out and vice versa
tcp_pass = &quot;{ 22 25 80 443 587 993 995 }&quot;
# This is the UDP port for DNS that I will have to allow, otherwise name resolution won't work
udp_pass = &quot;{ 53 }&quot;
# pf works from top to bottom. The last matching rule wins. 
# Here I will block everything and then poke holes. 
block all
# The quick command is an exception. It cancels any other rules for this packet 
# and causes an immediate action, regardless of the following rules. 
block quick from &lt;bruteforce&gt;
# This line means to block any IP that makes more than 5 connections in 3 seconds
# It also limits the number of connections per IP to 15
# Any IP that violates this will be stored in the table &lt;bruteforce&gt;
pass quick proto { tcp, udp } from any to any port ssh \
    flags S/SA keep state \
    (max-src-conn 15, max-src-conn-rate 5/3, \
    overload &lt;bruteforce&gt; flush global)
# This line means to allow in and out all ports that were listed in the $tcp_pass varaible
# The log directive also means to log all the traffic
pass log on $ext_if proto tcp to any port $tcp_pass keep state
# This line means to pass only the UDP traffic on port 53 outside. Inside access to UDP port 53 is blocked.
pass out on $ext_if proto udp to any port $udp_pass keep state
# This means that we allow our IP to be pinged or tracerouted.
# If you remove this line, everything will work fine, but you can't ping your IP and you can't ping
# anything outside. It's a good way to hide your presence, but most port scans will find you anyway
pass inet proto icmp from any to any
</pre>
<p>Now, enable the firewall and load the rules.</p>
<pre class="brush: plain; title: ; notranslate">
pfctl -e
pfctl -f /etc/pf.conf
</pre>
<p>From another computer, do a port scan and you&#8217;ll see that only the ports that we allowed are now open.<br />
<a href="https://blog.andreev.it/wp-content/uploads/2014/06/P043-01.png"><img loading="lazy" decoding="async" src="https://blog.andreev.it/wp-content/uploads/2014/06/P043-01.png" alt="" width="650" height="243" class="aligncenter size-full wp-image-7075" srcset="https://blog.andreev.it/wp-content/uploads/2014/06/P043-01.png 650w, https://blog.andreev.it/wp-content/uploads/2014/06/P043-01-300x112.png 300w, https://blog.andreev.it/wp-content/uploads/2014/06/P043-01-585x219.png 585w" sizes="(max-width: 650px) 100vw, 650px" /></a><br />
If you have a public IP for your server, most likely you&#8217;ll have a lot of brute force attacks on the sshd. You can check that with:</p>
<pre class="brush: bash; title: ; notranslate">
grep Invalid /var/log/auth.log
</pre>
<p>In our configuration file, we block those users and their IP is stored in the table <em>bruteforce</em>. For how long? Indefinitely or until you reboot and clear the table which is stored in the memory. The problem with this scenario is that your server can be up for a year and all these IPs will eat up the memory sooner or later. pf has a command to flush these IPs after certain period of time. Put this line in your crontab. It will run every Sunday at 5PM and clean the IPs blocked. The value of 604800 is in seconds which means 7 days. </p>
<pre class="brush: bash; title: ; notranslate">
00 17 * * 0 /sbin/pfctl -t bruteforce -T expire 604800 &gt; /dev/null 2&gt;&amp;1
</pre>
<p>If you want to see what IPs are blocked, do:</p>
<pre class="brush: bash; title: ; notranslate">
pfctl -t bruteforce -T show
</pre>
<p>And if you want to remove an IP (e.g. 193.194.195.196) from the list do:</p>
<pre class="brush: bash; title: ; notranslate">
pfctl -t bruteforce -T delete 193.194.195.196
</pre>
<p>Finally, if you want to watch the traffic in real time, do:</p>
<pre class="brush: bash; title: ; notranslate">
tcpdump -n -e -ttt -i pflog0
</pre>
<p>Only the first packet will be logged because of keep state. </p>
<p>You might also want to block some IPs permanently. In that case, we have to modify <strong>pf.conf</strong> to read these IPs from a file.<br />
Add this lines after line 11 (<strong>table &lt;bruteforce&gt; persist</strong>) </p>
<pre class="brush: bash; title: ; notranslate">
table &lt;blocked_subnets&gt; persist file &quot;/etc/blocked_subnets&quot;
</pre>
<p>&#8230;.and these two lines after line 18 (<strong>block all</strong>).</p>
<pre class="brush: bash; title: ; notranslate">
# Block some subnets
block in log quick on $ext_if from &lt;blocked_subnets&gt; to any
block out log quick on $ext_if from any to &lt;blocked_subnets&gt;
</pre>
<p>Then create <strong>/etc/blocked_subnets</strong> file and add whatever ranges (CIDR format) you want to block. E.g:</p>
<pre class="brush: bash; title: ; notranslate">
223.223.176.0/20
223.223.192.0/20
</pre>
<p>You can block certain countries if you want. Use this <a href="https://www.countryipblocks.net/country_selection.php" target="_blank" rel="noopener noreferrer">link</a> to see a full list. </p>
<p>Sometimes, you might want to restrict access to some port to only a handful of IPs. I&#8217;ll show how to restrict access to ssh based on IP.<br />
Create a file called <strong>/etc/allow_ssh</strong> and add a couple of IPs that will be allowed to remote (each IP in a separate line).<br />
Add the definition after line 11 (table &lt;bruteforce&gt;) so it looks like this.</p>
<pre class="brush: bash; title: ; notranslate">
table &lt;allow_ssh&gt; persist file &quot;/etc/allow_ssh&quot;
</pre>
<p>Remove port 22 from the <strong>tcp_pass</strong> table. The tcp_pass table should contain ports that should be allowed from everywhere.<br />
In line 25 (pass quick proto), replace <strong>from any to any</strong> with <strong>from &lt;allow_ssh&gt; to any</strong> and reload the config.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.andreev.it/2014/06/freebsd-10-and-pf-firewall/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
