Using SSH instead of FTP for WordPress updates

Under certain server configurations and conditions, WordPress may require an FTP connection to retrieve and process core, plugin, and theme updates.  If you only see an option for FTP on this screen, do not despair.  You are not alone!  If a server is without the libssl2 library and PECL’s ssh2 package, the SSH2 option will not be listed.  While there are WordPress plugins that mimic this capability using various PHP libraries, implementations at the server level often provide better security and performance.

  1. Download libssh2 (C library implementing SSH2 protocol)
  2. At the command line, type the following
    # Unzip the libssh2 archive
    tar -xf libssh2-1.4.3.tar.gz
    
    # Change directory to libssh2 source
    cd libssh2-1.4.3
    
    # Compile libssh2
    ./configure
    make && make install
    
    # Install ssh2 PECL library
    pecl install ssh2-beta
    

After that, the SSH2 option should appear on the WordPress update screen.
WordPress SSH updates

How to get client IP with PHP behind AWS Elastic Load Balancer

If a PHP application server is located behind Amazon Web Service’s Elastic Load Balancer, or another type of proxy server, it is likely that the traditional mechanism for retrieving the end user’s IP address will not work as expected.  As the request passes through the server, the REMOTE_ADDR key of the $_SERVER variable changes to that of the load balancer; however, all is not lost.  In particular, using the AWS Elastic Load Balancer results in the client IP being transferred to another key in the $_SERVER variable—HTTP_X_FORWARDED_FOR.

The code to find the correct IP address is quite simple:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR']) {
    $clientIpAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
    $clientIpAddress = $_SERVER['REMOTE_ADDR'];
}

Keep in mind, we have made no considerations for IP spoofing. As always, ensure you protect yourself with a variety of security techniques.

Preparing an SSL certificate for use with AWS Elastic Load Balancer

Today I was tasked with re-keying our SSL certificate in preparation for the implementation of Amazon Web Service’s Elastic Load Balancer service.  In order to properly implement the load balancer into our existing architecture, it must be able to handle SSL connections.  We current employ GoDaddy’s Premium SSL Certificate, which gives you the familiar green bar in the address bar of your browser.  After copying and pasting the private key, certificate, and certificate chain data into the provided inputs, Amazon returned the following message: “Invalid private key.”

When I generate SSL certificate signing requests, I generally use the following command:

openssl req -new -newkey rsa:2048 -nodes -keyout yourdomain.key -out yourdomain.csr

Unfortunately, the resultant format is not compatible with AWS’s Elastic Load Balancer.  In order to counter the “Invalid private key” error, I issued the following commands:

openssl genrsa -des3 -out yourdomain.key 2048
openssl req -new -key yourdomain.key -out yourdomain.csr

After that, copy and paste the CSR contents into the CSR input provided by GoDaddy.  After doing this, I attempted to restart Apache HTTP Server, and noticed the following errors in /etc/httpd/logs/error_log.

[Mon Oct 07 17:55:24.779930 2013] [ssl:emerg] [pid 23786] AH02204: Init: Pass phrase incorrect for key of yourdomain:443
[Mon Oct 07 17:55:24.779981 2013] [ssl:emerg] [pid 23786] SSL Library Error: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag

[Mon Oct 07 17:55:24.780076 2013] [ssl:emerg] [pid 23786] SSL Library Error: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag
[Mon Oct 07 17:55:24.780093 2013] [ssl:emerg] [pid 23786] SSL Library Error: error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error (Type=PKCS8_PRIV_KEY_INFO)

Unfortunately, the new private key required a passphrase and Apache didn’t like that. While there are a number of approaches to resolve the issue between Apache and private key passphrases, I chose to remove it, both for the sake of simplicity, and because the Elastic Load Balancer will not accept a private key containing a passphrase. To remove the passphrase, use the following command:

openssl rsa -in yourdomain.key -out yourdomain.key.nopass

At this point, the HTTP server can be restarted, and the SSL certificate’s private key will work with Amazon Web Service’s Elastic Load Balancer.

Redirect from base URL using Apache HTTP Server

What I was trying to accomplish was quite simple—redirection from the base URL (e.g. http://webjawns.com) to a specified path within the same domain.  Even with a lot of experience, one can easily fall prey to assumptions about proper Redirect usage.  Instead of working as expected, the code below caused the repeated concatenation of the destination URL term (“tools” in this example).

# The WRONG way to redirect from the base URL
Redirect / /tools
Redirect / http://webjawns.com/tools

Traditionally, the Redirect directive is used as a simple method of redirection from one page to another. In the following example, the HTTP server will redirect the end user from old-index.html to new-index.html.


# Redirect from old-index.html to new-index.html
Redirect /old-index.html /new-index.html

If there is a way to use a Redirect directive to accomplish redirection from the base URL, I have not figured it out. To solve this problem, I used the rewrite engine, which works flawlessly.


RewriteEngine On
RewriteRule ^/$ http://tools.caffeinatedaviator.com/xgoflight [R=302,L]

Benchmark: Amazon EC2 vs. GoDaddy VPS

I recented started looking into Amazon EC2 as a potential replacement for my GoDaddy VPS servers, specifically for serving basic PHP-driven web sites. I used the standard ./Run command for UnixBench to obtain the results.  The GoDaddy VPS seems to deliver benchmark results closer to the dedicated server numbers I’ve seen, so I’m a little skeptical.  Also, remember that these tests do not consider network or database performance.  The results merely show raw performance metrics for general system functions, the filesystem, and processing.  The pricing for the AWS m1.small on-demand instance is close to that of the m1.medium high utilization reserved instance, and GoDaddy’s Value VPS.

Amazon EC2 (m1.small)

1 CPU; 1 parallel process

Test Score Unit Time Iters. Baseline Index
Dhrystone 2 using register variables 10319739.8 lps 10.0 s 7 116700.0 884.3
Double-Precision Whetstone 598.2 MWIPS 10.0 s 7 55.0 108.8
Execl Throughput 503.4 lps 29.9 s 2 43.0 117.1
File Copy 1024 bufsize 2000 maxblocks 99004.0 KBps 30.0 s 2 3960.0 250.0
File Copy 256 bufsize 500 maxblocks 26650.5 KBps 30.0 s 2 1655.0 161.0
File Copy 4096 bufsize 8000 maxblocks 320858.3 KBps 30.0 s 2 5800.0 553.2
Pipe Throughput 136761.9 lps 10.0 s 7 12440.0 109.9
Pipe-based Context Switching 27738.9 lps 10.0 s 7 4000.0 69.3
Process Creation 995.9 lps 30.0 s 2 126.0 79.0
Shell Scripts (1 concurrent) 798.2 lpm 60.0 s 2 42.4 188.2
Shell Scripts (8 concurrent) 107.8 lpm 60.1 s 2 6.0 179.6
System Call Overhead 114607.8 lps 10.0 s 7 15000.0 76.4
System Benchmarks Index Score: 164.4

Amazon EC2 (m1.medium)

1 CPU; 1 parallel process

Test Score Unit Time Iters. Baseline Index
Dhrystone 2 using register variables 20679983.9 lps 10.0 s 7 116700.0 1772.1
Double-Precision Whetstone 1203.0 MWIPS 10.0 s 7 55.0 218.7
Execl Throughput 1007.9 lps 29.8 s 2 43.0 234.4
File Copy 1024 bufsize 2000 maxblocks 200955.9 KBps 30.0 s 2 3960.0 507.5
File Copy 256 bufsize 500 maxblocks 52142.0 KBps 30.0 s 2 1655.0 315.1
File Copy 4096 bufsize 8000 maxblocks 645663.0 KBps 30.0 s 2 5800.0 1113.2
Pipe Throughput 271624.2 lps 10.0 s 7 12440.0 218.3
Pipe-based Context Switching 49830.7 lps 10.0 s 7 4000.0 124.6
Process Creation 2039.6 lps 30.0 s 2 126.0 161.9
Shell Scripts (1 concurrent) 1635.5 lpm 60.0 s 2 42.4 385.7
Shell Scripts (8 concurrent) 221.6 lpm 60.2 s 2 6.0 369.4
System Call Overhead 221863.8 lps 10.0 s 7 15000.0 147.9
System Benchmarks Index Score: 327.1

GoDaddy VPS (Value)

8 CPUs; 1 parallel process

Test Score Unit Time Iters. Baseline Index
Dhrystone 2 using register variables 9835137.0 lps 10.0 s 7 116700.0 842.8
Double-Precision Whetstone 1950.9 MWIPS 10.0 s 7 55.0 354.7
Execl Throughput 2848.4 lps 29.5 s 2 43.0 662.4
File Copy 1024 bufsize 2000 maxblocks 349825.6 KBps 30.0 s 2 3960.0 883.4
File Copy 256 bufsize 500 maxblocks 110633.5 KBps 30.0 s 2 1655.0 668.5
File Copy 4096 bufsize 8000 maxblocks 826791.7 KBps 30.0 s 2 5800.0 1425.5
Pipe Throughput 729108.2 lps 10.0 s 7 12440.0 586.1
Pipe-based Context Switching 139871.3 lps 10.0 s 7 4000.0 349.7
Process Creation 6944.0 lps 30.0 s 2 126.0 551.1
Shell Scripts (1 concurrent) 2804.8 lpm 60.0 s 2 42.4 661.5
Shell Scripts (8 concurrent) 1118.6 lpm 60.0 s 2 6.0 1864.4
System Call Overhead 574243.2 lps 10.0 s 7 15000.0 382.8
System Benchmarks Index Score: 674.6

8 CPUs; 8 parallel processes

Test Score Unit Time Iters. Baseline Index
Dhrystone 2 using register variables 64631491.4 lps 10.0 s 7 116700.0 5538.3
Double-Precision Whetstone 15359.3 MWIPS 10.2 s 7 55.0 2792.6
Execl Throughput 13342.2 lps 29.5 s 2 43.0 3102.8
File Copy 1024 bufsize 2000 maxblocks 299406.7 KBps 30.0 s 2 3960.0 756.1
File Copy 256 bufsize 500 maxblocks 91395.5 KBps 30.0 s 2 1655.0 552.2
File Copy 4096 bufsize 8000 maxblocks 720403.8 KBps 30.0 s 2 5800.0 1242.1
Pipe Throughput 4444252.9 lps 10.0 s 7 12440.0 3572.6
Pipe-based Context Switching 1509897.0 lps 10.0 s 7 4000.0 3774.7
Process Creation 32437.4 lps 30.0 s 2 126.0 2574.4
Shell Scripts (1 concurrent) 13964.5 lpm 60.0 s 2 42.4 3293.5
Shell Scripts (8 concurrent) 1931.7 lpm 60.3 s 2 6.0 3219.5
System Call Overhead 2955368.4 lps 10.0 s 7 15000.0 1970.2
System Benchmarks Index Score: 2263.1