Your computer is not a black box - Understanding Processes and Ports on Windows by exploring
I did a blog post many years ago reminding folks that The Internet is not a Black Box. Virtually nothing is hidden from you. The same is true for your computer, whether it runs Linux, Mac, or Windows.
Here's something that happened today at lunch. I was testing a local DNS Server (more on this on Thursday) and I started it up...and it didn't work.
In order to test a DNS server on Windows, you can go to the command line and run "nslookup" then use the command "server 1.1.1.1" where 1.1.1.1 is the DNS server you'd like to try out. Go ahead and try it now. Run cmd.exe or powershell.exe and then run "nslookup" and then type any domain name. You should get an IP address.
Given that I was trying to run a DNS Server on localhost:53 (Port 53 is where DNS usually hangs out, just like Port 80 is where Web Servers (HTTP) hang out and 443 is where Secured Web Servers (HTTPS) usually are) I should be able to do this. I'm trying to send DNS requests to localhost:53
C:\Users\scott> nslookup
Default Server: pihole
Address: 192.168.151.6
> server 127.0.0.1
Default Server: localhost
Address: 127.0.0.1
> hanselman.com
Server: localhost
Address: 127.0.0.1
*** localhost can't find hanselman.com: No response from server
> hanselman.com
Weird, that didn't work. Let me try a DNS Server I know works like Google's 8.8.8.8 public DNS
> server 8.8.8.8
Default Server: google-public-dns-a.google.com
Address: 8.8.8.8
> hanselman.com
Server: google-public-dns-a.google.com
Address: 8.8.8.8
Non-authoritative answer:
Name: hanselman.com
Address: 206.72.120.92
Ok, it seems my local DNS isn't listening on point 53. Checking the logs of the Technitium local DNS server shows this:
[2019-04-15 23:26:31 UTC] [0.0.0.0:53] [UDP] System.Net.Sockets.SocketException (10048): Only one usage of each socket address (protocol/network address/port) is normally permitted
at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at DnsServerCore.DnsServer.Start() in Z:\Technitium\Projects\DnsServer\DnsServerCore\DnsServer.cs:line 1234
[2019-04-15 23:26:31 UTC] [0.0.0.0:53] [TCP] DNS Server was bound successfully.
[2019-04-15 23:26:31 UTC] [[::]:53] [UDP] DNS Server was bound successfully.
[2019-04-15 23:26:31 UTC] [[::]:53] [TCP] DNS Server was bound successfully.
The DNS Server's process is trying to bind to TCP:53 and UDP:53 using IPv4 (expressed as "all local network adapters" with 0.0.0.0:53) and then TCP:53 and UDP:53 using IPv6 (expressed as localhost using [::]:53) but it seems like the UDP binding to port 53 on IPv4 failed. Weird.
Someone else is listening in on Port 53 localhost via IPv4.
That's weird. How can we find out what ports are open locally?
I can run "netstat" and ask Windows for a list of all TCP/IP connections and the processes that are listening on which ports. I'll also PIPE the results to "clip" which will put it in the clipboard automatically. Then I can look at it in a text editor (or I could pipe it through find or findstr).
You can run netstat --help to get the right arguments. I've asked it to tell me the process IDs and all the details it can.
Active Connections
Proto Local Address State PID
TCP 0.0.0.0:53 LISTENING 27456
[dotnet.exe]
UDP 0.0.0.0:53 LISTENING 11128
[svchost.exe]
TCP [::]:53 *:* 27456
[dotnet.exe]
UDP [::]:53 *:* 27456
[dotnet.exe]
Hm, a service is already listening on port 53. I'm running Windows 10, not a Server so it's odd there's already a DNS listener on port 53.
I wonder what service is it?
I can check the Services Tab of the Task Manager and sort by PID. Or can I run "tasklist" and ask directly.
C:\WINDOWS\system32>tasklist /svc /fi "pid eq 11128"
Image Name PID Services
========================= ======== ============================================
svchost.exe 11128 SharedAccess
That's Internet Connection Sharing, and it's used by Docker and other apps for NAT translation and routing. I can shut it down with the sc (service control) or with "net stop."
C:\WINDOWS\system32>net stop sharedaccess
The Internet Connection Sharing (ICS) service is stopping.
The Internet Connection Sharing (ICS) service was stopped successfully.
Now I can start my DNS Server again (it's written in .NET Core) and I can see with tcpview.exe that it's listening on all appropriate ports.
In conclusion, it's a good reminder to refresh yourself on the basics of IPv4, IPv6, how processes talk to/allocate ports, what Process IDs (PIDs) are, and their relationships. Much of this is taught in computer science university courses but if you're self taught or not doing low level work every day it's easy to forget.
Virtually nothing on your computer is hidden from you!
Sponsor: Manage GitHub Pull Requests right from the IDE with the latest JetBrains Rider. An integrated performance profiler on Windows comes to the rescue as well.
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter
Oh, and your copyright statement still says 2018. Might want to update that.
We aren't using Docker because there's a lot of barriers in our way to adopting it. But we do have a bunch of services, many of them hosted in IIS. For local development, we wanted to have each web service listening at a different hostname on our machine and have corresponding certificates for them. We ended up writing PowerShell scripts that automatically adds/removes the necessary entries from our hosts file (%WINDIR%\System32\Drivers\etc\hosts). We have a config file that specifies the file path locations of our sites and what we want the DNS name to be. Then we leverage PowerShell DSC to create the IIS sites and app pools and SSL certs and host entries. It worked out fairly well.
`dir | code -`
note the hyphen. Also works on Linux (or at least my Ubuntu)
I'm very happy that computers are a black box because that's how they're largely designed and they've made life easier for both users and developers. Hardly anyway codes in machine language or assembly anymore, and I would hazard a guess that you're happy about this too.
The sense that Scott is using is what I would call a "true black box". This is a description of a system with input and output, but of which we can't see the inner workings. He's pointing out that what happens between the keyboard/mouse and screen is not a black box in this sense. There's a lot of what happens inside the computer that you can pry into, observe, and understand. You can't do that with a true black box.
Of course there are a lot of black boxes in play in the operation of a computer. *nix command-line utilities operate that way. The kernel is essentially a black box. But in terms of the overall operations of the computer, a black box it ain't.
I can also add comments and share.
Do you have recommended books where we can learn "the basics of IPv4, IPv6, how processes talk to/allocate ports, what Process IDs (PIDs) are, and their relationships"? Please tell us if you have.
Or please tell us an example of a name of a course that teaches these things.
Thank you so much :)
Comments are closed.