Windows Firewall Basics
By Mark Minasi
Mark Minasi is a best-selling author, commentator and all-around alpha geek. He is best known for his books in the Mastering Windows series. The following excerpt is from chapter eight of Minasi's newest book, Mastering Windows Server 2003 Upgrade Edition for SP1 and R2, entitled "Windows Firewall Basics." Read the entire chapter here.
While raising a firewall makes a server more secure, it can also make it useless, as you've seen— take a web server and turn on WF and it's not a web server anymore. But fear not, you needn't forgo a firewall. Just open up a few ports.
By "open up a few ports," I mean to tell the firewall to continue to discard unsolicited incoming packets, unless those packets are destined for a particular port—TCP port 80, in this case. In Windows Firewall-ese, this is called creating an exception. WF lets you do that in two ways:
- You can specify a particular port to open, creating a port exception, or
- You can tell Windows Firewall, "Look, I don't know what ports XYZ server program needs, so just let XYZ server program open whatever ports it wants." That's called creating a program exception.
Here's how to create each type.
Creating Port Exceptions
To create a port exception, just do two things. First, find out what port or ports your server application uses. Second, use the GUI, group policy, or the command line to tell WF to open those ports.
Which Ports to Open? (Part One)
How do you know what ports your server application uses? Sometimes it's relatively easy, as when your server implements some standard protocol. For example, let's return to your web server. What ports would it need opened? Simple: ports 80 and 443. How'd I know that? It's in the documentation of most kinds of web server software, or you could Google "list of standard internet service ports," a search that will yield many answers. Sometimes it makes sense to create what WF calls a program exception, which we'll talk about in a few pages, whereby you don't need to open port numbers at all; instead, you just tell WF the name of the program and direct WF, "Open whatever ports that application wants."
Another approach is to use netstat. Set up your server application on a computer and connect a client to the server application so that you know the server app is active. Then open a command prompt and type.
You'll see an output like this, which I've shortened to simplify reading it:
|Proto||Local Address||Foreign Address||State||PID|
"Listening" means "I'm watching this port for incoming requests." Servers listen, clients don't. To read the Local Address and Foreign Address columns, translate 0.0.0.0 to "any IP address." So you could read the first line's components as "Local Address = any data coming into port 42 from any one of my IP addresses," and "Foreign Address = I'll take data from any address on the Internet." PID stands for Process ID, and it's the internal identifier that the operating system uses to name each running process. So you know that process number 1820 listens on port 42, process 1584 listens on port 53, and process number 2028 listens on port 80.
But what are those processes? To answer that, type tasklist, and you'll get an output that looks like this (which, again, I've shortened for clarity):
|Image Name||PID||Session Name||Mem Usage|
Here, you see that something called dns.exe has PID 1584. That makes sense, as DNS's standard ports are TCP and UDP 53. Similarly, you see that wins.exe—the WINS server, obviously—runs on port 42, and something called svchost.exe runs on port 80.
I threw in that last one to demonstrate that while this can be useful, it's not perfect. Svchost.exe is an application that acts as something called a wrapper for services. One svchost.exe can hold one or more services, so merely saying that a given svchost uses port 80 doesn't tell you all that much. As Microsoft has implemented IIS inside a svchost, then, you lack an easy way to figure out what ports are associated with IIS, and in that case you would, as I've already suggested, either look up the ports on the Web or look in the IIS documentation to discover that IIS needs TCP ports 80 and 443 open.
Now that you've got the particular port or ports, let's open 'em up! For my example, I'll open up TCP port 80.
Opening Port 80 From the GUI
To create a port exception, return to the Windows Firewall property page (Start _ Control Panel _ Windows Firewall) and click the Exceptions tab. It'll look like Figure 8.4.
WF tries to be smart and detect what exceptions you might want to create; file and print is pretty common amongst servers, as is remote desktop. But it hasn't anticipated the web server, so you'll have to create one of your own. To do that, click Add Port to see a dialog box like Figure 8.5.
The dialog box asks for a label for the exception, and as you can see I've filled in Web Server. It also wants to know the port number, and whether it's a TCP or UDP port. You could click OK, but then you'd be missing one of the neater things that WF does: it lets you be very picky about who gets to use a port. Click Change Scope to see a dialog box like Figure 8.6.
Exceptions tab in Windows Firewall
Opening port 80 in Add a port
Limiting the exception to just the 10.50.50x subnet.
While much of WF is sort of basic, I think this is pretty neat—more than I expected. (Actually that's true for two reasons. The first is, as I said, I didn't expect Microsoft to offer something this useful in a free tool. The second is that the first time WF appeared, in XP SP2, this feature did not exist in even the near-final betas. But enough of us beta testers said, "Hey, we need better finetuned control of exception scopes!" and, mirabile dictu, they answered our prayers!) This lets me say, "This web server should only be available on this subnet."
More specifically, this lets you tell WF, "I want you to open up port 80, but only to packets from IP address 10.50.50.0 through 1050.50.255." That's what the 10.50.50.0/255.255.255.0 means— network number followed by subnet mask. Note, by the way, that I didn't have to type all of that out, because there's a My Network (Subnet) Only radio button. The Custom List option even lets you specify a list of addresses or address ranges, separated by commas.
Opening Port 80 from the Command Line
If you return to the Exceptions tab, you'll see that there's now, in addition to the three optional exceptions, a new one named Web Server, and it's checked. Click it and then click the Delete button so you can rebuild the exception from the command line. (It'll ask if you're sure; tell it that you are.)
You create a port exception with the netsh firewall command. A basic port exception looks like:
netsh firewall add portopening protocol=tcp|udp port=n name=descriptive name scope=all|subnet|custom
Yeah, I know, that looks ugly, but it'll make more sense with a few examples. If you remember that the command line just does the same thing as the GUI, which you've already seen, then it gets a bit easier. To simply open up port 80 to the entire Internet, you'd type:
netsh firewall add portopening protocol=tcp port=80 name="Web Server"
As with all netsh commands, that's all one line, even if it broke on the printed page. Make sure that you type all of the netsh commands in this chapter as one big line, even it wraps—only press Enter once, at the end of the line. If you typed it right, then you'll get netsh's normal laconic response—Ok.—and all of the world will be able to see your web page. But this is supposed to be a secure web server, only available to folks on the same subnet. So you could instead type:
netsh firewall add portopening protocol=tcp port=80 name="Web Server" scope=subnet
And you could get even more specific with the scope=custom format. To show custom IP ranges, you add scope=custom addresses= followed by a list of either IP addresses, and/or IP address ranges. For example, if I wanted to block port 80 to every system on the Internet except for a system at 10.50.50.37, I'd type:
netsh firewall add portopening protocol=tcp port=80 name="Web Server" scope=custom addresses=10.50.50.37
Or, to only allow the entire A-class 10.x.x.x network and the C-class 192.168.1.x network, I'd type:
netsh firewall add portopening protocol=tcp port=80 name="Web Server" scope=custom addresses=10.0.0.0/255.0.0.0,192.168.1.0/255.255.255.0
As you can probably see, the format for identifying a network is the network's number, a forward slash and a subnet mask in dotted quad notation, with multiple ranges separated by a comma. (Review Chapter 6 in Mastering Windows Server 2003 if you're unclear on any of that.)
You can remove a port exception with the netsh firewall delete portopening command, which looks like:
netsh firewall delete portopening protocol=udp|tcp|all port=portnumber
In this case, I'd lock port 80 back up with:
netsh firewall delete portopening protocol=tcp port=80
Opening Port 80 with Group Policy Settings
Using the GUI to configure WF on a few systems is quick, easy, and efficient. But to configure WF on a whole domain's worth of servers and/or workstations, there's nothing like group policy. That's why Microsoft included 15 new group policy settings to control WF.
The preceding excerpt is from Chapter 8 of Mark Minasi's book, "Mastering Windows Server 2003 Upgrade Edition for SP1 and R2". Visit amazon.com to purchase the book or click here to read the entire chapter.
|Mark Minasi is a best-selling author, commentator and all-around alpha geek. Mark is best known for his books in the Mastering Windows series. What separates him from others is that he knows how to explain technical things to normal humans, and make them laugh while doing it. Mark's firm, MR&D, is based in Pungo, a town in Virginia's Tidewater area that is distinguished by having one -- and only one -- traffic light.
Copyright 2005 TechTarget