At this point, I have set up my Amazon EC2 server with the Ubuntu operating system and a standard LAMP (Linux, Apache, MySQL, PHP) stack. AWS instances already have SSH set up, so I start by making sure that SSH is running.
Most of the commands I use have to be run in super-user mode, so I start by doing:
$ sudo su
If you do not want to switch to super-user mode, then simply prepend sudo in front of the commands below.
$ systemctl status ssh
This article has useful information on how to safely modify our SSH configuration file and more importantly, how to check our SSH configuration to make sure it is ok before restarting our SSH server. This is important because if we lose our SSH server, we lose our only way of reaching our AWS EC2 instance.
1. Create an SFTP User
$ adduser sftp_user Adding user `sftp_user' ... Adding new group `sftp_user' (1001) ... Adding new user `sftp_user' (1001) with group `sftp_user' ... Creating home directory `/home/sftp_user' ... Copying files from `/etc/skel' ...
Enter in a secure password even though you will not need to use it in SFTP. This will create a new user with the home directory at /home/sftp_user.
In order to restrict SFTP access to one directory, first, we have to make sure the directory complies with the SSH server’s permissions requirements, which are very particular. Specifically, the directory itself and all directories above it in the filesystem tree must be owned by root and not writable by anyone else. For my Amazon EC2 Ubuntu server I do the following:
$ chown root:root /var/www $ chown sftp_user:sftp_user /var/www/html
Now, I need to edit my SSH configuration file. Before doing so, I first make a copy of it and protect it from being overwritten.
$ cp /etc/ssh/sshd_config /etc/ssh/sshd_config.original $ chmod a-w /etc/ssh/sshd_config.original $ vi /etc/ssh/sshd_config
Go to the end of the file and paste the following:
Match User sftp_user ForceCommand internal-sftp ChrootDirectory /var/www PermitTunnel no AllowAgentForwarding no AllowTcpForwarding no X11Forwarding no
Save, quit, and before restarting we check our configuration:
sshd -t -f /etc/ssh/sshd_config
If no errors show up, we can restart our sshd service.
$ systemctl restart sshd $ systemctl status ssh
2. Create and Install SFTP Keys
Since I use a Windows Desktop at home, I generate my SFTP keys using PuTTYGen. I do this by following step 5 of this article.
Once I have generated my keys, I do the following:
cd /home/sftp_user mkdir .ssh chmod 700 .ssh touch .ssh/authorized_keys chmod 600 .ssh/authorized_keys cd .ssh vi id_rsa.pub
I copy the public key that I generated using PuTTYGen into the id_rsa.pub file. My public key looks something like this
ssh-rsa AAAAQ3NzaC1yc2EAAAABJQAAAQEAioCJQqMqHeqJJqxcg2+LpIkTb4PDbNYvbpVMBj/TeIl+/HIKFlQDl/eU5uF7P1tHCfgs7bZ8cnDi2b5UCgRHXfzSGLgoTHPY5hxAhRRDCymRI08+y2VLqOCgBzqpwifO4sUQ/FtA/naNYb7p1ZI/a9Lc3GGaos2MH73PbYN2X6rfOAe+6DX5Nzx8ND+qp63vndjjAhuaGBiSHdsdsdK1I3eSbAD2Ib82XYoEqFpehYS3tA17yAy08N/pgKrRf2yd3dO/PN/VnICTUJN68/PHGzPS4FDIu4D4+/UxroX5v5KW+nCnJKITGLKSdexAb8oXWY4KlDZ/Rq72Tr1CbMcPf/w== rsa-key-20220101
After doing this, I add my new public key to my authorized_keys file. Then I change file ownership to my sftp_user. From the .ssh directory I do:
$ cat id_rsa.pub >> authorized_keys $ cd .. $ chown sftp_user:sftp_user .ssh $ chown sftp_user:sftp_user .ssh/* $ chmod 0600 .ssh/id_rsa*
Ultimately, my .ssh directory has the following permissions and ownership:
drwx------ 2 sftp_user sftp_user 4096 Jan 27 01:49 .ssh
The contents of my .ssh directory look like this:
-rw------- 1 sftp_user sftp_user 399 Jan 27 02:00 authorized_keys -rw------- 1 sftp_user sftp_user 399 Jan 27 01:49 id_rsa.pub
We can now test our SFTP connection by opening a cmd window and using psftp:
psftp -i "C:\path\mykey.ppk" sftp_user@your_domain
C:\path\mykey.ppk is where we saved our private key that we generated with PuTTYGen previously.
I also use WinSCP to download and upload files to and from my Amazon EC2 server so I also create and test a WinSCP connection here. To do this, I open WinSCP. I click on New Site to the left, and fill in the particulars in the Session Screen.
I can now click the Save button to save the information that I have. I name my new SFTP configuration and click OK.
Finally, I want to enter in the private key that I created using PuTTYGen earlier.
- I click on Edit to edit my newly saved configuration.
- I click on Advanced which opens up an Advanced Site Settings pop-up window.
- I click on Authentication on the left.
- In the Authentication parameters to the right, there is a Private key file field. This is where I need to enter my PuTTYGen private key.
- I click on the … button and navigate to where I saved my PuTTYGen private key.
- I select the key and click OK.
- I click Save to save my updated configuration.
- I click Login to test my new SFTP connection.
3. Enable SFTP on WordPress
To enable SFTP on WordPress we need to provide BOTH our SFTP public and private keys. DO NOT do this in the .ssh directory we set up previously. The previous directory has very limited permissions to bolster security. The WordPress keys will need to be readable by our web server.
I create two files in my sftp_user home directories:
- id_rsa.pub contains the public sftp_user key I created earlier.
- id_rsa contains the private sftp_user key I created earlier.
I change the ownership and permissions of those two files as follows:
chown sftp_user:www-data /home/sftp_user/my_wp_keys_dir/id_rsa* chmod 0640 /home/sftp_user/my_wp_keys_dir/id_rsa*
Example Private Key
-----BEGIN RSA PRIVATE KEY----- MIIEoQIBAAKCAQEAlFoQjkQzymsyWItMIGAS7OedjZc5pcx+cMOONp65T8TKw+qL NEjeuV4T4VslE0FwsLffDHtGlrvfRa9hIw14wfy8GH31ZVUa7if0B+lJyz+cEQsL fHnjRyOD65oGQZHAguMzvDiUei0n8LeAJdBTOyG+w5ac+gW15SttOspVpWZmwHFE iCzdBqs5oNhLE19QybLL3ZaoWIbfMVhvH5KsbuGTI4wmkcC5rUwYrs7rxAIBKXKV 3D6QAyw4DwSj67Y85nusyTeK0sReN3mhiniJyR4tR02LkgHDpOSd7adgxUkx2lvM h0tbS04/b3C5pv6U3uD3FNlunl1sIS8gEIh4mQIBJQKCAQB4SQaBMGFYA+OhvQ1K rsM8oB7hgYiv8en6kLh/UEM5wifdHwkVot4ZweabC6GFO/qBcn1/veY1BwgO/Ob5 05JYGQP4Lsb4NyqXlgQiFxk9AySYMngED80JP2QLIvBQ1wrK/Wg3vyxHYuIdHymi HoisfDnPBH9HQuaCdjzjj0xclvdy6Tti1QQa9XROshHgbwWFv2uK76IlnLhvX+BI z7X9G3MH3sHOA+cFfagqOeU1RUitTyGjzRSzaZ3ltBDki7pwtjxlGDSS8Vxn9tji lJUCgYBNYwsdn7GKN/U1UJ8z8liDMoSORPbFipEZWOc3mNG6XE1ar7lWvueMmdmw 47+Wm+Uk1GOARIAObhmisoIekufO0PvOxlrG21trjjHja4Wfjvso9GIPYcLmwD5X 8QtwID/NlD7UfMFrnnKSlcRjnIuQwEiND8hR/iRqMY1CpLUPQQ== -----END RSA PRIVATE KEY-----
Finally, I add the locations of those keys to my wp-config.php file, below the line that says: /* Add any custom values between this line and the “stop editing” line. */
/* Add any custom values between this line and the "stop editing" line. */ define('FTP_PUBKEY','/home/sftp_user/my_wp_keys_dir/wp_rsa.pub'); define('FTP_PRIKEY','/home/sftp_user/my_wp_keys_dir/wp_rsa'); define('FTP_USER','sftp_user'); define('FTP_PASS',''); define('FTP_HOST','127.0.0.1:22');
Remember to set your wp-config.php file permissions to 440 or 640. It should not be readable by the public.
For more details on setting up permissions for your WordPress site check out this Rackspace article or this WordPress article.
Congratulations! WordPress should now work with your SFTP keys for installing themes and plugins.
Common SSH WordPress Errors
If you want to use SSH2 in WordPress you may need to install the php-ssh2 module. I do:
$ apt install php8.1-ssh2 $ php -m | grep ssh2 $ systemctl reload apache2
If you continue to run into problems go to /etc/php/mods-available/. See if ssh2 is listed there. Sometimes an incorrect version may have been installed making it unavailable to your version of php. You can also try the following:
$ dpkg --list | grep ssh2
dpkg –list show all the packages installed, and grep looks for ssh2 out of that list.
This article has a lot more on listing installed and available packages on our ubuntu server. If all the proper packages are installed but SSH2 is still not available, then this article may help.