Using Windows Firewall

Opening and closing ports on a Windows server from the GUI and with New-NetFirewallRule, and how that relates to the panel's port rules.

Windows8 min read

On this page
  1. What the firewall does before you touch it
  2. Opening a port in the GUI
  3. Opening a port with PowerShell
  4. Scoping a rule to specific sources
  5. How rules are evaluated
  6. Inbound versus outbound
  7. Listing what is in force
  8. Disabling and removing rules
  9. How this relates to the panel's port rules
  10. Related

Windows Firewall decides what the server itself accepts, on the machine, after traffic has already arrived. This page covers opening a port, closing it again, scoping a rule to particular sources, and reading back what is actually in force.

The full name in the GUI is Windows Defender Firewall with Advanced Security, and the console is wf.msc. The PowerShell cmdlets all end in -NetFirewallRule.

What the firewall does before you touch it

Two defaults explain most of the behaviour you will see:

  • Inbound connections are blocked unless a rule allows them. A service you install and start is listening, and still unreachable, until something opens its port. Some installers add their own rule, some do not, and that difference is the usual reason a freshly installed service does not answer.
  • Outbound connections are allowed unless a rule blocks them. The server can reach out to anything by default.

Windows keeps three sets of rules, called profiles: Domain, Private, and Public. Only the profile matching the network the interface is on is in force. On a standalone server on the internet that is normally Public, which means a rule created for Private only does nothing.

Check both at once:

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

A DefaultInboundAction of NotConfigured means the built-in default applies, which is to block. Get-NetConnectionProfile tells you which profile your interface is actually using, under NetworkCategory.

Opening a port in the GUI

  1. Open the firewall console

    Run wf.msc, or find Windows Defender Firewall with Advanced Security in the Start menu.

  2. Start a new inbound rule

    Select Inbound Rules in the left pane, then New Rule on the right.

  3. Choose Port

    Pick Port, then Next. The Program option is the other one worth knowing: it allows an executable whatever ports it opens, which suits software that picks its ports at runtime.

  4. Enter the protocol and ports

    Choose TCP or UDP, then Specific local ports. The box takes a single port, a comma-separated list such as 80,443, or a range such as 30120-30130. A service that uses both protocols needs two rules.

  5. Allow the connection

    Pick Allow the connection, then Next.

  6. Tick the profiles

    Leave all three ticked unless you have a reason not to. A rule that is missing the profile your interface is on has no effect.

  7. Name it something you will recognise

    Use a name that says what the port is for, such as Game server UDP 30120, not Rule 1. You will be reading this list in six months trying to work out what is safe to remove.

To restrict the rule after creating it, double-click it in the list, open the Scope tab, and under Remote IP address choose These IP addresses and add the sources allowed to use it.

Opening a port with PowerShell

New-NetFirewallRule does the same thing in one line, and unlike the GUI it can be pasted into a build script. Run PowerShell as Administrator.

PowerShell
New-NetFirewallRule -DisplayName "HTTP" -Direction Inbound -Protocol TCP -LocalPort 80 -Action Allow

A UDP game port:

PowerShell
New-NetFirewallRule -DisplayName "Game server UDP 30120" -Direction Inbound -Protocol UDP -LocalPort 30120 -Action Allow

Several ports, and a range. Quote a range so PowerShell passes it through as written:

PowerShell
New-NetFirewallRule -DisplayName "Web" -Direction Inbound -Protocol TCP -LocalPort 80,443 -Action Allow
New-NetFirewallRule -DisplayName "App ports" -Direction Inbound -Protocol TCP -LocalPort "30120-30130" -Action Allow

A rule for a program rather than a port, which covers software that opens ports of its own choosing:

PowerShell
New-NetFirewallRule -DisplayName "MyApp" -Direction Inbound -Program "C:\apps\myapp.exe" -Action Allow

The parameters worth knowing:

ParameterWhat it sets
-DirectionInbound or Outbound. Defaults to Inbound.
-ProtocolTCP, UDP, ICMPv4, Any.
-LocalPortThe port on this server. A number, a list, or a quoted range.
-RemotePortThe port at the far end. Used on outbound rules.
-RemoteAddressWhich sources the rule applies to. Defaults to Any.
-ActionAllow or Block.
-ProfileDomain, Private, Public, or Any. Defaults to Any.
-ProgramPath to an executable, instead of a port.
-EnabledTrue or False. Create a rule switched off with False.

Scoping a rule to specific sources

An open port that only answers the addresses that should be using it is dramatically safer than one that answers everybody. This is the single most useful thing on the page for a management port, a database port, or anything else that is not meant for the public.

Create the rule scoped from the start:

PowerShell
New-NetFirewallRule -DisplayName "MySQL from app server" -Direction Inbound -Protocol TCP -LocalPort 3306 -RemoteAddress "203.0.113.10" -Action Allow

Change the scope of a rule that already exists, including one Windows shipped:

PowerShell
Set-NetFirewallRule -DisplayName "MySQL from app server" -RemoteAddress @("203.0.113.10", "203.0.113.20")

CIDR ranges are accepted, so 203.0.113.0/24 covers a whole block. Read back what a rule is scoped to:

PowerShell
Get-NetFirewallRule -DisplayName "MySQL from app server" | Get-NetFirewallAddressFilter

Put it back to everything with -RemoteAddress Any.

Scoping the Remote Desktop rules is a special case with its own steps and its own risks, on Hardening Remote Desktop.

How rules are evaluated

There is no rule order to manage. Windows applies two principles:

  • A block rule beats an allow rule. If any rule blocks the traffic, it is blocked, whatever else allows it.
  • With no matching rule, the profile default applies, which is to block inbound and allow outbound.

The practical consequence is that you narrow an open port by scoping the allow rule that opens it, not by adding an allow rule for the sources you want. Adding one leaves the original wide-open rule in place next to it.

Add an allow rule for your addressNew-NetFirewallRule beside the open oneInbound allow rules for TCP 3306Allow TCP 3306 from AnyStill thereAllow TCP 3306 from 203.0.113.10AddedA connection to 3306 from203.0.113.10Allowed198.51.100.7Allowed, by the Any ruleScope the rule that opens itSet-NetFirewallRule -RemoteAddressInbound allow rules for TCP 3306Allow TCP 3306 from 203.0.113.10ScopedA connection to 3306 from203.0.113.10Allowed198.51.100.7No rule matches: blockedNo rule order to manage: a block rule beats any allow rule, and with no matching rule the profiledefault blocks inbound.Add an allow rule for your addressNew-NetFirewallRule beside the open oneInbound allow rules for TCP 3306Allow TCP 3306 from AnyStill thereAllow TCP 3306 from 203.0.113.10AddedA connection to 3306 from203.0.113.10Allowed198.51.100.7Allowed, by the Any ruleScope the rule that opens itSet-NetFirewallRule -RemoteAddressInbound allow rules for TCP 3306Allow TCP 3306 from 203.0.113.10ScopedA connection to 3306 from203.0.113.10Allowed198.51.100.7No rule matches: blockedNo rule order to manage: a block rule beatsany allow rule, and with no matching rulethe profile default blocks inbound.
Two ways to try to limit MySQL to one address. An added allow rule sits beside the open one, so every other source is still let in by it; scoping the rule that opens the port leaves other sources matching nothing, and the default blocks them. Illustration.

Inbound versus outbound

Inbound rules control what may reach services on this server. Outbound rules control what this server may reach elsewhere. Because outbound is allowed by default, most people never write an outbound rule, and that is a reasonable place to stay.

The case where one earns its place is containing a compromise or a misbehaving application: a server that has been broken into is usually being used to reach something else, whether that is sending spam or joining a botnet.

PowerShell
New-NetFirewallRule -DisplayName "Block outbound SMTP" -Direction Outbound -Protocol TCP -RemotePort 25 -Action Block

Note the parameter change. On an outbound rule the interesting port is at the far end, so it is -RemotePort, not -LocalPort.

Listing what is in force

Every allow rule that is currently switched off is noise, so filter to the ones that matter:

PowerShell
Get-NetFirewallRule -Direction Inbound -Enabled True -Action Allow |
  Sort-Object DisplayName |
  Format-Table DisplayName, Profile, Enabled

That does not show ports, because a rule and its port filter are separate objects. To see both:

PowerShell
Get-NetFirewallRule -Direction Inbound -Enabled True -Action Allow | ForEach-Object {
  $filter = $_ | Get-NetFirewallPortFilter
  [pscustomobject]@{
    Name      = $_.DisplayName
    Protocol  = $filter.Protocol
    LocalPort = ($filter.LocalPort -join ",")
  }
} | Sort-Object Name | Format-Table -AutoSize

Going the other way, to find every rule touching one port:

PowerShell
Get-NetFirewallPortFilter |
  Where-Object { $_.LocalPort -eq 3389 } |
  Get-NetFirewallRule |
  Format-Table DisplayName, Direction, Action, Enabled

That last one is the query to run when a port is open and you cannot work out which rule is opening it.

Disabling and removing rules

Switch a rule off, keeping it for later:

PowerShell
Disable-NetFirewallRule -DisplayName "HTTP"
Enable-NetFirewallRule -DisplayName "HTTP"

Delete it outright:

PowerShell
Remove-NetFirewallRule -DisplayName "HTTP"

How this relates to the panel's port rules

The two firewalls sit at different points in the same path, and traffic has to pass both.

Panel rules are applied at the network edge, before packets reach your server. Windows Firewall is applied on the machine, after they have arrived on its network interface. So:

  • The panel stops traffic earlier. Something dropped at the edge never consumes your server's bandwidth, CPU, or connection table. A flood that Windows Firewall blocks has still arrived, and blocking it still costs the machine work. That is the whole reason the edge layer exists.
  • Windows Firewall knows things the edge cannot. Which program is listening, which local account is running it, and what is happening on ports the edge was never asked about.
  • A port needs to be open in both places. In the panel, a port with no rule of its own falls to the Default for unlisted ports setting, which starts on Allow. So on a new server, opening a port in Windows is enough to make it reachable. Add the panel rule anyway: rate limits and protocol checks only apply to a port that has one. See Port rules.
  • Closing a port is worth doing in both places too. The edge rule saves your server the traffic, and the Windows rule means a mistake in one layer is not the whole story.

When a service is unreachable, this split is the first thing to check: run the listening-ports command from First steps to confirm something is actually bound to the port, then check the Windows rule, then check the panel rule. Those are three separate reasons for the same symptom.

A player connectsUDP, to port 30120 on 203.0.113.103The panel's rules, before your serverNo rule of its own: the port falls to Default for unlistedports, Allow on a new server. Add the rule anyway for itsrate limits and checks.Blocked here: a block, or norule under Deny all2Windows Firewall, on the machineNeeds an allow rule in the profile in force, normallyPublic.No allow rule in thatprofile: blocked by thedefault1Something listening on 30120Confirm it with the listening-ports command from Firststeps.Nothing bound to the port: noanswerA player connectsUDP, to port 30120 on 203.0.113.103The panel's rules, before your serverNo rule of its own: the port falls toDefault for unlisted ports, Allow on anew server. Add the rule anyway for itsrate limits and checks.Blocked here: a block, or no ruleunder Deny all2Windows Firewall, on the machineNeeds an allow rule in the profile inforce, normally Public.No allow rule in that profile: blockedby the default1Something listening on 30120Confirm it with the listening-portscommand from First steps.Nothing bound to the port: no answer
The three places a connection can stop, in the order it meets them, numbered in the order to check them: from the inside out. On a new server the panel layer lets an unlisted port through, which is why opening it in Windows is enough there. Illustration.

Need a server, or a hand with one?

Pick a plan to deploy a server, or open a ticket in the panel. Support runs 24/7/365.