IIS7 Localhost port binding
by Wil van Antwerpen
IIS Web services on Windows 7 and higher does not just bind to 127.0.0.1 when binding itself but binds itself to any available IP address on your host, not convenient if you want to bind something on that same ports to for example 127.0.0.2
|No Files Available
||Wil van Antwerpen
IIS Web services on Windows 7 and higher does not just bind to 127.0.0.1 when binding itself but binds itself to any available IP address on your host, not convenient if you want to bind something else on port 80 to for example 127.0.0.2.
In IIS you can define where you want to bind a certain website to using the binding option under IIS Manager.
By default it is set to *:80
This means that the webserver will listen on any address on your host so you can access that website.
On a development machine however I do not really want that, as I want to bind other services to port 80 as well.
An example here would be apache or a putty session where I want to forward port 80.
On earlier versions of windows this was simple, you bind them to a loopback address that is not equal to localhost (127.0.0.1).
Most people only know 127.0.0.1 as local loopback (localhost).. but in practice you have many more loopback addresses as 127.0.0.0/8 is all available. this means that you can easily use 127.0.0.2 as a loopback address for anything that you want to bind a service to. Binding apache to 127.0.0.2 port 80 gives you both apache as well as IIS on port 80.
The problem with IIS7 is that it wants to listen on 0.0.0.0:80
If you then try to bind port 80 to another process. For example if you want to port forward a service on port 80 via PuTTY to say 127.0.0.2:80 then you can't, because IIS is hogging ALL available IP addresses on your host with for port 80.
A typical error is:
bind: operation not permitted.
So you have to limit the IIS process to not use ALL available IP addresses and for example only bind to localhost (127.0.0.1).
The text below discusses the steps needed.
Note that the steps below still work in 2023, even while this was written in 2012.
Run the following command from an elevated command shell and you'll see 0.0.0.0:80 in the list:
netstat -anob -p TCP
You can stop IIS7 using:
net stop W3SVC
net stop IISADMIN
and run the netstat command from above again.
You'll notice that the 0.0.0.0:80 line has disappeared.
Now restart IIS again:
net start IISADMIN
net start W3SVC
Checking with netstat again, will bring back the dreaded line with 0.0.0.0:80.
Even using the binding option in IIS Manager to bind the websites to only 127.0.0.1:80 did not fix it for me.
Limiting the binding for W3SVC
The trick to getting IIS to only listen to your advertised address is to use the NETSH command.
netsh http show iplisten
Will show you all addresses to which your IIS will bind its services.
On my machine that did not show anything, meaning it would bind to EVERYTHING regardless of what you tell it in IIS7. The IIS7 setting only makes your website reply to 127.0.0.1 in all other cases IIS will reply with a 404 error.
I guess in a way that makes sense.
As this is a development machine having IIS listen on localhost ONLY is exactly what I want.
You do this by adding 127.0.0.1 to the listen addresses.
netsh http add iplisten ipaddress=127.0.0.1
Rerunning the above show listen command should only display this address.
Rerunning the netstat command from above however displays that IIS is still listening on everything.
You fix this by running IISRESET
This will restart your IIS. I expect that simply restarting your host will have the same effect.
Verify again with
netstat -anob -p TCP
and you should now see that only 127.0.0.1:80 is listening for HTTP traffic.