Further Soekris net6501 improvements for OpenBSD

April 30th, 2015

The release of OpenBSD 5.7 brings the latest batch of improvements I made for Soekris net6501 users.

The first change adds platform detection that should in fact work on all Soekris boards, (I think this change actually went in circa 5.4 but I never posted about it). Normally this information comes via the SMBIOS extensions but Soekris boards have a much stripped-down BIOS that lacks any of this support. There are however some vendor and product strings embedded in the BIOS image (probably used for printing on the serial console at POST) so they get picked out and used. For example:

# sysctl hw.vendor hw.product
hw.vendor=Soekris Engineering

The second change adds the skgpio(4) driver which provides access to the GPIO & LEDs on the net6501. Two GPIO devices are provided; gpio0 for the 16 real GPIO pins, (JP8 in the net6501 manual); and gpio1 for the error and ready LEDs coerced into the GPIO framework as output-only pins. Here is what is displayed in dmesg at boot:

skgpio0 at isa0 port 0x680/32                                                  
gpio0 at skgpio0: 16 pins                                                      
gpio1 at skgpio0: 2 pins

You still need to configure the GPIO pins prior to raising the securelevel so add the following to /etc/rc.securelevel as a minimum:

gpioctl -q gpio1 0 set out error_led
gpioctl -q gpio1 1 set out ready_led

Now once the system is booted you can toggle the error LED with the following:

# gpioctl gpio1 error_led 2
pin error_led: state 0 -> 1
# gpioctl gpio1 error_led 2
pin error_led: state 1 -> 0

Exporting Mobile Configuration Profiles from Apple Configurator

January 9th, 2015

As I’ve secured my main Wi-Fi network with WPA2 Enterprise, my Apple Airport devices are pointed at a RADIUS server, which in turn is pointed at an LDAP directory which contains the user details. The LDAP directory does not store the password in the clear which means that authentication methods like CHAP, MSCHAP and MSCHAPv2 don’t work as they require the original password. I need to use EAP-TTLS with PAP authentication however iOS and OS X clients will not attempt this method by default.

It’s theoretically easy to make iOS and OS X clients use this method, you simply install a Mobile Configuration Profile (a file with a .mobileconfig extension) which amongst other things instructs the client how to connect to a given Wi-Fi network. The tricky part is generating this file if you maybe don’t have access to an OS X Server. Apple originally provided the iPhone Configuration Utility (iPCU) which has been deprecated in favour of the Apple Configurator utility. This works fine for iOS devices that you can attach directly by USB but sometimes you might want to transfer a profile to someone via e-mail or install it on an OS X client. It’s not obvious how to export a profile from the tool, but there is a way.

When you open Apple Configurator it looks like this:


If you enable Supervision the Profiles section changes to allow you to click + and create a new profile:


In my profile as a minimum I needed to import the root certificate of the authority used to sign the certificate on my RADIUS server. Then configure my Wi-Fi network with the SSID, Security Type, EAP Type of TTLS and then select PAP as the Inner Authentication. I also trusted the certificate I’d just imported which prevents iOS and OS X prompting you to trust it. By not setting the Username and Password this keeps the profile generic for any user. Then after saving the profile you can then export it:


This gives you the familiar .mobileconfig profile which can then be imported on any iOS or OS X client.

Apple Airport devices and guest networks in bridging mode

January 9th, 2015

The feature of being able to configure a separate guest Wi-Fi network has been present for a while now on Apple Airport gear. However, the documentation only ever alludes to this feature working when the Airport device is running in router/NAT mode, i.e. it’s in charge of connecting directly to the Internet and sharing the connection from your ISP.

Quite often people (like myself) use the Airport device(s) in bridging mode, i.e. as regular access points to attach Wi-Fi clients onto the Local Area Network and then some other device handles the routing and NAT function, (in my case an OpenBSD host), and it would be nice if you could also create a guest Wi-Fi network in this mode. The obvious way I would expect it to work is to utilise VLANs; the Airport device uses a single unique VLAN ID to tag Ethernet frames from clients on the guest Wi-Fi network. As the administrator you can then use that tag to segregate the traffic on your network; usually to allow guests some form of heavily-restricted Internet-only access, and not be able to access the rest of the network. The Airport Utility lets you create the guest network in bridging mode but doesn’t give you any details as to the mechanics of it.

Well it turns out my hunch was correct, it does use VLANs; Ethernet frames from clients on the normal Wireless network stay untagged so they Just Work on your network as before, however Ethernet frames from clients on your guest network are tagged with the VLAN ID 1003. This ID is not mentioned anywhere, nor can it be changed so you’d better hope you’ve not already used that ID for something else.

Armed with that information, I configured my Cisco SG300 switch like so:

switch#configure terminal
switch(config)#vlan database
switch(config-vlan)#vlan 1003
switch(config)#interface vlan 1003
switch(config-if)#name wifi
switch(config)#interface GigabitEthernet 1
switch(config-if)#switchport mode trunk
switch(config-if)#switchport trunk allowed vlan add 1003
switch(config)#interface GigabitEthernet 2
switch(config-if)#switchport mode trunk
switch(config-if)#switchport trunk allowed vlan add 1003
switch#show vlan
Created by: D-Default, S-Static, G-GVRP, R-Radius Assigned VLAN, V-Voice VLAN
Vlan       Name           Tagged Ports      UnTagged Ports      Created by    
---- ----------------- ------------------ ------------------ ---------------- 
 1           1                               gi1-8,Po1-8            D         
1003       wifi             gi1,gi2                                 S

This creates the VLAN, names it, configures two trunk ports where my Airport and OpenBSD router are attached and adds the new VLAN to the list of allowed ones on each port. Finally all that is left to do is to create a VLAN interface on the OpenBSD router:

# cat /etc/hostname.vlan1003
inet vlan 1003 vlandev em0

Providing any DHCP and/or DNS services and firewalling the traffic is outside the scope of this post but you now have a separate interface and subnet that you can treat it like any other regular network.

So now I have two separate wireless networks; one that gives me access to my LAN which I can secure using WPA2 Enterprise and another that can only reach the Internet which can be unrestricted or more likely secured with WPA2 Personal.

Monitoring file modifications with auditd with exceptions

November 19th, 2014

Playing with auditd, I had a need to monitor file modifications for all files recursively underneath a given directory. According to the auditctl(8) man page there are two ways of writing a rule to do this:

-w /directory/ -p wa
-a exit,always -F dir=/directory/ -F perm=wa

The former rule is basically a shortcut for the latter rule; the latter rule is also potentially more expressive with the addition of extra -F conditions. I also needed to ideally exclude certain files and/or sub-directories in the directory from triggering the audit rule and it turns out you do this:

-a exit,never -F dir=/directory/directory-to-exclude/
-a exit,never -F path=/directory/file-to-exclude
-a exit,always -F dir=/directory/ -F perm=wa

According to this post order is important; list the exceptions before the main rule.

Building mod_proxy_wstunnel for CentOS 6

August 6th, 2014

I had a need to be able to put an Apache-based reverse proxy in front of an install of Uchiwa which is a Node.js-based dashboard for Sensu. The only problem is that it uses WebSockets which means it doesn’t work with the regular mod_proxy_http module. In version 2.4.5 onwards there is mod_proxy_wstunnel which fills in the gap however CentOS 6 only has a 2.2.15 (albeit heavily patched) package.

There are various instructions on how to backport the module for 2.2.x (mostly for Ubuntu) but these involve compiling the whole of Apache from source again with the module added via an additional patch. I don’t want to maintain my own Apache packages but more importantly Apache has provided apxs a.k.a the APache eXtenSion tool to compile external modules without requiring the whole source tree available.

So, I have created a standalone RPM package for CentOS 6 that just installs the mod_proxy_wstunnel module alongside the standard httpd RPM package. In order to do this I took the original patch and removed the alterations to the various build files and also flattened the source into a single file, (the code changes were basically adding whole new functions so they were fine to just inline together). The revised source file and accompanying RPM spec file are available in this Github gist.

Using Ultimate GPS to bootstrap Maxim DS3231M

June 11th, 2014

I’m currently building a project that is based around a Maxim DS3231M, which is an I2C-attached RTC.

I’m currently using the chip through the TinyTempus breakout from Phenoptix which only lacks the 32.768 KHz output which I don’t use anyway. I’m using the provided CR1216 battery to keep the clock ticking at all times however I had a need to get the clock set to the right time.

As I had an Adafruit Ultimate GPS breakout I figured it would be easy to just use the time from that to bootstrap the clock to the right time rather than deal with user input. I put together the following basic circuit:


I’ve uploaded the sketch I wrote to GitHub: https://github.com/bodgit/ds3231-from-gps

The sketch uses the undocumented $GPZDA NMEA sentence to retrieve the time from the GPS module and reprograms the DS3231 on receipt of every new sentence so you just need to run the sketch long enough to get the message that the clock is set. Assuming your battery is good, the clock will keep ticking and maintain time accurately after you pull the power.

Enabling $GPZDA NMEA sentence on Adafruit Ultimate GPS

June 10th, 2014

I’ve been using an Adafruit Ultimate GPS module as a time source which with their standard GPS Library provides the $GPRMC NMEA 0183 sentence containing the time and date however I had a preference for the $GPZDA sentence for the simple fact it provides the year as four digits instead of only two.

This forum post suggested it was possible on the MTK3339 chip by sending an unsupported variant of the command that enables the various sentences:


However, this didn’t work. The datasheet provided by Adafruit doesn’t document the majority of the data fields in this command, just identifying them as reserved. I found another datasheet elsewhere which I think is just an older revision of the same document and this has slightly better information. In fact, the command was only slightly wrong, it’s in fact this:


It’s the 18th field, not the 17th as the forum post originally suggested. Sending this command to the GPS module now returns the $GPZDA NMEA sentence. It can be enabled with other sentences, you just need to update the XOR checksum after the * using something like this online tool.

Annoying Keychain bug on Mavericks

January 27th, 2014

Just been bitten by this annoying bug on Mavericks after a seemingly innocuous reboot whereby I’m prompted repeatedly to unlock my “Local Items” keychain. No password I’m aware of works and mashing Cancel just puts you in an endless loop cycling through each application or framework that wants to access said keychain.

The solution is simple as outlined in the linked support document; just nuke the UUID-named folder in ~/Library/Keychains and reboot. The same folder will reappear afterwards but it’s fine to leave it if you’re not prompted to unlock it again. Obviously something got corrupted, possibly related to iCloud.

HP Microserver TPM

January 10th, 2014

I’ve been dabbling with DNSSEC which involves creating a few zone- and key-signing keys, and it became immediately apparent that my headless HP Microserver has very poor entropy generation for /dev/random. After poking and prodding it became apparent there’s no dormant hardware RNG that I can just enable to fix it.

Eventually I stumbled on this post which suggests you can install and make use of the optional TPM as a source of entropy.

I picked up one cheaply and installed it following the above instructions to install and configure it; I found I only needed to remove the power cord for safety’s sake, the TPM connector on the motherboard is right at the front so I didn’t need to pull the tray out.

Also, since that blog post, the rng-tools package on RHEL/CentOS 6.x now includes an init script so it’s just a case of doing the following final step:

# chkconfig rngd on
# service rngd start

It should then be possible to pass this up to any KVM guests using the virtio-rng.ko module.

IPsec between Meraki and OpenBSD

August 6th, 2013

I recently acquired some (Cisco) Meraki networking kit including an MX60 security appliance (read: router, firewall, NAT, etc.).

Once it’s set up and running, I was browsing the dashboard and the site-to-site VPN configuration options. Normally with multiple Meraki devices in use, a fully-meshed VPN can be created automatically with very little configuration.

I also noticed the ability to add non-Meraki VPN peers so I added details for my OpenBSD-based gateway. You can see from the screenshot the details are basic:

meraki dashboard

On the OpenBSD side, I started with a basic configuration in /etc/ipsec.conf:

ike esp from to \
        peer example-xyzzy.dynamic-m.com \
        psk mekmitasdigoat

The Meraki dashboard allows you to register a dynamic DNS record for the MX60 which will be in the .dynamic-m.com domain so you can use this to refer to the remote peer in the configuration, (especially if you have a dynamic IP address).

This configuration didn’t work, but using isakmpd(8)‘s handy -L option to write to /var/run/isakmpd.pcap all of the unencrypted IKE traffic it then becomes apparent the OpenBSD and the Meraki disagree on the phase 1 negotiation; mainly that the Meraki end wants to use Triple DES and OpenBSD prefers AES by default. As there’s no way to tweak the cryptography options on the Meraki side, we change the OpenBED side like so:

ike esp from to \
        peer example-xyzzy.dynamic-m.com \
        main auth hmac-sha1 enc 3des group modp1024 lifetime 28800 \
        quick auth hmac-sha1 enc aes-256 group none lifetime 28800 \
        psk mekmitasdigoat

The main option sets the phase 1 parameters and the quick option sets the phase 2 parameters that match the highest settings out of the handful proposed by the Meraki side.

With that done, all that remains is to ensure isakmpd(8) starts at boot and the rules in /etc/ipsec.conf are automatically loaded by adding the following to /etc/rc.conf.local: