Deploy own Root CA Certificates in Firefox

Companies sometimes do not want to sign their intranet-webserver X509 certificates through a Certificate Authority like VeriSign or Thawte to save costs.
Firefox comes with some CAs included, but it looks like there is no easy way to distribute your own CA to your users.

Today I made some tests with certutil and got a promising solution by distributing an own cert8.db file in /etc/firefox

cd /tmp
# retrieve all CA you wish to make available to your users
wget http://pki.example.com/Root-CA-base64.crt
wget http://pki.example.com/…-base64.crt
….

# install certutil
apt-get install libnss3-tools
# Create new certificate and key databases.
# only cert8.db is important for your users
mkdir tmp
certutil -N -d tmp/
# Insert CAs into cert8.db
for i in *crt ; do certutil -A -n “$i” -t “CT,c,c” -d tmp/ -i “$i” ; done
chmod a+r tmp/cert8.db
cp tmp/cert8.db /etc/firefox-3.5/profile/cert8.db

Unfortunately this solution only works for users not having already a firefox profile in their home. A workaround could be to iterate over all user homes and modify directly the profile folders with certutil.
If you know better ways to distribute a custom root CA certificate, please let me know!

Window Buttons (Minimize, Maximize, Close) issue in Ubuntu 10.04 LTS

Many users complained about the arrangement of the windows button (minimize,maximze,close) in Ubuntu 10.04 LTS. To get the old behavior back a user would have to use
gconftool-2 --set /apps/metacity/general/button_layout --type string "menu:minimize,maximize,close"

As I have to roll out Ubuntu 10.04 on several desktops I wanted to fix this “bug” globally on the whole system without modifying any user profiles. These two lines do the trick:

echo '/apps/metacity/general/button_layout "menu:minimize,maximize,close"' > /usr/share/gconf/defaults/99_fix-menu
/usr/bin/update-gconf-defaults

802.1x & EAP-TLS: Alert (Level: Fatal, Description: Unexpected Message)

Today we achieved to connect to our corporate WLAN (802.1x / EAP-TLS). Normally certificates are only issued to our Windows Users but with help of our IT Department we got certificates for our linux machines. My colleagues tried it several times but it didn’t work with networkmanager neither with wpasupplicant. The last days I had the “chance” to try myself. I started wpasupplicant together with wireshark. After sending Client Hello to our accesspoint (connected to a radius server) , it returned an error message:

Alert (Level: Fatal, Description: Unexpected Message)

The fatal alert Unexpected Message “should never be observed in communication between proper implementations”. The server did not want to see my my certificates and stopped talking to me immediately. After comparing Client Hello bit-by-bit with RFC 2246, I hit on the SessionTicket TLS Extension (defined in RFC 4507) sent by my client:

Ethernet II
802.1X Authentication
Extensible Authentication Protocol
Secure Socket Layer
SSL Record Layer: Handshake Protocol: Client Hello
Handshake Protocol: Client Hello
….
Compression Methods Length: 2
Compression Methods (2 methods)
Extensions Length: 4
Extension: SessionTicket TLS
Type: SessionTicket TLS (0×0023)
Length: 0
Data (0 bytes)

I was asking myself what would happen if I would remove this Extension from the Client Hello so it would look like a old-fashioned RFC2246 datagram? To accomplish this I downloaded the openssl sourcecode with apt-get source openssl, removed enable-tlsext from rules/debian and rebuilt the code with make -f debian/rules (I didn’t want to install it).
I started wpasupplicant with

LD_LIBRARY_PATH=~/openssl-0.9.8g/ wpa_supplicant -d -i wlan0 -Dwext -c WLAN.conf

and it worked! The TLS Extension is not sent by my client and in wireshark the response from the accesspoint looks now like a well formed Server Hello

TLSv1
Certificate, Client Key Exchange, Certificate Verify, Change Cipher Spec, Encrypted Handshake Mess

Conclusion: I am now sure that the server handles the Client Hello wrong. RFC2246 describes in its “Forward compatibility” note:

In the interests of forward compatibility, it is permitted for a client hello message to include extra data after the compression methods. This data must be included in the handshake hashes, but must otherwise be ignored.

Mass unattended Linux installation with FAI

Me and my colleague are responsible for linux installations at our customer. In our scenario installations are complicated:

  • We are not allowed to operate an own DHCP server. The corporate DHCP server does not allow us to modify the TFTP/NFS Server settings
  • Our users/clients are not at our site which makes installations difficult: We have to go to our users or our users have to bring-in their client. The distance to our customers is high
  • Users with different hardware (RAM, HD,…) and different configuration (local users,…)

Finally we found a solution which allows us to do installations with FAI. FAI is a tool for mass unattended Linux installation. FAI works well when your hardware and configuration is the same. As we have different clients we had to implement a hook for interactive configuration.
The picture shows our final installation procedure:

We prepared an ISO file to allow our customers to remote boot an rescue system with SSH enabled. This ISO file does not have to be touched anymore as all configuration is stored on our servers. The user would only have to write this ISO (a dd-dump) to an USB stick, connect it with the client to be installed and power it on. The rescue system gets an IP with DHCP and uses a NFS export of our server as nfsroot. The kernel parameter nfsroot= make sure it uses our NFS server. After booting the rescue system, the User gets a message with the actual IP and our telephone number. The user has to call us to start the installation procedure.

We can then connect with ssh and the client IP. As the nfsroot contains our public SSH keys we do not need any passwords. Our corporate DNS allows the use of dynamic DNS. It would also be possible to use a hostname to connect. Unfortunatelly the actual “ipconfig” in the ramdisk has not all DHCP features included and does not send its own hostname in the DHCPREQUEST. There exists already a patch, but it is still not merged.
Before this “rescue linux with nfsroot=” solution we tried gPXE and a patch of me. It did do the DNS update, but gPXE has problems booting some NICs so we abandoned it.

After log-in with ssh we start with preconfiguration of some individual items which would not make sense to configure them in our FAI repository: userid of the owner, install target (sda/sdb/….), encryption yes/no, size of the swappartition,…
The config is written to /tmp/fai/myvars.sh. Hooks and scripts can later access this config to prevent user interaction during installation.
We trigger then the start of the installation procedure (FAI) and watch the installation progress with

tail -f /tmp/fai/fai.log

FAI uses tarballs as base image and installs further packages on it. To speed up the installation we have images with preinstalled KDE/GNOME.

Now we have a standard way to install our clients. FAI also allows to install other distributions like Ubuntu, but it is still not the same : Installations with DVD are different with FAI.
FAI requires a list of packages to be installed. It would be helpful if Ubuntu would provide a meta-package which would also install the same packages as the Ubuntu installer does. FAI could then do the same procedure without using a tarball.

DNS service location in Windows XP

My employer has a big active directory infrastructure with many subsidaries. While configuring Linuxnotebooks to authenticate with kerberos (pam_krb5) against Active Directory. I was asking myself why I have to insert all our local corporate Active Directory server IPs into krb5.conf. Is there no way to just use the DNS-Name of the Domain-Name to locate my nearest Domain Controller? How do Windows XP Clients locate a domain controller? I asked a similar question already 7 years ago, but now I am able to answer this question. The KB Article of MS did not satisfy me so I tried to put here together the most interessting information.

Here is a strong simplification how a XP Client discovers a Domain Controller:

  • Step 1) Lookup SRV-/A-Records for a given Domainname to locate a random Domain Controller.

    $ DOMAIN=mydomain.example.net
    $ dig -t srv _ldap._tcp.$DOMAIN +short

  • Step 2) The Records of some Domain Controller are returned. We could use this results to log-in and stop here, but the client tries to discover an DC near its site.
  • Step 3) In the order of the results the Domain Controller are contacted with an “LDAP Ping”. This is an connection-less and anonymous LDAPSEARCH over UDP. In the Samba source is a script 
which allows sending cldap datagrams to a DC LINK

    ./cldap.pl –domain $DOMAIN –server

  • Step 4) Active Directory has a map between “sites” and “subnets”. The Domain Controller compares the client IP with its map and returns the name of the “site” (here: SiteA)
  • Step 5) The Client will use the “site” in further DNS request to locate Domain Controllers at its site.

    $ dig -t srv _ldap._tcp.SiteA._sites._msdcs.$DOMAIN +short

  • Step 6) The DNS responds with Domain Controllers responsible for SiteA
  • Step 7+8) The client uses the Domain Controllers in its site in further requests. The client saves the sitename in a registry key DynamicSiteName to prevent step 1)-6). The client could also be forced to use a certain site with setting the registry key SiteName. Beginning with Windows Vista, it is also possible for a client to lookup the nearest DC with the associated costs.

Why do I explain explain this stuff on a LinuxBlog? Because I would be happy to see these features more in linux applications (e.g. ldapsearch).

site-discovery
If there a different locations with site-local servers, the client should alway use its nearest server to prevent WAN traffic.
This technique is also used in CDNs. There are also some approaches with geoip and DNS which could be helpful here. Some years ago I had to modify all site-local DNS servers so that the same DNS entry returns the IP of our site-local OpenVPN server but this was more a hack than a technique.

single DNS entry = all available servers
Instead of configuring different servers in client applications e.g. ldap1,ldap2,ldap3,…. it would be nicer (?) to control the clients just with one DNS entry.
This would also make the applications more robust as new failover servers can easily be published via DNS.
If the first IP returned by DNS is unavailable, the client should also use the other results (just like SMTP does it with MX-records)
Using DNS instead of an IP is also not a drawback her as there are usually more than one working DNS server in an organisation. As DNS is replicated, the same information is available on all other DNS servers, too.

btw: A microsoft consultant told me, that samba is site-aware – Nice! :-)
Update: Also Yum supports site-discovery and fault-tolerance

Learning while in holiday: Kerberos

I had already user experience with Kerberos, but now I wanted to install it myself. I took the MIT Kerberos implentation. Even I was used to use “single-sign-on” with SSH keys, it was amazing to see how ssh, telnet, smbclient and ldapsearch on an Active Directory Server works without logging in. Kerberos is also capable to encrypt telnet network traffic.
Installation was fast, too. It took only long to understand the architecture of Kerberos. Fortunatelly oreilly has a nice book, too.