SFTP uses port 22, the same port as SSH, because SFTP is not a separate protocol with its own daemon — it is a subsystem that runs inside an SSH connection. If SSH works on a host, SFTP already works, with no extra port, no extra service, and no extra firewall rule. Port 21 is FTP, and FTPS is FTP with TLS bolted on; neither is related to SFTP despite the names.
The naming is genuinely bad and causes real configuration mistakes, so the useful thing is to be precise about which of the three protocols people mean.
Table of contents
- Three protocols with confusingly similar names
- Why one port matters more than it sounds
- Connecting on a non-standard port
- Restricting a user to SFTP only
- Should you move SSH off port 22?
- When file transfer is how you deploy
- How this fits the rest of the stack
- FAQ
Three protocols with confusingly similar names
- SFTP — SSH File Transfer Protocol. Runs inside SSH on port 22. One connection, encrypted, authenticated by SSH keys or password.
- FTP — the original, from 1971. Port 21 for commands plus a separate data connection. Entirely unencrypted.
- FTPS — FTP with TLS. Port 21 with explicit TLS, or 990 with implicit. Still uses separate data connections.
SFTP and FTPS are unrelated protocols that solve the same problem. SFTP won in practice because it needs one port, works through NAT without special handling, and reuses SSH’s authentication rather than requiring separate certificates.
The concrete consequence: opening port 21 to “enable SFTP” does nothing at all. And a client configured for FTPS will not talk to an SFTP server no matter which port you point it at.
Why one port matters more than it sounds
FTP’s design uses one connection for commands and separate connections for each transfer. In active mode the server connects back to the client, which almost never survives NAT. Passive mode helps but requires a configured range of open ports on the server.
SFTP has none of that. Commands, directory listings, and file data all travel over the single SSH connection. One inbound port, no data channel negotiation, no passive port range, no NAT workarounds.
That is why firewall rules for SFTP are trivial and firewall rules for FTP are a recurring support ticket.
Connecting on a non-standard port
If SSH has been moved, SFTP moves with it — same port, because same daemon.
# Interactive SFTP on a custom port -- capital P
sftp -P 2222 deploy@203.0.113.10
# scp uses capital -P too
scp -P 2222 file.txt deploy@203.0.113.10:/tmp/
# ssh uses lowercase -p. Yes, really.
ssh -p 2222 deploy@203.0.113.10
sftp and scp take -P; ssh takes -p. There is no good reason for this and it catches everyone at least once.
Define the host once and stop caring:
Host prod
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/deploy_key
Then sftp prod, ssh prod, and scp prod:/path . all work, and every GUI client that reads ~/.ssh/config picks it up too.
Restricting a user to SFTP only
The common real requirement: give someone file access without giving them a shell. OpenSSH does this with an internal SFTP subsystem and a chroot.
# /etc/ssh/sshd_config
Subsystem sftp internal-sftp
Match Group sftponly
ChrootDirectory /srv/sftp/%u
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
PermitTunnel no
internal-sftp runs in the SSH daemon rather than as a separate binary, which is what makes the chroot work without copying libraries into it.
The requirement that trips everyone up: the chroot directory must be owned by root and not writable by the user. Give the user a writable subdirectory instead.
sudo mkdir -p /srv/sftp/alice/upload
sudo chown root:root /srv/sftp/alice
sudo chmod 755 /srv/sftp/alice
sudo chown alice:alice /srv/sftp/alice/upload
sudo sshd -t # validate config before restarting
sudo systemctl restart sshd
Always run sshd -t before restarting. A syntax error in sshd_config plus a restart is how people lock themselves out of a remote machine, and it is entirely avoidable.
Should you move SSH off port 22?
Moving to a high port removes essentially all of the automated background scanning from your logs. It is not a security control — anyone targeting you runs a port scan — but log noise reduction has real value when you are trying to spot a genuine anomaly.
The changes that actually matter are different:
PasswordAuthentication no— key-based authentication only. This is the one that matters most.PermitRootLogin no— no direct root login.AllowUsersorAllowGroups— an explicit list of who may connect.fail2ban— ban addresses after repeated failures.- Firewall the port to known source addresses where that is practical.
Disabling password authentication is worth more than every other item combined. A credential that cannot be guessed cannot be brute-forced, and the entire category of scanning traffic becomes irrelevant rather than merely quieter.
When file transfer is how you deploy
A great deal of SFTP usage is deployment: build locally, upload the output, hope the timing works out. It is a reasonable place to start and it has three specific weaknesses.
It is not atomic — during the upload the server holds a mix of old and new files. It is not reproducible — the artefact came from someone’s laptop with whatever was installed on it. And it has no rollback — the previous version was overwritten in place.
Building from the repository fixes all three at once: the build is repeatable because it runs from a known commit in a clean environment, the switch to the new version is atomic, and the previous deploy is still there to roll back to. That is the model on RunxBuild, and for WordPress specifically there is a file manager and a database browser in the dashboard, so the routine “SFTP in to edit one file” errand does not need an SSH client at all.
How this fits the rest of the stack
SFTP is port 22 because it is an SSH subsystem, not a separate service. Port 21 is FTP and FTPS, which are different protocols despite the similar names. Use -P for the port with sftp and scp and -p with ssh, or define the host in ~/.ssh/config and forget the difference. Lock accounts down with internal-sftp and a root-owned chroot, and disable password authentication.
If the SFTP session is really a deployment, that is the thing worth replacing. Building from a repository gives you an atomic switch and a rollback that uploading cannot. If you are pricing that up, the RunxBuild hosting calculator shows service, database, storage, and bandwidth separately.
Useful related references:
- SFTP Commands: The Working Set You Actually Need
- The Hypertext Transfer Protocol Port: Why 80 and 443, and What Changed
- Health Check Response Protocol for APIs That Stay Up
- Services on RunxBuild
FAQ
What port does SFTP use?
Port 22, the same as SSH. SFTP is a subsystem running inside an SSH connection rather than a standalone service, so if SSH is reachable then SFTP is too, with no additional port or daemon to configure.
Is SFTP the same as FTPS?
No. SFTP is SSH File Transfer Protocol, running over SSH on port 22. FTPS is the old FTP protocol with TLS added, using port 21 or 990 and separate data connections. They are unrelated protocols, and a client built for one cannot talk to a server running the other.
Why does SFTP not use port 21?
Port 21 belongs to FTP, a different and much older protocol. SFTP inherits port 22 from SSH because it runs inside an SSH session. Opening port 21 on a server to enable SFTP achieves nothing, since no SFTP service listens there.
How do I connect to SFTP on a custom port?
Use sftp -P 2222 user@host, with a capital P. scp also uses capital -P, while ssh uses lowercase -p. Adding a Host block with a Port line to ~/.ssh/config avoids the inconsistency entirely and is picked up by most GUI clients as well.
How do I give someone SFTP access without shell access?
Use ForceCommand internal-sftp with ChrootDirectory in a Match Group block in sshd_config. The chroot directory must be owned by root and not writable by the user, so create a writable subdirectory beneath it. Validate with sshd -t before restarting the daemon.