Diagnosing Sockets and Ports
Goal
You tell apart the binding scope of listening sockets and confirm the same fact through two paths, ss and /proc/net/tcp.
Why it matters
Most reports of "curl works inside the server but not from outside" are a binding problem, not a firewall problem. A socket bound to 127.0.0.1:8080 accepts only connections from the same host, and the kernel does not deliver external packets at all. This distinction is also security design - deliberately binding management ports only to loopback is standard practice. And on a listening socket, Send-Q is the backlog maximum and Recv-Q is the current length of the queue waiting for accept. It is often misread because it means something different from its meaning on an established connection.
Steps
You work in the /root/net directory.
- Start
python3 -m http.server 8080 --bind 127.0.0.1in the background and write its PID to/root/net/http_pid.txt. - Start
python3 -m http.server 8081 --bind 0.0.0.0in the background and write its PID to/root/net/all_pid.txt. 8080 must remain loopback-only. - Write the binding scopes of the two ports to
/root/net/binding.txtas the following two lines. The value isloopbackorall.8080=<값>(the value)8081=<값>(the value)
- Start a process that opens one connection to 8081 and keeps it without closing, and write its PID to
/root/net/client_pid.txt. - Convert decimal 8080 to 4 uppercase hexadecimal digits and write it to
/root/net/hexport.txt. - Write the maximum backlog of the 8080 listening socket to
/root/net/backlog.txt, as a number only. - Check with
ssthe PID of the process holding 8080 and write it to/root/net/owner.txt. - Create
/root/net/portcheck.sh <포트>(the argument is a port). If something is listening on that port, printport=<포트> state=listen pid=<PID>and exit with code 0; if nobody is listening, printport=<포트> state=freeand exit with code 1. With no arguments, it is a nonzero code.
Notes
ss -ltnHshows only listening TCP sockets, without a header. The column order isRecv-Q Send-Q Local Peer.- In
/proc/net/tcp,local_addressisIP:PORTall in hexadecimal, and state0Ais LISTEN. - You can hold a connection with
python3 -c "import socket,time; s=socket.create_connection(('127.0.0.1',8081)); time.sleep(9999)" &. - Common mistake 1: if in step 4 you close the connection right after opening it, the ESTABLISHED disappears.
- Common mistake 2: in step 7, without
-p, using justss -ltngives no process information.
Start a server bound only to loopback
Start python3 -m http.server 8080 --bind 127.0.0.1 in the background and write its PID to /root/net/http_pid.txt.
python3 -m http.server has a --bind option. Start it in the background and write the PID.
Start one bound to all addresses
Start python3 -m http.server 8081 --bind 0.0.0.0 in the background and write its PID to /root/net/all_pid.txt. 8080 must remain loopback-only.
If you bind to 0.0.0.0, it accepts connections arriving on any interface. 8080 must stay on loopback.
Record the binding scopes
Write the binding scopes of the two ports to /root/net/binding.txt as the following two lines. The value is loopback or all.
8080=<값>(the value)8081=<값>(the value)
Look at the Local Address column of ss -ltn. Write how the two ports differ.
Hold a connection
Start a process that opens one connection to 8081 and keeps it without closing, and write its PID to /root/net/client_pid.txt.
You must keep the connection open without closing it. In python3, call create_connection and then sleep.
Read /proc/net/tcp directly
Convert decimal 8080 to 4 uppercase hexadecimal digits and write it to /root/net/hexport.txt.
Ports are written in hexadecimal. Try converting 8080 into 4 uppercase hexadecimal digits.
Read the backlog maximum
Write the maximum backlog of the 8080 listening socket to /root/net/backlog.txt, as a number only.
On a listening socket, Send-Q is the backlog maximum. It is the second column of ss -ltn.
Find the owner of a port
Check with ss the PID of the process holding 8080 and write it to /root/net/owner.txt.
ss has an option that shows process information. Extract the pid= part from the output.
A port occupancy check script
Create /root/net/portcheck.sh <포트> (the argument is a port). If something is listening on that port, print port=<포트> state=listen pid=<PID> and exit with code 0; if nobody is listening, print port=<포트> state=free and exit with code 1. With no arguments, it is a nonzero code.
If someone is listening, report the pid too and exit 0; if it is empty, print free and exit 1.