WordPress admin, SSL, Apache + nginx · uwot.eu
another meaningless subtitle

WordPress admin, SSL, Apache + nginx

· by fabio · Read in about 3 min · (518 Words)
Apache CentOS httpd HTTPS linux nginx reverse proxy SSL

Let’s say we have a WordPress blog and we would like to encrypt our login pages and the whole back-end of the site.
There are many ways to do it, but since I already have a nginx instance configured as reverse proxy running in front of Apache I’ll use it to “protect” my admin pages and logins.
In this page I’ll not cover Apache’s configuration, which, by the way, is trivial to say the least, so please refer to this other post: Apache + nginx as reverse proxy.
Using the configuration posted in the above’s link as starting point, to add SSL encryption to admin pages we should add a couple more bunch of lines of code.
First of all, we must create our own Certificate Authority and issue a SSL certificate.
Another option is buying a certificate, but I don’t trust CA (certificate forgery anyone?) and I don’t mind having a properly signed certificate for a page I am the only one accessing to.
Follows a brief explanation on how to create a CA and issue a certificate.

mkdir /etc/nginx/ssl
cd /etc/nginx/ssl
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr   # Common Name=domain_name
# remove password
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
# sign the certificate
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

Now that we have a certificate, we can go back configuring nginx.
We should already have a virtual host file, open it with our favourite editor and add what follows:

# a new server instance, configured to listen to port 443
server {
        listen 443;
        ssl on;
        server_name uwot.eu;

        access_log      logs/ssl-access.log;
        error_log       logs/ssl-error.log;

        ssl_certificate         /path/to/server.crt;
        ssl_certificate_key     /path/to/server.key;

        ssl_protocols        SSLv3 TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers RC4:HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers on;
        keepalive_timeout    60;
        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  10m;


        location /blog/wp-login.php {
                proxy_pass  http://127.0.0.1:8080;

                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

                proxy_set_header        Accept-Encoding   "";
                proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto https; #$scheme;
                add_header              Front-End-Https   on;

                proxy_redirect          off;
        }


        location /blog/wp-admin {
                proxy_pass  http://127.0.0.1:8080;

                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

                proxy_set_header        Accept-Encoding   "";
                proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto https; #$scheme;
                add_header              Front-End-Https   on;

                proxy_redirect          off;
        }
}

# add what follows in the server instance listening on port 80

        location /blog/wp-login.php {
                proxy_pass  http://127.0.0.1:8080;

                rewrite ^ https://$http_host$request_uri? permanent;

                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

                proxy_set_header        Accept-Encoding   "";
                proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto https; #$scheme;
                add_header              Front-End-Https   on;

                proxy_redirect          off;
        }


        location /blog/wp-admin {
                proxy_pass  http://127.0.0.1:8080;

                rewrite ^ https://$http_host$request_uri? permanent;

                proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;

                proxy_set_header        Accept-Encoding   "";
                proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto https; #$scheme;
                add_header              Front-End-Https   on;

                proxy_redirect          off;
        }

One last thing to do is edit WordPress wp-config.php file and add on top of it:

if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
       $_SERVER['HTTPS']='on';

Now WordPress login page and the whole back-end should be HTTPS.
On a side note, I’m facing some minor issues with back-end pages rendering/visualization, I’ll investigate a bit further and report back in case I’ll find something useful.