nc
Overview
nc (netcat) is a Swiss-army TCP/UDP tool: open connections, listen for inbound sockets, scan ports simply, and pipe data across the network. Ubuntu typically ships OpenBSD netcat as nc / netcat (openbsd-netcat package family; classic netcat-traditional may also be available). Flag details differ slightly between implementations — check nc -h on your host.
Syntax
nc [options] host port
nc -l [options] port
command | nc host port
nc host port < fileCommon Options (OpenBSD nc on Ubuntu)
| Option | Description |
|---|---|
-l |
Listen mode |
-p port |
Local port (with -l, often just nc -l port) |
-u |
UDP |
-v |
Verbose |
-z |
Scan mode: no data, just connect |
-w secs |
Connect/idle timeout |
-n |
Numeric only (no DNS) |
-k |
Keep listening after client disconnect (where supported) |
-s addr |
Source address |
-q secs |
Quit after EOF on stdin after delay |
-4 / -6 |
IPv4 / IPv6 only |
Safety
- Listening services with
nc -lbind whatever you tell them — do not expose on public interfaces unless intended; combine with firewall rules. - “Shell over netcat” patterns are classic attack/persistence techniques. Use only on systems you own, with authorization, for legitimate recovery labs.
-zport scans against machines you do not operate may violate policy.
Examples with Explanations
Test if a TCP port is open
nc -vz example.com 443
nc -vz -w 3 10.0.0.10 22Verbose zero-I/O connect is the operator’s quick “is something listening?” check.
HTTP GET by hand
printf 'GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n' \
| nc example.com 80Useful when debugging virtual hosts or seeing raw headers without curl.
TLS is not built into classic nc
# Prefer:
openssl s_client -connect example.com:443 -servername example.com
# or curl -v https://...Plain nc speaks TCP bytes; it does not negotiate TLS for you.
Simple file transfer (lab / trusted LAN)
Receiver:
nc -l 9000 > received.tgzSender:
nc -w 3 receiver.example.com 9000 < payload.tgzPrefer scp/rsync for anything real (auth, encryption, integrity).
UDP probe
nc -u -vz -w 2 10.0.0.10 53UDP “success” is weaker than TCP — lack of ICMP unreachable may still print as open/filtered depending on version.
Port range scan (light)
nc -vz 10.0.0.10 20-25For serious inventory use nmap; nc is fine for a handful of ports.
Pipe program output to a remote listener
# listener:
nc -l 7000 | tar xzf -
# sender:
tar czf - ./project | nc -w 3 host 7000Bind to a specific local address
nc -l -s 127.0.0.1 8080Localhost-only listeners reduce accidental exposure.
Chatty timeout for scripts
if nc -z -w 2 db.internal 5432; then
echo db-port-open
else
echo db-port-closed
fiUnderstanding Output
- Connect success (OpenBSD nc): often
Connection to host port [tcp/*] succeeded!with-v/-z. - Failure: connection refused (nothing listening / RST), timed out (filtered or blackholed), name resolution errors.
- In connected mode, stdin goes to the socket and socket data goes to stdout — making nc a network pipe.
Notes & Pitfalls
- Implementation flags differ. Scripts written for
netcat-traditional(-eexec) will not match OpenBSD nc. On Ubuntu,update-alternativesor package choice can change behavior — verify withnc -handreadlink -f $(command -v nc). - Exit codes for
-zare useful in bashif nc -z ...; thenbut confirm on your variant. - Listening without
-kusually exits after one client (OpenBSD). Plan for that in demos. - IPv6 addresses need careful syntax; prefer
-6and explicit addresses when debugging dual-stack. - For HTTP(S) health checks,
curl -fsS -o /dev/null -w '%{http_code}\n'is usually better than raw nc.
Additional Resources
man ncman ncat(Nmap’s netcat, if installed as separate tool)