Setup a wordpress multisite network on AWS EC2 (4)

Update 12/29/2012: I just came across Stephen White’s instruction: It walked through the setting up of FTP service itself on EC2 if you haven’t done that yet.  The valuable part I picked up is forbidding FTPuser to open a shell, and stopping WordPress continually asking for your FTP login details. But in the user permission setting part, he didn’t restrict the FTPuser within their home directory with chroot.

Another thing we need to take care of before going into multisite setup, is the user permission. Because the wordpress we just installed belongs to either root (my case, because I used sudo when unzip the file) or EC2-user, but we don’t want to use the root account for later on FTP handling.

My solution is to create a new user (wp_admin for example) and change the wordpress folder owner to it. To put some restriction, you can also chroot so that wp_admin are restricted within the www folder.

sudo groupadd FTPusr
sudo useradd -d /var/www -M -N -g FTPusr -s /sbin/nologin wp_admin
sudo passwd wp_admin
sudo chown -R wp_admin:FTPusr /var/www/wordpress

Add the following lines to the end of your sshd_config:

Match Group FTPusr 
ChrootDirectory /var/www
ForceCommand internal-sftp
AllowTCPForwarding no
X11Forwarding no

Restart the sshd service:

sudo service sshd restart

OR, you can chroot the user itself by using Match User wp_admin in the sshd_config.

IMPORTANT: the httpd service owner might not be able to create the wp_config.php for you now. So go through that setup before changing the owner of the wordpress folder, or you have to manually create the wp_config.php on the server.

After all these, you can now setup the FTP in your wordpress and enjoy playing with plug-ins, themes and etc.

To stop WordPress continually asking for your FTP login details every time you update a plugin or theme, edit the wp-config.php file: You need to add the following lines after the MySQL database settings:

/** FTP Settings */
define("FTP_HOST", "YOUR_ELASTIC_IP");
define("FTP_USER", "wp_admin");
define("FTP_PASS", "YOUR_PASSWORD");

For more details on chroot, here are some useful refs:
http://askubuntu.com/questions/134425/how-can-i-chroot-sftp-only-ssh-users-into-their-homes
http://serverfault.com/questions/392601/how-to-add-user-with-sftp-ftp-access-to-var-www-html-website-abc-folder-on-a

josircg:

To chroot an SFTP directory, you must

1) create an user and force root to be owner of it

cd /home
mkdir john
useradd -d /home/john -M -N -g users john
sudo chown root:root /home/john
sudo chmod 755 /home/john

2) Change the subsystem location on /etc/ssh/sshd_config:

#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp

and create a user section:

Match User john
ChrootDirectory /home/john
ForceCommand internal-sftp
AllowTCPForwarding no
X11Forwarding no

Oli♦:

All this pain is thanks to several security issues as detailed here. Basically the chroot directory has to be owned by root and can’t be any group-write access. Lovely. So you essentially need to turn your chroot into a holding cell and within that you can have your editable content.

sudo chown root /home/bob
sudo chmod go-w /home/bob
sudo mkdir /home/bob/writeable
sudo chown bob:sftponly /home/bob/writeable
sudo chmod ug+rwX /home/bob/writeable

And bam, you can log in and write in /writeable.

Setup a wordpress multisite network on AWS EC2 (3)

AWS RDS is awesome. But it doesn’t come with a database management tool. All the searching results pointed to this tutorial from Ben Kuhl.

A short summary: First setup your phpMyAdmin on EC2.

Then in the config.inc.php file, add the following line after the existing server setup or setup loop:

$cfg['Servers'][$i]['auth_type'] = 'HTTP';
    $cfg['Servers'][$i]['hide_db'] = '(mysql|information_schema|phpmyadmin)';
    /* Server parameters */
    $cfg['Servers'][$i]['host'] = 'xxxxx.l2kj35ncj3.us-east-1.rds.amazonaws.com';

PHPMyAdmin uses $cfg[‘Servers’][$i] so that it can support multiple servers on one installation.  Having more than 1 server will give you the option to select a server when you login.  After that last you’ll want to add the following code, but of course with your own Amazon RDS instance URL.

In my case, I don’t have a config.inc.php file, so I made a copy from the config.sample.inc.php, and here is what it looks like now:

/*
* Servers configuration
*/
$i = 0;

/*
* First server
*/
$i++;
/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = 'cookie';
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['connect_type'] = 'tcp';
$cfg['Servers'][$i]['compress'] = false;
/* Select mysql if your server does not have mysqli */
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['AllowNoPassword'] = false;
/*
* AWS RDS server
*/
$i++;
$cfg['Servers'][$i]['auth_type'] = 'HTTP';
$cfg['Servers'][$i]['hide_db'] = '(mysql|information_schema|phpmyadmin)';
/* Server parameters */
$cfg['Servers'][$i]['host'] = 'xxx.rds.amazonaws.com';

Then… it works like a charm!

Salute to Ben Kuhl!

Setup a wordpress multisite network on AWS EC2 (5)

IMPORTANT: Although WordPress.org claims the following on Giving WordPress Its Own Directory:

Many people want WordPress to power their site’s root (e.g.http://example.com) but they don’t want all of the WordPress files cluttering up their root directory. WordPress allows you to install it into a subdirectory, but have your blog exist in the site root.

As of Version 3.5, Multisite users may use all of the functionality listed below. If you are running a version of WordPress older then 3.5, please update before installing a Multisite WordPress install on a subdirectory.

But be careful, it is a trap. In most of the case, you will be setting up Multisite network for different domains, right? Read on, in Before You Create A Network:

You cannot choose Sub-domain Install (for a domain-based network) in the following cases:

  • The WordPress URL contains a path, not just a domain. (That is, WordPress is not installed in a document root, or you are not using the URL of that document root.)

So, don’t be a fool like me, setting up the whole thing with WordPress in a subdirectory then found the Multisite’s Network Admin panel link cannot resolve to the current path. (All the single WordPress dashboard links point to the subdirectory correctly, but all the network dashboard links point to the root. I tried to change the PATH_CURRENT_SITE in the wp_config.php but the browser gives me a too many redirects error. Anyone knows how to solve that? I suspect that it has something to do with Permalinks and/or the .htaccess file, but didn’t figure out.)

Here is a walk through with a WordPress on its own root directory (with my add-ons to the official tutorial):

1. Setup the single WordPress (ref to my post Setup a wordpress multisite network on AWS EC2 (2)).

2. First deactivate all the plugins, then allow Multisite: Open up wp-config.php and add this line above the first line that begins with require or include:

/* Multisite */
define('WP_ALLOW_MULTISITE', true);

3. After refresh your browser, you should be able to see the “Network Setup” option under “Tools” menu. Follow the on screen instruction to install. Here I chose the Sub-domains type.

4. Then you need to modify the wp-config.php and .htaccess files. (If the .htaccess file doesn’t exist, just create one at where the wp-config.php locates, then copy & paste the code into it.)

The official tutorial has a line at this point:

In some cases you might also have to add Options FollowSymlinks at the start of the file.

Maybe that is the solution to the subdirectory problem I mentioned at the beginning. I will try this out another day.

5. After modifying the files, log in again with the link on the screen. You will find the Multisite panel appeared:

At the left of your WordPress toolbar, My Sites is now the second item. There, all your sites are listed, with handy fly-out menus, as well as a Network Admin menu item. Under Network Admin you can use the Dashboard item to go to the Network Dashboard screen.

6. Then you can start working on creating your own network.

At this point you will only be able to create subdomain type network, i.e., sub1.example.com and sub2.example.com.

If you want to use different domains, you need to install the WordPress MU Domain Mapping plugins.

Follow the installation instruction. You need to copy the sunrise.php from the wp-content/plugins/wordpress-mu-domain-mapping/ into wp-content/ and add define( 'SUNRISE', 'on' ); to wp-config.php near where you added define('WP_ALLOW_MULTISITE', true);

If everything works fine, in the Network Admin Dashboard -> Settings, you will find Domain Mapping. Set it up in the way fits your needs. I filled the IP address with my EC2’s Elastic IP.

Hu… now you can add new sites. The Add New Site page might still only allow you to add subdomain type site. But after adding, you can edit the site and change the domain address to anything you want.

Configure your domain register DNS to point to your server IP. Configure the Apache Virtual Host setting to point the domain to the wordpress path. In my case:

<VirtualHost *:80>
    ServerAdmin webmaster@www.ex1.org
    DocumentRoot /var/www/wordpress
    <Directory /var/www/wordpress>
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      Order allow,deny
      allow from all
    </Directory>
    ServerName ex1.org
    ServerAlias *.ex1.org
    ErrorLog logs/www.ex1.org-error_log
    CustomLog logs/www.ex1.org-access_log common
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin webmaster@www.ex2.com
    DocumentRoot /var/www/wordpress
    <Directory /var/www/wordpress>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
    </Directory>
    ServerName ex2.com
    ServerAlias *.ex2.com
    ErrorLog logs/www.ex2.com-error_log
    CustomLog logs/www.ex2.com-access_log common
</VirtualHost>

After restarting your httpd service, you should see both site alive.

Setup a wordpress multisite network on AWS EC2 (2)

WordPress provided the BitNami Multisite stack, but it includes LAMP stack in the install. I don’t want to mess up the existing Apache, so I decided to do the manual install. Plus, it should be more fun to DIY.

Basically the setup followed http://www.slideshare.net/mrjain/installing-wordpress-on-aws

Skipped the EC2 Setup. Setting up RDS is easy. The difference from using the EC2 MySQL is here:

Don’t make the wp-config.php from wp-config-sample.php by manually input the localhost MySQL database info.

Instead, go to the mapped URL, which is pointed to the WordPress path via Apache’s Name base Virtual Host. Then follow the screen instruction to create the config file with RDS’ endpoint address.

Then the normal wordpress site should be ready to run.

The next will be two side notes on how to manage the RDS database with phpMyAdmin and how to setup FTP users, then we will come back to the real setting up WordPress Multisite.

Setup a wordpress multisite network on AWS EC2 (1)

I tried to setup a blog for the share future project in the beginning of Dec. At the beginning I forgot that AWS Free Usage Tier included RDS service, so I used the MySQL service on our micro EC2 instance. As you can expect, the whole site crashed before long because out of memory.

The mysqld.log:

121212 1:03:04 InnoDB: Fatal error: cannot allocate memory for the buffer pool
121212 1:03:04 [ERROR] Plugin ‘InnoDB’ init function returned error.
121212 1:03:04 [ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.
121212 1:03:04 [ERROR] Unknown/unsupported storage engine: InnoDB
121212 1:03:04 [ERROR] Aborting

After some research, I found that making swap space solved the problem (Ref here).

Now we decided to setup a separate wordpress site for the project itself. I decided to use the RDS service for the database handling and use the multisite network feature support by wordpress 3.0.

In the following posts I will write down my notes.

%d bloggers like this: