Waking up a NAS from OS X at boot time using Wake-on-LAN (WOL)

Since OS X 10.11 El Capitan protects certain system directories from modifications, my NASwake solution to wake a NAS once the Mac starts up published back in 2010 is no longer working.

I decided against building another .pkg installer since it requires root permissions and I also prefer using Homebrew instead of some obscure binary for sending the magic WOL packet. Here are the four steps to start your Wake-on-Lan-capable NAS once your Mac starts up:

  1. Install “Homebrew” (required for the wakeonlan script)
  2. Install the wakeonlan script using the Homebrew package manager
  3. Save the naswake plist to /Library/LaunchDaemons
  4. Save the naswake shell script to /usr/local/bin and set your NAS’s MAC-address

1. Install Homebrew

See http://brew.sh for instructions. Once installed, check with brew doctor if Homebrew was installed properly.

2. Install the wakeonlan script using the Homebrew package manager

brew install wakeonlan

This will install the wakeonlan Perl script. See man wakeonlan for details.

3. Save the naswake plist to /Library/LaunchDaemons

sudo nano /Library/LaunchDaemons/com.trick77.wol2.plist

Paste the XML below into the editor.

4. Save the naswake shell script to /usr/local/bin

sudo nano /usr/local/bin/naswake.sh
sudo chmod +x /usr/local/bin/naswake.sh

Paste the script below into the editor. Don’t forget to set your NAS’ MAC address in the last line of the script!

That’s it! Make sure WOL is enabled in the NAS.

Tips & tricks for the PC Engines APU

Being somewhat addicted to Linux mini computers, I just had to lay my hands on a PC Engines APU. A lot of information about the APU is strewn all over the Internet so I wanted to consolidate it all in one single post.

Installing Ubuntu Server using the serial console

To boot the Ubuntu Server installer using the serial console, some startup config files have to be modified. See this post for instructions.

On the Mac, I’m using serial. It already contains the drivers for my PL2303 based USB serial adapter. As a free alternative, Prolific’s PL2303 OS X drivers work pretty well together with minicom from the brew project. If output is being displayed with minicom but input doesn’t work, make sure to turn off hardware flow control. The screen command may work as well.

Show network devices as eth0, eth1, eth2 instead of p4p1, p4p2, p4p3

Edit /etc/default/grub as follows:

GRUB_CMDLINE_LINUX_DEFAULT="biosdevname=0"

Update grub configuration
# update-grub
and
# reboot

Don’t forget to update /etc/network/interfaces accordingly.

Show output during boot

Edit /etc/default/grub as follows:

GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8"
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"

Update grub configuration
# update-grub
and
# reboot

Enable NMI Watchdog

# modprobe sp5100_tco && echo "sp5100_tco" >> /etc/modules

Enable temperatur sensor

apt-get install lm-sensors

# sensors
k10temp-pci-00c3
Adapter: PCI adapter
temp1:        +52.0°C  (high = +70.0°C)
                       (crit = +100.0°C, hyst = +97.0°C)

Enable LEDs and reboot button

Check out the apu-led-button repository on Github.

Use max. cpufreq

Ubuntu will always set the CPU governor to ondemand during boot.

# cat /proc/cpuinfo
vendor_id	: AuthenticAMD
model name	: AMD G-T40E Processor
cpu MHz		: 800.000

For the APU this means the CPU will be run at 800 MHz instead of 1 GHz. If you prefer the CPU to run at full speed at all times:

# wget -O /usr/local/sbin https://gist.githubusercontent.com/trick77/21cfc65c769609be29e2/raw/076e21c7b844a9eeb67ca4184544ec27d11164f7/gov

Insert into /etc/rc.local just above exit 0 :

/usr/local/sbin/gov performance

Or as an alternative, just disable the Ubuntu ondemand init script from the command line:

# update-rc.d ondemand disable
# cat /proc/cpuinfo
vendor_id	: AuthenticAMD
model name	: AMD G-T40E Processor
cpu MHz		: 1000.000

Enable beep

apt-get install beep
modprobe pcspkr && echo pcspkr >> /etc/modules

Comment pcspkr in /etc/modprobe.d/blacklist.conf to unblacklist the module.

Imperial March:

beep -l 350 -f 392 -D 100 -n -l 350 -f 392 -D 100 -n -l 350 -f 392 -D 100 -n -l 250 -f 311.1 -D 100 -n -l 25 -f 466.2 -D 100 -n -l 350 -f 392 -D 100 -n -l 250 -f 311.1 -D 100 -n -l 25 -f 466.2 -D 100 -n -l 700 -f 392 -D 100 -n -l 350 -f 587.32 -D 100 -n -l 350 -f 587.32 -D 100 -n -l 350 -f 587.32 -D 100 -n -l 250 -f 622.26 -D 100 -n -l 25 -f 466.2 -D 100 -n -l 350 -f 369.99 -D 100 -n -l 250 -f 311.1 -D 100 -n -l 25 -f 466.2 -D 100 -n -l 700 -f 392 -D 100 -n -l 350 -f 784 -D 100 -n -l 250 -f 392 -D 100 -n -l 25 -f 392 -D 100 -n -l 350 -f 784 -D 100 -n -l 250 -f 739.98 -D 100 -n -l 25 -f 698.46 -D 100 -n -l 25 -f 659.26 -D 100 -n -l 25 -f 622.26 -D 100 -n -l 50 -f 659.26 -D 400 -n -l 25 -f 415.3 -D 200 -n -l 350 -f 554.36 -D 100 -n -l 250 -f 523.25 -D 100 -n -l 25 -f 493.88 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 25 -f 440 -D 100 -n -l 50 -f 466.16 -D 400 -n -l 25 -f 311.13 -D 200 -n -l 350 -f 369.99 -D 100 -n -l 250 -f 311.13 -D 100 -n -l 25 -f 392 -D 100 -n -l 350 -f 466.16 -D 100 -n -l 250 -f 392 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 700 -f 587.32 -D 100 -n -l 350 -f 784 -D 100 -n -l 250 -f 392 -D 100 -n -l 25 -f 392 -D 100 -n -l 350 -f 784 -D 100 -n -l 250 -f 739.98 -D 100 -n -l 25 -f 698.46 -D 100 -n -l 25 -f 659.26 -D 100 -n -l 25 -f 622.26 -D 100 -n -l 50 -f 659.26 -D 400 -n -l 25 -f 415.3 -D 200 -n -l 350 -f 554.36 -D 100 -n -l 250 -f 523.25 -D 100 -n -l 25 -f 493.88 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 25 -f 440 -D 100 -n -l 50 -f 466.16 -D 400 -n -l 25 -f 311.13 -D 200 -n -l 350 -f 392 -D 100 -n -l 250 -f 311.13 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 300 -f 392.00 -D 150 -n -l 250 -f 311.13 -D 100 -n -l 25 -f 466.16 -D 100 -n -l 700 -f 392

How to receive Cymru’s IPv6 Bogon list using Quagga

The provided BGP sample configuration for Quagga on Cymru’s web site didn’t work for me. Since my AS is IPv6-only, I’m only interested in the IPv6 Bogon feed. Here’s an excerpt from my Quagga bgpd.conf:

router bgp aut-num
bgp router-id id
bgp log-neighbor-changes
no bgp default ipv4-unicast

neighbor cymru-bogon peer-group
neighbor cymru-bogon remote-as 65332
neighbor cymru-bogon timers 3600 10800
neighbor cymru-bogon description AS65332 Cymru FullBogon Feed
neighbor cymru-bogon ebgp-multihop 255
neighbor cymru-bogon password changeme
neighbor cymru-bogon activate
neighbor cymru-bogon prefix-list pl-cymru-ipv4-in in
neighbor cymru-bogon prefix-list pl-cymru-out out
neighbor 38.xx.xx.xx peer-group cymru-bogon
neighbor 193.xx.xx.xx peer-group cymru-bogon

address-family ipv6
  neighbor cymru-bogon activate
  neighbor cymru-bogon soft-reconfiguration inbound
  neighbor cymru-bogon route-map rm-cymru-ipv6-in in
  neighbor cymru-bogon prefix-list pl-cymru-ipv6-out out
  neighbor 38.xx.xx.xx peer-group cymru-bogon
  neighbor 193.xx.xx.xx peer-group cymru-bogon
exit-address-family

ip prefix-list pl-cymru-ipv4-in seq 5 deny any
ip prefix-list pl-cymru-out seq 5 deny any
ipv6 prefix-list pl-cymru-ipv6-out seq 5 deny any
ip community-list 10 permit 65332:888

route-map rm-cymru-ipv6-in permit 10
  match community 10
  set ip next-hop 192.0.2.1
  set ipv6 next-hop global 100::dead:beef:1

Since Zebra won’t install routes learned over BGP that are not routable, I also needed to make sure that 100::dead:beef:1 is (null-)routed. My solution was to install a Cisco-style Null0 interface in /etc/network/interfaces:

# blackhole
iface Null0 inet manual
  pre-up ip link add dev Null0 type dummy
  pre-up ip link set Null0 up
  up ip -6 route add 100::/64 dev Null0 proto static metric 255
  up ip -4 route add 192.0.2.1/32 dev Null0 proto static metric 255
  down ip link del dev Null0

By the way, that 100::/64 I’m using to null-route is a designated (RFC6666) IPv6 discard-only address block.

Once the BGP session is up, only IPv6 routes will be learned from Cymru’s bogon feed. I’m using IPv4 transport for the BGP session but it should work using IPv6 transport as well.

BGP neighbor is 38.xx.xx.xx, remote AS 65332, local AS xxxxx, external link
 Member of peer-group cymru-bogon for session parameters
  BGP version 4, remote router ID 38.xx.xx.xx
  BGP state = Established, up for 18:52:18
  Last read 00:11:49, hold time is 10800, keepalive interval is 3600 seconds
  Configured hold time is 10800, keepalive interval is 3600 seconds
  Neighbor capabilities:
    4 Byte AS: advertised and received
    Route refresh: advertised and received(old & new)
    Address family IPv4 Unicast: advertised and received
    Address family IPv6 Unicast: advertised and received
  Message statistics:
    Inq depth is 0
    Outq depth is 0
                         Sent       Rcvd
    Opens:                  1          1
    Notifications:          0          0
    Updates:                0        118
    Keepalives:            20         19
    Route Refresh:          0          0
    Capability:             0          0
    Total:                 21        138
  Minimum time between advertisement runs is 30 seconds

 For address family: IPv4 Unicast
  cymru-bogon peer-group member
  AF-dependant capabilities:
    Outbound Route Filter (ORF) type (128) Prefix-list:
      Send-mode: received
  Community attribute sent to this neighbor(both)
  Inbound path policy configured
  Outbound path policy configured
  Incoming update prefix filter list is *pl-cymru-ipv4-in
  Outgoing update prefix filter list is *pl-cymru-out
  0 accepted prefixes

 For address family: IPv6 Unicast
  cymru-bogon peer-group member
  Inbound soft reconfiguration allowed
  Community attribute sent to this neighbor(both)
  Inbound path policy configured
  Outbound path policy configured
  Outgoing update prefix filter list is *pl-cymru-ipv6-out
  Route map for incoming advertisements is *rm-cymru-ipv6-in
  60088 accepted prefixes

  Connections established 1; dropped 0
  Last reset never
  External BGP neighbor may be up to 255 hops away.
Local host: 185.xx.xx.xx, Local port: 59623
Foreign host: 38.xx.xx.xx, Foreign port: 179
Nexthop: 185.xx.xx.xx
Nexthop global: 2001:xxxx:xxxx::
Nexthop local: fe80::225:xxxx:xxxx:xxxx
BGP connection: non shared network
Read thread: on  Write thread: off

Setting up a Huawei E3276-150 4G/LTE USB modem on Ubuntu Server/Desktop

I just received an unlocked Huawei E3276s-150 4G/LTE USB modem/surfstick I bought on eBay the other day. I went for the E3276s-150 because the 150 seemed to be the most compatible option for European 4G mobile networks. There are even cheaper Huawei E3276 models like the E3276-920 which you can buy for less than 20 bucks. However, the 920 seems to be frequency-optimized for Asian mobile networks and may not perform as well as a E3276s-150 in Western Europe.
huawei_e3276_lte_cat4_usb_dongle
To my great surprise, setting up the Huawei E3276 on Ubuntu 15.04 Desktop was literally plug & play. After a few seconds after plugging it in, I was greeted with a “Connection Established” message. Nicely done, Canonical!

On Ubuntu Server, like most Huawei modems, the stick is recognised as a memory card reader. It has to be switched to a USB modem device first using the usb_modeswitch command in order to establish a mobile network connection. If it’s not already installed, usb_modeswitch can be installed using apt-get -y install usb-modeswitch.

Memory card reader mode:

drfalken@wopr:~# lsusb
Bus 001 Device 007: ID 12d1:1f01 Huawei Technologies Co., Ltd.

To turn the E3276 into a modem:

drfalken@wopr:~# usb_modeswitch -v 12d1 -p 1f01 -M '55534243123456780000000000000011062000000101000100000000000000'

If the change was successful, lsusb shows a different USB product id now:

drfalken@wopr:~# lsusb
Bus 001 Device 007: ID 12d1:14db Huawei Technologies Co., Ltd.

At the same time, dmesg should output something like this:

drfalken@wopr:~# dmesg -T
[Fri May 29 20:55:41 2015] usb 1-1: New USB device found, idVendor=12d1, idProduct=14db
[Fri May 29 20:55:41 2015] usb 1-1: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[Fri May 29 20:55:41 2015] usb 1-1: Product: HUAWEI Mobile
[Fri May 29 20:55:41 2015] usb 1-1: Manufacturer: HUAWEI Technology
[Fri May 29 20:55:41 2015] cdc_ether 1-1:1.0 eth1: register 'cdc_ether' at usb-0000:00:14.0-1, CDC Ethernet Device, 57:2d:70:33:22:10

Since the modem registered itself on eth1 (the name depends on the number of network devices, it doesn’t HAVE to be on eth1), we now simply fetch an IP address from the modem using:

drfalken@wopr:~# dhclient -v eth1
Internet Systems Consortium DHCP Client 4.2.4
Copyright 2004-2012 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/eth1/57:2d:70:33:22:10
Sending on   LPF/eth1/57:2d:70:33:22:10
Sending on   Socket/fallback
DHCPDISCOVER on eth1 to 255.255.255.255 port 67 interval 3 (xid=0x3b73326b)
DHCPREQUEST of 192.168.1.100 on eth1 to 255.255.255.255 port 67 (xid=0x3b73326b)
DHCPOFFER of 192.168.1.100 from 192.168.1.1
DHCPACK of 192.168.1.100 from 192.168.1.1
bound to 192.168.1.100 -- renewal in 36557 seconds.

Yay, the modem has made itself available on 192.168.1.100 (it even has a web interface on port 80) with a /24 prefix and a gateway at 192.168.1.1.
By the way, make sure none of your local networks use 192.168.1.0/24 or it will collide with the Huawei’s local network.

Depending on a few factors dhclient may or may not have changed the default gateway. If the default gateway points to the modem, it will be at 192.168.1.1 on eth1:

drfalken@wopr:~# ip route show | grep default
default via 192.168.1.1 dev eth1

If this is not the case, you may have to remove the existing default gateway and replace it using:

drfalken@wopr:~# ip route del default ; ip route add default via 192.168.1.1

And… connected!

drfalken@wopr:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=22.7 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=34.9 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=39.7 ms

Make sure /etc/resolv.conf contains a valid nameserver if you can’t resolve domain names.

To switch the Huawei E3276 into a modem at boot time, create /etc/udev/rules.d/70-usb-modeswitch.rules and insert this line:

ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="1f01", RUN+="/usr/sbin/usb_modeswitch -v 12d1 -p 1f01 -M '55534243123456780000000000000011062000000101000100000000000000'"

To automatically add a valid nameserver in /etc/resolv.conf when eth1 comes up, add these lines to /etc/dhcp/dhclient.conf:

interface "eth1" {
  prepend domain-name-servers 8.8.8.8;
  request subnet-mask, broadcast-address, time-offset, routers,
          domain-name, domain-name-servers, domain-search, host-name,
          dhcp6.name-servers, dhcp6.domain-search,
          netbios-name-servers, netbios-scope, interface-mtu,
          rfc3442-classless-static-routes, ntp-servers,
          dhcp6.fqdn, dhcp6.sntp-servers;
  require routers, domain-name-servers;
}

If you don’t want to run dhclient manually, you can either add an eth1 dhcp section in /etc/network/interfaces or add the dhclient eth1 command to /etc/rc.local.

Just FYI: I’ve been using Vivid Vervet’s (Ubuntu 15.04) 3.19 kernel in Ubuntu Server 14.04 LTS. Vivid’s newer kernel can be installed using apt-get install linux-image-generic-lts-vivid. Not sure if it makes a difference compared to 14.04’s default kernel though.

Dockerflix: Docker-based SNI proxy for watching U.S. Netflix, Hulu, MTV, Vevo, Crackle, ABC, NBC, PBS…

Recently, I published a new project on Github called Dockerflix. Instead of HAProxy, Dockerflix uses sniproxy. To make the installation a breeze, I boxed the proxy into a Docker container and wrote a small, Python-based Dnsmasq configuration generator. And voilà: DNS-unblocking as a service (DAAS) ;-)

Thanks to sniproxy’s ability to proxy requests based on a wildcard/regex match it’s now so much easier to add support for a service. Now it’s usually enough to just add the main domain name to the proxy and DNS configuration and Dockerflix will be able to hop the geo-fence in most cases. Since most on-demand streaming media providers are using an off-domain CDN for the video stream, only web site traffic gets sent through Dockerflix. A few exceptions may apply though, notably if the video stream itself is geo-fenced.

Dockerflix only handles requests using plain HTTP or TLS using the SNI extension. Some media players don’t support SNI and thus won’t work with Dockerflix.
If you need to proxy plain old SSLv1/v2 for a device, have a look at the non-SNI approach shown in tunlr-style-dns-unblocking.
A few media players (i.e. Chromecast) ignore your DNS settings and always resort to a pre-configured DNS resolver which can’t be changed (it still can be done though by rerouting these requests using iptables).

Check it out: https://github.com/trick77/dockerflix