One of the handy features in the latest WordPress is the support to upgrade plugins in one click through the WordPress administration interface. It needs FTP or FTPS access to the server where you have hosted your WordPress installation. But turning on FTP for users (non-anonymous) is a bad idea. Using FTP involves transferring user passwords as plain text during authentication. This is a great security concern and the primary reason for why one shouldn’t turn on FTP for user accounts. However, WordPress also supports FTPS, FTP over SSL. This shouldn’t be confused with SSH FTP or Secure FTP. FTPS uses TLS or SSL for authentication and commands. Let us see how to setup FTPS on a server using vsftpd.
Step 1: Install vsftpd
Using the package manager for your distribution, install vsftpd. On Debian and Ubuntu, it can be installed by the following command.
$ sudo apt-get install vsftpd
Step 2: Configure FTPS
Edit /etc/vsftpd.conf and do the following.
2a. comment out anonymous_enable line.
# Allow anonymous FTP? (Beware - allowed by default if you comment this out). #anonymous_enable=YES
2b. Uncomment local_enable and write_enable lines.
# Uncomment this to allow local users to log in. local_enable=YES # # Uncomment this to enable any form of FTP write command. write_enable=YES
2c. Override the umask for local users to 022 by uncommenting the local_umask line.
# Default umask for local users is 077. You may wish to change this to 022, # if your users expect that (022 is used by most other ftpd's) local_umask=022
Note: Failing to do this, will make the plugin directory unreadable by your webserver and you will start getting PHP include errors. If this happens, you have to disable the plugin and remove the directory or change the permission of the directory to 755.
2d. Turn on SSL by adding the following lines. This is disable plain FTP and allow only FTPS.
ssl_enable=YES allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES ssl_tlsv1=YES ssl_sslv2=YES ssl_sslv3=YES
It is assumed that the RSA certificate and key are in the standard locations /etc/ssl/certs/ssl-cert-snakeoil.pem and /etc/ssl/private/ssl-cert-snakeoil.key respectively. If not, create these and put them there.
# This option specifies the location of the RSA certificate to use for SSL # encrypted connections. rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem # This option specifies the location of the RSA key to use for SSL # encrypted connections. rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
Step 3: Restart vsftpd.
Restart vsftpd by issuing the following command.
$ sudo /etc/init.d/vsftpd restart
Now your vsftpd is ready to serve FTPS connections.
I did this exact config but got errors.
Connecting to 192.168.1.108:990…
Status: Connection attempt failed with “ECONNREFUSED – Connection refused by server”.
Error: Could not connect to server
Status: Waiting to retry…
Status: Connecting to 192.168.1.108:990…
Status: Connection attempt failed with “ECONNREFUSED – Connection refused by server”.
Error: Could not connect to server
Telnet to the server over port 990 doesn’t work either. Any ideas?
Under this configuration, vsftpd still listens in port 21 for FTP control except the fact that non-anonymous sessions should use encryption. To verify if things work fine, please telnet to port 21.
praveen@athena:~$ telnet kumar.in 21
Trying 64.79.194.219...
Connected to kumar.in.
Escape character is '^]'.
220 (vsFTPd 2.0.6)
If you see the above, then your vsftpd is running fine. Then type ‘USER’ and press return in the telnet console.
USER
530 Non-anonymous sessions must use encryption.
And if you see the above, you are all set to use encryption.
Well, I do see the response that users must use encryption, but here’s what happened after that:
530 Non-anonymous sessions must use encryption.
Error: Could not connect to server
Status: Resolving address of (server name removed)
Status: Connecting to x.x.x.x(IP removed):990…
Status: Connection attempt failed with “ECONNREFUSED – Connection refused by server”.
Error: Could not connect to server
Status: Waiting to retry…
Status: Resolving address of (server name removed)
Status: Connecting to x.x.x.x(IP removed):990…
Status: Connection attempt failed with “ECONNREFUSED – Connection refused by server”.
Error: Could not connect to server
This was over ftps with filezilla. I did connect to another server, not owned by me, over ftps with filezilla to test the client out.
When I run netstat -an | grep “LISTEN” I don’t see port 990 listening even though ssl_enable=YES is set in the config file. So I set “listen_port=990″ and it stops listening on port 21 and now I see port 990 when I view netstat. Seems like it’s good at that point.
When I try to connect now, I get this:
Status: Resolving address of (server name removed)
Status: Connecting to x.x.x.x(IP removed):990…
Status: Connection established, initializing TLS…
Error: Connection timed out
Error: Could not connect to server
So it’s like the server can’t establish the connection even though vsftpd and openssh is installed. I’ve ran some commands, forgot what they were, that are supposed to verify if vsftpd is able to do ftps and they came back good. So I’m stumped. All the sites I’ve read state how easy it is to set up and I’ve been working on it for a couple of days now. Maybe it doesn’t like the certificate????? Any other thoughts? Thanks so much for your help.
looks like a helpful howto. maybe i am missing something, but is it necessary to enable anonymous logins by default?
This worked perfectly for me! The only suggestion I’d make is that for step 2d, when you describe the “ssl-cert-snakeoil” files, the user might not know that those are actual/real files on their system (the name makes them sound like placeholder/fakes just used in an example.) I was surprised when I went into my filesystem and saw them in there.
Great tutorial and a real lifesaver. Thanks a ton Praveen!
Nice Post, I would mention that you may want to set up a specific user to do those updates with the following commands:
sudo useradd ftpuser -d /var/www
sudo passwd ftpuser
I also then chrooted my server so they can’t escape from that specified home directory.
My only battle beyond that was giving permissions to that ftpuser so it could write to the files it was trying to update during the automatic update process.
OK
So now adding a user for ftp purposes(themes, media uploads, updating)? I’ve got webmin at my disposal (local server – Debian Lenny) and I’ve added a user as a member of www-data group, their home directory is /var/www (did not select “create home directory” or “copy template files..” during creating them under webmin). I get this
Downloading update from http://wordpress.org/wordpress-2.8.3.zip.
Unpacking the update.
Warning: ftp_mkdir() [function.ftp-mkdir]: Create directory operation failed. in /var/www/wp-admin/includes/class-wp-filesystem-ftpext.php on line 240
Could not create directory: /var/www/wp-content/upgrade
Installation Failed
Before I go chown’ing, chmod’ing etc(still hazy on these) I’d love some advice!!! Sorry if this is simple stuff….these are baby steps for me….building the server from scratch has been a big effort!!!
Cheers Everyone:)
Praveen,
I had been banging my head off this for a couple of days before I found your post. The critical thing for me was the rsa_private_key_file which was not described in any of the other posts I have seen.
I included this parameter (per your step 2d) and now vsftpd is accepting implicit SSL connections.
May I ask one question, however? Which version of vsftpd are you using? Red Hat supplies 2.0.5 which apparently doesn’t support implicit SSL. This was included in 2.0.7. I used 2.2.1 (released in October 2009) which I compiled from source.
Many thanks for your help.
Colin Brett
Nice post, Praveen. Been stuck on this for a while and was getting nowhere with the WordPress documentation. Looks like I was asking the wrong question.
This helped.
Any way someone could create a shell script that can do this in an automated way?