Home / Alt manpages / nc_openbsd(1)

  • nc_openbsd(1)
  • User command
  • linux

Test TCP Services Safely with OpenBSD nc on Linux

You will finish with a repeatable way to test a TCP service on loopback, send a small payload, inspect a plain HTTP response and check selected listening ports. The examples target the OpenBSD implementation installed here as netcat-openbsd 1.226-1ubuntu2. Its executable is usually called nc, and the aliases nc.openbsd and netcat refer to the same style of tool.

Allow about fifteen minutes. You need a shell and the netcat-openbsd package. The normal examples need no elevated privileges. Use sudo only when the service you are testing is itself restricted, or when you deliberately need a privileged source port. Do not scan systems or ports without permission.

1. Confirm the installed command

Check the binary, package version and local option set before copying an example. This prevents a common distraction: different netcat implementations use different flags.

$ command -v nc
/usr/bin/nc
$ dpkg-query -W -f='${Package} ${Version}\n' netcat-openbsd
netcat-openbsd 1.226-1ubuntu2
$ nc -h 2>&1 | sed -n '1,4p'
OpenBSD netcat (Debian patchlevel 1.226-1ubuntu2)
usage: nc [-46CDdFhklNnrStUuvZz] ...

This guide is for that installed command. In particular, this build has no -e or -c option for executing a shell or creating a TLS connection. Do not add flags from a guide written for another netcat.

Checkpoint

If command -v nc points somewhere unexpected, inspect it with readlink -f "$(command -v nc)" and stop until you know which implementation you are using.

2. Prove a local TCP path

Use two terminals. In the first, start a listener on loopback. Binding to 127.0.0.1 keeps the test off the network, and port 43123 is only an example. Choose another unused high port if necessary.

$ nc -l 127.0.0.1 43123

The process waits for one incoming TCP connection. In the second terminal, send one line and close the network side after standard input reaches EOF:

$ printf 'loopback-check\n' | nc -N 127.0.0.1 43123

The first terminal should print loopback-check. The -l flag listens; -N asks the client to shut down its network socket after EOF on input. Without that half-close, a service may wait for more data and the command can appear to hang.

When the listener exits, the test has changed no persistent configuration. If you started a listener with -k, press Ctrl-C when finished. The -w timeout does not limit a listener, so it is not a substitute for stopping one.

Checkpoint

A successful test has the exact payload in the listener terminal and both nc processes have exited.

3. Move a file only when both ends are controlled

Netcat sends raw bytes. It does not add authentication, encryption, integrity checking or a file name. Use this only between hosts and processes you control, on a network you trust. For sensitive data, use a protocol designed for transfer, such as SSH.

On the receiving host, choose a new output path and listen:

$ nc -l 127.0.0.1 43124 > received.bin

On the sending host, connect and provide the input file. The -N flag lets the receiver see EOF and finish:

$ nc -N RECEIVER_IP 43124 < ./original.bin

Verify the result before replacing anything important:

$ sha256sum ./original.bin received.bin
HASH  ./original.bin
HASH  received.bin

The two hashes must match. If the transfer is interrupted, remove the incomplete output before trying again, but do not overwrite a valuable file without checking its path first. The listener writes to the destination with the shell's redirection, so an existing file at that path is truncated as soon as the command starts.

4. Ask a plain HTTP service one precise question

For an HTTP service that accepts unencrypted TCP on a known port, pipe a complete request into nc. The blank line terminates the headers:

$ printf 'GET /health HTTP/1.0\r\nHost: SERVICE_HOST\r\n\r\n' | nc -w 5 SERVICE_HOST 80

Expect an HTTP status line followed by headers and, if the service sends one, a response body. Replace SERVICE_HOST and the path with values for a service you are authorised to test. Port 80 is not HTTPS; do not send credentials or private data to it.

For a line-oriented service that expects CRLF, the -C option translates input line feeds to CRLF. Do not combine it with input that already has the correct line endings unless you have checked the result, because duplicate carriage returns can make a protocol request invalid.

5. Scan a small, authorised range

Use zero-I/O mode when you only need to know whether TCP connections can be established. Add -v for a readable result, -n to avoid DNS and service-name lookups, and -w 1 to keep each attempt short:

$ nc -zvn -w 1 HOST_YOU_OWN 22 80 443
Connection to HOST_YOU_OWN 22 port [tcp/ssh] succeeded!
nc: connect to HOST_YOU_OWN port 80 (tcp) failed: Connection refused

Output varies with the host and firewall. A successful connection means that something accepted the TCP connection at that moment; it does not identify the application or prove that the service is healthy. A refusal, timeout and filtered result also have different causes.

You can scan a numeric range, such as 8000-8010, but keep it narrow and approved. The local manpage says ports in a range are checked in increasing order unless -r is used. UDP is different: the -uz combination reports success regardless of the target's state, so do not treat it as proof that a UDP service is listening.

6. Avoid the traps that waste time

  • Nothing connects: check the address family with -4 or -6, then check the destination and port. Use -v for diagnostics.
  • The command waits: a normal client has no timeout by default. Add -w 5 for a five-second connection or idle timeout. It has no effect on -l.
  • A name fails: try a numeric address and -n. That separates network failure from DNS or service-name resolution.
  • Local binding fails: the port may already be used, or -p may request a source port you cannot use. Let the kernel choose a source port unless the test genuinely needs a fixed one.
  • Unexpected data appears: remember that nc copies bytes between standard input, standard output and the socket. Redirect standard error separately when parsing output in a script.

Do not expose a diagnostic listener on all interfaces by omitting the address in a shared or untrusted environment. A listener is a network service. Stop it after the test and check with ss -ltn if you are unsure whether it remains.

Done means

  • You confirmed the OpenBSD netcat binary and package version.
  • You completed a loopback TCP exchange with -l and -N.
  • You understand that file transfer is raw and unauthenticated.
  • You can make a bounded HTTP request without confusing HTTP with HTTPS.
  • You scan only an approved target, using narrow ranges and a timeout.
  • You stopped temporary listeners and changed no persistent service configuration.