Diagnosing Sockets and Ports
Goal
You read listening sockets, reproduce for yourself the effect of the binding address on remote access, and confirm the difference between Connection refused and a normal connection.
Why it matters
A process listening on 127.0.0.1:8080 works perfectly from the same host, but a connection coming from outside is rejected by the kernel with an RST — that is, refused. So when you get a report that "it works locally but only remote fails", just looking at the single cell of the Local Address column of ss -ltnp finishes half of it. Conversely, if that address is 0.0.0.0 and it still times out from outside, then you start looking at the firewall and network policy. This fork halves the scope of the investigation.
Steps
- Create the
/root/sockdirectory and save the list of currently listening TCP sockets to/root/sock/listen.txt.:2222must be included. - Start an HTTP server listening on
0.0.0.0:8080in the background. It must still be alive at grading time. - Start a second server listening only on
127.0.0.1:8081, and write theLocal Address:Portof the two sockets, one per line, in/root/sock/bind.txt. (For example:0.0.0.0:8080and127.0.0.1:8081) - Save the result of checking whether a connection to
127.0.0.1:8080works to/root/sock/nc-open.txt. - Save the result of trying to connect to
127.0.0.1:9999, where nobody is listening, to/root/sock/nc-refused.txt. The output must contain wording that means refused. - Find the LISTEN socket line for port 8080 in
/proc/net/tcpand save it as is to/root/sock/proctcp.txt. - Knock on 8080 and 8081 separately with your own interface IP (not loopback), and write the results on two lines in
/root/sock/scope-test.txt.8080=<open|closed>/8081=<open|closed> - Make
/root/sock/report.csv. The first line is the headerport,bind,proto, and below it write one line each for the three ports 2222, 8080, and 8081.bindis the actual listening address andprotoistcp.
Notes
- The combination
ss -ltnp,nc -zv -w 2 <ip> <port>, andip -4 -br addr show scope globalis enough. - You start a server in the form
nohup python3 -m http.server 8080 --bind 0.0.0.0 >/dev/null 2>&1 &. - The ports in
/proc/net/tcpare hexadecimal. Check the converted value withprintf '%04X\n' 8080. - Common mistake 1: if you test with the loopback address in step 7, both ports look open and the difference does not show.
- Common mistake 2: a background server dying when the shell exits. Detach it with
nohuporsetsid.
Checking listening sockets
Create the /root/sock directory and save the list of currently listening TCP sockets to /root/sock/listen.txt. :2222 must be included.
It is the option combination that shows only TCP listening sockets, without name resolution, with the process too. sshd is running on 2222.
Starting a test server
Start an HTTP server listening on 0.0.0.0:8080 in the background. It must still be alive at grading time.
Start python3's built-in HTTP server in the background. It must be alive at grading time, so it is safer to use nohup or setsid together.
Two servers with different binding scopes
Start a second server listening only on 127.0.0.1:8081, and write the Local Address:Port of the two sockets, one per line, in /root/sock/bind.txt. (For example: 0.0.0.0:8080 and 127.0.0.1:8081)
python3 -m http.server has an option to specify the binding address. Compare the Local Address columns of the two servers.
Checking an open port
Save the result of checking whether a connection to 127.0.0.1:8080 works to /root/sock/nc-open.txt.
nc's -z tries only to connect without sending data. You need to add -v for the result sentence to come out.
Checking a closed port
Save the result of trying to connect to 127.0.0.1:9999, where nobody is listening, to /root/sock/nc-refused.txt. The output must contain wording that means refused.
If you connect to a port nobody is listening on, the kernel returns an RST. Save that result wording as it is.
Reading /proc/net/tcp directly
Find the LISTEN socket line for port 8080 in /proc/net/tcp and save it as is to /root/sock/proctcp.txt.
The port is written in hexadecimal. What does 8080 become in hexadecimal? 0A in the state column is LISTEN.
Knocking from an outside address
Knock on 8080 and 8081 separately with your own interface IP (not loopback), and write the results on two lines in /root/sock/scope-test.txt.
8080=<open|closed> / 8081=<open|closed>
The difference shows only if you connect with your own interface IP, not loopback. The results for the two ports must differ.
Making a listening-socket table
Make /root/sock/report.csv. The first line is the header port,bind,proto, and below it write one line each for the three ports 2222, 8080, and 8081. bind is the actual listening address and proto is tcp.
A CSV is separated by commas. Include the header line, and both ports you started earlier must be included.