Running Moin Moin in Apache With SSL

Simple Authentication

This wiki is powered by MoinMoin, a python based wiki which stores its data in flat files. I choose it because:

MoinMoin has the ability to make use of various different authentication schemes, but what I really wanted to do was very simple: I wanted the wiki to be editable by a select group of users (me, and whomever else I chose), and read-only to everyone else. It didn't matter to me (at that point) how my users were created.

This was actually quite straightforward to set up with the standard MoinAuth scheme that comes enabled with Moin out of the box.

In your wikiconfig.py, make sure you have this setup:

acl_rights_default = u"All:read"
acl_rights_before = u"WebmasterGroup:read,write,delete,revert,admin"

The acl_rights_default line says that by default, each user can read your pages. It's as if you put an equivalent acl line on each and every page.

The acl_rights_before line is applied before your defaults, and hence overrides it. It says that anyone in the WebmasterGroup group can read, write, delete, revert pages, as well as add #acl lines to pages (this is what the admin privilege gives you).

Note that I could have said this:

acl_rights_before = u"DesmondRivet:read,write,delete,revert,admin"

which would have given me (Desmond Rivet) the same rights as those in the WebmasterGroup. How did Moin know that WebmasterGroup is group and not a user? Because it ends in the word "Group". You can change this behaviour by fiddling with the page_group_regex config item in wikiconfig.py

How do we add users to WebmasterGroup? Note that WebmasterGroup is a page like any other. Users with editing privileges can edit it. You add users to the WebmasterGroup by adding the user to a first level list on the page. You can see my WebmasterGroup by clicking the link.

Making Accounts

You can make yourself an account in Moin by clicking the Login link on the top of every page and choosing to create yourself a new account. Note that I have not yet figured out how to disable this.

Secure Wiki Authentication

You log into Moin by clicking the Login link available on every page. This will bring you to the Login page as which point you can login as per normal.

Unfortunately, the username and password are sent in the clear, where anyone can see it. How can we prevent this? One way is by encrypting your entire wiki with SSL.

Note that this may be somewhat overkill. There might be a way to encrypt your wiki only if you login. I have not yet, however, figured out how to do this. So, until I figure out how to be a bit more surgical in how I do this, I will encrypt the whole wiki.

My goal seemed fairly simple: I wanted desmondrivet.net to be unencrypted by default (i.e. http), but I wanted users of my wiki to be forced into using https. Before explaining how this was done, a digression into Virtual Hosts is in order, since this will play heavily into my setup.

Virtual Hosts

I run apache2 on Debian, which has a Virtual Host setup by default. Virtual Hosts let you run multiple websites, with multiple hostnames and/or IP addresses, from a single apache installation. A full discussion of this subject is beyond the scope of this page (plus, I don't know much about it), but more info can be found in apache's documentation. But in a nutshell, VirtualHost sections enclose directives that apply to a particular virtual host. For example:

<VirtualHost 192.168.1.9:80>
    ServerName host.example.com
    ...
</VirtualHost>

<VirtualHost 192.168.1.9:80>
    ServerName host2.example.com
    ...
</VirtualHost>

<VirtualHost 192.168.1.20:80>
    ServerName anotherhost.example.com
    ...
</VirtualHost>

<VirtualHost *:443>
    ServerName securedhost.example.com
    ...
</VirtualHost>

Name based versus IP based Virtual Hosts

The apache documentation makes a distinction between named based versus IP base Virtual Hosts. Named based virtual hosts distinguish themselves by different hostnames operating on the same IP address. IP based virtual hosts all operate on the different IP addresses. From what I can tell, however, the distinction is somewhat artificial, since there is a unified mechanism for figuring out which VirtualHost section to use, and that unified mechanism makes use of both IP address and names.

Basically, a VirtualHost section is matched against the IP address/port in the VirtualHost directive, followed by the ServerName. So you can have multiple IP addresses, each with a bunch of servers having different names.

Virtual Hosts and SSL

Up until very recently you couldn't use name based VirtualHosts with SSL, due to the nature of the SSL protocol. Named based virtual hosting relies on the client to send the host it's trying to connect to. With SSL, this information in encrypted, so you can't use it to match against a particular ServerName.

Recently, SNI is supposed to change all that, but I haven't looked into it yet.

Dividing and Securing the Domain

With all that in mind, I attacked the main problem by

The first thing to do is to make sure that my DN provider, Netfirms, will recognize the wiki.desmondrivet.net hostname. The only way I figured out how to do this is to set up a CNAME alias on the Netfirms panel. There might be a better way.

By default, nothing is encrypted. This requires a relatively standard entry in /etc/apache2/sites-enabled/000-desmondrivet.net. I'm not going to paste that here, but it contains typical directives for the DocumentRoot, etc. It basically starts with:

<VirtualHost *:80>

This basically matches any request on port 80. It also contains a few RewriteRule's:

RewriteCond %{HTTP_HOST} ^desmondrivet\.net$
RewriteRule ^/(.*)$ http://www.desmondrivet.net [R,L]

The RewriteCond line says that the next RewriteRule's only apply when the hostname begins with desmondrivet.net. The RewriteRule forces a redirect to http://www.desmondrivet.net, which is the canonical hostname I want people to connect with. The R flag is what causes the Redirect, while the L flag forces the Rewrite processing to end at the point.

There's another RewriteRule:

RewriteRule ^/moin_static171/(.*) /usr/share/moin/htdocs/$1 [L]

This basically just maps any static content requests to /usr/share/moin/htdocs, and stops the processing right after.

And finally:

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^wiki\.desmondrivet\.net$
RewriteRule ^/(.*)$ https://wiki.desmondrivet\.net/$1 [R,L]

This one says that if the user connected to wiki.desmondrivet.net for some resource, but did not connect with HTTPS (the first two RewriteCond's), then we will do a hard redirect to https://wiki.desmondrivet.net (and stop processing). This is how I force HTTPS for all users wanting to use my wiki. Note that the regular expression match in RewriteRule basically matches anything beginning with a slash. It effectively matches any resource request and tacks it on to the end of the new https address. We know the resource request will be for wiki.desmondrivet.net because of the second RewriteCond line.

I also have a virtual host configuration for the SSL requests, located in /etc/apache2/sites-enabled/001-desmondrivet.net-ssl. It looks like this:

<IfModule mod_ssl.c>
<VirtualHost _default_:443>
...
</VirtualHost>
</IfModule>

It looks more or less like a typical SSL virtual host entry. It has one particularly important RewriteRule:

RewriteCond %{HTTP_HOST} ^wiki\.desmondrivet\.net
RewriteRule (.*) /cgi-bin/moin.cgi/$1 [L,QSA,PT]

This means that any request involving wiki.desmondrivet.net will be secretly transformed into a request for /cgi-bin/moin.cgi, which is the main wiki CGI script. Processing stops right after that (the L flag). The QSA flag preserves the query string and the PT flag allows further handling by other directives, such as the Alias directive.

SecuredMoinMoinWithApache (last edited 2013-04-21 01:53:15 by DesmondRivet)