Network - netcat (nc, ncat)
Table of Contents
About
netcat 1) is a command line tool that reads and writes data across network connections, using TCP or UDP protocol.
Example
Testing a port
An utility function to control that the service is up by controlling that we can make a tcp connection to the service port
Simple if statement
TOMCAT_PORT=6006
if [[ $(nc -z localhost ${TOMCAT_PORT}) -eq 0 ]]; then
echo "Tomcat is up"
else
echo "Tomcat is shutdown"
fi
While Statement
- while <note important>A port may be not open but still locked by a process. See the second statement</note>
while [[ $(nc -z localhost ${TOMCAT_PORT}) -eq 1 ]]; do
echo "Waiting for the tomcat port ${INFA_TOMCAT_PORT} to be closed before starting"
sleep 5 # wait 5 second before check again
done
###############################################################
# It seems that a port may returns 0 even if a process is still bound to a port
###############################################################
while [[ ! $(netstat -t|grep ${TOMCAT_PORT} | wc -l) -eq 0 ]];
do
echo "Waiting for the tomcat port ${INFA_TOMCAT_PORT} to be closed before starting"
sleep 5 # wait 5 second before check again
done
Wait function with timeout
# usage
# wait_for_service service_name port
wait_for_service() {
local SERVICE_NAME=$1
local PORT=$2
SERVICE_WAIT_TIMEOUT_SEC=20
echo "Waiting for $SERVICE_NAME to start..."
local CURRENT_WAIT_TIME=0
while [[ $(echo | nc -w1 localhost $PORT >/dev/null 2>&1 ;echo $?) -ne 0 ]]; do
printf '.'
sleep 1
if [ $((++CURRENT_WAIT_TIME)) -eq $SERVICE_WAIT_TIMEOUT_SEC ]; then
printf "\nError: timed out while waiting for $SERVICE_NAME to start.\n"
exit 1
fi
done
printf '\n'
echo "$SERVICE_NAME has started";
}
Wait for it
For a full functional example, see wait-for-it.sh
Send a HTTP request to a process
After having created a tcp connection, an application:
- send a standard input (on a io level) to the host via the connection (ie a request)
- receive the result as a standard output.
As netcat creates a tcp connection, you can for instance send HTTP get request. Example:
GET / HTTP/1.1
Host: gerardnico.com
we can send it as standard input with echo to a connection created with netcat
For SSL connection, you need to use another utility such as openssl because netcat does not support it. For HTTPS, you may use CURL
echo -e "GET / HTTP/1.1\nHost: gerardnico.com\n" | nc gerardnico.com 80
and you should get a redirection response telling you that you need to go to https://gerardnico.com/
HTTP/1.1 301 Moved Permanently
Date: Mon, 13 Apr 2020 12:26:26 GMT
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: max-age=3600
Expires: Mon, 13 Apr 2020 13:26:26 GMT
Location: https://gerardnico.com/
Server: cloudflare
CF-RAY: 58352ceb1ba9bf78-AMS
Send a directory between two computers
- On the source server, pipe the result of a tar (archive) to a connection created witn nc
tar -cz . | nc -l -p $PORT
# l for listen
# p to define the port
- On the remote server, read the connection and untar.
nc -w 10 $REMOTE_HOST $PORT | tar -xz
Syntax
After a connection is established, the standard input is sent to the host, and anything that comes back across the connection is sent to your standard output.
Client
Server
Netcat can also function as a server, by listening for inbound connections on arbitrary ports
- Linux
nc -l -p port
Why not telnet
- Telnet has the “standard input EOF” problem. ie it will shut everything down and exit after an end-of-file on the standard input.
- Telnet will not transfer arbitrary binary data, because certain characters are interpreted as telnet options
- Telnet also emits some of its diagnostic messages to standard output, where netcat keeps such things separated from its *output*
- Telnet is incapable of listening for inbound connections, or using UDP instead.
Installation
Windows
- install nmap on Windows
Linux
apt-get install -y netcat
# centos, Redhat
yum install nmap