{"id":551,"date":"2026-09-23T13:15:08","date_gmt":"2026-09-23T13:15:08","guid":{"rendered":"https:\/\/sites.wp.odu.edu\/ian-burd\/?page_id=551"},"modified":"2026-09-24T15:27:20","modified_gmt":"2026-09-24T15:27:20","slug":"kali-linux-host-based-firewall","status":"publish","type":"page","link":"https:\/\/sites.wp.odu.edu\/ian-burd\/kali-linux-host-based-firewall\/","title":{"rendered":"Kali Linux Host Based Firewall (In Progress)"},"content":{"rendered":"\n<p>I decided to make a firewall on my current Kali Linux VM. Rather than use an application like pfSense, I chose a host-based firewall. While some of the work I completed in my classes was related to this, much of it was new, so I used several resources, including some AI, to help me progress while still learning from the project. I wanted to start with something simple, so I opted to set up and test a UFW (Uncomplicated Firewall). I have worked with pfSense and setting up firewalls before (including configuring my own on my PC in the past, but I have only set up a UFW once, quite some time ago, so this was a fun project.  <\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1 &#8211; Update Kali, install UFW and Enable UFW; <\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"628\" height=\"334\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/Screenshot-2026-09-23-093504.png\" alt=\"\" class=\"wp-image-558\" style=\"width:489px;height:auto\" \/><figcaption class=\"wp-element-caption\">For the initial update of Kali, it took significantly longer than I would have expected. This could have been due to this particular machine being idle for a few months while in college, or it could have been due to an unstable internet connection. Regardless, once it completed, I was able to begin the installation of UFW. <\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"648\" height=\"294\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-4.png\" alt=\"\" class=\"wp-image-559\" style=\"width:510px;height:auto\" \/><figcaption class=\"wp-element-caption\">Once the update completed, I installed UFW. This was a very fast install, whereas the update took well over 15 minutes. This was a super simple thing to do, as Linux preconfigures all of the packages, and the command to install it was extremely straightforward. The commands &#8216;apt update&#8217; and &#8216;apt install&#8217; are some of the most important basic commands you need to know and will help you get started on various projects. <\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"403\" height=\"57\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-5.png\" alt=\"\" class=\"wp-image-560\" \/><figcaption class=\"wp-element-caption\">Now, after UFW was installed, a simple &#8220;sudo ufw enable&#8221; command enabled the firewall. By default, this host-based firewall becomes active upon my system&#8217;s startup, meaning I don&#8217;t manually have to remember to turn it on each time I log onto my VM. <\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 2 &#8211; Establish a Baseline<\/strong>:<\/h3>\n\n\n\n<p>Establishing a baseline involves checking the current (often default) configuration before making changes. This is what I am doing with my firewall next. I will be checking my current configuration before making any changes. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"508\" height=\"115\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-6.png\" alt=\"\" class=\"wp-image-563\" \/><figcaption class=\"wp-element-caption\">The command &#8216;sudo uft status verbose &#8216; allows me to check the status and configuration for the firewall. The keyword &#8216;Status &#8216;allows me to view if it is active or inactive, while &#8216;verbose&#8217; provides additional information such as basic policies, which are currently unchanged from the default. <\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"630\" height=\"262\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-7.png\" alt=\"\" class=\"wp-image-564\" \/><figcaption class=\"wp-element-caption\">The &#8216;ip addr&#8217; command allows me to look at my network information. There is some super important information here, such as my interface name, IP, subnet information, and whether the interface is currently up. This information is crucial when you are trying to test the firewall from another machine. I may have to make some changes to my network on this VM in the future to allow communication between separate VMs. <\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"614\" height=\"60\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-8.png\" alt=\"\" class=\"wp-image-565\" \/><figcaption class=\"wp-element-caption\">This command is one of the most important for the baseline, and while usually you would see TCP or UDP Traffic present below the columns, the fact that there is nothing beneath them means that there are no listening TCP\/UDP sockets detected by this command. Hopefully this does not cause issues later, but if it does, I will come back to fix it. <\/figcaption><\/figure>\n\n\n\n<p>Netid: Type of Network Connection.<br>State: Current State (such as LISTEN).<br>Recv-Q (Data waiting to be received).<br>Send-Q (Data waiting to be sent).<br>Local Address:Port: Kali VM&#8217;s address and listening port.<br>Peer Address: The computer it is connected to. <\/p>\n\n\n\n<p>With this baseline established, as mentioned before, I was able to gain an understanding of how this UFW is configured before any changes, security or otherwise, are made. Establishing a baseline is important in more than just firewalls, and is especially important in monitoring situations. Generally, users need to establish a baseline to know what normal looks like. This allows for easier detection of anomalies or behavior that strays suspiciously far from normality. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3 &#8211; Configure the Firewall:<\/h3>\n\n\n\n<p>Next, I created a simple ruleset for the uncomplicated firewall. I needed to deny incoming traffic and allow outgoing traffic to my Kali VM. The commands to do this were relatively straightforward and intuitive. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"360\" height=\"152\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-9.png\" alt=\"\" class=\"wp-image-566\" \/><figcaption class=\"wp-element-caption\">As mentioned above, these commands changed the default policy to allow outgoing traffic but deny incoming traffic. These rules are extremely basic, but help to at least gain an understanding of how a firewall is supposed to work. There are, however, more advanced firewalls with significantly more advanced configuration possibilities. <\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4 &#8211; Allow SSH: <\/h3>\n\n\n\n<p>While this step is not necessary due to the fact that this firewalls is being built simply as a basic lab, I still opted to allow SSH, in case I decided to expand the project beyond it&#8217;s current scope later down the line. This step could, however be skipped in order to get a test service set up sooner. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"476\" height=\"218\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-10.png\" alt=\"\" class=\"wp-image-567\" \/><\/figure>\n\n\n\n<p>These commands enable the use of SSH through Port 22 and request its status information. Based on the information provided, the rule is active and allows TCP through anywhere, not any one particular IP address. This rule, combined with the previously created default rules, blocks all incoming traffic except for traffic on TCP Port 22, or SSH. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5 &#8211; Create a Temporary Test Service<\/h3>\n\n\n\n<p>Next, to ensure that the firewall is working properly, we need to test it. To do this, I opted to create a temporary Python web server. Testing the firewall ensures that the configurations are working properly and provides evidence of this.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"509\" height=\"77\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-11.png\" alt=\"\" class=\"wp-image-569\" \/><figcaption class=\"wp-element-caption\">Now, the server is up and running. This command starts a simple Python web server, listening on TCP 8080. This service will be used as a controlled test to verify that the UFW is working to block or allow the traffic specified in the default rules. <\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 6 &#8211; Find my Kali IP<\/h3>\n\n\n\n<p>To do this, I needed to open up a second terminal to ensure that the web server I need to have up and running does not shut down, as it is needed for testing. To find my IP again, I can use the same command as before &#8216;ip addr&#8217;. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"624\" height=\"273\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-12.png\" alt=\"\" class=\"wp-image-570\" \/><figcaption class=\"wp-element-caption\">This image shows the output of the &#8216;ip addr&#8217; command. While there is a lot of information showing up, the most important piece is the IP address. In this case, the one we needed is 192.168.1.124. Now I know what IP to look for when testing the UFW. <\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 7 &#8211; Test Port 8080:<\/h3>\n\n\n\n<p>To do this, I needed another VM, not the same Kali machine I have been building the firewall on. This is to ensure that the incoming traffic rule is working as it should be. Once the other machine was up and running, there were a few commands I needed to run. I opened up an Ubuntu Machine, found the IP address.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"806\" height=\"354\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-13.png\" alt=\"\" class=\"wp-image-572\" \/><figcaption class=\"wp-element-caption\">Just like in the Kali VM, the command ip addr can be used to find the IP address of my Ubuntu Machine. I got some useful information from this command. The IP address of this Ubuntu Machine, is 192.168.1.187. This means it is on the same subnet as the Kali Linux machine, since both IPs are variations of 192.168.1.x.<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"611\" height=\"137\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-14.png\" alt=\"\" class=\"wp-image-574\" \/><figcaption class=\"wp-element-caption\">The ping command was used to verify a connection to the Kali Machine could be made using its IP. The information provided demonstrated that a connection could, in fact, be made. This was a good sign and meant that I could go on to scan for the web server port. <\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"802\" height=\"282\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-15.png\" alt=\"\" class=\"wp-image-575\" \/><figcaption class=\"wp-element-caption\">Here I scanned for Port 8080 on my Kali VM using Nmap. Nmap is a port scanning tool that can find open ports, versions, open services, and more when using the correct arguments or operators. At first, I had an issue where the host seemed down, so I retried the command with the suggested operator and got a better response.  <br><br>See how TCP port 8080 was listed as a found port, but its state says &#8216;filtered&#8217;? This means that our firewall is working as it should be, as it is blocking incoming traffic as its rules state. <\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 8 &#8211; Test Port 8080, with a firewall rule set to &#8216;allow&#8217;:<\/h3>\n\n\n\n<p>I needed to set up a new rule in my Kali VM to allow port 8080 traffic into my VM to test if running a port scan on my Ubuntu machine using Nmap would now show the state as &#8216;open&#8217; rather than &#8216;filtered&#8217;.  <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"496\" height=\"271\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-16.png\" alt=\"\" class=\"wp-image-576\" \/><figcaption class=\"wp-element-caption\">Here are the two commands I used to create the new rule to allow TCP port 8080 traffic and to verify that the rule is active. Once I did this, I was able to move back to Ubuntu and re-run the Nmap port scan. <\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 9 &#8211; Test the Nmap Scan on Ubuntu with new Kali Firewall Rules:<\/h3>\n\n\n\n<p>Next, I went back to my Ubuntu VM and ran the same Nmap command as last time &#8220;nmap -Pn -p 8080 &lt;kali IP&gt; and got the following information.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"783\" height=\"242\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-17.png\" alt=\"\" class=\"wp-image-578\" \/><figcaption class=\"wp-element-caption\">Running the same command created a different result this time around, due to the firewall rules being changed on the Kali VM. The results were exactly as I expected. The port was still detected properly, and the state this time around changed to &#8216;open,&#8217; actively verifying that the firewall was working as intended. <\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 10 &#8211; Remove the test rule and re-test the Nmap scan:<\/h3>\n\n\n\n<p>Next, I wanted to test what would happen if I deleted the firewall rule that explicitly allowed port 8080 traffic. If it was working as intended, the status of the next Nmap scan would go back to &#8216;filtered&#8217; to show that the firewall was once again filtering out the traffic from TCP Port 8080. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"465\" height=\"220\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-18.png\" alt=\"\" class=\"wp-image-579\" \/><figcaption class=\"wp-element-caption\">I used re-ran the command to add the rule, only this time I added the keyword delete, resulting in the rule being deleted. Once it was deleted, I verified the status of the change and saw that the rule was deleted from the firewall. <\/figcaption><\/figure>\n\n\n\n<p>I returned once again to my Ubuntu machine and ran the same nmap scan: &#8220;nmap -Pn -p 8080 &lt; Kali IP&gt;&#8221;<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"698\" height=\"195\" src=\"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-content\/uploads\/sites\/37980\/2026\/09\/image-19.png\" alt=\"\" class=\"wp-image-580\" \/><figcaption class=\"wp-element-caption\">The scan completed once again, and the state of the port returned to filtered after the rule explicitly allowing TCP Port 8080 traffic on the Kali Machine was deleted. <\/figcaption><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Project Reflection:<\/h2>\n\n\n\n<p>This project helped me gain a stronger understanding of how host-based firewalls work to control network traffic. Throughout this project, I configured an Uncomplicated Firewall (UFW) on a Kali Linux Virtual Machine, set incoming traffic to be denied by default, then created a rule to explicitly allow SSH traffic. Then, I used an Ubuntu VM and Nmap to test a temporary web server, running on port 8080. I altered the specific firewall rules regarding traffic over port 8080 and re-ran the Nmap scans several times to verify that the firewall was working as intended.  I had some prior knowledge of firewalls from past classes during my time at Old Dominion University, but most of the knowledge was related to pfSense and Windows Defender firewalls, so this was a great learning opportunity to expand my knowledge of host-based firewalls. <br><br>I ran into a few issues with VMs not being updated or Nmap not being installed correctly, but these issues were easy to work past and provided useful insight into basic troubleshooting. Overall, this was a great learning experience and a fun project to work on. It was a simple project, but one that provided relavant knowledge and experience when pursing a carrerr in Cybersecurity. <br><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I decided to make a firewall on my current Kali Linux VM. Rather than use an application like pfSense, I chose a host-based firewall. While some of the work I completed in my classes was related to this, much of it was new, so I used several resources, including some AI, to help me progress&#8230; <\/p>\n<div class=\"link-more\"><a href=\"https:\/\/sites.wp.odu.edu\/ian-burd\/kali-linux-host-based-firewall\/\">Read More<\/a><\/div>\n","protected":false},"author":30246,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"_links":{"self":[{"href":"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-json\/wp\/v2\/pages\/551"}],"collection":[{"href":"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-json\/wp\/v2\/users\/30246"}],"replies":[{"embeddable":true,"href":"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-json\/wp\/v2\/comments?post=551"}],"version-history":[{"count":5,"href":"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-json\/wp\/v2\/pages\/551\/revisions"}],"predecessor-version":[{"id":582,"href":"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-json\/wp\/v2\/pages\/551\/revisions\/582"}],"wp:attachment":[{"href":"https:\/\/sites.wp.odu.edu\/ian-burd\/wp-json\/wp\/v2\/media?parent=551"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}