IPSec on Netgear R6300 using DD-WRT or OpenWRT

This is still WIP, so the following just represents a brain dump so I know where to pick up when I come back to this again.

It seems that the current state of Linux is that the KAME patches are integrated into the kernel. All that is required to run IPSec is to configure it correctly, which apparently can be done mostly in two ways using strongSwan or KAME's original racoon.

I'm unsure whether the kernel in DD-WRT v3.0-r29396 giga (04/04/16) contains everything needed to run strongSwan or racoon. Packages for strongSwan and ipsec-tools appear to be available via ipkg from OpenWrt once I enable jffs2 in the GUI under »Administration«.

Once either of them are running, the OpenWrt wiki has instructions for road-warriors to set up strongSwan or racoon.

The problem with running OpenWRT directly is that (as of 2016-02-08) there are no open-source drivers for the 5GHz module. Also note that DD-WRT for Netgear's R6300v1 is based on the brcm47xx branch of OpenWrt (as indicated for example by cat /etc/ipkg.conf) unlike R6300v2 which relies on bcm53xx. This is in spite of the CPU model of the former being reported as »Broadcom BCM5300 chip rev 1«.

Logging https traffic using Raspbian

In order to intercept https traffic, it is necessary to run software on a router or access point that provides its own certificates to clients. Using Mirko Dölle's beautiful instructions, today I set up mitmproxy on a Raspberry Pi 2 running Raspbian based on Debian Jessie. I have an RT5572 based dual band wifi dongle that works very well with Raspbian which I am going to use for clients to connect while the Raspberry Pi 2 itself is connected to the internet via ethernet.

First, I set up Raspbian in the usual way. Then I modified the dhcpcd configuration to assign a static IP address to the wifi adaptor which is going to be my access point. I added the following lines to the end of /etc/dhcpcd.conf.

interface wlan0
static ip_address=192.168.6.1/24

Next, I added the hostapd package and created a configuration file for it:

# apt-get install hostapd
# cat >/etc/hostapd/hostapd.conf <<EOF
interface=wlan0
driver=nl80211
country_code=GB
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0

ssid=rpi-mitm

# 802.11g on #8
hw_mode=g
channel=8

# encryption
wpa=2
wpa_passphrase=pleasehackme
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

# gobbledigook
beacon_int=100
auth_algs=1
wmm_enabled=1
EOF

Before activating, one line in /etc/default/hostapd has to be adjusted:

DAEMON_CONF="/etc/hostapd/hostapd.conf"

In order to assign IP addresses to clients and handle DNS forwarding, I then installed dnsmasq, again creating a configuration for it.

# apt-get install dnsmasq
# cat >>/etc/dnsmasq.conf <<EOF
interface=wlan0
dhcp-range=192.168.6.50,192.168.6.100,12h
EOF

Next, I activated package forwarding by uncommenting the following lines in /etc/sysctl.conf:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

I then set up network address translation by adding a POSTROUTING rule for my WAN interface to the NAT iptables. This setting needs to be persisted by installing the iptables-persistent package.

# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# apt-get install iptables-persistent

Then I restart all the services involved. I disable legacy Debian networking because it takes the wlan0 interface up which prevents hostapd from starting. This completes the setup of the access point.

# systemctl disable networking
# systemctl start hostapd
# systemctl start dnsmasq
# systemctl restart procps

In order to inspect client traffic through the access point, I installed mitmproxy. The version 0.10.1-2 installed by apt-get (on Jessie) is too old, so I install the current version 0.18.2 manually. Since Jessie only provides Python 3.4, I went with Python 2.7.

# apt-get install python-pip python-dev libffi-dev libssl-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev g++
# pip install mitmproxy

To run it, I add a couple of redirections to the inbound interface.

# iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 80 -j REDIRECT --to-port 8080
# iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 443 -j REDIRECT --to-port 8080
# mitmproxy -T --host

Install mitmproxy's certificate on the device by browsing to http://mitm.it/.

To deactivate the capture, it suffices to remove the iptables rules.

# iptables -t nat -F PREROUTING

Logging mobile apps using DD-WRT

Today, I wanted to log the transmissions of a mobile app. I logged into my DD-WRT router and ran the following command.

# tcpdump -i br0 -w moto.pcap host 192.168.5.119

The IP address shown is the address of my mobile phone in my local network.

I then copied the captured file moto.pcap to my desktop computer and opened it in Wireshark which provides a very nice visual way to inspect the transmitted data.

Songs that make me cry

Works almost every time: »Der Weg« by Herbert Grönemeyer, from »Mensch«. »Never ever« by All Saints works almost as well.

Correct local domain and host-name DD-WRT setup

For a long time, I've struggled with inconsistent results for name queries on my local network. For example, sometimes OS X (El Capitan) couldn't ping a host by name while dig (host, nslookup) worked fine.

Also, I had never really tried to understand several options in the DD-WRT setup for domain and host names and the way they affected dnsmasq's configuration, the default DHCP and DNS server on DD-WRT.

My situation is that of a typical home user with a DHCP-assigned IPv4 address and no public host name or top-level domain.

As it turned out, I had got the setup wrong: the »hostname« and »domain name« on the main setup page refer to DHCP options sent to the ISP by the router's DHCP client, udhcpc. My ISP doesn't require any of those, so the fields should be left blank on my setup.

Instead, the right place to set the router's host name is the aptly-named »Router name« field.

The correct place to define the top-level domain of the local network is the »domain name« field in the »DHCP Server« section on the »Services« tab. In addition, »Used domain« must be set to »LAN and WLAN« instead of »WAN« because we don't actually have a »WAN« domain.

By the way, I chose »lan« as the name of my local domain because »local« has been specified for use by mDNS.

As a result, the router's host name is correctly entered into /etc/hosts (both with and without my local domain) and dnsmasq resolves names of local DHCP clients both in their short and long forms.

Use all USB3 ports of Intel DH87RL on El Capitan

Today I succeeded in enabling all of my Intel DH87RL motherboard's USB3 ports.

As it turns out, El Capitan's XHCI driver has a limit of 15 ports which was taken up by the board's USB2 ports, leaving just one USB3 port usable.

Since only 8 USB2 ports are actually physically accessible from the outside, disabling the unused ports makes more USB3 ports available.

In theory, this should happen automatically because OS X evaluates the board's DSDT which should flag the user-accessible ports. Needless to say, the DH87RL's DSDT is buggy, so this method fails. ioreg is a helpful tool to find out the current configuration.

Helpfully, Apple has implemented a port disabling feature to handle the case of buggy DSDTs. Examples can be seen by examining the existing plug-ins of the XHCI drivers, to be found at /System/Library/Extensions/IOUSBHostFamily.kext/Contents/PlugIns/AppleUSBXHCIPCI.kext/Contents/Info.plist. This file contains port specifications for each different computer model.

In order to create my own port specification for my DH87RL, I used the fact that the XHCI controller uses a label of 'XHC1' on Apple's DSDT's, while the DH87RL's XHCI is labelled 'XHC' by the DSDT. This allowed me to create my own kext by matching on the emulated model name 'iMac14,2' in combination with 'XHC'.

By trial and error I found out that the USB2 ports provided by the DH87RL are numbered 1, 2, 3, 4, 6, 8, 9 and A. I created a file /EFI/CLOVER/OEM/DH87RL/kexts/10.11/InjectUSB.kext/Contents/Info.plist with the following contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
 <key>CFBundleDevelopmentRegion</key>
 <string>English</string>
 <key>CFBundleGetInfoString</key>
 <string>1.0.1, Copyright © 2000-2014 Joki Inc. All Rights Reserved.</string>
 <key>CFBundleIdentifier</key>
 <string>org.joki.injector.usb.USBXHCIDH87RL</string>
 <key>CFBundleInfoDictionaryVersion</key>
 <string>6.0</string>
 <key>CFBundleName</key>
 <string>XHC1 injector for DH87RL</string>
 <key>CFBundlePackageType</key>
 <string>KEXT</string>
 <key>CFBundleShortVersionString</key>
 <string>1.0.1</string>
 <key>CFBundleSignature</key>
 <string>????</string>
 <key>CFBundleVersion</key>
 <string>1.0.1</string>
 <key>IOKitPersonalities</key>
 <dict>
  <key>iMac14,2-XHC1</key>
  <dict>
   <key>CFBundleIdentifier</key>
   <string>com.apple.driver.AppleUSBMergeNub</string>
   <key>IOClass</key>
   <string>AppleUSBMergeNub</string>
   <key>IONameMatch</key>
   <string>XHC</string>
   <key>IOProviderClass</key>
   <string>AppleUSBXHCIPCI</string>
   <key>IOProviderMergeProperties</key>
   <dict>
    <key>port-count</key>
    <data>FQAAAA==</data>
    <key>ports</key>
    <dict>
     <key>HS01</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>AQAAAA==</data>
     </dict>
     <key>HS02</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>AgAAAA==</data>
     </dict>
     <key>HS03</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>AwAAAA==</data>
     </dict>
     <key>HS04</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>BAAAAA==</data>
     </dict>
     <key>HS06</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>BgAAAA==</data>
     </dict>
     <key>HS08</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>CAAAAA==</data>
     </dict>
     <key>HS09</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>CQAAAA==</data>
     </dict>
     <key>HS0A</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>CgAAAA==</data>
     </dict>
     <key>SSP1</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>EAAAAA==</data>
     </dict>
     <key>SSP2</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>EQAAAA==</data>
     </dict>
     <key>SSP3</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>EgAAAA==</data>
     </dict>
     <key>SSP4</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>EwAAAA==</data>
     </dict>
     <key>SSP5</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>FAAAAA==</data>
     </dict>
     <key>SSP6</key>
     <dict>
      <key>UsbConnector</key>
      <integer>3</integer>
      <key>port</key>
      <data>FQAAAA==</data>
     </dict>
    </dict>
   </dict>
   <key>model</key>
   <string>iMac14,2</string>
  </dict>
 </dict>
 <key>OSBundleRequired</key>
 <string>Root</string>
</dict>
</plist>

After reboot, I could use all of my USB3 ports (for reference, numbered 9, A, B, C, D and E).

A handy command to see the kernel boot messages is

$ log show --debug --last boot --style compact

Using SATA link power management with Microsoft's driver

Microsoft's default SATA driver starahci.sys appears not to support SATA link power management. So far, I've always installed Intel's Rapid Storage Technology driver iaStor.sys in order to get the benefit of SATA link management.

As it turns out, Microsoft's driver supports link power management, but the setting is hidden in the control panel and the default settings are HIPM only (balanced), HIPM+DIPM (power saving) and deactivated (high performance). However, PowerCfg can be used to change this hidden setting using certain GUIDs.

PowerCfg.Exe /SetACValueIndex SCHEME_MAX SUB_DISK 0b2d69d7-a2a1-449c-9680-f91c70521c60 2
PowerCfg.Exe /SetACValueIndex SCHEME_MIN SUB_DISK 0b2d69d7-a2a1-449c-9680-f91c70521c60 2
PowerCfg.Exe /SetACValueIndex SCHEME_BALANCED SUB_DISK 0b2d69d7-a2a1-449c-9680-f91c70521c60 2
PowerCfg.Exe /SetDCValueIndex SCHEME_MAX SUB_DISK 0b2d69d7-a2a1-449c-9680-f91c70521c60 2
PowerCfg.Exe /SetDCValueIndex SCHEME_MIN SUB_DISK 0b2d69d7-a2a1-449c-9680-f91c70521c60 2
PowerCfg.Exe /SetDCValueIndex SCHEME_BALANCED SUB_DISK 0b2d69d7-a2a1-449c-9680-f91c70521c60 2

The following method can be used to show the link power management settings in control panel. All that is required is to change two values in the registry:

Windows Registry Editor Version 5.00

; Created by: Shawn Brink
; http://www.sevenforums.com
; Tutorial: http://www.sevenforums.com/tutorials/177819-ahci-link-power-management-enable-hipm-dipm.html

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\0012ee47-9041-4b5d-9b77-535fba8b1442\0b2d69d7-a2a1-449c-9680-f91c70521c60]
"Attributes"=dword:00000002

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\PowerSettings\0012ee47-9041-4b5d-9b77-535fba8b1442\dab60367-53fe-4fbc-825e-521d069d2456]
"Attributes"=dword:00000002

Doesn't even require a restart!

Setting WiFi regulatory domain on OpenELEC

When I connected my new 802.11 dongle to a Raspberry Pi running OpenELEC, I got the following messages in the system log:

cfg80211: World regulatory domain updated:
cfg80211:  DFS Master region: unset
cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
cfg80211:   (2457000 KHz - 2482000 KHz @ 20000 KHz, 92000 KHz AUTO), (N/A, 2000 mBm), (N/A)
cfg80211:   (2474000 KHz - 2494000 KHz @ 20000 KHz), (N/A, 2000 mBm), (N/A)
cfg80211:   (5170000 KHz - 5250000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2000 mBm), (N/A)
cfg80211:   (5250000 KHz - 5330000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2000 mBm), (0 s)
cfg80211:   (5490000 KHz - 5730000 KHz @ 160000 KHz), (N/A, 2000 mBm), (0 s)
cfg80211:   (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 2000 mBm), (N/A)
cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 0 mBm), (N/A)

A quick check with cat /sys/module/cfg80211/parameters/ieee80211_regdom revealed that the regulatory domain was set to 00.

In order to fix this, I executed

# echo 'options cfg80211 ieee80211_regdom="DE"' > ~/.config/modprobe.d/cfg80211.conf
and rebooted.

cfg80211: Regulatory domain changed to country: DE
cfg80211:  DFS Master region: ETSI
cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
cfg80211:   (2400000 KHz - 2483000 KHz @ 40000 KHz), (N/A, 2000 mBm), (N/A)
cfg80211:   (5150000 KHz - 5250000 KHz @ 80000 KHz, 200000 KHz AUTO), (N/A, 2000 mBm), (N/A)
cfg80211:   (5250000 KHz - 5350000 KHz @ 80000 KHz, 200000 KHz AUTO), (N/A, 2000 mBm), (0 s)
cfg80211:   (5470000 KHz - 5725000 KHz @ 160000 KHz), (N/A, 2700 mBm), (0 s)
cfg80211:   (57000000 KHz - 66000000 KHz @ 2160000 KHz), (N/A, 4000 mBm), (N/A)

Denon RC-1146 remote with Kodi

Today I created a configuration file for my Denon RC-1146 remote. Since Kodi is connected to the DVD input of my amp, I used the remote's default DVD profile.

First, I wired up the IR detector to the Raspberry Pi's GPIO pins as shown in the tutorial.

Because I use OpenELEC rather than RaspBMC, I then had to edit the configuration file to load the device tree overlay.

# mount -o remount,rw /flash
# echo dtoverlay=lirc-rpi >> /flash/config.txt
# mount -o remount,ro /flash

From LibreELEC 9, rc-core is used instead of lircd, so the instructions below will need to change.

For the /storage/.config/lircd.conf file, I tweaked some of the codes for Kodi: the key labelled »menu« on the remote sends a KEY_INFO code since that seems to be the most useful code in Kodi (file info or playing info, respectively). The »top level« key sends KEY_MENU which takes you to Kodi's main menu and toggles the play menu. I assigned KEY_EPG to the »setup« key since KEY_SETUP doesn't seem to do anything while KEY_EPG invokes the context menu in the menu and the decoder info while playing. Finally, I cheekily remapped the »10+« key to KEY_SUBTITLE since the former seems to be unused and I use the latter a lot.

The numeric keys are assigned KEY_NUMERIC prefixes because Kodi requires it.

Also, the key labelled »enter« is assigned to KEY_OK and »return« is assigned to KEY_EXIT since that seems to be more appropriate in the context of lircd.

# Please make this file available to others
# by sending it to <lirc@bartelmus.de>
#
# this config file was automatically generated
# using lirc-0.9.1-git(default) on Tue Apr  5 23:36:06 2016
#
# contributed by <jocki84@googlemail.com>
#
# brand: Denon
# model no. of remote control: RC-1146
# devices being controlled by this remote: Denon DVD Players
# This multi-purpose remote has many emulations, these codes
# were generated using the default setting for DVD, 32134.
#

begin remote

  name  DENON_RC1146_DVD
  bits           15
  flags SPACE_ENC|CONST_LENGTH
  eps            30
  aeps          100

  one           290  1815
  zero          290   760
  ptrail        290
  gap          66911
  toggle_bit_mask 0x0

      begin codes
          KEY_POWER                0x300C
          KEY_UP                   0x08D4
          KEY_DOWN                 0x092B
          KEY_LEFT                 0x082B
          KEY_RIGHT                0x09D4
          KEY_OK                   0x088B # KEY_ENTER
          KEY_INFO                 0x09DB # KEY_MENU
          KEY_MENU                 0x090B # KEY_DVD
          KEY_EPG                  0x08F4 # KEY_SETUP
          KEY_EXIT                 0x0924
          KEY_REWIND               0x089B
          KEY_PLAY                 0x0814
          KEY_FASTFORWARD          0x0964
          KEY_PREVIOUS             0x099B
          KEY_PAUSE                0x091B
          KEY_STOP                 0x09EB
          KEY_NEXT                 0x0864
          KEY_NUMERIC_1            0x0904
          KEY_NUMERIC_2            0x08FB
          KEY_NUMERIC_3            0x0884
          KEY_NUMERIC_4            0x097B
          KEY_NUMERIC_5            0x0984
          KEY_NUMERIC_6            0x087B
          KEY_NUMERIC_7            0x0844
          KEY_NUMERIC_8            0x09BB
          KEY_NUMERIC_9            0x0944
          KEY_NUMERIC_0            0x09FB
          KEY_SUBTITLE             0x08C4 # KEY_102ND
      end codes

end remote

Note for LibreELEC 8.2 In order for lircd to start, it's necessary to

$ touch /storage/.cache/services/lircd.conf

Note for LibreELEC 7.90.008: lircd should be started when the /dev/lirc0 device is created by the lirc_rpi kernel module. This is achieved using udev which starts an appropriate instance of /usr/lib/systemd/system/lircd.service (such as lircd@lirc0:default:lircd.conf.rpi) from /usr/lib/udev/rules.d/98-lircd.rules when the device appears. Occasionally, there might be a link in .config/system.d/multi-user.target.wants which leads to lircd being started before the device node has been created. Such a link should not exist.