Posts Tagged VirtualHost

Ubuntu, Apache, VirtualHosts, and SSL – part 2

In my first post about Ubuntu, Apache, VirtualHosts, and SSL I covered generating self-signed certificates and implementing them for Apache VirtualHosts. What I didn’t cover was — if you implemented this without a correct base configuration — you’d end up with some unexpected results if you tried to visit your base domain over SSL.

It’s simple to resolve this. First, edit /etc/apache2/ports.conf and modify as follows:

  
  # If you add NameVirtualHost *:443 here, you will also have to change
  # the VirtualHost statement in /etc/apache2/sites-available/default-ssl
  # to 
  # Server Name Indication for SSL named virtual hosts is currently not
  # supported by MSIE on Windows XP.
+ NameVirtualHost *:443
  Listen 443
  

If you were reading closely, you know what to do next. Modify sites-available/default-ssl file and change the directive as follows:

Now, restart apache:

/etc/init.d/apache2 reload

Your base SSL domain will now display the expected DocumentRoot, but the certificate will contain the URL localhost.localdomain. To fix this run, as root:

make-ssl-cert generate-default-snakeoil --force-overwrite

— From /usr/share/doc/apache2.2-common/README.Debian.gz

If you install the ssl-cert package, a self-signed certificate will be
automatically created using the hostname currently configured on your computer.
You can recreate that certificate (e.g. after you have changed /etc/hosts or
DNS to give the correct hostname) as user root with:

make-ssl-cert generate-default-snakeoil –force-overwrite

Questions, comments, and feedback regarding this guide and welcome!

, , , , ,

Leave a comment

Forcing SSL for phpMyAdmin

After configuring WordPress to force SSL in the administration area, I was in phpMyAdmin and realized that it’s also not configured to do the same by default.

From the phpMyAdmin Wiki, add the following line at the end of your /etc/phpmyadmin/config.inc.php file

$cfg['ForceSSL'] = TRUE;

This will cause sessions to force SSL.

If you’re having issues making this work for you, check out my article involving Apache and SSL.

Questions, comments, and feedback are welcome.

, , , ,

Leave a comment

Forcing the WordPress administration over SSL

From the WordPress administration over SSL guide, add the following directive to your wp-config.php file:

define('FORCE_SSL_ADMIN', true);

This will cause logins and admin pages to force SSL sessions.

If you’re having issues making this work for you, check out my article involving Apache and SSL.

Questions, comments, and feedback are welcome.

, , , ,

Leave a comment

Ubuntu, Apache, VirtualHosts, and SSL

The goal of this guide is to provide you with an Apache SSL configuration with a unique self-signed certificate for each VirtualHost.

These self-signed certificates are not intended for e-commerce or public-facing web sites. Rather, they are intended for SSL encryption of administration areas on personal websites or administration programs that have HTTP interfaces. Of course, if you have a commercially-signed certificate, you can skip the certificate-generation part of the guide, and proceed to implementing it in a VirtualHost configuration.

Written for Apache on Ubuntu Server 10.04.

First, install the base Apache SSL certificate and enable the Apache SSL module

sudo apt-get install ssl-cert
a2enmod ssl

This installs a base SSL certificate and a generic ‘default-ssl’ site configuration. We will be generating per-domain self-signed certificates later. We will also not be using the ‘default-ssl’ site configuration.

Generating Certificates

Generate a hostname-specfic SSL certificate by following these instructions quoted

— From /usr/share/doc/apache2.2-common/README.Debian.gz

To create more certificates with different host names, you can use
make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /path/to/cert-file.crt
This will ask you for the hostname and place both SSL key and certificate in
the file /path/to/cert-file.crt . Use this file with the SSLCertificateFile
directive in the apache config (you don’t need the SSLCertificateKeyFile in
this case as it also contains the key). The file /path/to/cert-file.crt should
only be readable by root. A good directory to use for the additional
certificates/keys is /etc/ssl/private .

Example:

make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/private/example.com.crt

Implementation

Now that the key is generated, we’re going to create an Apache VirtualHost configuration for SSL connection. Chdir to /etc/apache2/sites-available and copy (for example) example.com.conf to example.com-ssl.conf

Next, edit the example.com-ssl.conf file and make the following changes:

* At the beginning of the file (before the tag, add:

Example:


...

* Change the defined port number in the tag from 80 to 443

Example:

...

...

* At the end of the file, after the tag, add

Example:
...

* Within the tag, add the following directives:

SSLEngine On
# The following should point to your SSL cert file in /etc/ssl/private
SSLCertificateFile    /etc/ssl/private/example.com.crt

— From /etc/apache2/sites-available/default-ssl

#   SSL Engine Switch:
#   Enable/Disable SSL for this virtual host.
SSLEngine on
#   A self-signed (snakeoil) certificate can be created by installing
#   the ssl-cert package. See
#   /usr/share/doc/apache2.2-common/README.Debian.gz for more info.
#   If both key and certificate are stored in the same file, only the
#   SSLCertificateFile directive is needed.
SSLCertificateFile    /etc/ssl/certs/ssl-cert-snakeoil.pem

* Add the SSL workaround for MSIE in your section as follows:

BrowserMatch "MSIE [2-6]" 
nokeepalive ssl-unclean-shutdown 
downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown

— /usr/share/doc/apache2.2-common/README.Debian.gz

SSL workaround for MSIE
———————–
The SSL workaround for MS Internet Explorer needs to be added to your SSL
VirtualHost section (it was previously in ssl.conf but caused keepalive to be
disabled even for non-SSL connections):
BrowserMatch “MSIE [2-6]”
nokeepalive ssl-unclean-shutdown
downgrade-1.0 force-response-1.0
BrowserMatch “MSIE [17-9]” ssl-unclean-shutdown
The default SSL virtual host in /etc/apache2/sites-available/default-ssl
already contains this workaround.

Lastly, enable the newly-created site and reload apache:

a2ensite example.com-ssl.conf

Enabling site example.com-ssl.conf.

Run '/etc/init.d/apache2 reload' to activate new configuration!

(This creates the symlink from /etc/apache2/sites-enabled to your config file in /etc/apache2/sites-available – you can also create it manually if your configuration requires it)

/etc/init.d/apache2 reload

* Reloading web server config apache2                                   [ OK ]

Of course, make sure after all of this that your firewall isn’t blocking port 443.

Questions, comments, and feedback regarding this guide and welcome!

, , , ,

2 Comments

WordPress, suPHP, and Ubuntu Server 10.04

If you have WordPress running under an unprivileged user account, you may have noticed that when trying to install or delete a plugin that it prompts you for FTP information. This is due to a rather unintuitive way that WordPress checks for file access:

The following code is from the get_filesystem_method() method in the wp-admin/includes/file.php file:

if( function_exists('getmyuid') && function_exists('fileowner') ){
    $temp_file = wp_tempnam();
    if ( getmyuid() == fileowner($temp_file) )
        $method = 'direct';
    unlink($temp_file);
}

This code creates a temporary file and confirms that the file just created is owned by the same user that owns the script currently being run. In the case of installing plugins, the script being run is wp-admin/plugin-install.php.

This may seem a little counter-intuitive, since the only thing WordPress really needs to be able to do is write to the wp-content/plugins directory.

If you’re on your own server (i.e. your own box or a VPS) and not worried about security implications, you can simply make the files owned by your web server process (usually www-data or nobody). This will have WordPress’ check succeed and no longer ask for your information.

If you’re on your own server and running a shared hosting environment, or just care about the security implications, you should install suPHP.

What are the security implications? If all web files are owned by the web server process, it’s extremely easy for someone to introduce malicious php code which can affect other sites on the server. Since the web server process has access to all of the web server files across the server, malicious code would have no problem gaining access to other files and directories on the server.

suPHP, configured correctly, causes all php scripts under a defined directory (usually /home) to run as the user account they are owned by. It also enforces other security measures, such as requiring that directories and files do not have write permissions for anyone other than the user.

I could go on and on about what it does, but my biggest struggle has been getting it to work. Installation is easy, but it’s painfully clear it does not work out of the box. After dozens of searches I found varying different ways of making it work, but sometimes drastic and not clean nor easy, few didn’t require recompiling something (which I wasn’t going to do), and none of them seemed to work.

After more than a day of searching and testing, I finally came up with a simple, elegant, working solution. Note that this was written and based on Ubuntu Server 10.04 64-bit, and libapache2-mod-suphp 0.7.1-1 and may or may not work for other platforms.

Install suPHP:

apt-get install suphp-common libapache2-mod-suphp

Edit the sites-enabled/xxxx.conf file for your VirtualHost

Inside your directive, add:

php_admin_flag engine off
AddHandler application/x-httpd-php .php .php3 .php4 .php5 .phtml
suPHP_AddHandler application/x-httpd-php
suPHP_Engine on

Lastly, edit /etc/suphp/suphp.conf and under ;Handler for php-scripts (at the bottom) change:

application/x-httpd-suphp="php:/usr/bin/php-cgi"

to

application/x-httpd-php="php:/usr/bin/php-cgi"

Restart apache and all should be well.

/etc/init.d/apache2 restart

Note: You might get an error message like the following:

Syntax error on line 7 of /etc/apache2/sites-enabled/example.com.conf:
Invalid command 'php_admin_flag', perhaps misspelled or defined by a module not included in the server configuration

In this case, check that you actually have the Apache PHP mod installed and enabled. In can get uninstalled or disabled on occasion when upgrading Apache. Here’s how to reinstall/reenable:

sudo apt-get install libapache2-mod-php5
sudo a2enmod php5

Checking that it’s working

Create a phpinfo.php file with the follow contents:

<?php phpinfo(); ?>

Call it via your browser and check the Server API line near the top: CGI / FastCGI means suphp is working. Anything else means it’s not.

Suphp is slow!

Yes, unfortunately suphp is slow. Suphp runs PHP scripts in CGI mode, which reportedly causes them to run slower. I would argue that the security advantages outweigh the need for fast scripts, but each situation is unique. You have to decide for yourself.

500 Internal Server Error

If you’re getting the 500 Internal Server Error, it means that suphp is probably working, but for some reason it won’t allow the script to run.

Check that you don’t have any PHP opcode caching (APC, etc) running. If you are running any type of PHP opcode cache suphp will never work. You must disable your opcode caching. If you’re using APC, you can disable it system-wide by simply editing /etc/php5/conf.d/apc.ini and commenting the line out with a semicolon as follows:

;extension=apc.so

Another element of importance is file permissions. SuPHP will fail (with a 500 Internal Server Error) any file that has permissions which are not allowed, as defined in /etc/suphp/suphp.conf. For example:

; Security options
allow_file_group_writeable=false
allow_file_others_writeable=false
allow_directory_group_writeable=false
allow_directory_others_writeable=false

Any file or directory with the attributes defined as allow=false will fail. Based on the configuration above, any file that is group- or world-writable will automatically fail. Same with directories. It’s best to leave these options alone (instead of changing them), and change the permissions on your scripts instead.

However, it is supposedly possible to disable it on a per-VirtualHost basis. I haven’t tested this.

Also check that your /var/log/suphp/suphp.log file isn’t over 2GB. If it is, rotate it or delete it.

If all else fails, check /var/log/suphp/suphp.log and /var/log/apache2/error.log for hints.

Many thanks to all of the blogs and articles that each held a piece of this puzzle. :)

, , , , , , , , ,

11 Comments