• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

Jonathan Dingman

Dad, Product Guy, WordPress, SEO, and TailwindCSS.

  • SEO
  • Google
  • Google Sheets
  • WordPress
  • About Jonathan

Jonathan DOT VC » Tech » WordPress Tutorial: Using SSH to Install/Upgrade

WordPress Tutorial: Using SSH to Install/Upgrade

February 9, 2009 by Jonathan Dingman

This tutorial will guide you step by step on how to setup your server so you can install new plugins and upgrade existing plugins using an SSH2 layer in PHP and WordPress.

What is WordPress?
WordPress started in 2003 with a single bit of code to enhance the typography of everyday writing and with fewer users than you can count on your fingers and toes. Since then it has grown to be the largest self-hosted blogging tool in the world, used on hundreds of thousands of sites and seen by tens of millions of people every day.

What is SSH[2]?
SSH (Secure Shell) is a protocol allowing a secure channel to be established between a web server and a client’s local machine. Many web hosting companies now offer SSH for greater security.


Tutorial Pre-requisites

There are a few things that need to be in place before you can actually use this tutorial.

The first thing to do is make sure you have SSH2 installed via pecl. If it’s not installed or you’re not sure, run this command: pecl install ssh2

note: If your case is where the installed version of SSh2 is beta, run this command instead: pecl install channel://pecl.php.net/ssh2-0.11.0

If you don’t feel comfortable running these commands yourself and you know of a server administrator that can help, or you’re paying for managed services, ask them to install this for you.

After SSH2 is installed, follow these instructions to ensure that the SSH2 extension is enabled in PHP. Again, if you are using managed services, simply ask them to do this for you.

Ubuntu/Debian
cd /etc/php5/conf.d; echo “extension=ssh2.so” > ssh2.ini
/etc/init.d/apache2 restart
Red Hat, CentOS, Fedora
cd /etc/php.d; echo “extension=ssh2.so” > ssh2.ini
/etc/init.d/httpd restart

Step 1: Generating the server-side RSA keys

ssh-keygen

Generating public/private rsa key pair.
Enter file in which to save the key (/home/user1/.ssh/id_rsa):
Created directory ‘/home/user1/.ssh’.
Enter passphrase (empty for no passphrase): (just hit enter, no need for a password)
Enter same passphrase again: (same thing, hit enter again)
Your identification has been saved in /home/user1/.ssh/id_rsa.
Your public key has been saved in /home/user1/.ssh/id_rsa.pub.
The key fingerprint is:
xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx [email protected]

The xx:xx:xx etc. will be replaced with your actual fingerprint.

Step 2: Creating an ‘authorized_keys’ file

cd .ssh
cp id_rsa.pub authorized_keys

Step 3: Setting the proper file permissions

cd ~/
chmod 755 .ssh
chmod 644 .ssh/*

Step 4: Choosing the ‘SSH’ option

In this tutorial, I opted not to use a password, so you do not need to enter a password.

Step 5: Click “Proceed”

The last step is to click the proceed button and it will install a new plugin or upgrade an existing plugin via the integrated SSH layer in WordPress. You should see results something like this…

== Optional ==

If you want to automate the process a bit more, there are a few more things you can do to make it even easier.

If you open up your wp-config.php and add these lines, it will make the process smoother.

define('FTP_PUBKEY','/home/user1/.ssh/id_rsa.pub');
define('FTP_PRIKEY','/home/user1/.ssh/id_rsa');
define('FTP_USER','user1');
define('FTP_PASS','');
define('FTP_HOST','server1.example.com:22');

Now, when you click “upgrade” or “install” on a new plugin, it will bypass the first screen you saw above asking for the details. It will automatically go into the process and start the install/upgrade.

Thank you

A huge thanks to Dion Hulse and Matt Martz for helping me with creating this tutorial.

Related Posts:

  • accordion-mockup
    How Accordion UX Impacts SEO: Pros, Cons, and Best Practices
  • openx-logo
    OpenX Advanced Targeting Using WordPress
  • schema-org-structured-data-validator
    Leveraging Structured Data Schema.org Markup for…
  • argetina-waterfalls-rainbow
    How to Setup a VAST/VPAID Waterfall with VideoJS

Filed Under: Tech Tagged With: WordPress

Reader Interactions

Comments

  1. Dan says

    May 6, 2009 at 10:13 am

    Hello there,

    Just thought i’d let you know that, for me anyway, creating an .ini file under /etc/php5/conf.d did not work for me. I had to add the extension to /etc/php5/apache2/php.ini as mentioned in this post http://devioustree.co.uk/2009/02/21/auto-update-wordpress-with-sftp/

    But thanks for the other information about setting this up

    Dan

  2. Weave says

    May 25, 2009 at 10:54 pm

    I had a devil of a time to get this work with a public/private key, but finally got it working.

    First off, the page at http://codex.wordpress.org/Editing_wp-config.php has a horrible error in that it says to use FTP_PRIVKEY and not FTP_PRIKEY — you have it right on your page, but I had previously edited the file using info from the Codex and didn’t catch it for hours.

    Second, my passphrase is empty but keeping password blank didn’t work. I had to put SOMETHING in it, didn’t matter what. Bizarre.

    Finally, a suggestion, no need to open up your .ssh dir to be readable by all. Just append the appropriate .pub contents to the accounts authorized_keys file, then park both the private and public key in some obscure place that the apache process can read.

    Thanks for the post. It was very helpful — unfortunately I trusted the wordpress codex page 🙁

  3. Alberto Guzmán says

    June 12, 2009 at 5:46 am

    Thanks for this complete and very well explained tutorial 😉
    Have fun!

  4. Forest says

    June 16, 2009 at 1:18 am

    I’m getting an error after pressing “proceed”:

    “Public and Private keys incorrent for (my username)”

    I’ve checked and double checked my paths and permissions. The hostname and username matches those listed in the id_rsa file. I am completely stumped as to what the issue is.

    Any thoughts?

  5. Tony says

    June 25, 2009 at 11:57 am

    Those are terrible permissions for you .ssh directory and keys

    • Steve says

      January 15, 2010 at 9:24 am

      I absolutely agree giving “Other” read access to your private key is a huge security issue. Unfortunately it seems like the WordPress Developers require you to keep this “private” key accessible by apache!

      What does this mean? It means that anyone with access to your server, legitimate or otherwise, will now have access to login to the user which has access to your WordPress directory and your WordPress SQL Database username, password, and location.

      What should I do? It almost seems like FTP could be more secure in this case, but if you really want to use SSH here are my recommendations:

      First: USE A PASSPHRASE, and make it strong (1), this way anyone who finds your “private” key won’t instantly have access to your server.

      Second: Don’t change the permissions of your .ssh folder, apache only needs access to these two files, put them somewhere else, but NOT IN A WEB DIRECTORY! The .ssh folder should be 700 and files 600 (2).

      Third: Don’t keep id_rsa readable by everyone when it doesn’t need to be. If you need to upgrade wordpress change its permissions to 644, upgrade, and then change it back to 600.

      Fourth: (security through obscurity) Don’t keep the file named id_rsa. If I were a hacker with unprivileged access to a wordpress server, after reading this article (and others like it), my first command would be:

      find / -name id_rsa 2>/dev/null

      Which would point me to any files named id_rsa on the server.

      Rick, in the post below, mentions that CentOS’s Apache install won’t let itself view ~/.ssh/ and that’s because CentOS knows this is a horrible idea!

      Instead of all of this, why not just setup an FTP daemon that only accepts traffic from localhost?

      References:
      1) http://www.utexas.edu/its/secure/articles/keep_safe_with_strong_passwords.php
      2) http://www.linuxforums.org/articles/file-permissions_94.html

  6. Rick Winkler says

    June 28, 2009 at 1:06 pm

    I could not get Apache (Centos 5.3) to allow the key files to be read when left in the given user’s home directory. I had to create a new directory in /var/www and copy the files there to be read. So I have:

    /var/www/ssh/(username).id_rsa
    /var/www/ssh/(username).id_rsa.pub

    Other than that, it works perfectly.

  7. Jonathan Dingman says

    July 5, 2009 at 8:31 pm

    @Weave, Thanks for the note. I corrected it on codex.wordpress.org so it’s correct now.

    Even if it’s readable by all, the webserver can’t access it because it’s outside of the readable directory of public_html for the good majority of users. I’ll take it into consideration when I write a second version of this tutorial, Thanks Weave!

    @Tony, alright. If they’re such terrible permissions, what do you recommend? It would be a lot more helpful to everyone if you offer a suggestion instead of just saying they’re bad. Saying they’re bad doesn’t help anyone.

    @Rick, thanks for the tip! I wrote this tutorial based on what I had access to, so I haven’t tested it in too many environments yet. I’ll add your details when I write a second version.

    Thanks everyone for the tips and suggestions and feedback, glad you guys are liking the tutorial!

  8. Nicolas Ward says

    July 21, 2009 at 6:35 pm

    I haven’t been able to get this working… as far as I can tell, it’s silently dying while unzipping a plugin package. I’m pretty sure I have the key file issues ironed out (thanks to your post), because wp-content/upgrade/ is getting created. The plugin’s update page loads for a long while, and then hangs, with an incompletely rendered menu on the left and blank content. Any ideas where I should look? I poked around in the PHP, but didn’t see anything immediately obvious, and no error is being returned.

    • Jonathan Dingman says

      July 27, 2009 at 10:19 pm

      What web server are you running? What version of PHP? Do you have the SSH2 installed in Apache?

      Try to give me as many details as possible and I’d be happy to help you try to debug it.

      • Nicolas Ward says

        February 17, 2010 at 2:35 pm

        Came back to this after a long hiatus (and just doing manual updates).

        The error the upgrade tool gives is “There was an error connecting to the server, Please verify the settings are correct.”

        I’ve confirmed that my public key works from the command line by doing:

        sudo su www-data
        ssh -i /path/to/private/id_rsa user@host

        (Although first I had to give www-data write permissions to /var/www/.ssh/known_hosts.)

        If I run with FTP_PASS empty, I get the error from the upgrade page and nothing in /var/log/auth.log. If I run with a random FTP_PASS, I get “Did not receive identification string from 192.168.1.1”.

        Version info:

        Server version: Apache/2.2.14 (Debian)
        Server built: Jan 2 2010 23:02:48
        OpenSSH_5.3p1 Debian-1, OpenSSL 0.9.8k 25 Mar 2009

        I have /etc/php5/conf.d/ssh2.ini set up as per your instructions.

  9. Alberto Guzmán says

    July 23, 2009 at 12:20 am

    Hi!, thanks for the tutorial 😉
    It worked fine, for updating plugins but there was a bug for updating the core.
    I left the time pass but now, i get an error


    Unable to locate WordPress directory.
    Installation Failed

    Which is weird, because now even plugins has the same error when upgrading ;(.
    Any idea of what causes that?

  10. Jonathan Dingman says

    July 27, 2009 at 10:09 pm

    @Alberto, I’ve seen that issues before and when I experienced it, it was directly related to the permissions. Make sure the permissions are set properly on the .ssh folder itself and the files inside of .ssh

    Run through the tutorial again to ensure you didn’t make any mistakes along the way.

  11. Calvin Robinson says

    August 6, 2009 at 1:37 pm

    Hey,

    I’ve run through this tutorial many times.

    I have ssh2 installed, but I don’t think php is loading the module because when I run the following script I get the message ssh2 is not installed:

    When viewing WordPress’ upgrade page, I see the option for FTP and not SSH, even though my wp-config has ssh information as per your tutorial. Very odd

    • Jonathan Dingman says

      August 6, 2009 at 6:47 pm

      Calvin,

      My tutorial on installing SSH2 isn’t very in-depth, although I may try to include a few more options in the future. Right now, I’d suggest just doing a Google search to see if that can help you out. Google -> “installing ssh2 apache” might help you.

  12. David Cramer says

    August 13, 2009 at 2:30 pm

    If you already use SSH keys (like many do) simply run this line instead:

    `cat id_rsa.pub >> authorized_keys`

    You also will want to enable the extension in apache2, which you can do with:

    `cd /etc/php5/apache2/conf.d; echo “extension=ssh2.so” > ssh2.ini`

  13. Robert Buzink says

    September 3, 2009 at 7:36 am

    If there is not already a directory ‘authorized_keys’ in the .ssh folder (as was the case with me), the command ‘cp id_rsa.pub authorized_keys’ will create a file called ‘authorized_keys’ instead of copying the file ‘d_rsa.pub’ to the ‘authorized_keys’ directory.

  14. Robert Buzink says

    September 3, 2009 at 7:41 am

    Are the keys necessary? Can’t you just login with a password and username if that’s the way you connect to your server through ssh normally?

  15. etienne says

    September 27, 2009 at 3:32 pm

    hello

    Thanks for this tutorial. I a
    I am already using ssh authentification through public/private key files to log into my dedicated server.
    It means that only the public key file is stored on my server while the private key file remains on the client I am connecting from.

    Thus I am surprised to see that, with this method, both the private and the public key files are stored on the remote directory.

    Does not it create a security issue ?
    etienne

    • Jonathan Dingman says

      September 27, 2009 at 3:50 pm

      I haven’t seen any security issues with it since the folder where the keys reside are not web server accessible.

      If you see any security problems with it, I’m open to suggestions and/or corrections. So if you have something to contribute to it, please do.

  16. prazetyo says

    November 9, 2009 at 5:38 am

    I already try this, and nothing error message show up. But when I try to insert you code at wp-config.php, at my Connection Information there no SSH at my type Connection. If I remove the code from my wp-config.php, everytime I insert my password, the error say : Failed to connect to FTP Server xxx.xxx.xxx.xxx:22

    Please advice

    • prazetyo says

      November 18, 2009 at 8:24 pm

      I already try again and it running well. I can upgrade all my plugins. But it still can’t upgrade the wordpress core. Always show error :

      Downloading update from http://wordpress.org/wordpress-2.8.6.zip.

      Unpacking the update.

      Could not copy file: /home/stikomedu/public_html/wp-content/upgrade/wordpress-2.8.6/wordpress/wp-includes/js/codepress/engines/khtml.js

      Installation Failed

      Please help me.

      Thank you

      • Jonathan Dingman says

        January 8, 2010 at 6:18 pm

        Prazetvo, this happens from time to time, it’s a weird bug. I haven’t been able to figure it out yet. I just upload normally and then the next time, it works just fine. I haven’t been able to consistently reproduce the bug yet.

  17. Nate Thelen says

    January 8, 2010 at 6:10 pm

    I have been looking online for some description to how the plugin upgrade process works so I can understand it better. The main reason is that I do not understand why this process is necessary. When I click the upgrade button shouldn’t PHP (wordpress) be able to download the plugin, extract it, and drop it into the plugin folder without the need for all this? Is it that php is running under the apache user and people do not want to make the plugin folder writable to the apache user?

    • Jonathan Dingman says

      January 8, 2010 at 6:17 pm

      Nate, the reason for this is because now all web hosts are setup properly to do that. Some web hosts, what you described works just fine. Often, it will not, for security reasons. If permissions are too open, someone could hack your site — so these are security precautions in place to prevent that.

      I’ll be writing a follow-up post soon about permissions and users, making it even easier to upgrade.

      • Scott Lee says

        July 24, 2011 at 12:01 pm

        Hey Jonathan, has there been an update to this yet? I’ver searched WPVibe and came up empty.

        • Jonathan Dingman says

          July 28, 2011 at 1:40 pm

          Sorry, nope, no follow-up on this.

          WordPress 3.2 actually made HUGE improvements to the upgrade system so it should be easier to follow and setup now.

  18. jldugger says

    January 26, 2010 at 6:31 pm

    Quick note, I see that libssh2-php is packaged in Ubuntu, so you can install that and skip the PEAR step if you have access to apt. It handles everything you listed, just reload apache after installing it.

  19. jldugger says

    January 26, 2010 at 7:10 pm

    Second note, giving your private key world read permission is VEEEERY not good. Anyone else with access to the server will be able to read it. I’m also not clear on why you need both the private and public key.

    While I don’t like the idea of consultants / experts demanding people point out how to fix it or shut up, I’ll take a stab at it.

    1. Read http://wiki.hands.com//howto/passphraseless-ssh/ . Not all of it can be applied, but it’s good to start with best practices.
    2. Determine the task that needs to be done; I gather the purpose is to transfer from wp-uploads to wp-content in situations where the web server is running with insufficient permissions.
    3. Restrict the SSH key to ‘from=localhost.’
    4. Perhaps write a local script to do this, and restrict the key to only that script with command=.
    5. Perhaps change the group key to something relevant; debian uses www-data as a group for webserver users.

  20. Brent says

    February 5, 2010 at 1:25 am

    @ jldugger I removed the read permission for the world on the private key (kept user and group permission) and seems to work fine still.

  21. Matt Dunlap says

    August 9, 2010 at 7:20 pm

    Have you tried with the FS_METHOD in wp_config.php? I use SSH for automatic upgrades and set the FS_METHOD to “direct”. No login and still uses SSH…

  22. Erick says

    April 28, 2011 at 11:05 pm

    You may want to indicate that most people will NOT have libssh2 installed, which means that simplistic looking pecl update will fail.

    —
    error: The required libssh2 library was not found. You can obtain that package from http://sourceforge.net/projects/libssh2/
    ERROR: `/root/tmp/pear/ssh2/configure –with-ssh2′ failed
    —

    How does one install libssh2?

  23. John Adams says

    May 2, 2011 at 2:04 pm

    It’s extremely dangerous to make your private key mode 644.

    Advising users to do this is terrifically bad security-wise.

    Making a copy of the key and making that key readable by the user that the web server runs as is marginally more secure, but still not a great solution.

    One option would be to create a new set of keys (outside of .ssh) readable only by the web server user, and adding that key to the authorized_keys file of the user you are trying to log in as.

  24. Caroline says

    March 15, 2012 at 7:46 pm

    What should I do if I get stuck at unpacking updates? I did get the SFTP radio to show up, so I think things installed correctly.

    • Jonathan Dingman says

      March 15, 2012 at 7:50 pm

      I’ve had that issue before, I would try just refreshing the page. I haven’t seen a refresh, do any harm. But still be careful.

      As always, backup backup backup, before doing any upgrades.

  25. Mike says

    April 21, 2012 at 11:35 pm

    I’ve had this page bookmarked for years, but have recently been switching to nginx on my VPS’. Can you add a new post or add a section for doing this using nginx?

    • Jonathan Dingman says

      April 25, 2012 at 3:00 am

      Hi Mike,

      Thanks for the comment. No plans as of right now to develop any code for Nginx.

Primary Sidebar

Jonathan "Jon" Dingman

Welcome to my little corner of the interwebz!

My name is Jonathan.

Recent Posts

  • [Humor] Giving Excel a September 10th rating.
  • Mastering Alphabetization in Google Sheets: A Step-by-Step Guide
  • 100% Free & Simple Full Site Caching at the Edge with Cloudflare
  • Leveraging Structured Data Schema.org Markup for Paginated eCommerce Category Pages
  • How Accordion UX Impacts SEO: Pros, Cons, and Best Practices
  • How to Create a Dropdown List in Google Sheets
  • Sparklines: The Pocket-Sized Warriors of Google Sheets for Quick Data Insights
  • Google Sheets and Data Analysis: Interpreting Zeroes
  • The Ultimate Guide to Dynamic Drop-Down Lists in Google Sheets
  • Google Sheets Best Practices: Perfecting Data Entry with Advanced Validation Techniques
  • Coloring By Numbers in Google Sheets: Making Zeros Disappear
  • 12 Easy to use Features of Google Analytics
  • Self-hosting WordPress: Looking at WordOps vs SlickStack
  • How I Setup a WordPress Cron Job Using AWS Lambda
  • Using Cloudflare, an Amazon Load Balancer, with Nginx and Fail2Ban
  • How to Automate WordPress Backups to Amazon S3 with a Bash Script
  • How to Track Light/Dark Mode in Google Analytics through Google Tag Manager
  • How to Track Ad Block Usage in Google Analytics through Google Tag Manager
  • How to Setup a VAST/VPAID Waterfall with VideoJS
  • How to Return an Empty Cell When the Value is Zero in Google Sheets

Friends

  • Dre is awesome
  • Rareform – Best Upcycled and Recycles Bags

Powered by DigitalOcean
Copyright © 2025

  • Sitemap
  • Privacy
  • Terms