How to Setup FTP (FTPS (not SFTP)) on an AWS EC2 Instance

Below are the commands required to setup FTP (well, FTPS in fact, and specifically not SFTP, which you can most easily use by adding your security certificate to your FTP program and accessing over SSH) on your AWS EC2 cloud instance.

I’m assuming you use the AWS flavour of Linux. If you do not use AWS Linux, and you use, say, Ubuntu, or Lightsail, please note… your mileage may vary. In plain English, this means, do not expect commands for one type of Linux to work in another. They may not.

If you use Ubuntu or whatever, file locations, commands, and other such will more than likely be different.

I have added in some commentary which may or may not help for the novice / intermediate user. I’m trying to bring you up to speed with what commands do, as a lot of tutorials assume knowledge which may or may not exist in the user.

This description, below, will allow you to add simple, or secure (FTPS – secured by vsftpd) FTP to your Amazon Linux AWS EC2 instance. This can often be useful to do things such as allowing service providers or third parties to drop files into a directory to which they are “chrooted”.

Please ignore anything you already know, and complain like fury in the comments where I’ve explained anything wrong 🙂

Step One – Getting Started

Login to your cloud server via Terminal. I often use PuTTy. Its up to you how you do this. This tutorial assumes you can login as ec2-user. If you cannot, you have bigger problems than I can address right now!

Commands to run

sudo -i

// to access as root henceforth (rather than typing “sudo” at the start of each command); for brevity, and to avoid wearing out your fingers.

yum update -y

// to update your cloud server to latest stable release of *everything*. The -y means when it asks if you want to install you’ve already said “yes”

yum install vsftpd

// to install the ftp gubbins you will need to say yes

Step Two – Open Ports in Security Group

You need to go to your AWS account in your browser and open up the ports required for FTP access.

This is done by:

1) Login to AWS https://aws.amazon.com/
2) Open up the EC2 panel from the management console
3) Select “security groups” from the left menu and find the relevant one OR select the EC2 instance in question and directly click on the security group from the bottom of the page area
4) Hit “Edit” on the relevant security group INBOUND rules
5) Add two rules Type > Custom TCP Rules – port ranges 20-21 and 1024-1048 (all from source “anywhere” if you want to allow FTP from anywhere, otherwise secure by locking down to just your IP, assuming a) you know this and b) it won’t change!)

Step 3 – Ensure vsftpd starts on server reboot

You want to make sure your new service will start when your server reboots, in future.

Enter the following into terminal

chkconfig --level 345 vsftpd on

// This makes sure that vsftpd starts when the instance reboots (note it will need starting initially – a restart we do below will achieve this!)

Step 4 – Update vsftpd.conf file

Back in your terminal window (PuTTy or whatever), run the following commands to update your vsftpd.conf file using vi.

vi /etc/vsftpd/vsftpd.conf

// this uses the vi editor to edit the vsftpd.conf file. Get familiar with vi if you are going to use PuTTy to regularly edit stuff on your AWS instance.

Hit the insert key or “i” to start inserting (well deleting, replacing, and whatever too) in vi, or use your favourite method to achieve the below:

Change

anonymous_enable=YES

to

anonymous_enable=NO

// this prevents ananymous access over FTP. Ananymous access is a Bad Thing. It (kind of) means any old yoyo can be on FTP.

Then add the following to the bottom of the file

pasv_enable=YES
pasv_min_port=1024
pasv_max_port=1048
pasv_address=[YOURPUBLICIP]

// Be SURE to replace [YOURPUBLICIP] with your public IP, or this will not work right! You can see what this is doing though, right? Its enabling passive connections, specifiying the ports to use, and the IP. All stuff to do.

// Press escape
// type
:wq
// Hit enter

// :wq tells vi to “write” this file and “quit” the colon means “commands coming” and the escape key beforehand says “I’m about to say some commands, stop inserting into file”.

NEXT Restart vsftpd

/etc/init.d/vsftpd restart

Step 5 – Create an FTP user

Type the following into terminal to create this user / password – replace “silicondales” with your intended username!

adduser silicondales
passwd silicondales

Step 6 – Restrict user to home directory

You will want to prevent an FTP user getting ideas above his station, and “chroot” him or her to their directory (means they cannot go “above” their home directory and try to tinker about with (for example) server settings).

Edit the vsftpd.conf again in terminal and again using vi:

vi /etc/vsftpd/vsftpd.conf

Uncomment (remove the # in front of) the line which says:

chroot_local_user=YES

Then its save and quit as before.

// Hit escape
:wq
// Enter

// again save your new settings by writing to vi and quitting

Restart vsftpd by entering this into terminal:

/etc/init.d/vsftpd restart

Step 7 -Change / Set user’s FTP home directory & give group permissions

Enter the below command into terminal to set the user (in this case our silicondales user – replace this with your actual username!) home directory. In this example, I’m saying the html is the user’s root (this is where the website in this pretend case lives – note you can use a subdirectory for service providers and lock ’em down!).

usermod -d /var/www/html silicondales

Then, make sure the user in question is part of the group which owns the files in this folder, to allow them to upload / change / delete as you wish. Read up on this. You might want to be careful allowing an FTP user to modify files in your server!

First for this, check the ownership status of files in your html (or whatever) folder, by doing the following:

cd /var/www/html/

// navigate to the folder in question

ls -l

// will output the permissions and ownership and group for the files in this directory. In our case we’re going to add the user to this relevant group. In our case, the group is “apache”

usermod -a -G apache silicondales

// the above adds the user silicondales to the group apache, which will mean this user gains the same access allowed to that group. This will help you with some permissions stuff you would otherwise experience with FTP’ing things up and down.

Finally, restart to apply everything and you should be done!

/etc/init.d/vsftpd restart

Leave a comment below if this worked or did not work for you. I may be able to help. But I hope the above did get you there! If it did, just leave a comment saying “hooray” or something :)!

52 thoughts on “How to Setup FTP (FTPS (not SFTP)) on an AWS EC2 Instance”

  1. Hi!

    Thanks it worked almost perfectly!

    Only thing that didn’t work was with service restart.
    When running on AWS EC2 you are running a systemd-based OS where traditional init scripts have
    been replaced by native systemd services files so /etc/init.d/ is empty. To make use of service
    files simply invoke “systemctl”. You have to replace /etc/init.d/vsftpd restart commands by:
    systemctl stop vsftpd.service
    systemctl start vsftpd.service

    Thanks,
    Karol

    Reply
  2. Hi

    Thanks for this it’s just what I need but when I try using Filezilla I get: (I’ve masked the ip addresses):

    Status: Resolving address of ec2-xx-xx-xx-xx.eu-west-2.compute.amazonaws.com
    Status: Connecting to xx.xx.xx.xx:21…
    Status: Connection established, waiting for welcome message…
    Status: Insecure server, it does not support FTP over TLS.
    Status: Logged in
    Status: Retrieving directory listing…
    Command: PWD
    Response: 257 “/”
    Command: TYPE I
    Response: 200 Switching to Binary mode.
    Command: PASV
    Response: 227 Entering Passive Mode (86,131,226,181,4,20).
    Command: LIST
    Error: Connection timed out after 20 seconds of inactivity
    Error: Failed to retrieve directory listing
    Status: Disconnected from server

    Reply
      • Hi Robin

        I tried that and only got as far as:

        Status: Connecting to xx.xx.xx.xx.eu-west-2.compute.amazonaws.com…
        Response: fzSftp started, protocol_version=8
        Command: open “username@xx.xx.xx.xx.eu-west-2.compute.amazonaws.com” 22
        Error: Disconnected: No supported authentication methods available (server sent: publickey)
        Error: Could not connect to server

        I’ve run through your steps but no luck

        I have set up a successful WinSCP connection using the “Transferring Files to Your Linux Instance Using WinSCP” section http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.htmlhowever that is for the default user ‘ec2-user’.

        Your article appealed to me as I want to give access to a specific folder to another user, and I like your writing style 🙂

        I’ve tried it again but connecting in passive mode and this happens:

        Status: Resolving address of ec2-xx.xx.xx.xx.eu-west-2.compute.amazonaws.com
        Status: Connecting to xx.xx.xx.xx.:21…
        Status: Connection established, waiting for welcome message…
        Response: 220 (vsFTPd 2.2.2)
        Command: AUTH TLS
        Response: 530 Please login with USER and PASS.
        Command: AUTH SSL
        Response: 530 Please login with USER and PASS.
        Status: Insecure server, it does not support FTP over TLS.
        Command: USER xxxxxxxxxx
        Response: 331 Please specify the password.
        Command: PASS ********
        Response: 230 Login successful.
        Command: OPTS UTF8 ON
        Response: 200 Always in UTF8 mode.
        Status: Logged in
        Status: Retrieving directory listing…
        Command: PWD
        Response: 257 “/”
        Command: TYPE I
        Response: 200 Switching to Binary mode.
        Command: PASV
        Response: 227 Entering Passive Mode (86,131,226,181,4,2).
        Command: LIST
        Error: Connection timed out after 20 seconds of inactivity
        Error: Failed to retrieve directory listing
        Status: Disconnected from server

        Any thoughts?

        Thanks again
        Mark

        Reply
  3. Ignore that, I’ve sussed that

    “pasv_address=[YOURPUBLICIP]

    // Be SURE to replace [YOURPUBLICIP] with your public IP” is the public IP of the server, not my IP. Doh!

    And it does work over plain FTP.

    Thanks for your article!

    Reply
  4. Thanks, this almost worked. When I tried to upload I got “Permission Denied.” Something was fishy to me when adding users to the group. Since we created the group www but we added the users to “apache.” When I changed that to “www,” I was able to upload.

    Reply
  5. I have added an ftp user and can login via filezilla and connect successfully. When I try to delete a file I get the 550 Delete operation failed error. When i look at the file permission it shows owner / group 48 /48 I added the user to the apache group and it still shows 48 / 48.

    Reply
    • Hi Ryan,

      Great to hear you got this working. This sounds like a permissions issue, and like the “group” membership was not quite working as expected. From what you said before, it sounds like the ownership wasn’t quite setup right.

      Good to hear you got this working.

      Its worth going through to understand what setfacl does – it tells the system which files username can have access to.

      In this tutorial, this (should be) covered by giving group membership, but this is likely what didn’t quite work in your case. There are always several ways to make things work though!

      Reply
    • So in your case, if owner / group were 48 / 48 then you would have needed to add your user to the “48” group (not apache, as this is not the group in your setup), by issuing the following command:

      usermod -a -G 48 someusername

      Reply
  6. For it works properly when i am connecting through (FTP) and using (Port 21).But when i tried to connect via (SFTP using port 22) i am facing an ERROR

    [Authentication log (see session log for details):
    Using username “ACLL”.
    Authentication failed.] Do i need to create a separate Username for SFTP??? and how to do it.
    please help me on this

    Reply
  7. Note for Others:
    I wasn’t sure what to put for the “Host:” at first. “IPv4 Public IP” or “Public DNS (IPv4)” as specific in your AWS console works.

    My Question:
    I just opened FileZilla, put in the above host, and then the username and password. and port: 22. I get the following error.

    Status: Connecting to ec2-xxxxxxxx.amazonaws.com…
    Response: fzSftp started, protocol_version=8
    Command: open “username@ec2-xxxxxxxx.amazonaws.com” 22
    Command: Trust new Hostkey: Yes
    Error: Disconnected: No supported authentication methods available (server sent: publickey)
    Error: Could not connect to server

    Could I please get some pointers I what is wrong?

    Thanks!

    Reply
  8. Hi
    First off, thank you for the step by step instructions. It’s been really quite helpful.

    I did everything above but ran into a small error.

    Once I try to connect to ec2 (lightsail) via filezilla I get the following error.
    Status: Connecting to 13.59.XXX.XX…
    Response: fzSftp started, protocol_version=8
    Command: keyfile “C:\Users\cwilliams2\Downloads\LightsailDefaultPrivateKey-us-east-2.pem”
    Command: open “cwilliams2@13.59.XXX.XX” 22
    Error: Connection timed out after 20 seconds of inactivity
    Error: Could not connect to server

    I’m not sure what else I could be doing wrong…any ideas?

    Reply
    • I can’t be sure where this is failing, but its worth checking ports are open in AWS settings (I can see its trying port 22 here) and also that you are connecting in the correct mode via Filezilla (active / passive). I’m not 100% sure this work with Lightsail, either.

      Reply
  9. Hi,
    I did follow the tutorial to the letter but I cam getting the following error. I did try several times to change the user permissions as you indicated on the user directory but no luck. At some point I got an error saying that “user apache does not exist” so I installed Apache in order for the user to be created. Re-ran the command usermod -a -G apache [my username] but it did not change anything. On interesting thing is that if I run ls -l the console returns “total 0”.

    Reply
  10. Robin Scott,
    I think you have your title wrong. This is to setup a FTP Server with Explicit SSL/TLS connection(FTPS). SFTP is Secure FTP using SSH. These are two different protocols. SFTP is setup via OpenSSH instead of VSFTPD. I think this is where 99% of your readers are confused.

    Reply
    • Hi Trevor, regarding the title – SFTP is in parenthesis, it was added later, to indicate the “secureness”, and yes, its actually incorrect :)… most users come here looking for the main part: the ability to add FTP to an AWS instance. SFTP (logging in over SSH with a security certificate) is not the same as FTP as you rightly point out. The ways to access AWS EC2 instances using SSH, which are in fact setup when the instance is created, are perhaps equally obscure to the novice user, so maybe there’s value in adding a description of how to do this. The above tutorial, as with almost all we post, was done with a specific end user in mind: one who wants to add FTP to EC2. The security of this traffic was something that basically I insisted on, but it should be differentiated from SSH (using the certificate) as the use-case it was written for is a situation where users would be issued to people not authorised to have this cert. For brevity, let’s say I should probably change the title to be FTPS and make a very short “here’s how to drop your certificate into Filezilla” post for people who cannot use Google 😉

      Reply
  11. This article helped me a lot. I got the FTP server running. But when client tried to login and change the dir it gives be below error
    Response: 500 OOPS: cannot change directory:/home/ec2-user

    what could i have done wrong?

    Reply
  12. This is a great white-page, except I am running into one issue. When I try to navigate to /var/www/html/ I am getting an error “-bash: cd: /var/www/html/: No such file or directory”

    I am not sure why the directory is not there, I have followed every step. Any advise would be greatly appreciated.

    Thanks!

    Reply
    • Hi Andrew,

      The question would be which directory is your webroot? What directory do your web files live in? This (sort of) depends on your EC2 install, the linux flavour you chose, and also you can move this around. If /var/www/html is not there, you probably aren’t using the AWS linux I trialled this on.

      Reply
  13. Thanks for posting this, it was a helpful start for me. From what I can tell, though, this is configuring neither FTPS nor SFTP, so I’d suggest the title should be changed or the missing info added.

    For FTPS (TLS), here’s what I found.

    Using AWS Lightsail and Amazon Linux (OS only image), the default vsftpd.conf file did not include the settings to enable FTPS. Those would be:

    ssl_enable=YES
    ssl_tlsv1=YES
    ssl_sslv2=NO
    ssl_sslv3=NO
    rsa_cert_file=/path/to/your/cert
    ssl_request_cert=NO

    Full instructions here, assuming you are using SSL/TLS certs from a certificate authority: https://knowledge.symantec.com/support/ssl-certificates-support/index?page=content&id=SO9224&&viewlocale=en_US

    If you don’t already have SSL/TLS certificates to use, you can glean what you need to generate a self-signed certificate with this article: https://www.digitalocean.com/community/tutorials/how-to-configure-vsftpd-to-use-ssl-tls-on-a-centos-vps

    I hope this helps.

    Reply
    • You can use SFTP using the same connection you go in via SSH, the certificate should not be an issue, as you “trust” the supplier (its you). But please note, Lightsail is not EC2.

      Reply
  14. HI,

    I get the following error after connecting.

    The data connection could not be established: WSAEADDRNOTAVAIL – Cannot assign requested address

    Reply
  15. Hi,
    I got this error after perform all steps provided by you. Currently I am using Ubuntu server (latest) on AWS ECS.

    Disconnected: No supported authentication methods available (server sent: publickey)

    Kindly tell me how to resolve this issue.

    Reply
  16. Hi Robin,

    Thanks for the clear instruction! I followed the steps and everything worked fine in the terminal, but I got the Login Incorrect message after I tried to connect through Yummy FTP. I couldn’t figure anything wrong but the password. How can I change the ftp account password in the terminal so that I can see if it’s the password issue? Any other issues I may have?

    Gary

    Reply
  17. Hi Robin,
    Thank you for the wonderful article. Everything worked as expected, except that I want my “ftpuser” to have write permissions. ftp://myserverip works perfectly fine on browsers. But when I use windows explorer or WinScp, I get the following error:

    An error occurred while opening that folder on the FTP Server. Make sure that you have permission to access that folder.
    Could not retrieve directory listing. Error listing directory ‘/’.

    How can I grant write access to “ftpuser”?

    Reply
  18. This worked for me.

    In WinSCP, go to advanced option.

    in SHELL Menu, type sudo su –

    in SSH Authentication Menu, Turn Off “Attempt Keyboard Interactive Authentication (SSH-2)”

    Reply
  19. Great article!

    However, even though I can connect to the instance, I cannot list or get the files at the FTP server, and if I put any file on it, it’s stored empty.

    See that:

    ftp> dir
    227 Entering Passive Mode (0,0,0,0,4,23).
    ftp: connect: Connection refused
    ftp> put test.txt
    local: test.txt remote: test.txt
    227 Entering Passive Mode (0,0,0,0,4,3).
    ftp: connect: Connection refused
    # AFTER THE LINE ABOVE, THE FILE IS CREATED AT THE REMOTE SERVER, BUT WITH 0 BYTES
    ftp> get remotetest.txt
    local: remotetest.txt remote: remotetest.txt
    227 Entering Passive Mode (0,0,0,0,4,13).
    ftp: connect: Connection refused

    Does anyone know what may be happening?

    Reply
    • The “connection refused” is your clue. You need to establish why you cannot connect. It may be the relevant ports are not open, or the user / password you setup isn’t quite right.

      Reply
  20. Hi,

    I am so new to the world of FTP. I never touch FTP before I am very intimidated by the steps above! I noticed that these commands are for Linux and Ubuntu. I was wondering if there’s a step procedures for macOS?

    Reply
  21. i tried but getting following error message.

    Password:
    230 Login successful.
    Remote system type is UNIX.
    Using binary mode to transfer files.
    ftp> ls
    227 Entering Passive Mode (34,233,229,183,191,42).
    ftp: connect: Invalid argument
    ftp> pwd
    257 “/”
    ftp> cd inbound
    550 Failed to change directory.
    ftp> cd ftp_data
    550 Failed to change directory.
    ftp>

    Reply
  22. Hey,
    I followed the same process. I am able to connect to the ftp and also particular folder, but i am not able to send the files to ftp server.

    ERROR:
    File “”, line 1, in
    File “****/ftplib.py”, line 504, in storbinary
    rest: Passed to transfercmd(). [default: None]
    File “/****/ftplib.py”, line 399, in transfercmd
    # this is conditional in case we received a 125
    File “****/ftplib.py”, line 361, in ntransfercmd
    given marker.
    File “****/socket.py”, line 728, in create_connection
    sock.close()
    File “****/socket.py”, line 716, in create_connection
    sock.settimeout(timeout)
    ConnectionRefusedError: [Errno 111] Connection refused

    I modifed this as well
    listen_ipv6=NO
    listen=YES

    Reply

Leave a comment

No links of any kind allowed in comments - if you add any links, your comment will automatically be deleted.