I’m going to start this one with the most important sentence in the whole article: you should not be using rlogin, rsh, or rcp on any system connected to a network you care about. I still cover them here because they show up in legacy environments, certification material, and old scripts that occasionally land on someone’s desk with instructions to “just get it working.” Understanding what these tools do — and exactly why they were replaced — is genuinely useful context, even if the practical advice at the end of nearly every section is “use SSH instead.”
What rlogin, rsh, and rcp Are
These three commands are part of the old BSD “r-commands” suite, designed in the early days of Unix networking for remote login and file transfer between trusted hosts:
- rlogin — remote login, similar in purpose to
telnetorssh, opens an interactive remote shell session. - rsh (remote shell) — executes a single command on a remote host without an interactive session.
- rcp (remote copy) — copies files between hosts, syntactically similar to the local
cpcommand.
All three share the same fundamental design flaw: authentication and trust are based on hostname/IP and username, not cryptography, and all data — including any passwords that are exchanged — travels in plaintext.
How the Trust Model Works (and Why It’s Dangerous)
The r-commands rely on two configuration files to decide who’s allowed in without a password prompt:
System-wide: /etc/hosts.equiv
trusted-host.example.com
+@trusted-netgroup
Per-user: ~/.rhosts
trusted-host.example.com someuser
192.168.1.50 anotheruser
If a connecting host/username pair matches an entry in either file, the daemon grants access without a password at all. This trust is based entirely on the claimed source IP and username in the connection request — both of which are trivially spoofable on any network where you don’t fully control routing, which is to say, nearly every real network.
This is the core reason these tools are considered obsolete: IP spoofing, DNS spoofing, and simple network sniffing (since even password-based sessions send credentials in plaintext) can each independently compromise the entire trust model.
rlogin Syntax and Usage
rlogin [-l username] [-8] [-E] [-K] hostname
Common parameters:
-l username— log in as a different remote username than your local one-8— allow 8-bit data (needed for non-ASCII characters)-E— disable escape character recognition-K— turn off Kerberos authentication (on Kerberized variants)
Example:
rlogin -l admin remotehost.example.com
If a matching .rhosts/hosts.equiv entry exists, this connects directly with no password prompt at all. If not, it typically falls back to prompting for a password — which then travels across the network in plaintext.
rsh Syntax and Usage
rsh [-l username] hostname command
Example — run a single command remotely without an interactive shell:
rsh -l admin remotehost.example.com "uptime"
Example — remote script execution in older automation setups:
rsh backup-server "tar czf /backup/daily.tar.gz /data"
Because rsh has no interactive prompt for input in the typical case, it was historically popular in cron jobs and batch scripts on trusted internal networks — which is exactly the pattern SSH with key-based auth has cleanly replaced.
rcp Syntax and Usage
rcp [-p] [-r] source destination
-p— preserve modification times and modes from the source file-r— recursively copy directories
Copy a local file to a remote host:
rcp localfile.txt remotehost:/tmp/localfile.txt
Copy a remote file to local:
rcp remotehost:/var/log/app.log ./app.log
Copy a directory recursively:
rcp -r localdir/ remotehost:/tmp/localdir/
Copy between two remote hosts (executed from a third machine, both remotes must trust each other):
rcp host1:/data/file.txt host2:/data/file.txt
Installing the r-commands (If You Genuinely Need Them for Legacy Compatibility)
Debian/Ubuntu:
sudo apt install rsh-client rsh-redone-server
RHEL/CentOS/Fedora:
sudo dnf install rsh rsh-server
The server-side daemon (rlogind/rshd) is typically managed via xinetd or a standalone init script on older systems, since these predate systemd socket activation entirely.
Why These Were Replaced: The Case for SSH
SSH (Secure Shell) was designed specifically to solve every structural problem in the r-commands:
| Concern | r-commands | SSH |
|---|---|---|
| Data encryption | None — plaintext | Full session encryption |
| Authentication | IP/hostname trust or plaintext password | Public-key cryptography, optionally combined with passwords/MFA |
| Host verification | None | Host key fingerprinting detects MITM/spoofing attempts |
| Port/service | Uses privileged ports (513, 514) with source-port trust checks | Standard port 22, no reliance on source port trust |
| File transfer | rcp (plaintext) | scp/sftp (encrypted) |
The direct replacements, command for command:
rlogin host -> ssh host
rsh host command -> ssh host command
rcp file host:path -> scp file host:path
Functionally almost a drop-in replacement in terms of syntax, with the entire trust and encryption model rebuilt from the ground up.
Example: Migrating an Old rsh-Based Script to SSH
Old:
#!/bin/bash
rsh backupserver "tar czf /backup/daily-$(date +%F).tar.gz /data"
rcp backupserver:/backup/daily-$(date +%F).tar.gz /local/backups/
Migrated:
#!/bin/bash
ssh backupserver "tar czf /backup/daily-$(date +%F).tar.gz /data"
scp backupserver:/backup/daily-$(date +%F).tar.gz /local/backups/
Combined with SSH key-based authentication (so the script still runs unattended, without a password prompt, but without the IP-spoofing risk of .rhosts trust), this is a strict security upgrade with essentially the same operational behavior.
Setting Up Passwordless SSH as the Direct Replacement for .rhosts Trust
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@remotehost
Test:
ssh user@remotehost "uptime"
This gives you the same “no password prompt for automation” convenience the r-commands offered, but backed by asymmetric cryptography rather than a spoofable IP address check.
Security Implications and Why This Matters Beyond Nostalgia
If you find rsh, rlogin, or rcp (or their daemons rshd, rlogind) installed and enabled on a system you’re responsible for, that’s a finding worth acting on immediately, not a curiosity. The specific risks:
- Credential and data interception — any plaintext traffic on a shared network segment (including many switched networks with ARP spoofing) can be captured by anyone with a packet sniffer.
- Host spoofing — an attacker who can spoof a trusted IP address (or compromise a machine already in a
.rhosts/hosts.equivtrust relationship) inherits access with zero authentication. - Lateral movement — trust relationships between servers via
.rhostsare a classic pivot point; compromising one trusted host in a chain compromises everything downstream that trusts it. - Compliance — virtually every modern security standard (PCI-DSS, CIS Benchmarks, DISA STIGs) explicitly flags the r-commands as prohibited services.
How the Original Trust Model Was Actually Enforced
It’s worth understanding the specific mechanism the r-commands relied on, because it explains exactly why the trust model is so fundamentally broken on any network you don’t fully control at the routing level.
The r-command daemons (rlogind, rshd) checked two things about an incoming connection: the source IP address of the TCP connection, and that the connection originated from a privileged port (below 1024, historically only assignable by a root process on the sending machine). The theory was that only a trusted system administrator could bind a privileged source port, so a connection from a privileged port claiming to be a specific trusted host was assumed genuine.
This assumption fails in multiple independent ways on modern networks:
- IP spoofing — crafting packets with a forged source address defeats the IP-based check outright, particularly on networks without ingress filtering (BCP38) at the router level.
- Privileged port isn’t a meaningful barrier — any machine where an attacker has root (even temporarily, even on an unrelated compromised box) can bind low ports freely.
- DNS spoofing — if trust is configured by hostname rather than raw IP, poisoning DNS resolution can redirect trust to an attacker-controlled address.
- On-path attackers — anyone who can observe or inject packets on the network path (a compromised switch, a rogue Wi-Fi access point, a compromised router) can intercept plaintext credentials or hijack an already-authenticated session outright, since there’s no session encryption to prevent it.
None of these are exotic, advanced attacks — IP spoofing and ARP-based on-path attacks in particular have been well-understood, tooled, and automated for decades, which is precisely why any protocol relying purely on source-address trust has been considered unsuitable for real-world networks since at least the 1990s.
A Closer Look at .rhosts and hosts.equiv Syntax
Since these files are the actual attack surface if r-commands are ever found on a system you’re auditing, it’s worth knowing their full syntax rather than just the basic examples.
/etc/hosts.equiv (system-wide, applies to any user unless a .rhosts file overrides it):
trusted-host.example.com
+trusted-host2.example.com otheruser
-untrusted-host.example.com
+@some-netgroup
- A bare hostname trusts that host for any locally matching username.
+hostname usernametrusts that host only for connections claiming that specific remote username.- A leading
-explicitly denies, useful for carving out an exception within a broader trusted range. +@netgroupreferences an NIS netgroup — a now-rare but historically common way of trusting an entire group of machines at once.- A bare
+on its own line (not shown above, but worth flagging explicitly) means “trust literally any host” — this configuration has appeared in real historical security incidents and should be treated as a critical finding if ever discovered.
~/.rhosts (per-user, same syntax, layered on top of the system-wide file):
192.168.1.50 alice
+trusted-workstation.example.com
The critical detail auditors look for: a .rhosts file is honored regardless of the system-wide hosts.equiv policy, meaning an individual user can grant passwordless access to their own account even on a system where the administrator never intended hosts.equiv to allow it at all. This is exactly why historical security guidance for these tools, where they had to remain in use at all, insisted on actively searching for and removing stray .rhosts files across every user’s home directory as routine practice.
Kerberized r-commands: The Historical Middle Ground
Before SSH became the universal replacement, some environments used Kerberized versions of these tools (krlogin, krsh, krcp) as a partial fix — replacing the IP-based trust model with genuine Kerberos ticket-based authentication, while still using the same unencrypted data channel for the actual session content.
krlogin -x remotehost # -x requests encryption of the session, where supported
This closed the authentication gap but didn’t fully solve the confidentiality problem unless encryption was explicitly requested and supported by both ends — and even then, it required an existing, properly maintained Kerberos realm, which was a significant infrastructure investment relative to SSH’s comparatively simple key-based model. Kerberized r-commands still show up in some legacy enterprise Unix environments with existing Kerberos infrastructure (often alongside NFS), but they never saw anywhere near SSH’s adoption.
Historical Context: Why This Matters Beyond the Tools Themselves
The story of the r-commands is genuinely useful context for understanding modern protocol design, because SSH’s design is almost a direct point-by-point response to their specific failures:
| r-command weakness | SSH’s specific answer |
|---|---|
| Trust based on spoofable IP/hostname | Trust based on cryptographic key possession |
| No way to detect a spoofed/impersonated server | Host key fingerprinting, checked and cached on first connection |
| Entire session sent in plaintext | Full session encryption negotiated via key exchange |
| No mechanism to require strong per-user secrets | Public-key auth, allowing arbitrarily strong keys with no shared-secret transmission at all |
| Privileged source port as a weak proxy for trust | No reliance on source port trust whatsoever |
Every time I explain SSH’s host-key-checking prompt to someone new to it — “the authenticity of host X can’t be established, are you sure you want to continue?” — I find it lands better when they understand it’s specifically closing a hole that real, deployed protocols (these exact ones) left wide open for years.
Auditing a System for r-command Exposure
# Check if the daemons are installed
rpm -q rsh-server 2>/dev/null # RHEL
dpkg -l | grep rsh # Debian
# Check if anything is listening on the classic r-command ports
sudo ss -tulnp | grep -E ':513|:514|:512'
# Look for trust files that grant passwordless access
find / -name ".rhosts" 2>/dev/null
cat /etc/hosts.equiv 2>/dev/null
If you find any of this active, the remediation is straightforward: disable and remove the services, delete the trust files, and migrate whatever scripts depended on them to SSH.
sudo systemctl disable --now rsh 2>/dev/null
sudo apt remove --purge rsh-server rsh-client 2>/dev/null # Debian
sudo dnf remove rsh-server rsh 2>/dev/null # RHEL
Summary
rlogin, rsh, and rcp represent an era of Unix networking that assumed trusted, physically controlled LANs — an assumption that hasn’t held for decades. They’re worth understanding for what they reveal about the evolution of remote access security (particularly how much of modern SSH design is a direct response to their specific weaknesses), but they have no legitimate place on a production system today. If you inherit a system using them, the fix is the same in every case: migrate to SSH, scp, or sftp, and remove the r-command daemons and trust files entirely.
