🔴 This page is about Windows, and steps 1–3 need Linux. That is deliberate: Windows Firewall gives you no way to watch rule precedence happen, and the fastest way to understand what it is protecting you from is to feel the alternative. A VM or WSL is enough.
For steps 4–5 you need a Windows machine and administrator rights.
You need no firewall experience. One idea carries the lab: when two rules disagree, something has to decide — and different firewalls decide differently.
What Are Firewall Rules?
Windows Firewall rules are instructions that tell the firewall whether to allow or block specific network traffic. Rules can be based on programs, ports, protocols, or IP addresses.
By creating custom rules, you gain granular control over exactly which applications can communicate over the network and on which ports.
Inbound rules control traffic coming INTO your computer. Outbound rules control traffic going OUT from your computer to the network or internet.
Opening Advanced Firewall Settings
The basic Windows Firewall panel has limited options. For creating custom rules, use the advanced interface:
wf.msc and press Enter
This opens "Windows Defender Firewall with Advanced Security" where you can see all inbound and outbound rules.
Creating a Program Rule
To allow or block a specific application:
C:\Program Files\MyApp\app.exe)
Creating a Port-Based Rule
To control traffic on specific ports:
Using PowerShell
You can also create rules via PowerShell (run as Administrator):
# Allow inbound TCP port 8080
New-NetFirewallRule -DisplayName "Allow Port 8080" -Direction Inbound -Protocol TCP -LocalPort 8080 -Action Allow
# Block outbound connections for a program
New-NetFirewallRule -DisplayName "Block MyApp" -Direction Outbound -Program "C:\MyApp\app.exe" -Action Block
# Remove a rule
Remove-NetFirewallRule -DisplayName "Allow Port 8080"
Testing Your Rules
After creating a rule, verify it works:
- Check the rule appears in the rules list and is enabled (green checkmark)
- Test the connection the rule affects (try accessing the port or running the program)
- Use
netstat -anin Command Prompt to see active connections and listening ports - Temporarily disable the rule to confirm it was actually affecting traffic
Blocking outbound traffic for the wrong program can break Windows Update, antivirus updates, or other essential services. Test changes carefully.
Now Do It Yourself: Find Out Which Rule Wins
Every firewall answers one question when two rules disagree: which one wins? Get that wrong and you will write a rule that looks perfect, sits enabled in the list, and does nothing whatsoever. In twenty minutes you can feel that happen on a real firewall — and then see why Windows avoids that particular trap by having a different one.
Steps 1–3 need Linux (a spare machine, WSL, or a VM) and were run to produce every output below — they use real TCP connections against a real kernel firewall, entirely on 127.0.0.1. Steps 4–5 are on Windows and are marked where they could not be re-run here.
Go: a Linux terminal — a spare machine, WSL on Windows, or a virtual machine. mkdir fwlab then cd fwlab.
Do: save these two small programs. Save this first one as listen.py — it waits for connections on port 9000:
import socket, threading, time
s = socket.socket(); s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("127.0.0.1", 9000)); s.listen(8)
def serve():
while True:
try: s.accept()
except OSError: break
threading.Thread(target=serve, daemon=True).start()
time.sleep(30)
And save this one as probe.py — it tries to make a connection and reports what happened:
import socket, sys
c = socket.socket(); c.settimeout(1.5)
try:
c.connect(("127.0.0.1", 9000)); print(f"{sys.argv[1]:<34} CONNECTED")
except Exception as e:
print(f"{sys.argv[1]:<34} BLOCKED ({type(e).__name__})")
finally:
c.close()
You should see: two files. Nothing runs yet, and nothing leaves your machine — both talk to 127.0.0.1, your own computer.
You now have the two halves of every firewall test: something listening, and something knocking. Without both, you are reading rules rather than testing them — which is how people end up confident about a firewall that is not doing what they think.
If not: Address already in use later on means something else holds port 9000. Change 9000 to another number in both files.
Go: the same folder.
Do: save this as lab.sh. It builds a private network, then adds firewall rules one at a time and probes after each:
ip link set lo up
python3 listen.py &
LISTENER=$!
sleep 1
python3 probe.py "1. no rules"
iptables -A INPUT -p tcp --dport 9000 -j DROP
python3 probe.py "2. after DROP rule"
iptables -A INPUT -p tcp --dport 9000 -j ACCEPT
python3 probe.py "3. ACCEPT added AFTER the DROP"
iptables -I INPUT 1 -p tcp --dport 9000 -j ACCEPT
python3 probe.py "4. ACCEPT inserted BEFORE it"
echo
iptables -L INPUT -n --line-numbers
kill $LISTENER 2>/dev/null
Run it in an isolated network namespace, which gives you firewall control without touching your real machine and without sudo:
unshare --user --map-root-user --net -- sh lab.sh
You should see: four probes, and the third is the surprise:
1. no rules CONNECTED
2. after DROP rule BLOCKED (TimeoutError)
3. ACCEPT added AFTER the DROP BLOCKED (TimeoutError)
4. ACCEPT inserted BEFORE it CONNECTED
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9000
2 DROP 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9000
3 ACCEPT 6 -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9000
Nothing was simulated. Those are real TCP connections meeting a real kernel firewall.
If not: unshare: Operation not permitted means unprivileged user namespaces are disabled. On Debian or Ubuntu check sysctl kernel.unprivileged_userns_clone. If every probe says CONNECTED, the iptables lines failed silently — run the script again and read the output above the probes.
Go: the output you just produced.
Do: compare probes 2, 3 and 4 against the rule list underneath. Rule 3 is an ACCEPT for exactly the port being tested, and it sits in the table the whole time probe 3 runs.
You should see: an ACCEPT rule that does nothing at all. The traffic was already dropped by rule 2 before the kernel reached rule 3.
🔴 This firewall reads top to bottom and stops at the first rule that matches. A permission placed below a block is not a weaker permission — it is unreachable code. Probe 4 shows the same rule, unchanged, working perfectly once it sits above the block. The rules did not change. Only their order did.
If not: if probes 3 and 4 give the same answer, the -I INPUT 1 line ran as -A — -A appends to the end, -I INPUT 1 inserts at position 1. That one letter is the entire lesson.
Go: a Windows machine, and open Windows Defender Firewall with Advanced Security (press Win+R, type wf.msc, press Enter).
Do: click Inbound Rules and look at the list. Note what is not there: any way to reorder the rules. There is no move-up button and no rule numbers.
You should see: a sortable table with no inherent order — because Windows does not resolve conflicts by position.
🔴 Windows uses a precedence model, not an order model. Microsoft documents the ranking: explicit block rules beat explicit allow rules, whatever their position in the list. So the trap you just felt on Linux — a permission hidden under a block — cannot happen here. A different trap replaces it: an allow rule that appears correct, is enabled, and never takes effect because some block rule elsewhere in a list of hundreds outranks it, with nothing in the interface pointing at which one.
This step needs Windows and was not re-run for this page. Steps 1–3 were, on Linux, and they are what the reasoning rests on — the point is not that the two behave the same, but that they behave differently and you must know which you are in.
If not: if wf.msc does not open, you are on Windows Home with a restricted policy, or not an administrator. The simple Firewall panel in Settings cannot show rule precedence at all — it is exactly the view that hides this.
Go: a Windows PowerShell window opened as Administrator.
Do: list every enabled inbound block rule — the ones that outrank your allows and are the usual reason a rule “does not work”:
Get-NetFirewallRule -Direction Inbound -Enabled True -Action Block | Select-Object DisplayName, Profile
You should see: the block rules currently in force. Any allow rule you create that overlaps one of these will lose, no matter where it appears in the list or when you created it.
Not re-run for this page — PowerShell is Windows-only and this page was written on Linux. The command is from Microsoft's documented NetSecurity module.
Whichever system you are on, the habit from step 1 is the one that transfers: after writing a rule, test it with something that actually connects. A rule that appears in a list has not been shown to work; a connection that succeeds or fails has.
If not: Get-NetFirewallRule is not recognized means PowerShell is running as an older version or you are in Command Prompt rather than PowerShell. The older equivalent is netsh advfirewall firewall show rule name=all, which prints far more and is harder to read.
You add an inbound allow rule on Windows for your app on port 8080. It is enabled, the port is right, and the app still cannot be reached. From step 4, what is the most likely cause — and why would moving the rule up the list not help? Answer: An enabled block rule somewhere else overlaps port 8080, and on Windows block beats allow regardless of position. Moving it would not help because Windows has no rule order to move it within — that is precedence, not sequence. Find the offending block rule with the command in step 5.
Now do it without the page: on any firewall you use, write one rule and then prove it works with a real connection rather than by reading the rule list. If you can state which model that firewall uses — first match, or block-wins — you can predict its behaviour instead of testing hopefully.
Summary
In this tutorial, you learned:
- The difference between inbound and outbound firewall rules
- How to open the Advanced Firewall interface
- Creating rules based on programs and ports
- Managing rules with PowerShell commands
- How to test and verify your firewall rules
Custom firewall rules give you precise control over which programs and ports can communicate on your network.