Older blog entries for jas (starting at number 29)

Unattended SSH with Smartcard

I have several backup servers that run the excellent rsnapshot software, which uses Secure Shell (SSH) for remote access. The SSH private key of the backup server can be a weak link in the overall security. To see how it can be a problem, consider if someone breaks into your backup server and manages to copy your SSH private key, they will now have the ability to login to all machines that you take backups off (and that should be all of your machines, right?).

The traditional way to mitigate SSH private key theft is by password protecting the private key. This works poorly in an unattended server environment because either the decryption password needs to be stored in disk (where the attacker can read it) or the decrypted private key has to be available in decrypted form in memory (where attacker can read it).

A better way to deal with the problem is to move the SSH private key to a smartcard. The idea is that the private key cannot be copied by an attacker who roots your backup server. (Careful readers may have spotted a flaw here, and I need to explain one weakness with my solution: an attacker will still be able to login to all your systems by going through your backup server, however it will require an open inbound network connection to your backup server and the attacker will never know what your private key is. What this does is to allow you to more easily do damage control by removing the smartcard from the backup server.)

In this writeup, I’ll explain how to accomplish all this on a Debian/Ubuntu-system using a OpenPGP smartcard, a Gemalto USB Shell Token v2 with gpg-agent/scdaemon from GnuPG together with OpenSSH.

First we need to install some packages. The goal is to configure OpenSSH to talk to the gpg-agent which will start and talk to scdaemon which in turn talks to pcscd which talks to the smart card reader. For some strange reason, the scdaemon binary is shipped with GnuPG’s S/MIME interface in the gpgsm package.

# apt-get install pcscd gnupg-agent gpgsm

The above command should install and start pcscd and if all works well, you should be able to check the status of the smartcard using GnuPG.

# gpg --card-status

You need to initialize the smartcard and generate a private key on it, again using GnuPG. If you trust GnuPG more than the smartcard to generate a good private key, you may generate the private key using GnuPG and then move it onto the smartcard (hint: use the keytocard command). Make sure you don’t leave a copy of the private key on the same machine!

# gpg --card-edit
gpg: detected reader `Gemalto GemPC Key 00 00'
gpg/card> admin
Admin commands are allowed

gpg/card> name
Cardholder's surname:
Cardholder's given name: host.example.org
gpg: 3 Admin PIN attempts remaining before card is permanently locked

Please enter the Admin PIN
gpg: gpg-agent is not available in this session

gpg/card> lang
Language preferences: en

gpg/card> generate
Make off-card backup of encryption key? (Y/n) n

Please enter the PIN
What keysize do you want for the Signature key? (2048)
What keysize do you want for the Encryption key? (2048)
What keysize do you want for the Authentication key? (2048)
Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all
Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and Email Address in this form:
    "Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>"

Real name: host.example.org
Email address:
You selected this USER-ID:

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
gpg: existing key will be replaced
gpg: please wait while key is being generated ...
gpg: key generation completed (33 seconds)
gpg: signatures created so far: 0
gpg: existing key will be replaced
gpg: please wait while key is being generated ...
gpg: key generation completed (18 seconds)
gpg: signatures created so far: 1
gpg: signatures created so far: 2
gpg: existing key will be replaced
gpg: please wait while key is being generated ...
gpg: key generation completed (23 seconds)
gpg: signatures created so far: 3
gpg: signatures created so far: 4
gpg: key 12345678 marked as ultimately trusted
public and secret key created and signed.

gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
pub   2048R/12345678 2011-09-19
      Key fingerprint = 1234 5678 1234 5678 1234  5678 1234 5678 1234 5678
uid                  host.example.org
sub   2048R/23456789 2011-09-19
sub   2048R/34567890 2011-09-19

gpg/card> quit

Now for the interesting part. OpenSSH talks to an agent for private key handling, and GnuPG’s gpg-agent supports this protocol when the --enable-ssh-support parameter is given. During startup, gpg-agent will print some environment variables that needs to be set when ssh is run. Normally gpg-agent is invoked by the Xsession.d login scripts, so that the environment variables are inherited by all your processes. However, for an unattended machine without any normal login process, we need to write a script to start gpg-agent. First do these manual steps, to confirm that everything works.

# gpg-agent --daemon --enable-ssh-support > /var/run/gpg-agent-info.env
# . /var/run/gpg-agent-info.env
# ssh-add -L
ssh-rsa AAAAB3N... cardno:000500000BD8

If the final step printed a SSH public id, the (sometimes) tricky part in getting the hardware to work is (hopefully) complete. What remains is to script things so that gpg-agent is started on boot and to make sure that your backup scripts has the proper environment variables before launching whatever processes will launch ssh. Further, since we will be running unattended, we need a mechanism to unlock the smartcard using a PIN interactively once on each boot of the machine. I prefer manually entering the PIN on every boot over having the PIN stored in a file on the disk.

I will use the /etc/rc.local mechanism to start gpg-agent, like this:

# cat> /etc/rc.local
#!/bin/sh -e
exec gpg-agent --daemon --enable-ssh-support \
    --pinentry-program /usr/local/sbin/pinentry-unattended \
    --write-env-file /var/run/gpg-agent-info.env

The astute reader will now ask what /usr/local/sbin/pinentry-unattended is and why it is needed. Now here is the situation. scdaemon will normally query the user for a PIN using a tool called pinentry which reads and write to the user’s TTY directly. This won’t work in unattended mode, so we want the scdaemon to signal failure here — unless we are actually unlocking the smartcard manually. Here is the entire script:

# /usr/local/sbin/pinentry-unattended -- by Simon Josefsson
if test x"$PINENTRY_USER_DATA" = xinteractive; then
    exec pinentry "$@"
exit 1

What remains is a script to unlock the smartcard by providing the PIN. This is typically invoked manually if the server has restarted for some reason. Don’t worry, any ssh sessions invoked by cron until you have managed to unlock the smartcard will fail with an authentication error — it won’t hang waiting for a PIN to be entered.

# /usr/local/sbin/unlock-smartcard -- by Simon Josefsson.
. /var/run/gpg-agent-info.env; export GPG_AGENT_INFO SSH_AUTH_SOCK SSH_AGENT_PID
gpg-connect-agent 'scd killscd' /bye > /dev/null
while ! gpg-connect-agent 'scd serialno' /bye | grep -q SERIALNO; do
    sleep 1

And the script checkpin is as follows:

# /usr/local/sbin/checkpin -- by Simon Josefsson.
id=`gpg-connect-agent 'scd serialno' /bye | head -1 | cut -d\  -f3`
gpg-connect-agent "scd checkpin $id" /bye | grep -q OK

At this point, you should have everything configured and installed. Don’t forget to chmod +x the scripts. The typical use-pattern is as follows. After the machine has been started, gpg-agent is running but the smartcard is not unlocked with the PIN. You need to manually login to the machine and run ‘unlock-smartcard’ and enter the PIN. In the script that runs the backup jobs, invoked via cron, make sure that the first line of the scripts reads (assuming Bourne shell script syntax):

. /var/run/gpg-agent-info.env; export GPG_AGENT_INFO SSH_AUTH_SOCK SSH_AGENT_PID

To avoid needlessly attempting ssh connections if the smartcard is not unlocked, your backup script can also call the checkpin code and abort if it doesn’t return true.

checkpin || exit 1

Some final words about debugging. A basic command to run to check that the GnuPG side is working is gpg --card-status, it should print some information about the smartcard if successful. To check that the SSH agent part is working, use ssh-add -L. If you get error messages, try killing the scdaemon process by running killall -9 scdaemon and let gpg-agent respawn a new scdaemon process.

That’s it! If you like my writeup, please flattr it. :)

flattr this!

Syndicated 2011-10-11 09:34:41 from Simon Josefsson's blog

OpenWRT with Huawei E367 and TP-Link TL-WR1043ND

The ability to connect a 3G modem to a wireless router to form a Internet connected ad-hoc network of machines is very powerful. I’ve done this many times and have written about it before (e.g., see my OpenWRT writeup page) but I recently did it with modern hardware again. Here I will use the TP-Link TL-WR1043ND wireless router (available here for around $50) together with the Huawei E367 3G UMTS/HSDPA modem. Other wireless routers and modem should work fine. The software is OpenWRT 10.03 although I hope to redo this with LibreWRT eventually. My writeup is mostly focused around what is happening around the prompt, so it is mostly a cut’n'paste terminal session with a comment interlined.

TL-WR1043ND and Huawei 367

Router and modem

The first step is to flash the firmware with OpenWRT. The OpenWRT wiki page for the TL-WR1043ND covers this in detail, and for any other hardware you should find what you need in the OpenWRT wiki. If you have already installed OpenWRT on the TL-WR1043ND, and want to wipe it out and start from scratch (like I did for this writeup) here is how to do it:
root@choco:~# cd /tmp
root@choco:/tmp# wget http://downloads.openwrt.org/backfire/10.03/ar71xx/openwrt-ar71xx-tl-wr1043nd-v1-squashfs-sysupgrade.bin
Connecting to downloads.openwrt.org (
openwrt-ar71xx-tl-wr 100% |*******************************|  2688k 00:00:00 ETA
root@choco:/tmp# md5sum openwrt-ar71xx-tl-wr1043nd-v1-squashfs-sysupgrade.bin
9927973ba5da65d0d52e255397452b87  openwrt-ar71xx-tl-wr1043nd-v1-squashfs-sysupgrade.bin
root@choco:/tmp# mtd -r write /tmp/openwrt-ar71xx-tl-wr1043nd-v1-squashfs-sysupgrade.bin firmware
Unlocking firmware ...
Writing from /tmp/openwrt-ar71xx-tl-wr1043nd-v1-squashfs-sysupgrade.bin to firmware ...
Rebooting ...

The device will reboot automatically when it is done. After say 30 seconds, try to connect to it using the default IPv4 address I have connected the WAN port to the Internet and connect to the router over local network connected to the router’s LAN1 input. Let’s configure OpenWRT, I’m calling the host ‘choco’ and giving it the IPv4 address I’ll also set a good root password to disable telnet, and add some SSH keys to simplify remote login.

jas@latte:~$ telnet
Connected to
Escape character is '^]'.
 === IMPORTANT ============================
  Use 'passwd' to set your login password
  this will disable telnet and enable SSH

BusyBox v1.15.3 (2010-04-06 03:14:11 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 Backfire (10.03, r20728) --------------------------
  * 1/3 shot Kahlua    In a shot glass, layer Kahlua
  * 1/3 shot Bailey's  on the bottom, then Bailey's,
  * 1/3 shot Vodka     then Vodka.
root@OpenWrt:/# passwd
Changing password for root
New password:
Retype password:
Password for root changed by root
root@OpenWrt:/# sed -i -e 's/OpenWrt/choco/' /etc/config/system
root@OpenWrt:/# sed -i -e 's/' /etc/config/network
root@OpenWrt:/# cat>/etc/dropbear/authorized_keys
ssh-rsa AAAAB3NzaC1yc2...
root@OpenWrt:/# dropbearkey -y -f /etc/dropbear/dropbear_rsa_host_key
Public key portion is:
ssh-rsa AAAA... root@OpenWrt
Fingerprint: md5 45:fd:62...

You could reboot the machine here to switch from telnet to SSH, but I’ll install a bunch of packages while I’m at it. Run ‘opkg update’ to update the package list, and then install the wireless modules for the TL-WR1043ND.

root@OpenWrt:/# opkg update
Downloading http://downloads.openwrt.org/backfire/10.03/ar71xx/packages/Packages.gz.
Inflating http://downloads.openwrt.org/backfire/10.03/ar71xx/packages/Packages.gz.
Updated list of available packages in /var/opkg-lists/packages.
root@OpenWrt:/# opkg install kmod-ath9k wpad-mini
Configuring iw.
Configuring kmod-crypto-core.
Configuring kmod-crypto-arc4.
Configuring kmod-crypto-aes.
Configuring wireless-tools.
Configuring kmod-cfg80211.
Configuring kmod-mac80211.
Configuring kmod-ath.
Configuring kmod-ath9k.
Configuring crda.
Configuring wpad-mini.

Next I’ll install some packages that will are needed for the modem.

root@OpenWrt:/# opkg install comgt kmod-usb-serial kmod-usb2 kmod-usb-uhci kmod-usb-ohci usb-modeswitch
Configuring kmod-nls-base.
Configuring kmod-usb-core.
Configuring chat.
Configuring kmod-usb-ohci.
Configuring kmod-usb2.
Configuring comgt.
Configuring usb-modeswitch.
Configuring kmod-usb-serial.
Configuring kmod-usb-uhci.

Now let’s reboot the machine and try to get things to really work.

root@OpenWrt:/# sync
root@OpenWrt:/# reboot

Use SSH to connect to the router, and don’t forget the use its new IPv4 address!

3G modems are notoriously known for not acting as a modem directly. Instead they often simulate a CD-ROM that will install device driver software, for inferior operating systems. Fortunately the usb_modeswitch tool “fixes” the hardware for us. My Huawei E367 start up with the USB vendor/product IDs 0x12d1:0×1446, you normally find this out by looking in /proc/bus/usb/devices. Here is the output on my device:

root@choco:~# cat /proc/bus/usb/devices
T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=12d1 ProdID=1446 Rev= 0.00
S:  Manufacturer=Huawei Technologies
S:  Product=HUAWEI Mobile
C:* #Ifs= 2 Cfg#= 1 Atr=c0 MxPwr=500mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
E:  Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

This means I have to go find a usb-modeswitch configuration for this device. Fortunately, I found it on my Debian Squeeze box in /etc/usb_modeswitch.d/12d1:1446 (from the usb-modeswitch-data package). There was a slight problem with the file, it didn’t specify the correct USB vendor/product ID of the device after it has been “switched”. My Huawei E367 switches to 12d1:1506, so I add ’1506′ to the ‘TargetProductList’ list. Here is the final configuration:

root@choco:~# cat>/etc/usb-modeswitch.conf

DefaultVendor= 0x12d1

TargetVendor=  0x12d1



Now you should be able to run usb_modeswitch to perform the “switch”:

root@choco:~# usb_modeswitch 

Looking for target devices ...
 No devices in target mode or class found
Looking for default devices ...
 Found default devices (1)
Accessing device 002 on bus 001 ...
Using endpoints 0x01 (out) and 0x81 (in)
Inquiring device details; driver will be detached ...
Looking for active driver ...
 No driver found. Either detached before or never attached

SCSI inquiry data (for identification)
  Vendor String: HUAWEI
   Model String: Mass Storage
Revision String: 2.31

USB description data (for identification)
Manufacturer: Huawei Technologies
     Product: HUAWEI Mobile
  Serial No.: not provided
Setting up communication with interface 0 ...
Trying to send the message to endpoint 0x01 ...
 OK, message successfully sent

Checking for mode switch (max. 20 times, once per second) ...
 Waiting for original device to vanish ...
 Original device can't be accessed anymore. Good.
 Searching for target devices ...
 Searching for target devices ...
 Searching for target devices ...
 Searching for target devices ...
 Searching for target devices ...
 Found correct target device

Mode switch succeeded. Bye.


The /proc/bus/usb/devices file will now contain information about the real device:

root@choco:~# cat /proc/bus/usb/devices
T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  3 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=12d1 ProdID=1506 Rev= 0.00
S:  Manufacturer=Huawei Technologies
S:  Product=HUAWEI Mobile
C:* #Ifs= 7 Cfg#= 1 Atr=c0 MxPwr=500mA
A:  FirstIf#= 1 IfCount= 2 Cls=02(comm.) Sub=00 Prot=00
I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=01 Prot=01 Driver=(none)
E:  Ad=81(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
I:* If#= 1 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=01 Prot=09 Driver=(none)
E:  Ad=83(I) Atr=03(Int.) MxPS=  64 Ivl=2ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=08 Driver=(none)
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=03 Driver=(none)
E:  Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=01 Prot=02 Driver=(none)
E:  Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms
I:* If#= 5 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
E:  Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 6 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none)
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms

Let’s put that command in /etc/rc.local so that it will be run on every boot.

root@choco:~# cat /etc/rc.local
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

exit 0

We are not quite ready, the “usbserial” module needs to be told which USB vendor/product to use. The /etc/modules.d/60-usb-serial file is used during boot to set the right parameters. You can also run ‘rmmod’ followed by ‘insmod’ with the proper parameters to avoid a reboot. You can use the “gcom info” tool to find some information about the modem. Normally you use /dev/ttyUSB0 but for some reason it does not work for me and instead I had to use /dev/ttyUSB3.

root@choco:~# cat>/etc/modules.d/60-usb-serial
usbserial vendor=0x12d1 product=0x1506 maxSize=4096
root@choco:~# rmmod usbserial
root@choco:~# insmod usbserial vendor=0x12d1 product=0x1506 maxSize=4096
root@choco:~# gcom -d /dev/ttyUSB3 info
##### Wireless WAN Modem Configuration #####
Product text:

Manufacturer: huawei
Model: E367
Revision: 11.807.05.00.00
IMEI: 353613040739180
Manufacturer:           huawei
IMEI and Serial Number: 353613040739180
Manufacturer's Revision:
Hardware Revision:      NOT
Network Locked:         ERROR:
Customisation:          NOT SUPPORT
Band settings:          (NOT)
APN:                    ERROR:
##### END #####

Let’s configure network and wireless. The configurations files are /etc/config/network and /etc/config/wireless. Edit them using your favorite editor, or vi. I’m setting up a PSK2 encrypted WLAN and I have a WDS to connect two wireless routers. Note that you need to use the correct PIN for your SIM card (here I’m using 8328) and set the APN correctly (I’m using ‘bredband.tre.se’). Reboot after making these changes.

root@choco:~# cat /etc/config/network
config 'interface' 'loopback'
       option 'ifname'   'lo'
       option 'proto'    'static'
       option 'ipaddr'   ''
       option 'netmask'  ''

config 'interface' 'lan'
        option 'ifname'   'eth0.1'
        option 'type'     'bridge'
        option 'proto'    'static'
        option 'ipaddr'   ''
        option 'netmask'  ''

#config 'interface' 'wan'
#        option 'ifname' 'eth0.2'
#        option 'proto' 'dhcp'

config 'switch'
	option 'name' 'rtl8366rb'
        option 'reset' '1'
        option 'enable_vlan' '1'

config 'switch_vlan'
        option 'device' 'rtl8366rb'
        option 'vlan' '1'
        option 'ports' '1 2 3 4 5t'

config 'switch_vlan'
        option 'device' 'rtl8366rb'
        option 'vlan' '2'
        option 'ports' '0 5t'

config interface wan
        option ifname   ppp0
        option proto    3g
        option device   /dev/ttyUSB0
        option apn      bredband.tre.se
        option pincode  8328
root@choco:~# cat /etc/config/wireless
config wifi-device  radio0
	option type     mac80211
	option channel  5
	option macaddr	00:27:19:fc:87:b2
	option hwmode	11ng
	option htmode	HT20
	list ht_capab	SHORT-GI-40
	list ht_capab	DSSS_CCK-40

config wifi-iface
	option device   radio0
	option network  lan
	option mode     ap
	option ssid     Grisslan
	option encryption psk2
	option key	  notforyoutosee

config wifi-iface
        option device     radio0
        option network    lan
        option mode       wds
        option bssid      00:1F:C6:60:D3:11
        option ssid       GrisslanWDS
        option encryption psk2
        option key        thisisalsosecret
root@choco:~# reboot

Once the machine have rebooted, you can bring up the 3G connection by using “ifup wan”. Look at the log by using “logread” and tail the log in the background by doing “logread -f &”.

root@choco:~# ifup wan
Trying to set PIN
PIN set successfully
root@choco:~# logread |tail -20
May 21 13:41:20 choco local2.info chat[2419]: send (ATD*99***1#^M)
May 21 13:41:20 choco local2.info chat[2419]: expect (CONNECT)
May 21 13:41:20 choco local2.info chat[2419]: ^M
May 21 13:41:20 choco local2.info chat[2419]: ATD*99***1#^M^M
May 21 13:41:20 choco local2.info chat[2419]: CONNECT
May 21 13:41:20 choco local2.info chat[2419]:  -- got it
May 21 13:41:20 choco local2.info chat[2419]: send ( ^M)
May 21 13:41:20 choco daemon.info pppd[2412]: Serial connection established.
May 21 13:41:20 choco daemon.info pppd[2412]: Using interface ppp0
May 21 13:41:20 choco daemon.notice pppd[2412]: Connect: ppp0  /dev/ttyUSB0
May 21 13:41:24 choco daemon.warn pppd[2412]: Could not determine remote IP address: defaulting to
May 21 13:41:24 choco daemon.notice pppd[2412]: local  IP address
May 21 13:41:24 choco daemon.notice pppd[2412]: remote IP address
May 21 13:41:24 choco daemon.notice pppd[2412]: primary   DNS address
May 21 13:41:24 choco daemon.notice pppd[2412]: secondary DNS address
May 21 13:41:24 choco daemon.info dnsmasq[1028]: reading /tmp/resolv.conf.auto
May 21 13:41:24 choco daemon.info dnsmasq[1028]: using nameserver
May 21 13:41:24 choco daemon.info dnsmasq[1028]: using nameserver
May 21 13:41:24 choco daemon.info dnsmasq[1028]: using local addresses only for domain lan
May 21 13:41:25 choco user.notice rdate: Synced with ptbtime1.ptb.de


Or almost so… usually the first time you connect, I often get incorrect DNS servers from the server. It shows up like this in the log:

May 21 12:25:04 choco daemon.notice pppd[1157]: primary   DNS address
May 21 12:25:04 choco daemon.notice pppd[1157]: secondary DNS address

The exact reason why this happens is beyond me. There are patches floating around for pppd, but I haven’t tried them. A common workaround is to hardcode static DNS servers (like Google DNS or OpenDNS). I have come up with my own workaround, based on the observation that when the problem has occurred it will not happen again if I disconnect and reconnect. Thus I have written a small script which is invoked whenever an interface is brought up (typically the WAN interface).

# Written by Simon Josefsson May 2011.
root@choco:~# cat> /etc/hotplug.d/iface/01-reconnect-if-dns-is-broken
case "${ACTION:-ifup}" in
	    if grep -q /tmp/resolv.conf.auto; then
		(sleep 30 && ifdown wan && ifup wan) &
root@choco:~# chmod +x /etc/hotplug.d/iface/01-reconnect-if-dns-is-broken

That’s it! If you found this writeup useful, please flattr it.

Syndicated 2011-05-22 07:25:56 from Simon Josefsson's blog

Introducing the OATH Toolkit

I am happy to announce a project that I have been working quietly on for about a year: the OATH Toolkit. OATH stands for Open AuTHentication and is an organization that specify standards around authentication. That is a pretty broad focus, but practically it has translated into work on specifying standards around deploying and using electronic token based user authentication such as the YubiKey.


OATH’s most visible specification has been the HOTP algorithm which is a way to generate event-based one-time passwords from a shared secret using HMAC-SHA1. HOTP has been published through the IETF as RFC 4226. Built on top of HOTP is the time-based variant called TOTP, which requires a clock in the token. OATH do some other work too, like specifying a data format for transferring the token configuration data (e.g., serial number and shared secret) called PSKC.

The aim of my project OATH Toolkit is to provide an implementation of various OATH related technologies. I’m intentionally leaving it open ended because you never know what they may specify that I find interesting. However, the primary goal has been to focus on HOTP and TOTP. Throughout 2010, the project was called HOTP Toolkit but that name made it difficult to support TOTP in a non-confusing way. During the last month, after discussion with Daniel Pocock on Dynalogin which is a potential consumer of my package, I took the time to create a fork of the HOTP Toolkit and the OATH Toolkit was born.

Now what does the OATH Toolkit actually do? Primarily it provides a library called liboath that implements HOTP and TOTP. Liboath is a relatively small library, and my goal is to keep it well documented and of high quality. There is GTK-DOC generated API documentation. Of course there is a command line tool to go with it, called oathtool which makes working with HOTP/TOTP from the command line easier. It can generate and validate one-time passwords. Let’s say you want to generate the first four OTP based on the dummy key 1234.

jas@latte:~$ oathtool -w4 1234

By default the tool is using HOTP, but you can switch it into TOTP mode with the –totp parameter. The output OTP will now depend on the current time on your machine, unless you specify the time manually using the –now parameter.

jas@latte:~$ oathtool –now=”2011-01-20 15:46 UTC” –totp 1234

The tool can do more, check the oathtool man page for all the details.

The final component of the OATH Toolkit is a PAM module pam_oath. With it, you can login to your machine using an OTP and optionally a password. Right now the user and password management is simplistic, but that should improve over time. To setup single-factor authentication for su you would create a file containing the user information and HOTP key as /etc/users.oath like this:

HOTP root – 1234

Then configure PAM to use the pam_oath module like this in /etc/pam.d/su:

auth requisite pam_oath.so debug usersfile=/etc/users.oath window=20

The user file will be rewritten every time you su to hold the current state. There is a README for the PAM-module with more documentation.

That’s it for an intro! From the OATH Toolkit webpage we link to binary packages for Debian and Ubuntu so please try the OATH Toolkit yourself and provide feedback to the oath-toolkit-help mailing list.

Syndicated 2011-01-20 16:09:37 from Simon Josefsson's blog

On Password Hashing and RFC 6070

The RFC Editor has announced a new document, RFC 6070, with test vectors for PKCS5 PBKDF2. The document grow out of my implementation of SCRAM for GNU SASL. During interop testing, more than one other implementation turned out to have mistakes in the PBKDF2 implementation. It didn’t help that there weren’t any stable test vectors for PBKDF2, so that we could do black-box testing of our PBKDF2 implementations against well-known and stable test vectors. Debugging this was time consuming. The document addresses this problem.

So what is PBKDF2?

Briefly, the PBKDF2 is the state of the art way to convert a password string into a cryptographic binary key. There are many ways to design such an algorithm. To understand why PBKDF2 is designed the way it is we need some basic understanding. The typical attack you would be concerned with is if someone compromises your authentication servers and steals the credential database. This is what happened with the recent Gawker attack, where passwords were apparently stored in clear text.

The first security improvement compared to storing passwords in clear text is to only store a hashed or encrypted form of the password. Hashing is preferable over encryption in this context, because with encryption it is possible to go back to the unencrypted form (if you know the key) whereas with a hash it is computationally infeasible to do so.

The downside of hashing is that it is impossible to be compatible with all kind of authentication systems: the hash of the password in the database needs to be computed using the same algorithm as the system will be using. Unfortunately there are many different schemes out there to do password hashing, including the old Unix crypt(3) algorithm and the Windows LM-hash. You normally never know in advance what kind of systems your hashed credential database needs to work for, so you have to pick some set of algorithms and hope for the best.

The next security improvements are iterations and salting.

Iterations means to run the hash function not once, but hundreds or even thousands of times, on the input data (e.g., password). The extra time is hardly noticeable for the user, but for an attacker who is testing an entire dictionary of common passwords against your hash, making the work cost thousand times higher quickly makes the attack vector computationally infeasible.

Salting means to include something other than the password in the input to the hash function, typically a random string. Without salting, a pre-computed rainbow table would provide a dictionary attack against all hashed password databases (one rainbow table per hashing algorithm). By using a sufficiently long and random salt, a rainbow table for one system is not applicable to another system. Since generating a rainbow table is time consuming, this adds another barrier to the attacker.

PBKDF2 combines these three concepts — hashing, iteration and salting — into one construct, and it is designed flexible enough so that it can work on any pseudo-random function. In practice, I’ve only ever seen HMAC-SHA1 be used.

Some final words on the publication behind RFC 6070: Out of my earlier publications, this was the document that (by a large margin) spent the least time in the IETF process. You see various milestones of the document in the RFC 6070 datatracker history page. The time in the publication process was from 2010-08-09 to 2011-01-06. One month was in the AUTH48 state, of which the initial 20 days were waiting for me to respond. Thank you to my sponsoring AD, Sean Turner, for making this possible!

Syndicated 2011-01-07 12:55:05 from Simon Josefsson's blog


I have finished the SCRAM implementation in GNU SASL. The remaining feature to be added were support for the “enhanced” SCRAM-SHA-1-PLUS variant instead of just the normal SCRAM-SHA-1 mechanism. The difference is that the latter supports channel bindings to TLS, which makes it possible to detect man-in-the-middle attacks even if TLS is not used with server authentication. In GnuTLS we recently added an API for applications to extract channel bindings, which you will need to use in order to use SCRAM-SHA-1-PLUS. I announced the experimental version 1.5.4 release together with a writeup on how to test it. With this, our support for SCRAM should be complete.

Syndicated 2010-11-16 23:24:48 from Simon Josefsson's blog

Debian on Lenovo X201

I have bought a new laptop/netbook, a Lenovo X201. My initial reactions are positive. It runs Debian better than my old Dell laptop does (see my Debian on Dell Precision M65 writeup). The rest of this article will be devoted to notes and information about running a GNU/Linux system on the Lenovo X201.

First the hardware configuration and quick status summary of how well each piece is working:

CPU Intel Core i7 620M 2.67GHz OK
RAMSamsung 4GB RAM DDR3 1333 MHz PC3-10600 OK
BIOS Lenovo v1.22 dated 2010-08-23 OK
Disk Seagate Momentus 320GB ST9320423AS OK
Graphics Intel GMA HD integrated OK
Screen (internal) 1200×800 12.1″ WXGA TFT OK
Screen (external) DisplayPort support for at least 1920×1200 OK
Webcam Lenovo/Chicony Camera OK
Mouse UltraNav TrackPoint/TouchPad OK
Ethernet Intel PRO/1000 (e1000) 82577LM OK
CD/DVD burner Matshita DVD-RAM (in Lenovo X200 UltraBase) OK
Card reader Generic USB2.0-CRW ID 0bda:0159 OK
Bluetooth Broadcom USB ID 0a5c:217f OK
Fingerprint Upek USB ID 147e:2016 ?
Modem ? ?
Audio Intel 5 Series/3400 HD-Audio FAIL
Wireless Intel Centrino Ultimate-N 6300 FAIL
3G Qualcomm Gobi 2000 FAIL
GPS Qualcomm Gobi 2000 FAIL

I’m also using a Omnikey 4321 ExpressCard smart card reader, but it was not included in the laptop.

For reference, this laptop was labeled “3323″ and “NUSRCMS” from the reseller. It included the UltraBase X200 as a combo.


The installation was unexciting except for software bugs that were easy to work around and that I expect will be resolved eventually. For more information, see my installation report. It also contains “lsusb” and “lspci” output if you are curious about hardware details.

Hdparm testing of the hard drive:

 Timing cached reads:   9188 MB in  2.00 seconds = 4596.31 MB/sec
 Timing buffered disk reads:  280 MB in  3.02 seconds =  92.78 MB/sec

The Intel graphics is working fine, both the internal TFT and the external DisplayPort. I’m driving my Dell 2405FPW (DVI) to 1920×1200 without issues. Cycling through monitors with Fn-F7 works out of the box.

Wired ethernet via X200 UltraBase works. The UltraBase do not appear to contain another ethernet card, it is just another ethernet socket for the internal ethernet port.

I have tested bluetooth for file browsing and connecting to the Internet via my Nokia N900.

The card reader handled a SD card fine, haven’t tested other formats.

The ExpressCard54 slot handles my OmniKey 4321 smart card reader without issues, together with pcscd and GnuPG. However, the mecanical button used to eject cards is poorly made and does not handle the force required to eject the card.

Suspend to RAM+Disk is working fine, and the special keys Fn+F4 to suspend works.

I’m able to hotplug connect to the UltraBase docking station.

Fingerprint reader is not yet tested.

Audio does not work

Not working out of the box. I’ll update this section when I know how to fix it.

Wireless does not work

The built-in Intel Centrino 6300 does not work without non-free software installed.

Workaround: I downloaded the firmware from Intel Linux Wireless and unpacked it into /lib/firmware. An older version of the firmware is available from the firmware-iwlwifi Debian package in non-free. With this installed, it is working reliable and handles suspend fine.

Gobi 2000 3G/GPS does not work

It appears to require non-free drivers. It works under Ubuntu 10.10 so it should be possible to get it to work under Debian as well. I’ll add more details here later once I figure things out.

Syndicated 2010-10-25 22:39:54 from Simon Josefsson's blog

GS2-KRB5 using GNU SASL and MIT Kerberos for Windows

I have blogged about GNU SASL and GS2-KRB5 with the native Kerberos on Mac OS X before, so the next logical step has been to support GS2-KRB5 on Windows through MIT Kerberos for Windows (KfW). With the latest release of GNU SASL 1.5.2 I have added support for the KfW GSS-API library. There were several issues in completing this due to problems with KfW, but I won’t bore you with those details.

What is important is to demonstrate how GNU SASL can now talk IMAP authenticated with GS2-KRB5 using KfW on native Windows. Below are two screenshots. The first shows how the MIT Network Identity Manager is invoked automatically to get a ticket. The next screenshot is showing the completed GS2-KRB5 login.

I have prepared GNU SASL with KfW binaries. The manual contains a new section about Kerberos on Windows with details how to build it. The build makefile is available too, if you want to build your own.

Syndicated 2010-09-27 12:14:58 from Simon Josefsson's blog

Bridging SASL and GSS-API: GS2

Yesterday (12th July 2010) the RFC editor announced the publication of RFC 5801, which I’m co-author of. The GS2 document has taken 5 years to reach this status, see my page on GS2 status.

So what is GS2? Briefly explained, it is a method that turns every GSS-API mechanism (with some caveats) into a SASL mechanism automatically. The document describes a way to transform GSS-API mechanism OIDs (e.g., 1.2.840.113554.1.2.2) into SASL mechanism names (e.g., GS2-QLJHGJLWNPL) which takes care of uniquely identifying each mechanism in each framework. The content of each SASL message is exactly the same as the GSS-API context tokens, except (no rules without exceptions..) for the first message from the client to the server. The first message is modified to include a short prefix — called the “GS2 header” — before the first GSS-API context token. The shortest GS2 header is “n,,” which denotes that no channel binding is supported and no authorization identity is present. The GSS-API context token is modified to remove the ASN.1 blob that RFC 2743 section 3.1 requires to be present.

One important aspect of the GS2 design is that we make it easy for SASL mechanisms to become GSS-API mechanisms. To align a SASL mechanism to the GS2 framework, and thus to make it a GSS-API mechanism, a few steps are required. First, you need to assign an OID for the mechanism (if you don’t know how to do this, just contact me and I’ll assign an OID for you). Then you need to make sure the first message is compatible with GS2 in that it uses the GS2 header to signal channel binding and authorization identity. Finally, you need some discussion about what it means for your SASL mechanism to be used as a GSS-API mechanism. This may include discussions on naming types, meaning and use of GSS-API flags, whether delegated credentials are supported, how per-message tokens work.

The primary example SASL mechanism to make use of the GS2 design to become a GSS-API mechanism is SCRAM: also published yesterday as RFC 5802. SCRAM is an updated variant of the CRAM-MD5 and DIGEST-MD5 mechanisms (for example, it uses SHA-1 instead of MD5). Another recent example is the OpenID SASL mechanism.

My project GNU SASL supports both GS2 and SCRAM, see my earlier post on testing GS2-KRB5. I am not aware of any other project that implements GS2 yet, that is why my implementation is still marked as experimental.

Syndicated 2010-07-13 13:58:33 from Simon Josefsson's blog

OpenWRT 10.03 “Backfire”

Earlier I have written about OpenWRT configuration for two routers in a home network and OpenWRT configuration for 3G dial-up (which succeeded my summerhouse OpenWRT writeup) before. The OpenWRT project recently announced a new release, OpenWRT 10.03 Backfire. Thus, this appeared like a good opportunity to wipe out the old configurations on my routers and rewrite the articles using the latest software. I have two articles:

Syndicated 2010-05-03 10:08:15 from Simon Josefsson's blog

GS2-KRB5 in GNU SASL 1.5.0

I have worked in the IETF on the specification for the next generation GSSAPI-to-SASL bridge called GS2 (see my status page for background) for a couple of years now. The specification is (finally!) in the RFC editor’s queue, and is supposed to be stable and final although we are still tuning some details. The next step is to implement the protocol and do interop testing. A couple of months of implementation and testing work culminated in tonight’s release of GNU SASL 1.5.0 (see announcement here). Or should I say that the work can now begin…

To get you started with GS2-KRB5 here is a brief walk-through on installing GNU SASL 1.5.0 on a Mac OS X machine and using it to connect to my GS2-KRB5 interop server. I’m assuming you have already installed a compiler on your system. Start by downloading and installing GNU SASL:

wget -q ftp://alpha.gnu.org/gnu/gsasl/gsasl-1.5.0.tar.gz
tar xfz gsasl-1.5.0.tar.gz
cd gsasl-1.5.0
./configure --prefix=$HOME CFLAGS=-g
make all check install

Next you need to configure Kerberos on your system. If you have already have a configuration, make sure to take a backup of your configuration files. First let’s tell your machine about my interop Kerberos V5 realm by creating a file ~/Library/Preferences/edu.mit.Kerberos with the following content:

        default_realm = interop.josefsson.org

        interop.josefsson.org = {
                kdc = interop.josefsson.org:88

        interop.josefsson.org = interop.josefsson.org

Next get a ticket for a dummy user. Use the password ‘pass’ at the prompt:

espresso:~ jas$ kinit user@interop.josefsson.org
Please enter the password for user@interop.josefsson.org:
espresso:~ jas$ klist
Kerberos 5 ticket cache: 'API:Initial default ccache'
Default principal: user@interop.josefsson.org

Valid Starting     Expires            Service Principal
03/31/10 00:59:04  03/31/10 10:59:02  krbtgt/interop.josefsson.org@interop.josefsson.org
	renew until 01/01/70 01:00:00

klist: No Kerberos 4 tickets in credentials cache
espresso:~ jas$

Next connect to my test IMAP server using the command-line ‘gsasl’ tool (long lines cut for legibility):

espresso:~ jas$ ~/bin/gsasl interop.josefsson.org -auser
Trying `interop.josefsson.org'...
* OK IMAP4rev1

. OK AUTHENTICATE GS2-KRB5 authentication successful
Client authentication finished (server trusted)...
Enter application data (EOF to finish):
. list "" "*"
* LIST (\NoInferiors) NIL INBOX
* LIST (\NoInferiors) "/" .bashrc
* LIST (\NoInferiors) "/" .bash_logout
* LIST (\NoInferiors) "/" .profile
* LIST (\NoInferiors) "/" .bash_history
. OK LIST Completed
. logout
* BYE Session terminating.
. OK LOGOUT Completed
Session finished...
espresso:~ jas$

There! You have just completed a GS2-KRB5 authenticated session.

Of course, this works just as well on your favorite GNU/Linux system, but I thought I’d explain it for a non-GNU platform and GSS-API library to show that the code is quite portable despite its experimental status.

Btw, the server is running GNU Shishi as the Kerberos V5 KDC and GNU MailUtils as the IMAP server. The IMAP server is using GNU SASL in server mode.

Syndicated 2010-03-30 23:10:22 from Simon Josefsson's blog

20 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!