Connecting to Sky Broadband from Debian

Posted on 2018-08-06 in sysadmin

Due to price, I've just changed my broadband supplier from Zen to NowTV.
While I love the service Zen have provided me over the years, i'm trying to save for a big project, so i'm cost-cutting across the board.

So I paid for the transfer, got everything sorted on that front, then had a look at how I could get the pppoe credentials for NowTV. Turns out Sky (Who run the NowTV broadband service) don't actually use PPPoE like every other Fibre provider, and have their own authentication system. Bugger.

Reading through the information around the web, you have to send a DHCP Option 61 with the credentials for your connection, and will be sent an IP address in response. Seems easy enough, once you can get the credentials.

Most of the information I could find points towards generating a username / password pair based on the mac address of your router, or extracting the credentials from an existing router. I also noticed some posts from 2016 saying this was no longer necessary, and you could send any credentials as long as they are in the correct format. Hmm. Lets try that.

DHCP Option 61 is a fancy name for the Client ID. This can be set manually in most quality routers. Personally, I have a Debian box that takes care of my home network firewall, so I added the following to /etc/dhcp/dhclient.conf:

1
send dhcp-client-identifier "hellothere@skydsl|thisshouldbeapassword";

rebooted the box, changed my iptables rules to use eth0 instead of the old ppp0 connection and it just... worked \o/


iptables for libvirt

Posted on 2018-02-14 in sysadmin

iptables for forwarding entire ip addresses to an internal IP

This is one way of achieving forwarding a whole IP to an internal IP. Personally i now use macvtap interfaces on the host, so the VM sits directly at layer 2 and the host doesn't have to worry about it, however sometimes you will want be able to block specific ports from ingress / egress on your vm and this solution helps.

1
2
3
4
5
6
7
8
# VM is allowed to receive packets
sudo iptables -I FORWARD -o virbr0 -d {internal_ip} -j ACCEPT

# All packets arriving at {external_ip} need to go to {internal_ip}
sudo iptables -t nat -I PREROUTING -p tcp -d {external_ip} -j DNAT --to {internal_ip}

# All packets leaving {internal_ip} should go from {external_ip}
sudo iptables -t nat -I POSTROUTING -s {internal_ip} -j SNAT --to-source {external_ip}

Iptables for forwarding a single port

If you only want to open pinholes from the internet to your libvirt VMs, you'll want to add a specific rule for each port.

1
2
3
4
5
# Allow the server to receive packets aimed at the port we're forwarding
iptables -I FORWARD -m state --state NEW,RELATED,ESTABLISHED -p tcp --dport {port_number} -d {internal_ip} -j ACCEPT

# Forward packets arriving on the port on the host to the port on the internal ip
iptables -t nat -I PREROUTING -p tcp --dport {port_number} -j DNAT --to-destination {internal_ip}:{port_number}

Note that this will forward packets arriving on any interface where there isn't already a rule in place! If you only want to forward packets from a specific external IP, change the second line to:

1
iptables -t nat -I PREROUTING -p tcp -d {external_ip} --dport {port_number} -j DNAT --to-destination {internal_ip}:{port_number}

Making iptables persist across reboots

To make iptables persist across reboots, i sugges using debian's iptables-persistent package.

1
2
sudo apt-get install iptables-persistent
sudo service netfilter-persistent save

Beginners Guide to Badge Hacking

Posted on 2016-08-05 in emf

We're going to create an LED torch for seeing our way around the camp.

Soldering the LED

You should have received an LED and a resistor with your badge. First, grab the resistor. Bend the legs over so they fit in the holes in the board, using the resistor lead bender.

Leg Bender

It doesn't matter way round the resistor goes.

Resistor Fitted

Flip over your board and solder the resistor in place, then trim down the legs to be flush against the board.

Next, the LED. It does matter which way round the LED goes - look for a flat side on the LED and match it up with the flat side on the board. Pull your LED out about a centimetre and bend it over a bit.

LED Fitted

Flip the board over and solder the LED into place.

Testing

Plug your badge into your laptop, and use the information on https://micropython.org/doc/tut-repl to connect to the usb-serial port. If you hit Ctrl-C, you drop out of the badge software, and get a REPL prompt. You can tell this is working because you'll see three > symbols.

Type the following at the prompt. This should turn your LED on!

1
2
3
>>> import pyb
>>> pin = pyb.Pin("LED_TORCH")
>>> pin.high()

Of course, thats a bit of a pain to do every time we want the LED on, so let's make an app!

The App

Your badge should have shown up as a USB drive. Open the folder apps, and create a folder within it called torch.

Create a file within this called main.py. This is your app's main file. Open it in a text editor.

First, we need to tell the badge some details about your app. This is done in a header section at the top of the file

1
2
3
4
5
6
### Author: Your Name
### Description: Torch
### Category: Flashy
### License: MIT
### Appname : Torch
### Built-in: no

You could save and run your app now, but it won't actually do anything yet. Lets add the code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
### Author: Your Name
### Description: Torch
### Category: Flashy
### License: MIT
### Appname : Torch
### Built-in: no

import pyb
pin = pyb.Pin("LED_TORCH")
pin.high()
while True:
  pass

Save, and run your app. When you run it the LED should turn on, brill!

Of course, we're not showing anything on the screen. Lets have a nice dialog box to show we're in the torch instead of that while loop.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
### Author: Your Name
### Description: Torch
### Category: Flashy
### License: MIT
### Appname : Torch
### Built-in: no

import ugfx, pyb, dialogs
pin = pyb.Pin("LED_TORCH")
pin.high()
ugfx.init()
ugfx.clear(ugfx.html_color(0x7c1143))
dialogs.notice("Shine a light!", title="Torch", close_text="Exit")

Run your app again and you should have a nice button you can press to shine a light in the camp!

You can unplug the badge from your computer when the LED has finished flashing, but we recommend you eject the drive first.


TiLDA for Wearable Electronics

Posted on 2016-08-03 in emf

Did you know that as well as being an awesome internet-connected, python-powered portal to nirvana (OK, one of those may be a lie), your badge is also a rad wearables controller?

At badge HQ, we love flashy LEDs, and we love sewing them to ourselves for no apparent reason. That's why each badge has support for attaching and driving a string of Neopixel / WS2812 LEDs up to X LEDs long.

If you already have some neopixels, you'll need to add a three-pin connector to the end of the string for connecting to the badge. The pinout is a servo-style pinout, with the +v in the center, which makes it more difficult to explode things if you plug it in backwards!

Neopixel Header

I would suggest using a right-angled connector, and having your wire go off the side of the badge. That way it isn't sticking out or stabbing you in the chest.

NOTICE: Unfortunately, the badges we've made for the event have the onboard neopixel fitted backwards (oops!), so unless you want to have a go at rotating it (we can help with that at the Badge Tent), you cant use the onboard header. Luckily, CH2 on the Servos connector block is also able to be used for neopixels, so you can solder the connector there instead.

The central V+ pin is at battery voltage when running from battery, so varies between 4.2 and 3.6 volts depending on how flat your battery is. We've tested this with a string of 5V neopixels, and it is enough to power them up fine. However, if you are worried about your battery running out too fast, or want to drive more neopixels than the badge can handle, you can plug a USB battery pack into the badge, and the LED strip will be provided with a full 5V.

The App

OK, so thats the hardware, now for the software. Step one is to load up the Wearables from the App Library. As soon as you reboot, the neopixel on your badge (or the first on your strip) should start cycling through the colour wheel.

What we need to do is tell the app what sequence to run, and how many LEDs you have connected to your badge. Lets try the rainbow:

Rainbow

Number of LEDs

Speed

Pretty Rainbow

Rad.

Note that once you've set up the number of LEDs connected, you can just press B to skip that screen in the future, it'll keep the setting.

Matrix next. This doesnt need anything extra configuring, and shows a green flickery pattern like on the film (which i'm informed is now 17 years old, what?!):

There is no spoon

And lastly, Colour displays a single colour so you can make everything pink! You need to enter a HTML colour code, this is ff00ff:

HTML Colour Code

Pink!

If you want to add any extra sequences, code for the wearables app is available at https://github.com/thinkl33t/TiLDA-Wearables . Just dump it on your badge at apps/wearables/ I'll accept pull requests if you add any extra sequences, so get making!


Automatically starting a Python script at boot on Raspbian Jessie

Posted on 2016-07-06 in sysadmin

As part of the Hackspace Manchester door control system, we have a raspberry pi running a little script that checks scanned cards against a database of members and opens the door if the card is known.  This has been humming along happily for around 3 years now, until recently it stopped updating card IDs when they were changed via the webui.

This led to a bit of a bug hunt, concluding with the fact the version of openssl on raspbian wheezy was waaaaay out of date, and we'd recently updated our members system to disable insecure cyphers on the HTTPS protocol.  We fixed it by upgrading to jessie, which as a side effect completely killed the auto-start of the door opening programme. Yay?

So.  Jessie.  Systemd.  Init system is a a bit different from sysvinit, but on the whole i find it a lot more sensible.  We want to run a script as the user 'alfred' (the door entry service user).  We also want to wait until the system is booted, and the serial port is available.

My script is called alfred, so i create the following file in /lib/systemd/system/alfred.service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[Unit]
Description=alfred
After=dev-ttyAMA0.device multi-user.target

[Service]
Type=idle
ExecStart=/home/alfred/FRED/fred/fred.py
WorkingDirectory=/home/alfred/FRED/fred/
User=alfred

[Install]
WantedBy=multi-user.target

The After= says what services need to be up before this is run. In this case, it wants ttyAMA0 to be available, along with multi-user (this is the point where you could normally log in)

ExecStart= specifies the script I will be running, WorkingDirectory= is the directory to run the thing from (as i use relative paths in my python script, i need to set this), and User= says what unprivileged user to run the script as, since you don't want to be running random things as root if at all possible!

WantedBy= says that this should be started at the same time as multi-user.target, so at the end of the boot process, at the point you could normally log in.

We can then set up our new service to start on boot, and run it for the first time:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ systemctl enable alfred
$ systemctl start alfred
No errors, so lets check the status:
$ sudo systemctl status alfred
● alfred.service - alfred
Loaded: loaded (/lib/systemd/system/alfred.service; enabled)
Active: active (running) since Wed 2016-07-06 16:42:59 BST; 30min ago
Main PID: 709 (fred.py)
CGroup: /system.slice/alfred.service
└─709 /usr/bin/python /home/alfred/FRED/fred/fred.py
Jul 06 16:42:59 alvin systemd[1]: Starting alfred...
Jul 06 16:42:59 alvin systemd[1]: Started alfred.
Jul 06 16:43:01 alvin fred.py[709]: 2016-07-06 16:43:01,577 FRED 0.7

Looks good, service is started, and we're getting some log output from it. Reboot to check everything comes up correctly and you're done!

... Though i wasnt. One gotcha I ran into is that because of the way raspbian's networking is set up, you can't get systemd to wait until after you have a network connection configured before starting the script (it will wait until the networking service is started, but not wait for the network to actually be up). This can be worked around pretty easily by setting the "Wait for network on boot" option in raspi-config, which will pause the whole boot process until it gets a DHCP lease.