November 14, 2005

CLI Magic: netcat

Author: Joe 'Zonker' Brockmeier

The response to my recent sysadmin toolbox article has been overwhelming. By far, readers' number one suggestion was to replace Telnet with netcat. Here then is an introduction to netcat for Linux users who may not be familiar with the "TCP/IP Swiss Army knife."

In the simplest terms, netcat is a utility that reads and writes data across the network. As you probably know already, you can write to a file or read from a file on your local machine using the cat utility. By running cat filename > filename2, you can write the contents of a file to another file. By using cat > filename, you can write directly to a file from standard input.

The netcat utility works on the same principle as the cat utility, but over the network. This can be very useful in a number of situations, such as testing remote services, or for use in scripts, or just to copy files over the network. According to one source, you can even clone a hard drive over the network using netcat and dd.

Most *nix-type operating systems should already have a package for netcat. The most popular version of netcat is available from the SecurityFocus Web site. This is the version that ships with most Linux distros, and the most recent release seems to have been in 1996, so it should be current even if you're running an older version of Linux. There is also a version called GNU Netcat in the works, though I believe it lacks some of the functionality of the original. There are even versions of netcat available for Windows.

The syntax for netcat is pretty simple: netcat hostnameport will connect you to a server on the port specified, and allow you to send input to whatever service answers on that port. For example, if you use netcat mailserver.mydomain.com 25, you'll connect to the SMTP daemon running on mailserver.mydomain.com -- assuming one is running, of course.

You can then send input to that host, and you'll see any response from the host. This is perfect for testing services like SMTP, IMAP, POP3, and HTTP interactively. You can do this with Telnet, but (as many readers pointed out) there can be problems with using Telnet. Telnet can interfere with some tests by sending additional data, the Telnet client can't be set up to listen for incoming connections, and Telnet doesn't easily lend itself to use in a script. Telnet is also limited in that it has support only for TCP and not UDP.

Using netcat

The netcat utility can also be used to transmit a file over the network, much as cat can be used to write the contents of a file to another file locally. Note that there are other methods that are usually more efficient, but there are occasions when netcat might come in handy.

To transmit a file, you use netcat on the host that's receiving the file and the host that's sending the file. On the receiving host, run netcat -l -p 1234 > filename. The -l option tells netcat to listen, and the -p option tells netcat the port number to listen on. You can replace the port number (1234) with any port number you'd like, though you need to run as root to bind to ports below 1024.

To send the file, run cat filename | netcat hostname1234 -q 10. This sends the file to netcat, which then sends the data to the host you specify, on port 1234. The -q option tells netcat to quit 10 seconds after the end of the file (EOF).

You can also use netcat to copy the output of a command to a remote server. For instance, if you want to do a quick and dirty backup to another host, you can pipe the output of the tar command on your local server to a remote server. On the remote machine, run netcat -l -p 1234 > filename.tgz. This will tell netcat to listen on port 1234, and to output the data it receives to a file called filename.tgz.

On the local server, run tar -zcf - file | netcat -w 10 hostname1234. This will run the tar command against the file specified on the command line. This will work with a directory as well; just replace file with the name of the directory. The "-" after the tar options tells tar to send its output to standard out, rather than to a file. The pipe symbol redirects the output from tar to netcat, which copies it to the host specified on the command line. The -w option tells netcat to wait for 10 seconds after it has copied the data, and then close the connection.

If you want to glean a little more information about what's going on with netcat, the -v option makes netcat more verbose. If you use -v with netcat in listening mode, it will tell you when a connection is made, and from where, like this:

$ netcat -l -p 3333 -v > filename.tgz
listening on [any] 3333 ...
connect to [10.0.0.26] from dhoffryn [10.0.0.15] 57450

If that's not enough information for you, turn on extra verbosity with -vv:

$ netcat -l -p 3333 -vv > filename.tgz
listening on [any] 3333 ...
connect to [10.0.0.26] from dhoffryn [10.0.0.15] 57451
sent 0, rcvd 133120

This has the added bonus of showing how much data was sent and received. This works either way, so you can turn on verbosity when using netcat to send data or act as a client for remote services, and netcat will show the host and port it's connecting to, and how much data has been sent or received.

Another option that may come in handy is the -c option, which tells netcat to execute a command with /bin/sh after it connects -- sending the output to the other side of the connection. This can be used on either side of the connection. To send data from a command to a remote host, you could use netcat -c '/bin/command' hostnameport. When netcat connects to the service on the remote host, it will attempt to send the output of /bin/command. If you use netcat -l -p 1234 -c '/bin/command', it will send the output of /bin/command to the first client that connects to port 1234, and then close the connection.

Learning more about netcat

I've only scratched the surface of netcat's capabilities. Be sure to read the netcat man page for additional information, and netcat's README file as well, which is located under /usr/share/doc/netcat/README.gz on Ubuntu and Debian, and /usr/share/doc/packages/netcat/README on SUSE 9.3.

The regular distribution of netcat also includes a set of sample scripts that use netcat for probing remote hosts, copying files over the network, or grabbing Web pages. These are somewhat useful in their own right, but also provide excellent examples of what netcat can do. Netcat is very powerful utility, and well worth trying out.

Click Here!