linux

Slipstreaming Windows XP SP3 in Linux

Unfortunately Windows is still a necessary evil sometimes: I keep a Windows virtual machine for times when it's absolutely necessary, and I still give my friends Windows tech support. I still like to do things properly, and so I wanted to create a Windows XP install CD with Service Pack 3 slipstreamed in1. I had two CDs to do, and slipstreamed the first one using a Windows VM, but then got curious and wondered if I could do it without Windows.

The answer is that it is possible using Wine to run the service pack installer. I followed this blog post (which was interesting since it's in French), but I then found another blog post which explains it in English. The steps are as follows:

  1. Copy contents of original CD to harddrive.
  2. Extract the service pack using cabextract.
  3. Use Wine to run the service pack installer.

    wine ~/sp3/i386/update/update.exe /integrate:~/xp/
    
  4. Use geteltorito to extract the bootloader from the original CD

  5. Make sure that all the filenames are upper case.

    convmv -r --upper --notest ~/xp/*
    
  6. Create the new CD image. I did this in K3b with the following settings.

    • Boot emulation: none
    • Boot load segment: 0x7c0
    • Boot load size: 0x4
    • Generate Joilet extensions
    • Omit version numbers in ISO9660 filenames (nothing else enabled under "ISO9660 Settings"
    • ISO Level 1
  7. Test in a virtual machine

It seems to be quite particular about the ISO9660 settings and the upper case filenames, so if it doesn't boot check the settings.


  1. This integrates the service pack into the install CD so that a fresh installation is already updated. 

Publishing SSH and GPG keys using DNS

I was looking through a list of DNS record types, and noticed the SSHFP and CERT records. I then proceded to implement these in my domain... just because I can ;-)

SSH Host Keys

The SSHFP record is used to publish the fingerprint of a host's SSH key. When an SSH client connects to a server for the first time, it can verify the host's key by checking for this DNS record. The format of the record is specified in RFC 4255, but there is also a tool which will generate the records for you.

$ sshfp -s mammon.gorven.za.net
mammon.gorven.za.net IN SSHFP 1 1 5e6772b6962f3328a0d73f7765097b7622f21447
mammon.gorven.za.net IN SSHFP 2 1 00e59b1843421f13d75e21abb06bf032a6e60b8b

The SSH client needs to be configured to check these records. Specifying "VerifyHostKeyDNS ask" in ~/.ssh/config will make the client look for SSHFP records, but will still prompt you to accept the key. (It will output a messaging saying that it found a matching key.) Specifying "VerifyHostKeyDNS yes" will skip the prompt if the record exists and matches the key presented by the server.

GPG Keys

The CERT record is used to publish public keys or fingerprints. It can be used for PGP, X.509 or SPKI keys. It is specified in RFC 4398, and there is very little mention of it other than this blog post I found. To generate records you need the make-dns-cert tool which is part of GnuPG. It isn't distributed in the Ubuntu package however, and so I had to compile GnuPG from source.

To determine the name of the record to use, convert your email address into a domain name by replacing the ampersand with a dot1. To publish your entire public key, run the tool as follows.

$ make-dns-cert -k ~/pubkey -n michael

The first parameter specifies the file containing your public key in binary format, and the second parameter specifies the domain name to use. To publish a reference to your public key, run the tool as follows.

$ make-dns-cert -f BF6FD06EA9DAABB6649F60743BD496BD6612FE85 -u http://michael.gorven.za.net/files/mgorven.asc -n michael

The first parameter specifies the fingerprint of your key, and the second parameter the URL at which the public key can be found. It is also possible to only publish the fingerprint or only the URL. Simply add the record which the tool outputs to your zone file2.

There is also another method to publish GPG keys called PKA. The only documentation I can find is a specification in German linked from the blog post mentioned above. I still managed to set it up though. This method uses a TXT record (similar to SPF). Here is my record.

michael._pka.gorven.za.net. TXT
"v=pka1\;fpr=BF6FD06EA9DAABB6649F60743BD496BD6612FE85\;uri=http://michael.gorven.za.net/files/mgorven.asc"

This specifies the fingerprint and URL, just as with the second CERT method above. In order to get gpg to check DNS for keys, you need to specify "--auto-key-locate cert,pka" on the command line or in the configuration file.


  1. So john@example.com becomes john.example.com

  2. It should be possible to clean the record up by using mnemonics, but I couldn't get nsd to accept it and so just left it as is. 

OpenVPN through an HTTP proxy server

I discovered that OpenVPN supports connections through an HTTP proxy server. This makes it possible to establish a VPN from a completely firewalled network where the only external access is through a proxy server1. It takes advantage of the fact that SSL connections are simply tunnelled through the server and aren't interfered with like unencrypted connections.

The server setup is almost identical to a normal configuration, except that the tunnel must use TCP instead of UDP (since the proxy server will establish a TCP connection). Since most proxy servers only allow SSL connections to certain ports, you will also need to change the port number that the server listens on. The best is 443 since that is used for HTTPS, but if the server is also running a web server on port 443, then 563 is probably the next best choice. This port is assigned to NNTPS, and is allowed by the default Squid configuration. The following two lines enable TCP connections and change the port number.

proto tcp-server
port 563

The client configuration is also very similar. It simply needs to enable TCP connections, set the correct port number, and specify the proxy server.

remote vpn.example.com 563
http-proxy cache.saix.net 8080
proto tcp-client

OpenVPN can also authenticate to the proxy server using either Basic or NTLM authentication. To enable this add "stdin basic" or "stdin ntlm" to the http-proxy line. This will prompt for the username and password when the VPN is started. For more details see the OpenVPN documentation.


  1. I am not commenting on the ethics of this. If you need to resort to this method, you probably shouldn't be doing it. 

Gmail-like mail setup

I have been using Gmail for a while now, and really think that it's about the best email provider out there. I recently moved my mail over from Google Apps to my own server, but I wanted the major features that I liked. I've always used a desktop mail client and used POP3 and SMTP to receive and send mail.

These are the features I particularly like:

  1. Secure access with TLS/SSL
  2. Outgoing SMTP with authentication
  3. Messages sent via SMTP are automatically stored in the mailbox
  4. Messages downloaded via POP3 are still stored on the server
  5. IMAP and Web access

I therefore set out to recreate this setup as closely as possible. The first two are satisfied by a standard Postfix setup with TLS and SMTP AUTH. The last one is done with Dovecot and Roundcube.

To automatically store sent messages on the server, I used Postfix's sender_bcc_maps to BCC messages I send to myself, and the following Procmail recipe to move these messages to the Sent folder.

:0
* ^Return-Path.*me@example.com
.Sent/

To make POP3 access independent from IMAP, I first configured Dovecot to use a different mail location for each as follows.

protocol imap {
    mail_location = maildir:~/Maildir
}
protocol pop3 {
    mail_location = /var/mail/%u
}

I then used the following Procmail recipe to send incoming messages to both locations.

DEFAULT=$HOME/Maildir/
:0c:
/var/mail/mgorven

At the moment this is only setup for my user, but it should be possible to do it for all users by creating a global procmailrc and telling Postfix to deliver all mail using Procmail. This is working fairly well. The only part missing is that Gmail can archive or mark messages as read when they are downloaded via POP3, whereas in my setup POP3 and IMAP are completely independent.

Postfix with SPF and DKIM

As most people know, email is horribly insecure. It is trivial to forge the From address in emails since there is no authentication when sending1. This means that one cannot trust the From address, and also that people can forge messages from your address. In order to address this a number of new schemes have been developed. These include SPF, DomainKeys, DKIM and SenderID. All of these aim to verify that mail is actually from the address it appears to be from. SPF and SenderID do so by restricting which hosts are allowed to send messages from a certain domain, while DomainKeys and DKIM use cryptographic signatures.

Unfortunately all of these schemes have problems due to the fact that they are an addition to the existing mail system. SPF and SenderID prevent plain forwarding (requiring additional schemes like SRS or whitelisting of forwarders), and MTAs and mailing lists which modify messages break DomainKey and DKIM signatures. Despite these issues, email forgery is an issue which needs to be addressed, and we cannot wait for a perfect solution before adopting it. Some major mail providers (including Gmail and Yahoo) are already implementing these schemes.

I have therefore configured SPF and DKIM in my Postfix mail setup. My SPF policy allows mail from my server and SOFTFAILs all other hosts, and all outgoing mail is signed with DKIM. Incoming mail is checked for SPF and DKIM, but aren't discared even if the checks fail. I will be keeping an eye on things and will revise my policy when I think it safe.

SPF Configuration

To create an SPF policy, add a TXT record to your DNS records according to the SPF syntax. The policy should authorise all hosts from which you send mail. (Mine simply authorises my mail server since I send all mail through it.) You also need a policy for the hostname presented by your mail server in its HELO/EHLO command. You should also create policies for all subdomains which aren't used for mail.

To check SPF records for incoming mail, I used the SPF policy daemon for Postfix. It is packaged for Ubuntu as postfix-policyd-spf-python. Simply follow the instructions in /usr/share/doc/postfix-policyd-spf-python/README.Debian2, and set defaultSeedOnly = 0 in the configuration file if you don't wish to reject mail which fails the test. Remember to whitelist any servers which forward mail to you (i.e. you have another address which gets forwarded to your mail server), unless they implement SRS3.

DKIM Configuration

To sign and check DKIM I use DKIMproxy. There isn't an Ubuntu package so I installed it from source. The instructions on the site are good, and include details for Postfix. You will need to generate a key to sign with and publish it in DNS, and then configure Postfix to sign outgoing messages and validate incoming messages. DKIMproxy won't discard messages with invalid signatures by default.

DKIM includes a component called ADSP which allows domains to publish their signing policy. The strongest policy states that all messages are signed with DKIM and any messages without signatures should be discarded. This will allow mail servers to reject messages not sent through your mail server. However, the standard is not finalised yet, and issues regarding mailing lists still need to be addressed.


  1. Yes, I know about SMTP authentication, but people can simply use a relay. 

  2. Just watch out for the location of the configuration file -- the README uses a different location to the package. 

  3. Gmail doesn't implement SRS as such, but does use a compatible rewriting scheme. 

Syndicate content