Tutorial

FTP vs SFTP: Security Differences and How to Set Up Both

April 13, 2026

Back to Blog

Introduction: Why File Transfer Protocol Choice Matters

Every website, application, and server deployment involves moving files between machines. Whether you are uploading your latest WordPress theme, deploying application code, or backing up critical data, you need a reliable file transfer protocol. For decades, FTP (File Transfer Protocol) has been the default choice. But in today's security-conscious environment, SFTP (SSH File Transfer Protocol) has emerged as the superior alternative.

The difference between these two protocols is not just academic — it directly impacts whether your credentials travel across the internet in plain text or inside an encrypted tunnel. In this comprehensive guide, we will explore how each protocol works at a technical level, compare their security models, walk through complete setup guides for both ProFTPD and OpenSSH SFTP, and help you make the right choice for your infrastructure.

Critical Security Fact: Traditional FTP transmits usernames, passwords, and file contents in plain text. Anyone on the same network segment can capture these credentials with a simple packet sniffer. This is not a theoretical risk — it is an active attack vector used in real-world breaches every day.

Understanding FTP: The Legacy Protocol

How FTP Works Under the Hood

FTP was designed in 1971 (RFC 114) and formalized in RFC 959 in 1985 — long before encryption was a standard concern. It operates on a client-server model using two separate TCP connections:

Control Channel (Port 21)

Carries all commands and responses between client and server. Authentication (USER/PASS commands), directory listing requests, and transfer initiation happen here. This channel stays open throughout the entire session.

Data Channel (Port 20 or dynamic)

Carries the actual file data and directory listings. A new data connection is established for each file transfer or directory listing operation. This channel opens and closes repeatedly during a session.

Active Mode vs Passive Mode

FTP has two connection modes that determine how the data channel is established. Understanding this distinction is critical for firewall configuration and troubleshooting:

ModeHow It WorksFirewall ImpactCommon Usage
Active ModeClient sends PORT command with its IP and port number. Server connects FROM port 20 TO the client on that port.Requires client to accept incoming connections — blocked by most NAT routers and firewallsRare in modern setups
Passive ModeClient sends PASV command. Server responds with an IP and port. Client connects TO the server on that port.All connections are initiated by the client — works through NAT/firewalls naturallyStandard for all modern FTP clients
Firewall Consideration: Passive mode requires a range of ports (e.g., 49152-65534) to be open on the server firewall. Without this, passive mode connections will fail with timeout errors. This is the single most common FTP troubleshooting issue that administrators encounter.

The FTP Authentication Flow (Unencrypted)

Here is what happens when a client connects to an FTP server — pay close attention to what travels in plain text over the network:

Client connects
to port 21
Server: 220
Ready
USER admin
plain text
PASS secret123
plain text
230 Login
successful

Every command, including the password, travels as readable ASCII text. A network sniffer running tcpdump -A -i eth0 port 21 would capture the complete credentials in seconds. This fundamental design flaw is why FTP is considered insecure for any environment where network traffic might be intercepted — which is essentially every production environment.

FTP Command Reference

FTP uses a simple text-based command protocol. Here are the most common commands you will see in server logs and packet captures:

CommandPurposeExample
USERSend usernameUSER webadmin
PASSSend passwordPASS mypassword123
LISTList directory contentsLIST /public_html
RETRDownload a fileRETR index.html
STORUpload a fileSTOR style.css
DELEDelete a fileDELE old-backup.zip
MKDCreate directoryMKD uploads
PASVEnter passive modePASV
QUITClose connectionQUIT

Understanding SFTP: The Encrypted Alternative

How SFTP Works

SFTP is not FTP over SSH — it is a completely different binary protocol that runs as a subsystem of the SSH protocol. It was designed from the ground up as part of the SSH-2 protocol specification. SFTP uses a single encrypted connection on port 22 (the standard SSH port), which makes it dramatically simpler to firewall and manage compared to FTP's multi-port architecture.

Common Misconception: Many people confuse SFTP with FTPS (FTP over TLS). They are entirely different protocols. SFTP is part of the SSH ecosystem and uses port 22. FTPS is traditional FTP wrapped in TLS encryption and uses ports 990 plus a passive range. SFTP is simpler to deploy, more secure in practice, and easier to manage through firewalls.

The SFTP Authentication Flow (Fully Encrypted)

Client connects
to port 22
SSH handshake
encrypted
Key exchange
encrypted
Auth (pass/key)
encrypted
SFTP subsystem
encrypted

The entire session — from the initial handshake through authentication and all file transfers — is encrypted using modern algorithms like AES-256-GCM or ChaCha20-Poly1305. Even if an attacker captures every packet, they see only encrypted bytes with no practical way to recover the original content.

SFTP Authentication Methods

SFTP inherits all SSH authentication methods, giving you far more secure options than FTP can offer:

  • Password authentication — encrypted in transit (unlike plain FTP where passwords are visible on the wire)
  • SSH key pairs — public/private key authentication where no password is transmitted at all
  • Certificate-based authentication — SSH certificates signed by a trusted Certificate Authority for enterprise environments
  • Multi-factor authentication — combine keys with passwords or TOTP tokens for maximum security

Why Single-Port Matters

SFTP's single-port design is a significant operational advantage over FTP:

1
Port required for SFTP (port 22)
16K+
Ports required for FTP passive mode

With SFTP, you open port 22 in your firewall and you are done. With FTP in passive mode, you need port 21 plus a range of thousands of high ports (typically 49152-65534). This massive port range creates a larger attack surface and more complex firewall rules. In containerized and cloud environments where port management is automated, SFTP's simplicity becomes even more valuable.

Complete Security Comparison

Security FeatureFTPFTPSSFTP
Credential encryptionNoneTLSSSH
Data encryptionNoneTLSSSH
Key-based authNot supportedClient certificatesSSH keys (simple)
Ports required21 + passive range990 + passive range22 only
Firewall complexityComplexComplexSimple
Chroot / jail supportYesYesYes
Data integrityNoneTLS MACSSH HMAC
MITM protectionNoneIf cert verifiedHost key pinning
Compliance (PCI-DSS)FailsPassesPasses

Setting Up ProFTPD: Complete FTP Server Guide

If you need to support legacy FTP clients or applications that require FTP specifically, ProFTPD is one of the most configurable FTP servers available for Linux. Below is a complete setup guide from installation through production hardening.

1
Installation
$ sudo apt update && sudo apt install proftpd -y
Reading package lists... Done
Setting up proftpd-basic (1.3.8+dfsg-4) ...
2
Core Configuration

Edit /etc/proftpd/proftpd.conf with these essential settings:

# /etc/proftpd/proftpd.conf
ServerName "My FTP Server"
ServerType standalone
DefaultServer on
Port 21
UseReverseDNS off
IdentLookups off

# Passive mode port range
PassivePorts 49152 65534
MasqueradeAddress YOUR_SERVER_IP

# Security settings
DefaultRoot ~
RequireValidShell off
MaxInstances 30
MaxLoginAttempts 3
TimeoutIdle 600
TimeoutNoTransfer 300

# Logging
TransferLog /var/log/proftpd/xferlog
SystemLog /var/log/proftpd/proftpd.log
3
Virtual Users (No Linux Account Required)

For hosting environments, create virtual FTP users independent of system accounts:

# Generate password hash for virtual user
$ /usr/bin/ftpasswd --passwd --name=webuser1 --uid=1001 \
--gid=1001 --home=/var/www/site1 --shell=/usr/sbin/nologin \
--file=/etc/proftpd/ftpd.passwd

# Create virtual group
$ /usr/bin/ftpasswd --group --name=ftpusers --gid=1001 \
--member=webuser1 --file=/etc/proftpd/ftpd.group

Add authentication directives to proftpd.conf:

AuthUserFile /etc/proftpd/ftpd.passwd
AuthGroupFile /etc/proftpd/ftpd.group
AuthOrder mod_auth_file.c
4
Adding TLS Encryption (Upgrading to FTPS)

At minimum, enable TLS encryption to protect credentials in transit:

# Generate TLS certificate
$ sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout /etc/ssl/private/proftpd.key \
-out /etc/ssl/certs/proftpd.crt

TLS module configuration:

# /etc/proftpd/conf.d/tls.conf
<IfModule mod_tls.c>
TLSEngine on
TLSProtocol TLSv1.2 TLSv1.3
TLSCipherSuite HIGH:!aNULL:!MD5
TLSRSACertificateFile /etc/ssl/certs/proftpd.crt
TLSRSACertificateKeyFile /etc/ssl/private/proftpd.key
TLSRequired on
</IfModule>
5
Firewall Configuration
$ sudo ufw allow 21/tcp
$ sudo ufw allow 49152:65534/tcp
$ sudo ufw reload
Firewall reloaded

Setting Up OpenSSH SFTP with Chroot Jails

SFTP is built into OpenSSH, which is already installed on virtually every Linux server. Setting up isolated SFTP access with chroot jails is straightforward and provides far better security than any FTP configuration.

1
Create the SFTP Group and Users
# Create a dedicated group for SFTP-only users
$ sudo groupadd sftpusers

# Create a user with no shell access
$ sudo useradd -m -g sftpusers -s /usr/sbin/nologin sftpuser1
$ sudo passwd sftpuser1

# Critical: chroot directory MUST be owned by root
$ sudo chown root:root /home/sftpuser1
$ sudo chmod 755 /home/sftpuser1

# Create writable subdirectory for the user
$ sudo mkdir -p /home/sftpuser1/files
$ sudo chown sftpuser1:sftpusers /home/sftpuser1/files
Chroot Ownership Requirement: The chroot directory and every parent directory up to / must be owned by root and not writable by any other user or group. If this requirement is not met, SSH will refuse the connection with "fatal: bad ownership or modes for chroot directory." The user's writable area must be a subdirectory inside the chroot.
2
Configure sshd_config
# /etc/ssh/sshd_config — Add at the END of the file

Subsystem sftp internal-sftp

Match Group sftpusers
ChrootDirectory %h
ForceCommand internal-sftp
AllowTcpForwarding no
X11Forwarding no
PermitTunnel no
AllowAgentForwarding no

Key directives explained:

  • ChrootDirectory %h — locks the user into their home directory, preventing access to system files
  • ForceCommand internal-sftp — prevents shell access entirely; only SFTP operations are allowed
  • AllowTcpForwarding no — prevents SSH tunnel abuse through the SFTP account
  • internal-sftp — uses the built-in SFTP server (faster and more secure than external sftp-server binary)
3
Validate and Test
# Validate configuration syntax
$ sudo sshd -t
(no output means configuration is valid)

# Test the SFTP connection
$ sftp sftpuser1@localhost
Connected to localhost.
sftp> pwd
Remote working directory: /
sftp> ls
files
sftp> cd /etc
Couldn't canonicalise: No such file or directory

The last command confirms the chroot is working — the user cannot access directories outside their jail.

4
SSH Key Authentication (Highly Recommended)
# On the client: generate an Ed25519 key
$ ssh-keygen -t ed25519 -f ~/.ssh/sftp_key -C "sftp access"

# Copy public key to server
$ sudo mkdir -p /home/sftpuser1/.ssh
$ sudo cp ~/.ssh/sftp_key.pub /home/sftpuser1/.ssh/authorized_keys
$ sudo chown -R sftpuser1:sftpusers /home/sftpuser1/.ssh
$ sudo chmod 700 /home/sftpuser1/.ssh
$ sudo chmod 600 /home/sftpuser1/.ssh/authorized_keys

# Connect with key — no password needed
$ sftp -i ~/.ssh/sftp_key sftpuser1@server

File Permissions Reference

PathOwnerPermissionReason
/home/user (chroot root)root:root755SSH chroot requires root ownership
/home/user/filesuser:group755User's actual working directory
/home/user/.sshuser:group700SSH refuses if group/world readable
/home/user/.ssh/authorized_keysuser:group600SSH refuses if group/world readable
Uploaded filesuser:group644Web server can read, owner can write
Uploaded directoriesuser:group755Web server can traverse
Umask Tip: Set the default umask for SFTP uploads in sshd_config: ForceCommand internal-sftp -u 0022. This ensures new files automatically receive 644 permissions and directories receive 755 permissions.

Automation and Scripting

FTP Automation with lftp

#!/bin/bash — deploy-ftp.sh
lftp -u "$FTP_USER,$FTP_PASS" "$FTP_HOST" <<CMD
set ssl:verify-certificate false
mirror --reverse --delete --verbose \
./public_html/ /var/www/site/
bye
CMD

SFTP/SSH Automation with rsync (Recommended)

#!/bin/bash — deploy-sftp.sh (recommended)
rsync -avz --delete \
-e "ssh -i ~/.ssh/deploy_key" \
./public_html/ user@server:/home/user/files/public_html/

# Single file with scp
scp -i ~/.ssh/deploy_key ./config.php user@server:/home/user/files/

CI/CD Pipeline Integration

# .github/workflows/deploy.yml
- name: Deploy via SFTP
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SFTP_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
source: "dist/*"
target: "/home/user/files/public_html"

FTPS: The Middle Ground

Explicit FTPS (FTPES)

Client connects to port 21, then issues AUTH TLS to upgrade the connection. If the server does not support TLS, the client can optionally fall back to plain FTP. This is the preferred and more widely supported method.

Implicit FTPS

Client connects to port 990, and TLS is required from the very start. There is no negotiation or downgrade possibility. Less common but prevents downgrade attacks entirely.

Performance Comparison

MetricFTPFTPSSFTP
Connection setupFastTLS adds latencySSH adds latency
Bulk transferFastestNear FTP~5-15% slower
Many small filesNew conn per fileTLS + new connSingle channel
CPU overheadMinimalTLS encryptionSSH encryption
Resume supportYesYesYes

Making Your Decision

1
Use SFTP for all new deployments. Secure by default, single port, key-based auth, works through any firewall.
2
Use FTPS only when legacy applications demand FTP. Enable TLS and enforce it — never permit plain FTP fallback.
3
Avoid plain FTP entirely. No legitimate reason to use unencrypted FTP in production.
4
Use rsync over SSH for large-scale operations. Transfers only differences, supports compression, preserves permissions.

Troubleshooting Common Issues

SFTP: "bad ownership or modes"

Chroot directory must be owned by root with permissions 755. Verify with: namei -l /home/sftpuser1

FTP: Passive mode timeout

Passive port range not open in firewall, or MasqueradeAddress not set to the server public IP.

SFTP: "Permission denied (publickey)"

Check .ssh (700) and authorized_keys (600) permissions. Verify key format and ownership.

FTP: "530 Login incorrect"

Virtual user AuthUserFile path may be wrong. Check /var/log/proftpd/proftpd.log.

How Panelica Handles File Transfer

Built-In Dual Protocol Support: Panelica includes both ProFTPD for legacy FTP access and SSH-based SFTP with per-user chroot jails. When you create a user account, the system automatically configures both protocols with proper isolation — no manual SSH or FTP configuration needed.

Each Panelica user automatically receives:

  • Isolated SFTP access with chroot jails preventing visibility of other accounts
  • ProFTPD virtual user for legacy clients requiring FTP protocol compatibility
  • Automatic file permissions with correct ownership and modes during user creation
  • Per-user resource limits where FTP/SFTP connections count toward cgroup allocation
  • Zero manual SSH configuration — the panel manages Match blocks, chroot directories, and keys

Conclusion

The choice between FTP and SFTP in 2026 is unambiguous: SFTP should be your default for everything. It provides strong encryption, uses a single port, supports superior authentication methods, and is already available on every Linux server through OpenSSH. FTP remains available for legacy compatibility, but it should always be wrapped in TLS if it must be used at all. Your credentials, your files, and your users deserve the protection that encryption provides. Plain-text FTP belongs in the history books.

Share: