FTP
Amazon Cloud
Server Setup
Cloud Computing
Network Configuration

Setting up FTP on Amazon Cloud Server

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Running FTP on an Amazon EC2 server is possible, but it requires careful networking and security configuration to avoid fragile or unsafe deployments. Many teams use SFTP instead, yet some integrations still require classic FTP or FTPS. This guide shows a practical EC2 setup with vsftpd, passive mode, TLS, and least-privilege network rules.

Start with the Right Protocol Choice

Before installing anything, decide what your client systems support.

  • SFTP uses SSH on one port and is usually simpler to secure.
  • FTP sends credentials in clear text unless TLS is enabled.
  • FTPS is FTP with TLS and is the safest option when FTP compatibility is required.

If your integration partner supports SFTP, use it. If they only support FTP semantics, configure FTPS and restrict inbound access to known source IP ranges.

EC2 and Security Group Preparation

Create an EC2 instance with a fixed public endpoint, either an Elastic IP or a DNS record pointing to a stable address. Then configure a security group with tight inbound rules.

For explicit FTPS in passive mode, you typically need:

  • TCP 21 for control channel.
  • A small passive range, for example TCP 40000 through 40010.
  • Source restricted to trusted IPs.

Avoid opening the passive range to the entire internet unless absolutely required.

Install and Configure vsftpd

The following commands target Amazon Linux 2023. For Ubuntu, replace package commands with apt equivalents.

bash
1sudo dnf update -y
2sudo dnf install -y vsftpd openssl
3sudo systemctl enable vsftpd
4sudo systemctl start vsftpd

Create a dedicated FTP user and directory layout:

bash
1sudo useradd -m -d /home/ftpuser -s /sbin/nologin ftpuser
2sudo passwd ftpuser
3sudo mkdir -p /home/ftpuser/upload
4sudo chown -R ftpuser:ftpuser /home/ftpuser
5sudo chmod 755 /home/ftpuser
6sudo chmod 755 /home/ftpuser/upload

Now configure vsftpd with local users, chroot, passive mode, and TLS.

conf
1# /etc/vsftpd/vsftpd.conf
2listen=YES
3listen_ipv6=NO
4anonymous_enable=NO
5local_enable=YES
6write_enable=YES
7local_umask=022
8chroot_local_user=YES
9allow_writeable_chroot=YES
10
11# Logging
12xferlog_enable=YES
13xferlog_std_format=NO
14log_ftp_protocol=YES
15
16# Passive mode
17pasv_enable=YES
18pasv_min_port=40000
19pasv_max_port=40010
20pasv_address=YOUR_PUBLIC_IP
21
22# TLS
23ssl_enable=YES
24allow_anon_ssl=NO
25force_local_data_ssl=YES
26force_local_logins_ssl=YES
27ssl_tlsv1=YES
28ssl_sslv2=NO
29ssl_sslv3=NO
30rsa_cert_file=/etc/ssl/private/vsftpd.pem
31rsa_private_key_file=/etc/ssl/private/vsftpd.pem

Generate a certificate and restart the service:

bash
1sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
2  -keyout /etc/ssl/private/vsftpd.pem \
3  -out /etc/ssl/private/vsftpd.pem
4
5sudo chmod 600 /etc/ssl/private/vsftpd.pem
6sudo systemctl restart vsftpd
7sudo systemctl status vsftpd --no-pager

For production, replace the self-signed certificate with one issued by your internal PKI or a trusted certificate authority.

Validate End-to-End Connectivity

Server startup alone is not enough. You need to verify login, data transfer, and passive channel behavior from an external client.

Using lftp from a trusted machine:

bash
1lftp -u ftpuser,YourStrongPassword ftps://YOUR_PUBLIC_IP
2
3# After connection
4pwd
5ls
6put ./test.txt -o upload/test.txt
7get upload/test.txt -o ./roundtrip.txt
8bye

If listing works but upload fails, the issue is usually passive-port networking. Recheck both:

  • Security group inbound rules for passive range.
  • Network ACL rules if your subnet uses restrictive ACL settings.

Hardening for Real Deployments

A secure setup includes more than TLS.

  • Restrict source IPs to known partner addresses.
  • Disable shell login for FTP users.
  • Keep each user in isolated directories.
  • Rotate credentials on a schedule.
  • Monitor logs and alert on repeated failed logins.

Example log inspection commands:

bash
sudo journalctl -u vsftpd --since "1 hour ago"
sudo tail -n 100 /var/log/vsftpd.log

For high-compliance environments, consider AWS Transfer Family instead of self-managed vsftpd. It reduces operational burden for certificates, patching, and availability.

Common Pitfalls

  • Opening only port 21 and forgetting passive ports. Fix by defining a narrow passive range and opening it in the security group.
  • Using plain FTP without TLS. Fix by forcing encrypted login and data channels.
  • Leaving broad source access. Fix by restricting inbound CIDR blocks to partner networks.
  • Setting pasv_address incorrectly. Fix by using the actual public endpoint that clients resolve.
  • Running FTP user with shell access. Fix by assigning nologin and limiting directory permissions.

Summary

  • Use FTPS when FTP compatibility is required, and prefer SFTP when possible.
  • Configure vsftpd with passive mode, chroot, and forced TLS.
  • Align server config, security group rules, and subnet ACLs for data channel traffic.
  • Validate transfers from an external client, not only from the instance itself.
  • Apply least privilege across users, network rules, and operational access.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.