Category Archives: MemoToSelf

Linux: add a USB network interface to a bridge

By   January 11, 2018

I have some Raspberry Pi0Ws that I’m connecting to a LAN via the USB gadget network driver on a Raspberry Pi3.  The problem I encountered was that the usb[0-3] interfaces weren’t showing up when the Pi3 booted because the Pi0w’s booted later.  Only ‘eth0’ appeared on ‘br0’.

You need to make sure to add the usb[0-3] interfaces to the Bridge when the Pi0w’s boot.  This also works if Pi0W’s are plugged in after the Pi3 is already booted.  A simple change to /etc/network/interfaces is all it took to make this happen:

auto br0
iface br0 inet dhcp
bridge_ports eth0 usb0 usb1 usb2 usb3
bridge_stp off
bridge_fd 0
bridge_waitport 0

allow-hotplug usb0
allow-hotplug usb1
allow-hotplug usb2
allow-hotplug usb3

auto usb0
iface usb0 inet static
up ifconfig usb0 up
up brctl addif br0 usb0

auto usb1
iface usb1 inet static
up ifconfig usb1 up
up brctl addif br0 usb1

auto usb2
iface usb2 inet static
up ifconfig usb2 up
up brctl addif br0 usb2

auto usb3
iface usb3 inet static
up ifconfig usb3 up
up brctl addif br0 usb3

Note the IP addresses on the individual usb[0-3] interfaces are irrelevant. Those are present only so I can bring the interface ‘up’.

Modifying a Proxmox LXC container

By   December 23, 2016

I was introduced to the awesomeness that is Proxmox VE and got down to convering my old virtual server to Proxmox VM’s… Along the way I decided some of my VM’s didn’t need to be VM’s but that LXC containers would be just fine.  After making my second container, I got tired of running the same handful of commands (create a user account, git clone my dotfiles, install tmux, etc) so decided to investigate modifying the Ubuntu 16.04 template.  This turns out to be very easy using ‘vzdump’.


So here’s another “memo to self”.

First build a container, set it up the way you want it, then use vzdump to create a tarball of it.  Copy it to your templates directory and you’re done:

cd <container template dir>
vzdump -dumpdir . 102
gzip vzdump-lxc-102-2016_12_23-07_53_55.tar
mv vzdump-lxc-102-2016_12_23-07_53_55.tar.gz ubuntu-16.04-mpv_1604-1_amd64.tar.gz

NFS client mount within a Proxmox LXC container.

By   December 23, 2016

Another “memo to self” …


[ Edit: minor change for Proxmox 5.x at bottom]

Having trouble doing an NFS mount from within a Proxmox LXC container?  A google search took me here and it pretty much answers the question but doesn’t work with Proxmox 4.4-1.  The error I was seeing after following the advice in the above was:

apparmor="STATUS" operation="profile_replace" profile="unconfined" name="lxc-container-default-cgns" pid=11339 comm="apparmor_parser"

So you also need to edit /etc/apparmod.d/lxc/lxc-container-default-cgns and make it look like so:

# Do not load this file. Rather, load /etc/apparmor.d/lxc-containers, which
# will source all profiles under /etc/apparmor.d/lxc

profile lxc-container-default-cgns flags=(attach_disconnected,mediate_deleted) {
 #include <abstractions/lxc/container-base>

# the container may never be allowed to mount devpts. If it does, it
 # will remount the host's devpts. We could allow it to do it with
 # the newinstance option (but, right now, we don't).
 deny mount fstype=devpts,
 mount fstype=nfs,
 mount fstype=cgroup -> /sys/fs/cgroup/**,

and then subsequently do:

service apparmor reload

Edit: On proxmox 5.2-1 the file is /etc/apparmor.d/lxc/lxc-default-cgns.  The rest of the above is still correct.

socat on OS X – TCDRAIN returns Invalid Argument.

By   June 26, 2016

When using socat, as installed by ‘brew install socat’ on OS X, you will likely get this error when trying to proxy a serial device to another host via TCP:

TCSADRAIN, 0x7fffffffe148):Invalid argument

This is because OS X uses the FreeBSD termios interface and the bug is explained here:

This is the patch you want to apply to ‘socat’:


Unfortunately, ‘brew install socat’ just gives you someone else’s precompiled binary and you want to retrieve the source so you can apply the above patch.


Do it like so:


cd `brew --cache`
brew unpack socat
cd socat-
curl > patch
patch < patch
make install


pfSense openvpn client to generic openvpn server in bridge mode

By   May 27, 2016

This should really go into the ‘memo to self’ category but I don’t have one.  Regardless…

I have an Ubuntu VM running OpenVPN in Bridge mode (tap).  I wanted to bridge my cottage network to my home network using pfSense out at the cottage. In the process of making this work, a fair amount of googling was involved so I decided to aggregate all of the information in one place in case I ever needed to reproduce it.  Friend Kurt was running up against some of the same issues.


First, make sure your OpenVPN server is working and that you have the following client specific files available (filenames will likely vary):

  • site.ovpn
  • ca.crt
  • ta.key
  • client.crt
  • client.key

On the server, I had to make some minor changes to make everything work:

If you can ping client->server but the connection hangs when you try to edit a file or view a web-page

mssfix 142
fragment 1200

If on the client, you see “OpenVPN Bad LZO decompression header byte:”? I had to comment out “comp-lzo” on the server… This seems bogus but it made it work. Need to investigate this later.

The client says “Authenticate/Decrypt packet error: cipher final failed”, the issue is the cipher being used. The default on the server was “BF-CBC” but the pfSense default was “AES-128-CBC”. Change the pfSense to “BF-CBC” and you’re good to go.

The general procedure for making this work in pfSense is the following:

    • Go to System->Cert. Manager and add your server’s “ca.crt” to Certificate Authorities. Give it a descriptive name.
    • Then go to System->Cert. Manager->certificates and add your client.crt and client.key.  Give it a descriptive name as well.   Ensure you do this after you’ve added ca.crt so that when you add this certificate, it will reference the above ca.crt.
    • Go to VPN->OpenVPN->Client and click ‘Add’
        • Select Peer-to-Peer under ‘Server mode’
        • Select ‘tap’ under ‘Device Mode’
        • Select ‘WAN’ under ‘Interface’
        • Set your server host/address to your VPN server address.
        • Set the port accordingly.
        • Set description to something you’ll recognize.
        • Under TLS Authetication, set ‘Enable authentication of TLS packets’.  It will drop down a text box into which you can paste the contents of ‘ta.key’.
        • Set ‘Peer Certificate Authority’ to the one you added above.
        • Set ‘Client Certificate’ to the one you added above.
        • Set encryption algorithm to whatever your VPN server is using (BF-CBC in my case)
        • Under ‘Custom Options’, I had:

      mssfix 142
      fragment 1200

The final note I’d like to add is one about IP addresses. When you set your ‘server-bridge’ parameter on the server’s VPN config, you assign a pool of IP addresses that are not in your dhcp server’s range. By default, the IP addresses assigned are specific to the client certificate. So if you find your clients are all getting the same IP address, it is because they each need a unique client certificate. You can override this behavior using the ‘duplicate-cn’ directive in your server’s config file. It’s generally not a good idea though so you should just create unique client certificates.

iterm2 arrow keys not working in cursor application mode

By   February 3, 2016

(TL;DR at the bottom)

This is one of those things that irritated me for ages.  I generally don’t use arrow/home/end keys for anything except when I run (rarely) certain applications like ‘make menuconfig’ where I’m forced to navigate using arrow keys.

For the longest time, the arrow keys didn’t work on iterm2 in certain applications.  After digging in, I discovered the problem.

Ages ago, I started using OS-X, but sucked so I installed iterm.  Then iterm2 came out and I upgraded.  Sometime thereafter I discovered the arrow keys didn’t work.  This morning, I decided enough was enough and I got to the bottom of it.  One of the answers on this question posted a handy little script to test whether the keys work in cursor application mode:


sh -c "$(cat <<\EOF
noecho_appmode() {
  stty -echo
  printf '\033[?1h'
modes="$(stty -g)"
restore_echo_and_appmode() {
  stty "$modes"
  printf '\033[?1l'
printf '\nType <Up> <Down> <Right> <Left> <Control-D> <Control-D>\n'
printf '(no output until after the first <Control-D>, please type "blindly")\n\t'
noecho_appmode             ; trap 'restore_echo_and_appmode' 0
cat -v
restore_echo_and_appmode   ; trap ''                         0
printf '\nExpected:\n\t'
printf 'kcu%c1\n' u d f b | /usr/bin/tput -S | cat -v
printf '\n\n'

This told me that iterm2 wasn’t working correctly. But it obviously works for many other people.



When I upgraded from iterm to iterm2, my settings survived and Preferences->Profiles->Keys (NOT Preferences->Keys) contained overrides for the arrow keys and home/end.  Once I loaded a Preset for “xterm default”, exited iterm2 and restarted it, arrow keys worked fine.



How to reboot a DLink router from a script

By   November 7, 2015

I have a Dlink DIR-615 that periodically drops its connection to the outside world. It appears to coincide with my wireless provider going down but the DLink never recovers. I don’t know why; but whatever.

I was going to use a relay Phrob to just power cycle it but figured I’d explore doing a soft reboot since that appears to bring the connection back up. Because the HTTP foo is not strong within me, I searched and found this article which gave me the basic steps required to login to a DLink and reboot it. It didn’t work and I didn’t need to append a “A” to the password; but after some futzing and looking at the POST headers in Google Chrome, I eventually reached this script that I put in cron:

# Check whether we can see google's DNS, if not, login to the router and reboot it.

ping() {
        echo Pinging;
        ping -q -c 1 -n >/dev/null && exit 0

login() {
        curl -o - -X POST -d "html_response_page=login.asp&login_name=YWRtaW4A&login_pass=$ADMIN_PASS&graph_id=5190c&&log_pass=$ADMIN_PASS&graph_code=&login=Login" http://$ADDR/login.cgi | grep index.asp

reboot() {
        echo "Rebooting ... " ;
        curl -X POST -d  "html_response_page=reboot.asp" http://$ADDR/reboot.cgi

ping || (login && reboot)

In order to encode your $ADMIN_PASS, you need to:

$ echo -n MYPASSWORD | base64

The ADMIN_PASS=”Zm9vCg==” above is what you’d get if your admin password was “foo”.

This works on my DIR-615, Hardware Version E3 and Firmware Version 5.10. Hope it helps someone.

tftpd and xinetd on Ubuntu

By   May 10, 2015

I’ve been doing embedded for a long time but I’ve been doing unix admin stuff for way longer. I’ve probably been using inetd and tftp for 25 years. I’m always shocked at the ability for tftp to take up a couple hours of time the first time you want to get it running on a host.

When doing embedded, I typically like to point tftpboot at my compiler output directory which saves a copy step. Sometimes you forget to copy and you can’t figure out why your printf()s aren’t showing up (because you’re still running an old version).

Anyway, on Ubuntu, you typically install xinetd and tftpd…

sudo apt-get install xinetd tftpd

Then you want to create /etc/xinetd.d/tftpd :

service tftp
        disable         = no
        socket_type     = dgram
        protocol        = udp
        wait            = yes
        user            = hpeyerl
        server          = /usr/sbin/in.tftpd
        server_args     = -s /home/hpeyerl/trunk/firmware/esp8266

Then poke xinetd:

$ sudo pkill -1 xinetd

I always like to debug by using tcpdump:

06:11:42.796755 IP (tos 0x0, ttl 255, id 4, offset 0, flags [none], proto UDP (17), length 56) >  28 RRQ "/images/antares.rom" octet
    0x0000:  4500 0038 0004 0000 ff11 ef48 c0a8 25f9  E..8.......H..%.
    0x0010:  c0a8 251e 0045 0045 0024 c8b6 0001 2f69  ..%..E.E.$..../i
    0x0020:  6d61 6765 732f 616e 7461 7265 732e 726f  mages/
    0x0030:  6d00 6f63 7465 7400                      m.octet.
06:11:42.799663 IP (tos 0x0, ttl 64, id 8086, offset 0, flags [DF], proto UDP (17), length 49) >  21 ERROR EACCESS "Access violation"
    0x0000:  4500 0031 1f96 4000 4011 4ebe c0a8 251e  E..1..@.@.N...%.
    0x0010:  c0a8 25f9 a67e 0045 001d cc96 0005 0002  ..%..~.E........
    0x0020:  4163 6365 7373 2076 696f 6c61 7469 6f6e  Access.violation
    0x0030:  00                                       .

Sometimes syslog is helpful:

May 10 06:03:57 pm001 in.tftpd[4564]: connect from (
May 10 06:03:57 pm001 tftpd[4565]: tftpd: trying to get file: antares.rom
May 10 06:03:57 pm001 tftpd[4565]: tftpd: serving file from /srv/tftp

The key there is “/srv/tftp”… Since there’s no mention of /srv/tftp in your xinetd.d config file, something else must be happening…

So, here are some gotchas that will consume some debug time:

  • If you’re testing this by using tftp on the same host as tftpd, you won’t see anything in tcpdump because the packets are short-cutting through your localhost interface.
  • On Ubuntu, there is also an /etc/inetd.conf which is your culprit:
#:BOOT: TFTP service is provided primarily for booting.  Most sites
#       run this only on machines acting as "boot servers."
tftp           dgram   udp     wait    nobody  /usr/sbin/tcpd  /usr/sbin/in.tftpd /srv/tftp
  • tftpd is very picky about permissions. You might be tempted to make every element in your path 777, I don’t need to tell you this is a bad idea.