I think, general principles of network troubleshooting are:
- Find out at what level of the TCP/IP stack (or some other stack) the problem occurs.
- Understand what the correct system behavior is and what the deviation from the normal system state is.
- Try to express the problem in one sentence or in several words.
- Using obtained information from the buggy system, your own experience, and experience of other people (Google, various forums, etc.), try to solve the problem until success (or failure).
- If you fail, ask other people about help or some advice.
As for me, I usually obtain all required information using all needed tools, and try to match this information to my experience. Deciding what level of the network stack contains the bug helps to cut off unlikely variants. Using experience of other people helps to solve the problems quickly, but often it leads to a situation, where I can solve some problem without its understanding and if this problem occurs again, it's impossible for me to tackle it again without the Internet.
And in general, I don't know how I solve network problems. It seems that there is some magic function in my brain named SolveNetworkProblem(information_about_system_state, my_experience, people_experience)
, which could sometimes return exactly the right answer, and also could sometimes fail (like here TCP dies on a Linux laptop).
I usually use utils from this set for network debugging:
ifconfig
(or ip link
, ip addr
) - for obtaining information about network interfaces
ping
- for validating if the target host is accessible from my machine. ping
could also be used for basic DNS diagnostics - we could ping a host by its IP address or by its hostname and then decide if DNS works at all. And then traceroute
or tracepath
or mtr
to look what's going on on the way there.
dig
- diagnose everything DNS
dmesg | less
or dmesg | tail
or dmesg | grep -i error
- for understanding what the Linux kernel thinks about some trouble.
netstat -antp
+ | grep smth
- my most popular usage of the netstat command, which shows information about TCP connections. Often I perform some filtering using grep. See also the new ss
command (from iproute2
the new standard suite of Linux networking tools) and lsof
as in lsof -ai tcp -c some-cmd
.
telnet <host> <port>
- is very useful for communicating with various TCP services (e.g. on SMTP, HTTP protocols), also we could check general opportunity to connect to some TCP port.
iptables-save
(on Linux) - to dump the full iptables tables
ethtool
- get all the network interface card parameters (status of the link, speed, offload parameters...)
socat
- the Swiss army tool to test all network protocols (UDP, multicast, SCTP...). Especially useful (more so than telnet) with a few -d
options.
iperf
- to test bandwidth availability
openssl
(s_client
, ocsp
, x509
...) to debug all SSL/TLS/PKI issues.
wireshark
- the powerful tool for capturing and analyzing network traffic, which allows you to analyze and catch many network bugs.
iftop
- show big users on the network/router.
iptstate
(on Linux) - current view of the firewall's connection tracking.
arp
(or the new ip neigh
in Linux) - show the ARP table status.
route
or the newer (on Linux) ip route
- show the routing table status.
strace
(or truss
, dtrace
or tusc
depending on the system) - is a useful tool that shows which system calls the problematic process performs. It also shows error codes (errno) when system calls fail. This information often says enough for understanding the system behavior and solving a problem. Alternatively, using breakpoints on some networking functions in gdb
can let you find out when they are made and with which arguments.
- to investigate firewall issues on Linux:
iptables -nvL
shows how many packets are matched by each rule (iptables -Z
to zero the counters). The LOG
target inserted in the firewall chains is useful to see which packets reach them and how they have already been transformed when they get there. To get further, NFLOG
(associated with ulogd
) will log the full packet.