Cataclysmic Mutation

Machine Learning and Whatever Else

Arch Linux Configuration

The following was written in 2009 as a set of notes for things I had to figure out in order to switch to Arch Linux. The Linux server it was running on didn’t make the trip with me to Iceland, but I wanted to have a place where this bit of documentation intended mostly for myself could still live, so I’m posting it here now. Much of it may no longer be relevant.

So, Gentoo has “teh suck.” Not its fault really. It’s just suffered from a lack of good leadership.

OK, that was a bit harsh. Part of the problem is that I don’t use Gentoo the way I think you’re supposed to – always obsessively keeping a bleeding edge distribution. I really like the Gentoo organization system, and I’d still be using it except for how it’s, you know, horribly broken. Specifically, if you don’t update for a while, you’re screwed. You end up with package versions that aren’t even in portage anymore, and the system basically refuses to build certain things. And good luck if you need a glibc update.

Anyway, as a result of this, my Gentoo box has been somewhat hosed for a while now. I needed to build a new GCC, and it wouldn’t unless I committed to spending my life tracking down one problem after another, so I gave up. This weekend, I finally bit the bullet, wiped it, and installed Arch. So far, it seems pretty good, but there were a number of weird little issues that I wanted to document.

I should vehemently note here that all of the following is from my recollection after the fact. I wasn’t taking good notes during the process, so it’s likely that I’ve left something out – probably several things.

Before I get too far, let me mention a couple of quick notes. Pacman, the Arch package manager is actually quite good. To install a package, I’ve been doing the following

$ pacman -Ss boost
extra/boost 1.37.0-1		Boost provides free peer-reviewed portable C++ source libraries.
$ pacman -S boost

which does a search (“-Ss”) of the supported repositories and reports back with what it found. I then install the package with a bare “-S”. There are other options, and the man pages are helpful, but that’s the gist of things.

“You did what with Xorg?” or “It turns out input devices are useful in X.”

For reasons that completely escape me, Arch takes the concept of “modular Xorg” to whole new heights. If you’re like me, you would search for xorg packages, see a bunch of stuff scroll by, and pick out “xorg-server” as the one you need. And indeed, installing this package produced what seemed at first glance to be a fairly normal X11 installation. Trying to start X was a beautiful failure, as although everything started correctly, I had no keyboard and no mouse. As I foolishly hadn’t gotten ssh going yet, I got to hard cycle the machine.

Turns out, the good folks of Arch decided to do two lovely things: fail to install mouse_drv.so and kbd_drv.so, and configure X to allow an empty set of input devices. Thus, instead of getting an error telling you you didn’t have a keyboard or mouse, you got a functioning X display that couldn’t be killed.

Short answer to the problem, scream “fuckmonkey” at the top of your lungs and install xf86-input-mouse and xf86-input-keyboard.

$ pacman -S xf86-input-mouse xf86-input-keyboard xf86-input-evdev

Of course, if you prefer to communicate with your computer via telepathy or by careful direct application of electric current to the board, feel free to ignore this step.

There’s actually quite a bit more to this bullet point, as the Arch method of installing Xorg is somewhere just shy of “one package per file”. There’s more than I want to go into here, but just be prepared to do a lot of searching the repositories for various bits of X you thought for sure would have been installed along with the core X11 system.

On the bright side, once I helpfully clarified that I wanted to be able to interact with X, it installed and worked well enough. I installed the nvidia drivers

$ pacman -S nvidia

and Xorg -configure worked great. I did add a line to the ServerLayout section containing

Option "AllowEmptyInput" "false"

to make it complain if it didn’t find any devices, but otherwise, I left the file mostly unmodified. I also added a LoadModule “evdev” line so that it would work with modern peripherals.

Look at me, I’m on the Internet

I do a bunch of stuff from Apache. I serve out different pages based on the hostname coming in (NameVirtualHosts in Apache vernacular), I run ajaxterm (protected by SSL for obvious reasons), and I run a dynamic site for some friends written in Python using Django. So while none of this is particularly Arch specific, it seemed like a good time to document the process of deploying all this stuff on Arch.

First, you need to install apache and all the other crap I need.

$ pacman -S apache python mod_python django ajaxterm openssl

I also had to add a line to /etc/httpd/conf/httpd.conf to load the mod_python module.

We’re going to need a certificate for this and a couple of other steps, so we can go ahead and create a key and certificate via the normal mechanism.

$ openssl req -new -x509 -newkey rsa:1024 -days 3650 -keyout server.key -out server.crt
[answer lots of questions]
$ openssl rsa -in server.key -out server.key
$ cp server.key /etc/ssl/private/
$ chown nobody.nobody /etc/ssl/private/server.key
$ chmod 0400 nobody.nobody /etc/ssl/private/server.key
$ cp server.crt /etc/ssl/certs/

In Arch, the default home of your web presence is /srv/http/. I created directories for each of my vhosts under that directory and configured the NameVirtualHost environments for each one.

NameVirtualHost *:80
<VirtualHost *:80>
ServerAdmin root@localhost
DocumentRoot "/srv/http/docs/site1.com"
ServerName www.site1.com
ServerAlias site1.com
ErrorLog "/var/log/httpd/site1.com-error_log"
CustomLog "/var/log/httpd/site1.com-access_log" common
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/srv/http/docs/site2.com"
ServerName www.site2.com
ServerAlias site2.com
ErrorLog "/var/log/httpd/site2.com-error_log"
CustomLog "/var/log/httpd/site2.com-access_log" common
<Location />
SetHandler python-program
PythonPath "[r'/srv/http/docs/site2.com/production/'] + sys.path"
SetEnv DJANGO_SETTINGS_MODULE myapp.settings
PythonHandler django.core.handlers.modpython
PythonDebug On
PythonInterpreter myapp
</Location>
<Location "/static/">
SetHandler None
</Location>
</VirtualHost>
<VirtualHost *:80>
ServerAdmin root@localhost
DocumentRoot "/srv/http/docs/site3.com"
ServerName www.site3.com
ServerAlias site3.com
ErrorLog "/var/log/httpd/site3.com-error_log"
CustomLog "/var/log/httpd/site3.com-access_log" common
</VirtualHost>

There’s a lot of stuff going on here. Basically, in my example configuration, I am running three sites: site1.com, site2.com, and site3.com. The site1.com domain is a simple set of static web pages hosted at /srv/http/docs/site1.com/. The second block sets up site2.com to point to the Django application mentioned earlier. The first five lines in this VirtualHost declaration are very similar to the previous stanza. The new

block redirects all requests to mod_python, configured to run Django loading “myapp”. Also note the final <Location “/static/”> block. Within this directory, requests will be handled by Apache rather than being passed through to mod_python. This allows the web application to refer to images, css files, and other static data without going through unnecessary hoops. Finally, the last block defines site3.com to point to another document root. With this configuration, Apache can serve out different content for each of the three domain names, and the data is published by simply writing into the specified subdirectory of /srv/http.

In order to allow SSL encrypted connections, a similar set of blocks was placed in /etc/http/conf/httpd-ssl, shown below.

NameVirtualHost *:443
SSLEngine on
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCertificateFile "/etc/ssl/certs/server.crt"
SSLCertificateKeyFile "/etc/ssl/private/server.key"
<FilesMatch ".(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory "/srv/http/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
<VirtualHost *:443>
ServerAdmin root@localhost
DocumentRoot "/srv/http/docs/site1.com"
ServerName www.site1.com:443
ServerAlias site1.com:443
ErrorLog "/var/log/httpd/site1.com-error_log"
CustomLog "/var/log/httpd/site1.com-access_log" common
# proxy requests for /ajaxterm/
<IfModule proxy_module>
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /ajaxterm/ http://localhost:8022/
ProxyPassReverse /ajaxterm/ http://localhost:8022/
</IfModule>
</VirtualHost>

This gives site1.com available over SSL in addition to the already configured options above. I also enable a proxy so that if I ask for https://www.site1.com/ajaxterm/, I’m redirected to the ajaxterm instance running on port 8022 of localhost. For security purposes, it’s a good idea to expose the Ajaxterm proxy only behind SSL, but if desired, the proxy block could be copied into the site1.com configuration and used without encryption. Note that you can’t really use NameVirtualHost with more than one SSL host, as the SSL connection has to be set up prior to initiating a GET or POST request. Thus the server wouldn’t know which domain the client was hitting and might send out the wrong certificate.

Setting up a mail server

This one isn’t really Arch specific, but I’m sure I’m not the only one who runs a similar setup, and I thought it would be useful to document the steps for getting my setup going with Arch. Basically, my mail server at home is a stock Courier-IMAP server using SSL and Postfix configured to require authentication and forward the mail to my ISP’s mail server. Additionally, my ISP (AT&T) blocks inbound port 25, so I have Postfix listening on port 8025 as well.

First things first, we need to install a bunch of packages.

$ pacman -S postfix courier-imap cyrus-sasl libsasl openssl pam procmail

Arch puts the Courier configuration files under /etc/courier-imap, and you should be able to modify the imapd-ssl and pop3d-ssl files as you ordinarily would for your setup. For my purposes, it was sufficient to set the following lines in the imapd-ssl file.

TLS_CERTFILE=/etc/courier-imap/imapd.pem
MAILDIRPATH=maildir/

Note that the imapd.pem file will have to be created. During the Apache configuration above, we created the server key and certificate files in /etc/ssl/certs/ and /etc/ssl/private/. To make them work for our purposes here, do the following.

$ cat /etc/ssl/private/server.key /etc/ssl/certs/server.crt >> /etc/courier-imap/imapd.pem

Additionally, edit /etc/courier-imap/imapd.cnf to contain the correct information about your certificate.

For Postfix, we need to set up sasl authentication and forwarding to the ISP. I assume you’re familiar with basic configuration, but here are the values I edited in /etc/postfix/main.cf. You’ll want to edit at least some of these as well.

myhostname = your.fqdn.com
mydomain = fqdn.com
myorigin = $mydomain
proxy_interfaces = your.public.ip.addr
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
# sasl authentication stuff here
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
check_relay_domains
relayhost = [mailserver.yourisp.net]
home_mailbox = maildir/

In addition, to sidestep the port 25 problem with AT&T, we need to set up a separate service for our SMTP server to run on. Because I want to allow normal” clients to easily connect whenever possible, I also keep port 25 open as well. The first step is to add a separate entry for our new service. I have the following lines in /etc/services.

smtp-hi     8025/tcp
smtp-hi     8025/udp

Then, in /etc/postfix/master.cf, I add a corresponding line to tell Postfix to use that service as well as the default port 25.

smtp-hi   inet  n       -       n       -       -       smtpd

You’ll need to make sure that a few other services are running at boot time in order for all this to work correctly. In particular, make sure that the DAEMONS line in /etc/rc.conf contains at least the following services:

  • fam
  • authdaemond
  • saslauthd
  • courier-imap