Networking Interview Prep
Application Protocols

FTP & SFTP

File Transfer Protocols

LinkedIn Hook

FTP is like shouting your password across a crowded room while handing someone a file.

SFTP is passing a sealed envelope through a secure lockbox — nobody else sees what's inside.

Most developers know to "use SFTP, not FTP" — but very few can explain why, or the difference between SFTP and FTPS (hint: they are completely different protocols that share almost nothing except three letters).

Here is what every software engineer should know about file transfer:

  • FTP runs on two ports: 21 (commands) and 20 (data) — both completely unencrypted
  • FTPS is FTP + TLS/SSL layered on top — still FTP under the hood
  • SFTP is not FTP at all — it is a completely separate protocol built on top of SSH (port 22)
  • SCP is also SSH-based — simpler than SFTP, designed for one-shot copies
  • FTP Active vs Passive mode determines who opens the data connection — and it matters a lot for firewalls

If you have ever deployed to a server, set up CI/CD file uploads, or wondered why your FTP client keeps breaking behind a corporate NAT — this lesson is for you.

Read the full lesson → [link]

#Networking #SFTP #FTP #BackendEngineering #SystemDesign #InterviewPrep #Security


FTP & SFTP thumbnail


What You'll Learn

  • Why FTP is fundamentally insecure and how it exposes credentials on the wire
  • FTP's two-port architecture: port 21 (control channel) and port 20 (data channel)
  • The difference between FTP Active mode and Passive mode — and why passive mode is the modern default
  • What FTPS is and how it differs from SFTP (spoiler: they are completely different protocols)
  • What SFTP actually is — an SSH subsystem, not a variant of FTP
  • What SCP is, when to use it, and why it is being phased out in favor of SFTP
  • Real command-line examples for SFTP and SCP
  • A Node.js SFTP example using ssh2-sftp-client
  • Which protocol to use in which scenario

The Analogy That Makes This Click

Imagine you need to send a file to a colleague in another building.

FTP is like standing in the middle of a crowded open-plan office and shouting across the room: "Hey Bob! My username is admin, my password is hunter2, and here is the content of the file!" Anyone in that office — and anyone with a packet sniffer on your network — hears everything. The file, the credentials, every command you type. All plain text.

SFTP is like placing that file in a sealed, tamper-evident envelope, handing it to a trusted courier who works inside a locked tunnel between your building and Bob's. Even if someone intercepts the courier, they cannot read the envelope, cannot change its contents without you knowing, and cannot impersonate you.

The key insight: the "S" in SFTP does not stand for "Secure FTP." It is a completely different protocol. SFTP is the SSH File Transfer Protocol — it runs over SSH the same way a terminal session does. FTP and SFTP share a similar purpose (moving files) but share no code, no ports, and no underlying architecture.


FTP — The Plain Text Protocol

How FTP Works

FTP was designed in 1971, standardized in RFC 959 in 1985. It predates widespread internet security by decades. It was designed for trusted academic networks where interception was not a realistic threat.

FTP uses two separate TCP connections:

ChannelPortPurpose
Control channel21Commands and responses (LOGIN, LIST, RETR, STOR, QUIT)
Data channel20 (Active) or dynamic (Passive)Actual file content transfer

Every command you type — including your username and password — travels over the control channel in plain ASCII text. Anyone running tcpdump or Wireshark on the same network segment can capture your credentials with zero effort.

# What an FTP session looks like on the wire — completely visible to any network observer
220 Welcome to FTP server
USER admin
331 Password required for admin
PASS hunter2
230 User admin logged in
RETR secret-config.txt
150 Opening data connection
226 Transfer complete
QUIT
221 Goodbye

No encryption. No obfuscation. The bytes you see are the bytes that travel across the network.

FTP Active vs Passive Mode

This is one of the most commonly misunderstood aspects of FTP, and it trips up firewalls constantly.

Active Mode

In Active mode, the server initiates the data connection back to the client.

  1. Client connects to server port 21 (control channel)
  2. Client sends a PORT command telling the server: "Connect to me at IP x.x.x.x, port Y for the data transfer"
  3. Server opens a connection FROM its port 20 TO the client's specified port Y

Problem: This requires the client's firewall to accept inbound connections from the server. In home networks, corporate networks, and anywhere behind NAT (Network Address Translation), this almost always fails. The server tries to connect to what it thinks is the client's IP — but that IP is the NAT gateway's external address, and the router has no idea which internal machine to forward it to.

Active Mode:
Client → Server:21      (control, client initiates)
Server:20 → Client:PORT (data, server initiates — blocked by most firewalls)

Passive Mode

In Passive mode, the client initiates both connections.

  1. Client connects to server port 21 (control channel)
  2. Client sends a PASV command: "I want passive mode"
  3. Server responds with a random port number it has opened: "Connect to me at port Y"
  4. Client opens a second connection to server port Y (data channel)

Benefit: The client initiates everything. Most firewalls allow outbound connections freely. NAT has no problem because the client is always the one opening connections.

Passive Mode:
Client → Server:21      (control, client initiates)
Client → Server:PASV    (data, client initiates — firewall-friendly)

Modern FTP clients use Passive mode by default. If you have ever seen an FTP client hang when listing a directory, it is almost always an Active mode firewall issue.


FTPS — FTP with TLS Added

FTPS is FTP with TLS/SSL encryption layered on top. It is still FTP — same two-port architecture, same command set, same file operations — but the communication is encrypted.

There are two modes of FTPS:

Explicit FTPS (STARTTLS)

  • Starts as a plain FTP connection on port 21
  • Client sends AUTH TLS command to upgrade the connection to encrypted
  • Server and client perform a TLS handshake
  • Subsequent commands and data are encrypted

Implicit FTPS

  • Encrypted from the very first byte
  • Typically uses port 990 for control, port 989 for data
  • Less common today — Explicit mode is the standard

When to use FTPS: When you are integrating with a legacy system that speaks FTP, already has FTP infrastructure, but needs encryption added. Many enterprise EDI (Electronic Data Interchange) systems still use FTPS.

FTPS is still FTP. It still has the two-channel architecture. It still has Active/Passive mode issues. It just adds a TLS wrapper. This is fundamentally different from SFTP.


SFTP — SSH File Transfer Protocol

What SFTP Actually Is

SFTP is not FTP. The name is misleading. SFTP is a binary protocol that runs as a subsystem of SSH (Secure Shell). It was designed from the ground up as a secure file transfer mechanism, standardized in RFC 4251.

  • Single connection on port 22 (same port as SSH terminal access)
  • Fully encrypted — every byte, from authentication through file content, is encrypted using SSH's cryptography
  • Authentication via password or SSH key pair (strongly prefer key pair)
  • Supports interactive file operations: rename, delete, list directory, change permissions, create directories — not just upload/download
  • Stateful session — you can navigate directories, execute operations, then exit

SFTP Command-Line Usage

# Basic SFTP connection
sftp user@server.example.com

# SFTP with specific SSH key
sftp -i ~/.ssh/id_rsa user@server.example.com

# SFTP with non-standard port
sftp -P 2222 user@server.example.com

Once connected, you get an interactive SFTP prompt:

sftp> pwd                          # print current directory on remote
sftp> ls -la                       # list remote files (long format)
sftp> cd /var/www/html             # change remote directory
sftp> lcd ~/Downloads              # change LOCAL directory
sftp> get remote-file.txt          # download a file
sftp> get remote-file.txt local-copy.txt    # download with rename
sftp> put local-file.txt           # upload a file
sftp> put local-file.txt /remote/path/new-name.txt  # upload with path
sftp> mkdir backups                # create remote directory
sftp> rename old-name.txt new-name.txt  # rename remote file
sftp> rm obsolete-file.txt         # delete remote file
sftp> chmod 644 config.txt         # change file permissions
sftp> exit                         # close session

Non-interactive SFTP (for scripts)

# Upload a file non-interactively using a batch file
sftp -b /dev/stdin user@server.example.com << 'EOF'
put /local/path/deploy.tar.gz /remote/releases/
chmod 644 /remote/releases/deploy.tar.gz
EOF

# Download a file non-interactively
sftp user@server.example.com:/remote/path/file.txt /local/destination/

Setting Up SSH Key Authentication for SFTP

SSH key authentication eliminates passwords entirely — far more secure than any password.

# Step 1: Generate an SSH key pair (if you don't have one)
ssh-keygen -t ed25519 -C "deploy@myapp.com"
# Creates: ~/.ssh/id_ed25519 (private key) and ~/.ssh/id_ed25519.pub (public key)

# Step 2: Copy the public key to the server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server.example.com
# This appends your public key to ~/.ssh/authorized_keys on the server

# Step 3: Test the connection (should not prompt for password)
sftp -i ~/.ssh/id_ed25519 user@server.example.com

# Alternatively, configure ~/.ssh/config to avoid typing flags each time:
# Host myserver
#   HostName server.example.com
#   User deploy
#   IdentityFile ~/.ssh/id_ed25519

# Then simply:
sftp myserver

SCP — Secure Copy Protocol

SCP is also built on SSH (port 22). It is simpler than SFTP — designed for one-shot file copies without an interactive session.

# Copy a local file to a remote server
scp file.txt user@server.example.com:/remote/path/

# Copy from remote server to local
scp user@server.example.com:/remote/path/file.txt ./local-copy.txt

# Copy a directory recursively
scp -r ./dist/ user@server.example.com:/var/www/html/

# SCP with specific SSH key
scp -i ~/.ssh/id_rsa file.txt user@server.example.com:/path/

# SCP with non-standard port (note: uppercase -P, unlike sftp's lowercase -P)
scp -P 2222 file.txt user@server.example.com:/path/

SCP's limitations:

  • No interactive session — one operation then done
  • No directory listing, renaming, or deletion
  • No ability to resume interrupted transfers
  • The underlying SCP protocol has known security issues (path injection vulnerabilities in certain implementations)
  • OpenSSH deprecated the old SCP protocol in 2022, with the scp command now using SFTP under the hood by default (-O flag restores old behavior)

Recommendation: Use SFTP even for simple one-off copies. The sftp command with batch mode handles everything SCP does, more safely.


Node.js SFTP Example

Using the ssh2-sftp-client package — the most widely used SFTP library in the Node.js ecosystem.

npm install ssh2-sftp-client

Upload a file

import SftpClient from 'ssh2-sftp-client';
import path from 'path';

const sftp = new SftpClient();

async function uploadFile(localPath, remotePath) {
  try {
    await sftp.connect({
      host: 'server.example.com',
      port: 22,
      username: 'deploy',
      // Option 1: SSH key (recommended for production)
      privateKey: require('fs').readFileSync(path.join(process.env.HOME, '.ssh', 'id_ed25519')),
      // Option 2: Password (avoid in production)
      // password: process.env.SFTP_PASSWORD,
    });

    console.log('Connected to SFTP server');

    // Upload a single file
    await sftp.put(localPath, remotePath);
    console.log(`Uploaded: ${localPath} → ${remotePath}`);

  } catch (err) {
    console.error('SFTP error:', err.message);
    throw err;
  } finally {
    await sftp.end();
  }
}

uploadFile('./dist/app.tar.gz', '/var/releases/app.tar.gz');

Download and list files

import SftpClient from 'ssh2-sftp-client';

const sftp = new SftpClient();

async function manageFiles() {
  await sftp.connect({
    host: 'server.example.com',
    port: 22,
    username: 'deploy',
    privateKey: require('fs').readFileSync(process.env.SSH_KEY_PATH),
  });

  try {
    // List remote directory
    const files = await sftp.list('/var/releases/');
    console.log('Remote files:', files.map(f => `${f.name} (${f.size} bytes)`));

    // Download a file
    await sftp.get('/var/releases/backup.tar.gz', './local-backup.tar.gz');
    console.log('Downloaded backup');

    // Check if file exists
    const exists = await sftp.exists('/var/releases/app.tar.gz');
    console.log('File exists:', exists); // false | 'd' (dir) | '-' (file) | 'l' (link)

    // Create a remote directory
    await sftp.mkdir('/var/releases/2026-04-22', true); // true = recursive

    // Rename/move a file on the server
    await sftp.rename('/var/releases/app.tar.gz', '/var/releases/2026-04-22/app.tar.gz');

    // Delete a file
    await sftp.delete('/var/releases/old-backup.tar.gz');

  } finally {
    await sftp.end();
  }
}

manageFiles().catch(console.error);

Using environment variables for credentials (production pattern)

// config/sftp.js
export const sftpConfig = {
  host: process.env.SFTP_HOST,
  port: parseInt(process.env.SFTP_PORT ?? '22', 10),
  username: process.env.SFTP_USER,
  // Prefer key-based auth: store private key content in env var
  privateKey: process.env.SFTP_PRIVATE_KEY
    ? Buffer.from(process.env.SFTP_PRIVATE_KEY, 'base64')
    : undefined,
  // Fallback to password only if no key provided
  password: process.env.SFTP_PRIVATE_KEY ? undefined : process.env.SFTP_PASSWORD,
  readyTimeout: 10000,  // 10s connection timeout
  retries: 3,
  retry_minTimeout: 2000,
};

When to Use Each Protocol

ScenarioProtocolReason
Internal legacy system integrationFTPSLegacy systems expect FTP; add TLS for minimum security
Any public internet file transferSFTPFully encrypted, SSH key auth, firewall-friendly
CI/CD deployment file uploadSFTPScriptable, key-based auth, supports batch mode
Quick one-off copy over SSHSFTP or SCPBoth work; SFTP is safer and more feature-complete
Hosting provider with FTP onlyFTPS if available, SFTP if offeredNever use plain FTP over the internet
Plain FTP on the open internetNeverCredentials and data are fully visible on the wire

Common Mistakes

  • Confusing SFTP with FTPS. They are entirely different protocols. FTPS is FTP + TLS — still two ports, still FTP under the hood, still the FTP architecture. SFTP is an SSH subsystem — one port (22), completely different protocol, no relation to FTP whatsoever. Mixing them up in an interview signals a surface-level understanding.

  • Using FTP over the internet. Plain FTP transmits credentials, commands, and file content as clear text. Any network observer — on your LAN, at your ISP, on a compromised router between you and the server — can read your username, password, and every file you transfer. There is no situation where plain FTP is acceptable for internet-facing file transfers. Even on "trusted" internal networks, prefer SFTP.

  • Not using SSH key authentication for SFTP. SFTP supports two authentication methods: password and SSH key pair. Password authentication is vulnerable to brute force, credential stuffing, and phishing. SSH keys are asymmetric — the private key never leaves your machine, and the server only holds the public key. In production deployments and CI/CD pipelines, always use SSH key authentication. Rotate keys when team members leave; never share private keys.


Interview Questions

1. What is the difference between FTP and SFTP?

FTP (File Transfer Protocol) is an older protocol that transmits everything — including usernames, passwords, and file contents — in plain text over two separate TCP connections: port 21 for commands (control channel) and port 20 for data (data channel). It offers zero encryption.

SFTP (SSH File Transfer Protocol) is a completely separate protocol that runs as a subsystem over SSH on port 22. Everything is encrypted end-to-end. Despite the similar name, SFTP shares no code or architecture with FTP. SFTP also supports richer file operations (rename, delete, list, permissions) beyond basic upload/download.


2. What is the difference between SFTP and FTPS?

FTPS is FTP with TLS/SSL encryption added on top. It is still fundamentally FTP — same two-port design, same command set, same Active/Passive mode considerations. It comes in two forms: Explicit FTPS (starts on port 21 and upgrades with AUTH TLS) and Implicit FTPS (always encrypted, typically port 990).

SFTP is a completely different protocol built on SSH. It uses a single port (22), has its own binary protocol entirely distinct from FTP, and is not an "encrypted FTP" — it is an SSH file transfer subsystem that happens to fulfill a similar purpose. The name similarity is misleading; they share almost nothing technically.


3. Why does FTP need two separate ports (20 and 21)?

FTP was designed with a separation of concerns between controlling the session and transferring data.

Port 21 carries the control channel — this is where commands like USER, PASS, LIST, RETR, STOR, and QUIT flow as plain ASCII text. The session persists on this connection for the life of the FTP session.

Port 20 (in Active mode) carries the data channel — the actual file bytes and directory listings. A new data connection is opened for each file transfer or directory listing, then closed when complete.

The separation exists because it made the original protocol design simpler — the control channel stays open for the entire session (stateful), while the data channel is ephemeral (opened and closed per operation). The downside is added complexity, two ports to manage, and significant problems with NAT and firewalls, especially in Active mode.


4. What is the difference between active and passive mode in FTP?

Both modes use port 21 for the control channel. The difference is who initiates the data connection.

Active mode: The client tells the server which port it is listening on (PORT command), and the server opens a connection from its port 20 to that client port. This is problematic with firewalls and NAT — the server initiates an inbound connection to the client, which most firewalls block by default.

Passive mode: The client sends a PASV command, and the server responds with a random port it has opened. The client then connects to that server port. Both connections are client-initiated — this is firewall-friendly because firewalls generally allow outbound connections freely.

Modern FTP clients default to Passive mode precisely because Active mode fails in the majority of real-world network environments (corporate NAT, home routers, cloud VMs). Passive mode also requires the FTP server's firewall to allow inbound connections on the range of ports it may open for data channels.


Quick Reference — Cheat Sheet

FeatureFTPFTPSSFTPSCP
Port(s)21 (ctrl), 20 (data)21 / 990 (ctrl), 20 / 989 (data)2222
EncryptionNone — plain textTLS/SSLSSH (full encryption)SSH (full encryption)
Underlying protocolFTPFTP + TLSSSH subsystemSSH
AuthenticationUsername + password (plain text)Username + password (encrypted)Password or SSH key pairPassword or SSH key pair
Two-port architectureYesYesNo (single port)No (single port)
Active/Passive modeYesYesNoNo
Interactive sessionYesYesYesNo
File ops (rename, delete, mkdir)YesYesYesNo
Resume interrupted transferPartial (REST command)PartialYes (client-dependent)No
Firewall-friendlyPassive onlyPassive onlyYesYes
Use caseLegacy internal systemsLegacy + encryption neededAny production file transferQuick one-off SSH copies
Recommended for internet?NeverAcceptableYes — preferredYes

Port Quick Reference

FTP  Control : TCP 21    (commands — always plain text in plain FTP)
FTP  Data    : TCP 20    (Active mode) or random port (Passive mode)
FTPS Control : TCP 21    (Explicit) or TCP 990 (Implicit)
FTPS Data    : TCP 20    (Explicit) or TCP 989 (Implicit)
SFTP         : TCP 22    (SSH — all traffic encrypted, single connection)
SCP          : TCP 22    (SSH — all traffic encrypted, single connection)

SFTP One-Liners to Remember

sftp user@host                          # interactive session
sftp -i ~/.ssh/key user@host            # with specific SSH key
sftp -P 2222 user@host                  # non-standard port
scp file.txt user@host:/path/           # one-shot upload
scp -r ./dir/ user@host:/path/          # recursive directory upload
scp user@host:/path/file.txt ./         # one-shot download

Previous: Lesson 5.3 — TLS/SSL (03-tls-ssl.md) Next: Lesson 5.5 — Email Protocols (05-email-protocols.md)


This is Lesson 5.4 of the Networking Interview Prep Course — 8 chapters, 32 lessons.

On this page