funwithlinux blog

How to Redirect Process Stdin and Stdout to Netcat for Embedded Linux CLI Network Access

Embedded Linux devices power countless systems, from IoT sensors to industrial controllers. Often, these devices have limited resources, making full-featured tools like SSH or Telnet unavailable. In such cases, accessing the command-line interface (CLI) over the network can be challenging—especially during development, debugging, or remote maintenance.

One lightweight solution is to redirect a process’s standard input (stdin) and standard output (stdout) to Netcat (nc), a versatile network utility. This setup creates a simple "network pipe" that lets you interact with a process (e.g., a shell or custom application) on the embedded device from a remote host.

In this guide, we’ll demystify stdin/stdout redirection, explain how Netcat facilitates network communication, and walk through step-by-step instructions to set up remote CLI access. We’ll also cover advanced configurations, security considerations, and troubleshooting tips.

2025-12

Table of Contents#

  1. Understanding Stdin, Stdout, and Netcat
    • What Are Stdin and Stdout?
    • File Descriptors: 0, 1, and 2
    • What Is Netcat?
  2. Prerequisites
    • Embedded Device Requirements
    • Host Machine Requirements
    • Network Setup
  3. Step-by-Step Guide to Redirecting Stdin/Out to Netcat
    • Step 1: Identify Netcat Capabilities on the Embedded Device
    • Step 2: Method 1 – Using Netcat with -e (Execute) (If Available)
    • Step 3: Method 2 – Without -e: Using Named Pipes (mkfifo)
    • Step 4: Test the Network CLI from the Host Machine
  4. Advanced Configurations
    • Running the Listener in the Background
    • Auto-Restarting with Systemd/Init Scripts
    • Restricting Access with Firewall Rules
  5. Security Considerations
    • Inherent Risks of Unencrypted Traffic
    • Alternatives for Production Environments
  6. Troubleshooting Common Issues
    • Port Already in Use
    • Connection Refused Errors
    • Shell Not Interactive
    • Network Reachability
  7. Conclusion
  8. References

Understanding Stdin, Stdout, and Netcat#

Before diving into the setup, let’s clarify the key components:

What Are Stdin and Stdout?#

Every process in Linux has three standard I/O streams:

  • stdin (Standard Input): Where the process reads input (default: keyboard).
  • stdout (Standard Output): Where the process writes normal output (default: terminal).
  • stderr (Standard Error): Where the process writes error messages (default: terminal).

By redirecting these streams, we can make a process read input from or write output to a network connection instead of the terminal.

File Descriptors: 0, 1, and 2#

Linux represents these streams as file descriptors (FDs):

  • 0: stdin
  • 1: stdout
  • 2: stderr

Redirection syntax like command > output.txt (redirect stdout to a file) or command 2>&1 (redirect stderr to stdout) manipulates these FDs.

What Is Netcat?#

Netcat (nc) is a "Swiss Army knife" for network communication. It creates TCP/UDP connections and transfers data between hosts. Key features include:

  • Listening for incoming connections (-l flag).
  • Specifying a port (-p flag).
  • Executing a command after connection (-e flag, though often disabled for security).

Netcat is lightweight and preinstalled on most Linux systems (including embedded devices with BusyBox, where it’s available as busybox nc).

Prerequisites#

Before starting, ensure the following:

Embedded Linux Device Requirements#

  • A Linux-based embedded device (e.g., Raspberry Pi, BeagleBone, or custom hardware).
  • Netcat installed (check with nc -h or busybox nc -h; install via opkg or apt if missing).
  • A shell (e.g., /bin/sh, /bin/bash, or BusyBox sh).

Host Machine Requirements#

  • A Linux/macOS/Windows host with Netcat installed (Linux: sudo apt install netcat-openbsd; macOS: brew install netcat; Windows: Use WSL or download Nmap’s Ncat).

Network Setup#

  • The embedded device and host must be on the same network (wired or Wi-Fi).
  • Know the embedded device’s IP address (find with ifconfig or ip addr on the device).

Step-by-Step Guide to Redirecting Stdin/Out to Netcat#

We’ll focus on redirecting a shell (e.g., /bin/sh) to Netcat, as this gives full CLI access. Adjust the process path (e.g., /usr/bin/myapp) if redirecting a custom application.

Step 1: Identify Netcat Capabilities on the Embedded Device#

First, check if your Netcat supports the -e (execute) flag, which directly runs a command after connection. Run:

nc -h | grep -e "-e"
  • If -e <command> appears in the help text, use Method 1 (simpler).
  • If not (common in secure builds like OpenBSD Netcat), use Method 2 (named pipes).

Step 2: Method 1 – Using Netcat with -e (Execute) (If Available)#

If -e is supported, run this on the embedded device to listen for connections on port 4444 and spawn a shell:

nc -l -p 4444 -e /bin/sh

Explanation:

  • -l: Listen for incoming connections.
  • -p 4444: Use port 4444 (choose any unused port, e.g., 1234).
  • -e /bin/sh: Execute /bin/sh (the shell) when a client connects.

Step 3: Method 2 – Without -e: Using Named Pipes (mkfifo)#

If -e is unavailable, use a named pipe (FIFO) to link the shell’s I/O to Netcat. A FIFO acts as a buffer for inter-process communication.

Step 3.1: Create a Named Pipe#

On the embedded device, create a FIFO in /tmp (temporary storage):

mkfifo /tmp/netcat_fifo

Run this command to redirect the shell’s stdin/stdout/stderr to Netcat:

cat /tmp/netcat_fifo | /bin/sh -i 2>&1 | nc -l -p 4444 > /tmp/netcat_fifo

Breakdown:

  • cat /tmp/netcat_fifo: Reads data from the FIFO and sends it to the shell’s stdin.
  • /bin/sh -i: Starts an interactive shell (-i flag ensures it accepts input).
  • 2>&1: Redirects stderr (2) to stdout (1), so errors appear in the output.
  • | nc -l -p 4444: Pipes the shell’s stdout/stderr to Netcat, which listens on port 4444.
  • > /tmp/netcat_fifo: Writes data received from the client (via Netcat) back to the FIFO, closing the loop.

Step 4: Test the Network CLI from the Host Machine#

On your host machine, connect to the embedded device using Netcat. Replace <device-ip> with the device’s IP (e.g., 192.168.1.100):

nc <device-ip> 4444

You should now see a shell prompt (e.g., # or $). Test it with commands like:

ls -l          # List files
uname -a       # Show system info
echo "Hello from embedded device!"  # Send a message

Example Session:

user@host:~$ nc 192.168.1.100 4444
# ls -l
total 12
-rwxr-xr-x 1 root root 8192 Jan  1 00:00 app
drwxr-xr-x 2 root root 4096 Jan  1 00:00 config
# uname -a
Linux embedded 5.10.100 #1 SMP PREEMPT Wed Jan 1 00:00:00 UTC 2023 armv7l GNU/Linux
# exit
user@host:~$

Advanced Configurations#

Running the Listener in the Background#

To keep the Netcat listener running after closing the terminal, use nohup (no hangup) and background the process:

For Method 1 (-e available):#

nohup nc -l -p 4444 -e /bin/sh &

For Method 2 (FIFO):#

nohup sh -c 'mkfifo /tmp/netcat_fifo; cat /tmp/netcat_fifo | /bin/sh -i 2>&1 | nc -l -p 4444 > /tmp/netcat_fifo' &

Use disown to detach the process from the terminal:

disown %1  # Replace "1" with the job ID from `jobs`

Auto-Restarting with Systemd/Init Scripts#

To auto-start the listener on boot, use a systemd service (for systemd-based devices) or an init script (for SysVinit).

Example Systemd Service (/etc/systemd/system/netcat-shell.service):#

[Unit]
Description=Netcat Shell Listener
After=network.target
 
[Service]
Type=simple
ExecStart=/bin/sh -c 'mkfifo /tmp/netcat_fifo; cat /tmp/netcat_fifo | /bin/sh -i 2>&1 | nc -l -p 4444 > /tmp/netcat_fifo'
Restart=always  # Restart if the process crashes
 
[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl enable netcat-shell
sudo systemctl start netcat-shell

Restricting Access with Firewall Rules#

Limit connections to specific IPs using iptables (embedded devices often support iptables via BusyBox):

# Allow only host 192.168.1.200 to connect to port 4444
iptables -A INPUT -p tcp --dport 4444 ! -s 192.168.1.200 -j DROP

Security Considerations#

Critical Warning: Netcat redirection is insecure for production use:

  • Plaintext Traffic: All data (including passwords) is sent unencrypted and can be intercepted with tools like Wireshark.
  • No Authentication: Anyone with network access can connect to the port and execute commands.

Alternatives for Production:

  • Use SSH (via dropbear or openssh-server—lightweight SSH servers for embedded systems).
  • Use mosh (Mobile Shell) for persistent connections.
  • For encrypted Netcat-like access, use ncat (from Nmap) with SSL:
    # On device: ncat --ssl -l -p 4444 -e /bin/sh
    # On host: ncat --ssl <device-ip> 4444

Troubleshooting Common Issues#

Port Already in Use#

Error: nc: Address already in use.
Fix: Check which process is using the port with netstat or ss:

netstat -tulpn | grep 4444  # or ss -lntu | grep 4444
kill <pid>  # Stop the conflicting process

Connection Refused#

Error: nc: connect to <device-ip> port 4444 (tcp) failed: Connection refused.
Fix:

  • Ensure Netcat is running on the device and listening on the port.
  • Verify the device’s IP and port with ip addr and netstat -lntu.
  • Check firewall rules blocking the port (iptables -L INPUT).

Shell Not Interactive#

Issue: The shell doesn’t accept input (e.g., no prompt).
Fix: Use the -i flag with the shell (/bin/sh -i) to force interactive mode.

Network Reachability#

Issue: Host cannot ping the device.
Fix: Verify network cables/Wi-Fi, subnet settings, and gateway configurations.

Conclusion#

Redirecting a process’s stdin/stdout to Netcat is a powerful technique for remote CLI access on resource-constrained embedded Linux devices. While simple to set up, it’s critical to use this only in trusted environments due to security limitations. For production, prioritize encrypted tools like SSH.

By mastering stdin/stdout redirection and Netcat, you’ll gain flexibility in debugging and maintaining embedded systems—even when traditional tools aren’t available.

References#