TT Lab
Get started
Learn Learning paths Courses

Linux Network Diagnosis

Diagnosing Sockets and Ports

Continue in TT Lab

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.

  1. Start python3 -m http.server 8080 --bind 127.0.0.1 in the background and write its PID to /root/net/http_pid.txt.
  2. 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.
  3. 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)
  4. Start a process that opens one connection to 8081 and keeps it without closing, and write its PID to /root/net/client_pid.txt.
  5. Convert decimal 8080 to 4 uppercase hexadecimal digits and write it to /root/net/hexport.txt.
  6. Write the maximum backlog of the 8080 listening socket to /root/net/backlog.txt, as a number only.
  7. Check with ss the PID of the process holding 8080 and write it to /root/net/owner.txt.
  8. 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.

Notes

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.

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.