Skip to content

Windows Firewall Basics

💡
Before you start

🔴 This page is about Windows, and steps 1–4 need Linux. That is deliberate: Windows Firewall cannot show you a packet being accepted or dropped, and the mechanism is identical. WSL on the same machine is enough.

For step 5 you need Windows and administrator rights.

No sudo and no firewall experience are required. The lab builds a private network inside one command, so nothing on your system changes and there is nothing to undo.

What is Windows Firewall?

A firewall is a security system that monitors and controls network traffic entering and leaving your computer. Think of it as a security checkpoint between your computer and the network: every connection attempt is inspected, and only those that match the allowed rules are permitted through.

Windows Defender Firewall (previously called Windows Firewall) is built into every version of Windows since XP SP2. It runs as a core operating system service and cannot be uninstalled, though it can be enabled or disabled. By default, it blocks unsolicited inbound connections while allowing all outbound connections.

i
Firewall vs. antivirus: different jobs.

An antivirus (like Defender) scans files for malicious content. A firewall controls which programs can communicate over the network. You need both working together for comprehensive protection. A file that passes antivirus checks could still send your data to an attacker if the firewall does not block the connection.

How the Firewall Makes Decisions

When a network connection is attempted, the firewall evaluates it against its rules in the following order:

  • 1. Block rules — If a block rule matches the connection, it is dropped immediately, regardless of any allow rules.
  • 2. Allow rules — If an allow rule matches, the connection is permitted.
  • 3. Default behavior — If no rule matches, the default profile behavior applies (typically: block inbound, allow outbound).

Checking Firewall Status

Before making any changes, you should verify whether the firewall is currently active and which profile is in use.

Method 1: Windows Security App

1
Open Windows Security from the Start menu or by clicking the shield icon in the system tray.
2
Click Firewall & network protection. You will see three network profiles listed: Domain, Private, and Public. The currently active profile is labeled "(active)".
3
Each profile displays whether the firewall is On or Off. All three should show "Firewall is on" with a green checkmark.

Method 2: PowerShell

Open PowerShell as Administrator and run:

Get-NetFirewallProfile | Format-Table Name, Enabled, DefaultInboundAction, DefaultOutboundAction

Expected output for a properly configured system:

Name    Enabled DefaultInboundAction DefaultOutboundAction
----    ------- -------------------- ---------------------
Domain     True                Block                 Allow
Private    True                Block                 Allow
Public     True                Block                 Allow

Method 3: Command Prompt (netsh)

netsh advfirewall show allprofiles state
!
All three profiles must be enabled.

Some users disable the firewall for the Private profile thinking their home network is safe. This is a mistake. Malware on another device in your network, a compromised router, or a guest on your Wi-Fi can all attack your computer. Keep the firewall enabled on every profile.

Understanding Firewall Profiles

Windows Firewall uses three profiles, each with its own set of rules and default behaviors. Windows automatically selects the appropriate profile based on the type of network you are connected to.

Domain Profile Active when your computer is connected to a corporate domain network (Active Directory). This profile is managed by Group Policy in enterprise environments. Home users will almost never see this profile active.
Private Profile Active when you connect to a network you have designated as trusted, such as your home or office network. Network discovery and file sharing are typically allowed. You set a network as Private when you first connect to it.
Public Profile Active when you connect to an untrusted network such as a coffee shop, airport, or hotel Wi-Fi. This is the most restrictive profile. Network discovery is disabled and your computer is hidden from other devices on the network.

Changing a Network's Profile

If Windows assigned the wrong profile to your network (for example, your home Wi-Fi is set to Public when it should be Private), you can change it:

1
Open Settings (Win + I) and go to Network & Internet.
2
Click on your active network connection (Wi-Fi or Ethernet).
3
Under Network profile type, select either Public or Private.

Via PowerShell:

# View current network profile assignments
Get-NetConnectionProfile | Format-Table Name, InterfaceAlias, NetworkCategory

# Change a network to Private
Set-NetConnectionProfile -InterfaceAlias "Wi-Fi" -NetworkCategory Private

# Change a network to Public
Set-NetConnectionProfile -InterfaceAlias "Wi-Fi" -NetworkCategory Public
i
When in doubt, use Public.

If you are unsure which profile to use, keep the network set to Public. It provides the strongest protection. Only set a network to Private if you specifically need features like file sharing, printer sharing, or network discovery on that network.

Inbound vs. Outbound Traffic

Understanding the difference between inbound and outbound traffic is fundamental to firewall configuration. Every network connection has a direction, and the firewall treats each direction independently.

Inbound Traffic

Inbound connections are initiated by a remote device trying to reach your computer. Examples include someone trying to connect to a web server running on your machine, a remote desktop connection, or a file sharing request.

By default, Windows Firewall blocks all unsolicited inbound connections. This means no one can connect to your computer unless you have explicitly created an allow rule for that type of connection. This is the most important security feature of the firewall.

Outbound Traffic

Outbound connections are initiated by your computer reaching out to a remote server. Examples include browsing a website, checking email, downloading a file, or an application sending telemetry data.

By default, Windows Firewall allows all outbound connections. This means any application on your computer can connect to any server on the internet. While this is convenient, it means malware can communicate freely with command-and-control servers once it is on your system.

!
Consider restricting outbound connections for high-security needs.

Advanced users can change the default outbound behavior to Block, then create explicit allow rules for each application that needs internet access. This is powerful but time-consuming to maintain, as every application and Windows Update component needs an allow rule. Only do this if you understand the implications and are prepared to troubleshoot connectivity issues.

Viewing Current Firewall Rules

# View all enabled inbound rules
Get-NetFirewallRule -Direction Inbound -Enabled True | Format-Table DisplayName, Action, Profile

# View all enabled outbound rules
Get-NetFirewallRule -Direction Outbound -Enabled True | Format-Table DisplayName, Action, Profile

# Count rules by direction and action
Get-NetFirewallRule -Enabled True | Group-Object Direction, Action | Format-Table Count, Name

Enabling and Disabling the Firewall

There are rare situations where you may need to temporarily disable the firewall for troubleshooting. This section covers how to do it safely.

Disabling via Windows Security

1
Open Windows Security and click Firewall & network protection.
2
Click the active network profile (e.g., Private network (active)).
3
Toggle Microsoft Defender Firewall to Off. You will need to approve the User Account Control prompt.

Disabling via PowerShell

# Disable firewall for a specific profile
Set-NetFirewallProfile -Profile Private -Enabled False

# Disable firewall for all profiles (not recommended)
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False

# Re-enable firewall for all profiles
Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled True

Disabling via Command Prompt

:: Disable all profiles
netsh advfirewall set allprofiles state off

:: Re-enable all profiles
netsh advfirewall set allprofiles state on

:: Disable only the Public profile
netsh advfirewall set publicprofile state off
!
Never leave the firewall disabled.

If you disable the firewall for troubleshooting, set a reminder to re-enable it. An unprotected computer on any network can be compromised within minutes. If a specific application is not working, create a targeted firewall rule instead of disabling the entire firewall.

Notification Settings

When the firewall blocks an application from accepting inbound connections, it can display a notification asking whether you want to allow the connection. Understanding and configuring these notifications helps you make informed decisions about network access.

Configuring Notifications

1
Open Windows Security and go to Firewall & network protection.
2
Click Firewall notification settings at the bottom of the page (or go to Settings > Notifications > Manage notifications).
3
Under Firewall & network protection notifications, you can toggle notifications on or off for each profile independently. Keep notifications enabled so you are aware when applications are blocked.

What to Do When a Notification Appears

When you see a firewall notification asking to allow an application through, ask yourself these questions before clicking Allow:

  • Did I just launch this application? If you just started a game, server, or development tool, allowing it is probably correct.
  • Do I recognize the application? If the program name is unfamiliar, do not allow it. Research the executable name first.
  • Does this application need to accept connections? A web browser does not need inbound connections. A game server does. Think about whether the request makes sense.
  • Which networks should it be allowed on? The notification lets you choose Private and/or Public networks. Most applications only need Private network access.

Via PowerShell, you can control notification behavior per profile:

# Disable notifications for the Private profile
Set-NetFirewallProfile -Profile Private -NotifyOnListen False

# Enable notifications for all profiles
Set-NetFirewallProfile -Profile Domain,Public,Private -NotifyOnListen True
i
Missed a notification?

If you accidentally dismissed a firewall notification or chose the wrong option, you can find and modify the rule in Windows Defender Firewall with Advanced Security (wf.msc). Look under Inbound Rules for the application name and adjust the rule as needed.

Now Do It Yourself: Turn On a Firewall and Watch What It Breaks

The page above explains inbound and outbound traffic and firewall profiles. Reading that is not the same as watching a connection die and working out which rule killed it — and the most common firewall mistake looks completely correct on paper.

Steps 1–4 need Linux (WSL, a VM, or a spare machine) and produced every output below: real TCP connections against a real kernel firewall, entirely on 127.0.0.1, no sudo. Step 5 is Windows and is marked where it could not be re-run.

1
Reuse the listener and probe, or build them again

Go: a Linux terminal — a spare machine, WSL on Windows, or a VM. If you did the rule-precedence lab on the companion page you already have listen.py and probe.py; cd into that folder and skip to step 2.

Do: otherwise create them. Save this as listen.py:

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:

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, and nothing running yet. Both speak only to 127.0.0.1 — your own machine — so nothing leaves it.

Windows Firewall gives you no way to watch a packet be accepted or dropped. A Linux firewall does, and what it shows applies directly to what Windows is doing quietly on your behalf.

If not: Address already in use means something holds port 9000 — change it in both files.

2
Turn the firewall on properly and watch everything stop

Go: the same folder.

Do: save this as lab2.sh. It probes after each change, so you see the effect of every single line:

ip link set lo up
python3 listen.py &
LISTENER=$!
sleep 1

echo "1. default policy ACCEPT on both chains"
python3 probe.py "   connect"

echo
echo "2. default-deny inbound: iptables -P INPUT DROP"
iptables -P INPUT DROP
python3 probe.py "   connect"

echo
echo "3. allow the destination port 9000"
iptables -A INPUT -p tcp --dport 9000 -j ACCEPT
python3 probe.py "   connect"

echo
echo "4. allow replies to connections we already made"
iptables -I INPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
python3 probe.py "   connect"

echo
echo "packet counters — which rule is doing the work:"
iptables -L INPUT -v -n
kill $LISTENER 2>/dev/null

Run it in an isolated network namespace — real firewall, no sudo, nothing touching your machine:

unshare --user --map-root-user --net -- sh lab2.sh

You should see: four probes, and the third one is not what most people expect. (The script prints a table of packet counters after these — that part is step 4, so it is shown there rather than repeated here.)

1. default policy ACCEPT on both chains
   connect                         CONNECTED

2. default-deny inbound: iptables -P INPUT DROP
   connect                         BLOCKED (TimeoutError)

3. allow the destination port 9000
   connect                         BLOCKED (TimeoutError)

4. allow replies to connections we already made
   connect                         CONNECTED

Step 2 is default-deny — the posture every firewall guide recommends and the one Windows uses for inbound traffic out of the box.

If not: unshare: Operation not permitted means unprivileged user namespaces are disabled; check sysctl kernel.unprivileged_userns_clone. If probe 1 is already BLOCKED, the listener did not start — look for a Python error above it.

3
Work out why step 3 did not fix it

Go: the output you just produced.

Do: read probe 3 again. The rule allows tcp dpt:9000, the connection is to port 9000, the rule is in the table — and the connection still fails. Before reading on, try to say why.

You should see: a rule that is correct and insufficient.

🔴 The reply does not come back on port 9000. Your machine opened the connection from a random high-numbered port, so the server's answer arrives addressed to that port — which the default-deny policy drops. Allowing the destination covers the outbound half of the conversation and nothing else.

This is the single most common way a hand-written firewall rule “does not work”. The rule is right; the model of the conversation is wrong.

If not: if probe 3 CONNECTED for you, the -P INPUT DROP line did not take effect — check the output above the probes for an iptables error.

4
Read the counters to find out which rule acted

Go: the bottom of the same output.

Do: look at the packet counts beside each rule in the output the script already printed — the last thing it does before exiting. They are the firewall telling you what it actually did, rather than what you intended. (The script runs iptables -L INPUT -v -n for you inside the namespace; running it in your own terminal would show your real machine's rules instead, which are a different thing entirely.)

You should see: the conntrack rule doing the real work, and the port rule handling only the opening packets:

Chain INPUT (policy DROP 5 packets, 300 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    5   268 ACCEPT     0    --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
    3   180 ACCEPT     6    --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:9000

Your exact counts will differ by a packet or two — TCP retries are timing-dependent.

The policy DROP 5 packets line is the traffic that matched nothing and was discarded, which is where a mysteriously failing service usually ends up. A rule with a zero counter has never once been used — that single number answers “is my rule even being reached?”, which no amount of re-reading the rule can.

If not: if all counters read 0, you are looking at a fresh namespace rather than the one the probes ran in — the counters only exist inside the unshare that created them, which is why the script prints them before exiting.

5
See that Windows already did all of this for you

Go: a Windows PowerShell window opened as Administrator.

Do: print the default inbound and outbound behaviour of each firewall profile:

Get-NetFirewallProfile | Select-Object Name, Enabled, DefaultInboundAction, DefaultOutboundAction

You should see: inbound defaulting to Block and outbound to Allow, for Domain, Private and Public.

Not re-run for this page — PowerShell is Windows-only and this was written on Linux. The command is from Microsoft's documented NetSecurity module. Steps 1–4 were run.

Two things follow. Windows Firewall is stateful by default, so the trap in step 3 cannot bite you there — return traffic for connections you started is allowed automatically, which is why nobody writing a Windows rule ever thinks about ephemeral ports.

And DefaultOutboundAction: Allow is worth sitting with. Anything already running on your machine may talk to anything on the internet, with no rule and no prompt. The firewall is a door policy for visitors, not a guard on what leaves — so it is not, and was never meant to be, a defence against something already inside.

If not: Get-NetFirewallProfile is not recognized means you are in Command Prompt rather than PowerShell. The older equivalent is netsh advfirewall show allprofiles.

🎉
Check yourself before moving on

Your firewall blocks all inbound traffic by default. You add a rule allowing inbound TCP on port 443 so a colleague can reach a web server you are running. It works. Why did that rule need nothing extra, when step 3's port rule was not enough? Answer: Direction. In step 3 you opened the connection, so the reply arrived on a random port your rule did not cover. For an incoming visitor, they open the connection to port 443, so the destination port really is 443 and your rule matches the packet that matters. The return traffic is then handled by the stateful rule — the one Windows applies automatically.

Now do it without the page: on any firewall you administer, find a rule whose packet counter is zero and work out whether it is unnecessary or unreachable. If you can tell those two apart, you can prune a rule set safely instead of leaving everything in place out of caution.

Summary

In this tutorial, you learned the fundamentals of Windows Firewall:

  • What a firewall does and how it differs from antivirus protection
  • How to check firewall status using the GUI, PowerShell, and command prompt
  • The three firewall profiles (Domain, Private, Public) and when each is active
  • The difference between inbound and outbound traffic and their default behaviors
  • How to safely enable and disable the firewall when needed
  • How to configure and respond to firewall notifications
+
Great foundation!

You now understand how Windows Firewall works at a conceptual level. In the next tutorial, you will learn how to create custom inbound and outbound rules to precisely control which applications and ports are allowed through the firewall.