{"id":522,"date":"2021-10-09T14:46:40","date_gmt":"2021-10-09T14:46:40","guid":{"rendered":"https:\/\/carson.fenimorefamily.com\/?p=522"},"modified":"2021-10-16T18:05:48","modified_gmt":"2021-10-16T18:05:48","slug":"making-a-transparent-firewall","status":"publish","type":"post","link":"https:\/\/carson.fenimorefamily.com\/?p=522","title":{"rendered":"Making a Transparent Firewall"},"content":{"rendered":"\n<p>In the latest iteration of my home networking stack I am factoring out my firewall from my router into discrete unit.  I decided to try a transparent firewall as this has the advantage of a reduced attack surface.  Plus i used it as a chance to try out nftables.  <\/p>\n\n\n\n<p>Hardware: I chose the raspberry pi compute module 4 with the DFRobot dual-nic carrier.  This board is able to push about 1Gbit of traffic while consuming less than 2 watts of power!  All this in about 2 inches square. To enable the 2nd NIC on this board I had to recompile the kernel &#8211; see my <a href=\"https:\/\/carson.fenimorefamily.com\/?p=516\" data-type=\"post\" data-id=\"516\">Recompiling the Kernel on the Pi Compute Module 4<\/a> post on this.<\/p>\n\n\n\n<p>Once this is done, we enable the serial port so we can manage the firewall out of band.  I specifically do not want a listening port on the firewall (remember, its transparent!). To do this I hooked up a FT232 USB-&gt;Serial converter to pins to the DFRobot headers. I then connect to the firewall using minicom, using 115200 8N1 for the serial params.  Inside the pi ensure you run &#8220;raspi-config&#8221; and enable the serial port under the interfaces section.  <\/p>\n\n\n\n<p>I also turned off dhcpd to ensure the pi is only passing through &#8211; not actually on the network. &#8220;systemctl disable dhcpcd; systemctl stop dhcpd&#8221;<\/p>\n\n\n\n<p>To get nftables, on the pi, I did have to install it: &#8220;apt-get install nftables.&#8221;  Then we write some basic rules.  Subjectively speaking, nftables is a lot nicer to write rules for than iptables, ebatables, etc. Here&#8217;s a brief sample:<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ntable inet firewallip {\n  chain c1 {\n       type filter hook input priority 0;\n       meta nftrace set 1\n        policy drop\n        ip saddr 10.55.0.10 icmp type echo-request  accept\n        reject with icmp type host-unreachable\n }\n}\n<\/pre>\n\n\n<p>A brief description of this example is apropos:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>The table is named &#8220;firewallip&#8221; (doesn&#8217;t matter) but &#8220;inet&#8221; can be one of &nbsp;<em>ip<\/em>,&nbsp;<em>arp<\/em>,&nbsp;<em>ip6<\/em>,&nbsp;<em>bridge<\/em>,&nbsp;<em>inet<\/em>,&nbsp;<em>netdev<\/em>  (see <a href=\"https:\/\/wiki.nftables.org\/wiki-nftables\/index.php\/Quick_reference-nftables_in_10_minutes\" data-type=\"URL\" data-id=\"https:\/\/wiki.nftables.org\/wiki-nftables\/index.php\/Quick_reference-nftables_in_10_minutes\">https:\/\/wiki.nftables.org\/wiki-nftables\/index.php\/Quick_reference-nftables_in_10_minutes<\/a>)<\/li><li>The chain, c1 (again, name doesn&#8217;t matter &#8211; although it makes sense to have it match the filter type) is instantiated with the type line &#8211; this is extremely significant, as  rules will only match packets if on the proper filter type.  <\/li><li>meta nftrace set 1 (can be 0 or 1) lets us run &#8220;nft monitor trace&#8221; and trace the rules live<\/li><li>there are a LOT of things that can go inside a chain &#8211; however it is worth noting &#8220;reject&#8221; phrases such as the one i show are not applicable in some chain types, such as bridge.<\/li><\/ul>\n\n\n\n<p>Note that for connection tracking <strong>inside a bridge<\/strong> i actually had to build my kernel yet again.  If you don&#8217;t do this youll get &#8220;Protocol unsupported&#8221; errors if you try to do connection tracking inside a bridge. To enable this module, follow the same steps as in the procedure for adding realtek driver, however the menu item to enable in the kernel is under: &#8220;Networking support&#8221; -&gt; &#8220;Networking options&#8221; -&gt; &#8220;Network packet filtering framework&#8221; -&gt; &#8220;IPV4\/IPV6 bridge connection tracking support&#8221;.  Or just add &#8220;CONFIG_NF_CONNTRACK_BRIDGE=m&#8221; to your &#8220;.config&#8221; file inside the linux tree. Once this is done you need to ensure &#8220;nf_conntrack_bridge&#8221; is loaded: &#8220;modprobe nf_conntrack_bridge&#8221; should do you.  <\/p>\n\n\n\n<p>At this point we can do things like connection tracking INSIDE the bridge. Which is great.  I won&#8217;t post my actual tableset, but here&#8217;s a beginning one that works well, allowing for ssh\/http\/https from the LAN (assuming LAN is on eth1), and only established connections and arp otherwise.<\/p>\n\n\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\ntable bridge firewall {\n  chain input {\n       type filter hook input priority 0; policy drop;\n  }\n  chain output {\n       type filter hook output priority 0; policy drop;\n  }\n  chain forward {\n       type filter hook forward priority 0;       policy drop;\n       meta protocol {arp} accept\n       ct state established,related accept\n       iifname eth1 tcp dport {ssh,http,https} accept\n  }\n}\n<\/pre>\n\n\n<p>Unfortunately, all this fun on the pi doesn&#8217;t seem as readily available on centos.  Cent 7.6 is still on a 3.x version of the kernel, and 8.4 is still on a 4.x version.  You can upgrade to kernel using elrepo-kernel (http:\/\/elrepo.org\/tiki\/kernel-ml).<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the latest iteration of my home networking stack I am factoring out my firewall from my router into discrete unit. I decided to try a transparent firewall as this has the advantage of a reduced attack surface. Plus i used it as a chance to try out nftables. Hardware: I chose the raspberry pi &hellip; <a href=\"https:\/\/carson.fenimorefamily.com\/?p=522\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Making a Transparent Firewall<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[36],"tags":[],"class_list":["post-522","post","type-post","status-publish","format-standard","hentry","category-networking"],"_links":{"self":[{"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=\/wp\/v2\/posts\/522","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=522"}],"version-history":[{"count":9,"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=\/wp\/v2\/posts\/522\/revisions"}],"predecessor-version":[{"id":535,"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=\/wp\/v2\/posts\/522\/revisions\/535"}],"wp:attachment":[{"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=522"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=522"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/carson.fenimorefamily.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=522"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}