Author Archives: Lorcan DK

Squeezelite scripts on Raspberry Pi

The requirement is to stop/start the squeezelite music client on the Raspberry Pi from the browser. This is a workaround for the problem that the raspotify player for Spotify doesn’t work if squeezelite is running.

Script to stop squeezelite:

root@pi-music:/home/pi# cat /var/www/cgi-bin/stopsqueezelite.pl
#!/usr/bin/perl
use strict;
use warnings;
use DateTime;

## Redirect to index page after the script runs
print "<META HTTP-EQUIV=refresh CONTENT=\"5;URL=http://192.168.11.254\">\n";
#print "<meta http-equiv=refresh CONTENT=\"5;URL='http://192.168.11.254'\" \/>\n";

system("sudo killall squeezelite-armv6hf");

my $filename = 'squeezelite.log';
open(my $fh, '>>', $filename) or die "Could not open file '$filename' $!";
my $dt = DateTime->now;
print $fh "Script stopsqueezelite.pl stopped squeezelite at $dt\n";
print "Stopping Squeezelite at $dt...", "\n";
print "Returning to the main page...", "\n";

close $fh;

Script to start squeezelite:

root@pi-music:/home/pi# cat /var/www/cgi-bin/startsqueezelite.pl
#!/usr/bin/perl
use strict;
use warnings;
use DateTime;

## Redirect to index page after the script runs
print "<META HTTP-EQUIV=refresh CONTENT=\"5;URL=http://192.168.11.254\">\n";

system("sudo /usr/bin/squeezelite-armv6hf -o front:CARD=MDAC,DEV=0 -n RaspberryPi -s 192.168.11.254 </dev/null >/dev/null 2>&1 &");

my $dt = DateTime->now;
my $filename = 'squeezelite.log';
open(my $fh, '>>', $filename) or die "Could not open file '$filename' $!";
print $fh "Script startsqueezelite.pl started squeezelite at $dt\n";
print "Starting squeezelite at $dt...", "\n";
print "Returning to the main page...", "\n";

close $fh;

Add the commands to sudoers.

root@pi-music:/home/pi# cat /etc/sudoers.d/cgi_permissions
www-data ALL = NOPASSWD: /usr/bin/squeezelite-armv6hf
www-data ALL = NOPASSWD: /usr/bin/killall squeezelite-armv6hf

HTML to call the scripts.

...
<li><a href="/cgi-bin/stopsqueezelite.pl">Stop Squeezebox Player</a></li>
<li><a href="/cgi-bin/startsqueezelite.pl">Start Squeezebox Player</a></li>
...

 

Advertisements

DNS Server Scripts

The requirement is to be able to switch between DNS providers depending on the service being used, and to trigger this switch from the browser. I generally use Unlocator as it lets me access BBC iPlayer from outside the UK, however some services such as Amazon Prime don’t work with Unlocator, so I sometimes have to switch back to OpenDNS. The approach uses CGI scripts to change the resolv.conf file and restart the DNS server.

Configure dnsmasq to use the upstream DNS servers from a different file.

root@voyage:/etc# cat /etc/dnsmasq.conf

resolv-file=/etc/resolv.conf.dynamic
root@voyage:/etc# cat /etc/default/dnsmasq

IGNORE_RESOLVCONF=yes

The new resolv.conf file is called resolv.conf.dynamic because we will allow the script to overwrite it with a new set of addresses.

root@voyage:/etc# cat /etc/resolv.conf.dynamic
#nameserver 127.0.0.1
nameserver 206.67.222.222
nameserver 208.67.220.220

The new resolv.conf file will be overwritten with one of these two files.
File containing the OpenDNS servers:

root@voyage:/etc# cat /etc/resolv.conf.opendns
#nameserver 127.0.0.1
nameserver 206.67.222.222
nameserver 208.67.220.220

File containing the Unlocator DNS servers.

root@voyage:/home/lorcan# cat /etc/resolv.conf.unlocator
#nameserver 127.0.0.1
nameserver 185.37.37.37
nameserver 185.37.37.185

CGI script to overwrite resolv.conf.dynamic with the OpenDNS version.

root@voyage:/var/www/cgi-bin# cat setopendns.pl
#!/usr/bin/perl
print "Content-Type: text/plain", "\n\n";
print "Setting DNS servers to OpenDNS...", "\n";

system("sudo remountrw");
system("sudo /bin/cp /etc/resolv.conf.opendns /etc/resolv.conf.dynamic");
system("sudo remountro");

CGI script to overwrite resolv.conf.dynamic with the Unlocator version.

root@voyage:/var/www/cgi-bin# cat setunlocatordns.pl
#!/usr/bin/perl
print "Content-Type: text/plain", "\n\n";
print "Setting DNS servers to Unlocator...", "\n";

system("sudo remountrw");
system("sudo /bin/cp /etc/resolv.conf.unlocator /etc/resolv.conf.dynamic");
system("sudo remountro");

The web server runs as user www-data so to allow specific operations as root, the commands have to be added to a sudoers.d file.

root@voyage:/home/lorcan# cat /etc/sudoers.d/cgi-permissions
www-data ALL= NOPASSWD: /bin/mount
www-data ALL= NOPASSWD: /bin/cp /etc/resolv.conf.unlocator /etc/resolv.conf.dynamic
www-data ALL= NOPASSWD: /bin/cp /etc/resolv.conf.opendns /etc/resolv.conf.dynamic
www-data ALL= NOPASSWD: /bin/sync
www-data ALL= NOPASSWD: /etc/init.d/dnsmasq restart

HTML to call the scripts.

root@voyage:/home/lorcan# cat /var/www/index.html
...
<li><a href="/cgi-bin/setunlocatordns.pl">Set Unlocator DNS</a></li>
<li><a href="/cgi-bin/setopendns.pl">Set OpenDNS</a></li>
...

 

 

 

 

 

 

L2TP/IPsec client on Debian

Packages needed: strongswan, xl2tpd
VPN server is Mikrotik RouterBoard 2011UiAS-2HnD. I’m creating a VPN to make it easier to connect GNS3 server running on home laptop to servers running on lab PCs.

root@laptop:/home/lorcan# cat /etc/ipsec.conf
config setup
conn %default
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
keyexchange=ikev1
authby=secret
ike=aes128-sha1-modp1024,3des-sha1-modp1024!
esp=aes128-sha1-modp1024,3des-sha1-modp1024!

conn bblab
keyexchange=ikev1
left=%defaultroute
auto=add
authby=secret
type=transport
leftprotoport=17/1701
rightprotoport=17/1701
right=VPN_SERVER_IP

ipsec.secrets

root@laptop:/home/lorcan# cat /etc/ipsec.secrets
: PSK "mypassword"

xl2tpd.conf

root@laptop:/home/lorcan# cat /etc/xl2tpd/xl2tpd.conf
[lac bblab]
lns = 86.43.53.22
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tpd.client
length bit = yes

options.l2tpd.client

root@laptop:/home/lorcan# cat /etc/ppp/options.l2tpd.client
ipcp-accept-local
ipcp-accept-remote
refuse-eap
noccp
noauth
idle 1800
mtu 1410
mru 1410
defaultroute
usepeerdns
debug
lock
connect-delay 5000
name "myusername"
password "mypassword"

Restart services:

service strongswan restart
service xl2tpd restart

Start IPsec tunnel:
ipsec up bblab

Start L2TP tunnel:
echo "c bblab" > /var/run/xl2tpd/l2tp-control

Add route:

route add -net 192.168.88.0/24 dev ppp0

Outputs:

Restart StrongSWAN IPsec daemon:

root@laptop:/home/lorcan# service strongswan restart

Start XL2TPD in debug mode:

root@laptop:/home/lorcan# service xl2tpd stop
root@laptop:/home/lorcan# xl2tpd -D

Start IPsec tunnel:

root@laptop:/home/lorcan# ipsec up bblab
initiating Main Mode IKE_SA bblab[1] to my_server_ip
generating ID_PROT request 0 [ SA V V V V V ]
sending packet: from 192.168.11.87[500] to my_server_ip[500] (208 bytes)
received packet: from my_vpn_server_ip[500] to 192.168.11.87[500] (132 bytes)
parsed ID_PROT response 0 [ SA V V V ]
received NAT-T (RFC 3947) vendor ID
received XAuth vendor ID
received DPD vendor ID
generating ID_PROT request 0 [ KE No NAT-D NAT-D ]
sending packet: from 192.168.11.87[500] to my_vpn_server_ip[500] (244 bytes)
received packet: from my_vpn_server_ip[500] to 192.168.11.87[500] (236 bytes)
parsed ID_PROT response 0 [ KE No NAT-D NAT-D ]
local host is behind NAT, sending keep alives
generating ID_PROT request 0 [ ID HASH ]
sending packet: from 192.168.11.87[4500] to my_vpn_server_ip[4500] (68 bytes)
received packet: from my_vpn_server_ip[4500] to 192.168.11.87[4500] (68 bytes)
parsed ID_PROT response 0 [ ID HASH ]
IKE_SA bblab[1] established between 192.168.11.87[192.168.11.87]...my_vpn_server_ip[my_vpn_server_ip]
scheduling reauthentication in 3293s
maximum IKE_SA lifetime 3473s
generating QUICK_MODE request 3538013880 [ HASH SA No KE ID ID NAT-OA NAT-OA ]
sending packet: from 192.168.11.87[4500] to my_vpn_server_ip[4500] (356 bytes)
received packet: from my_vpn_server_ip[4500] to 192.168.11.87[4500] (316 bytes)
parsed QUICK_MODE response 3538013880 [ HASH SA No KE ID ID NAT-OA NAT-OA ]
CHILD_SA bblab{1} established with SPIs c22c6072_i 05f74f62_o and TS 192.168.11.87/32[udp/l2f] === my_vpn_server_ip/32[udp/l2f]
connection 'bblab' established successfully

Start L2TP tunnel:

root@laptop:/home/lorcan# echo "c bblab" > /var/run/xl2tpd/l2tp-control

xl2tp debug output to follow…

View interface:

root@laptop:/home/lorcan# ifconfig ppp0
ppp0 Link encap:Point-to-Point Protocol
inet addr:192.168.88.197 P-t-P:192.168.88.1 Mask:255.255.255.255
UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1410 Metric:1
RX packets:6 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:3
RX bytes:80 (80.0 B) TX bytes:82 (82.0 B)

Add route:

root@laptop:/home/lorcan# route add -net 192.168.88.0/24 dev ppp0

View routing table:

root@laptop:/home/lorcan# netstat -rn
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 192.168.11.254 0.0.0.0 UG 0 0 0 wlan0
10.200.200.0 0.0.0.0 255.255.255.252 U 0 0 0 tap0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 tap0
192.168.11.0 0.0.0.0 255.255.255.0 U 0 0 0 wlan0
192.168.88.0 0.0.0.0 255.255.255.0 U 0 0 0 ppp0
192.168.88.1 0.0.0.0 255.255.255.255 UH 0 0 0 ppp0

Run script on USB detection

Raspberry Pi 3 is running squeezelite client for Squeezebox, and connected by USB to Audiolab M-DAC (sounds great!) I found that if I turned off the M-DAC at night (but not the pi), when I turned it back on then squeezelite would not work until manually restarted. To solve this there is a script which detects the USB connection and restarts squeezelite.

List all USB devices.

pi@raspberrypi:/etc/udev/rules.d $ lsusb
Bus 001 Device 004: ID 0451:adac Texas Instruments, Inc.
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Devices are managed by the udev daemon. Create a udev script referencing vendor and product ID reported by lsusb above.

pi@raspberrypi:/etc/udev/rules.d $ cat 00-usb-audiolab.rules
ACTION=="add", ATTRS{idVendor}=="0451", ATTRS{idProduct}=="adac", RUN+="/usr/local/bin/usb-audiolab-in_udev"

Script called by the udev script above, which in turn calls another script to complete the desired action

pi@raspberrypi:/usr/local/bin $ cat usb-audiolab-in_udev
#!/bin/bash
/usr/local/bin/usb-audiolab-in &

The final script, which restarts squeezelite.

pi@raspberrypi:/usr/local/bin $ cat usb-audiolab-in
#!/bin/bash
sleep 1
echo "restarting squeezelite..."
/etc/init.d/squeezelite restart

IPSec/L2TP Server on EC2

Script to generate all the needed config files for the VPN server. Tweaked from http://www.stormacq.com/build-a-private-vpn-server-on-amazons-ec2/

[ec2-user@lns-lorcan ~]$ cat lns.sh
#!/bin/sh

service ipsec stop
service xl2tpd stop
chkconfig ipsec off
chkconfig xl2tpd off

# Please define your own values for those variables
 IPSEC_PSK=mypassword
 VPN_USER=myusername
 VPN_PASSWORD=mypassword

# Those two variables will be found automatically
 PRIVATE_IP=`wget -q -O - 'http://instance-data/latest/meta-data/local-ipv4'`
 PUBLIC_IP=`wget -q -O - 'http://instance-data/latest/meta-data/public-ipv4'`

yum install -y --enablerepo=epel openswan xl2tpd

cat > /etc/ipsec.conf <<EOF
version 2.0

config setup
 dumpdir=/var/run/pluto/
 nat_traversal=yes
 virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:25.0.0.0/8,%v6:fd00::/8,%v6:fe80::/10
 oe=off
 protostack=netkey
 nhelpers=0
 interfaces=%defaultroute

conn vpnpsk
 auto=add
 left=$PRIVATE_IP
 leftid=$PUBLIC_IP
 leftsubnet=$PRIVATE_IP/32
 leftnexthop=%defaultroute
 leftprotoport=17/1701
 rightprotoport=17/%any
 right=%any
 rightsubnetwithin=0.0.0.0/0
 forceencaps=yes
 authby=secret
 pfs=no
 type=transport
 auth=esp
 ike=3des-sha1
 phase2alg=3des-sha1
 dpddelay=30
 dpdtimeout=120
 dpdaction=clear
EOF

cat > /etc/ipsec.secrets <<EOF
$PUBLIC_IP %any : PSK "$IPSEC_PSK"
EOF

cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[global]
 port = 1701

;debug avp = yes
 ;debug network = yes
 ;debug state = yes
 ;debug tunnel = yes

[lns default]
 ip range = 192.168.42.10-192.168.42.250
 local ip = 192.168.42.1
 require chap = yes
 refuse pap = yes
 require authentication = yes
 name = l2tpd
 ;ppp debug = yes
 pppoptfile = /etc/ppp/options.xl2tpd
 length bit = yes
EOF

cat > /etc/ppp/options.xl2tpd <<EOF
ipcp-accept-local
ipcp-accept-remote
ms-dns 8.8.8.8
ms-dns 8.8.4.4
noccp
auth
crtscts
idle 1800
mtu 1280
mru 1280
lock
connect-delay 5000
EOF

cat > /etc/ppp/chap-secrets <<EOF
# Secrets for authentication using CHAP
# client server secret IP addresses

$VPN_USER l2tpd $VPN_PASSWORD *
EOF

iptables -t nat -A POSTROUTING -s 192.168.42.0/24 -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

iptables-save > /etc/iptables.rules

cat > /etc/network/if-pre-up.d/iptablesload <<EOF
#!/bin/sh
iptables-restore < /etc/iptables.rules
echo 1 > /proc/sys/net/ipv4/ip_forward
exit 0
EOF

service ipsec start
service xl2tpd start
chkconfig ipsec on
chkconfig xl2tpd on

802.1X on Windows PC

Command to create WiFi profile from XML file:

netsh wlan add profile filename=”c:\temp\wireless\Wi-Fi-eir_WiFi.xml”

 

<?xml version=”1.0″?>
<WLANProfile xmlns=”http://www.microsoft.com/networking/WLAN/profile/v1″&gt;
<name>eir_WiFi</name>
<SSIDConfig>
<SSID>
<hex>6569725F57694669</hex>
<name>eir_WiFi</name>
</SSID>
<nonBroadcast>false</nonBroadcast>
</SSIDConfig>
<connectionType>ESS</connectionType>
<connectionMode>auto</connectionMode>
<autoSwitch>false</autoSwitch>
<MSM>
<security>
<authEncryption>
<authentication>WPA2</authentication>
<encryption>AES</encryption>
<useOneX>true</useOneX>
</authEncryption>
<OneX xmlns=”http://www.microsoft.com/networking/OneX/v1″&gt;
<cacheUserData>true</cacheUserData>
<authMode>user</authMode>
<EAPConfig><EapHostConfig xmlns=”http://www.microsoft.com/provisioning/EapHostConfig”><EapMethod><Type xmlns=”http://www.microsoft.com/provisioning/EapCommon”>25</Type><VendorId xmlns=”http://www.microsoft.com/provisioning/EapCommon”>0</VendorId><VendorType xmlns=”http://www.microsoft.com/provisioning/EapCommon”>0</VendorType><AuthorId xmlns=”http://www.microsoft.com/provisioning/EapCommon”>0</AuthorId></EapMethod><Config xmlns=”http://www.microsoft.com/provisioning/EapHostConfig”><Eap xmlns=”http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1″><Type>25</Type><EapType xmlns=”http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV1″><ServerValidation><DisableUserPromptForServerValidation>false</DisableUserPromptForServerValidation><ServerNames></ServerNames></ServerValidation><FastReconnect>true</FastReconnect><InnerEapOptional>false</InnerEapOptional><Eap xmlns=”http://www.microsoft.com/provisioning/BaseEapConnectionPropertiesV1″><Type>26</Type><EapType xmlns=”http://www.microsoft.com/provisioning/MsChapV2ConnectionPropertiesV1″><UseWinLogonCredentials>false</UseWinLogonCredentials></EapType></Eap><EnableQuarantineChecks>false</EnableQuarantineChecks><RequireCryptoBinding>false</RequireCryptoBinding><PeapExtensions><PerformServerValidation xmlns=”http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV2″>false</PerformServerValidation><AcceptServerName xmlns=”http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV2″>false</AcceptServerName><PeapExtensionsV2 xmlns=”http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV2″><AllowPromptingWhenServerCANotFound xmlns=”http://www.microsoft.com/provisioning/MsPeapConnectionPropertiesV3″>true</AllowPromptingWhenServerCANotFound></PeapExtensionsV2></PeapExtensions></EapType></Eap></Config></EapHostConfig></EAPConfig&gt;
</OneX>
</security>
</MSM>
</WLANProfile>

802.1X on Debian

Disable NetworkManager as we will use wpa_supplicant instead.

root@laptop2:/home/bblab# systemctl stop NetworkManager.service
root@laptop2:/home/bblab# systemctl disable NetworkManager.service

Network/interfaces:

root@laptop2:/home/bblab# cat /etc/network/interfaces
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

auto wlan0
iface wlan0 inet dhcp
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

wpa_supplicant.conf

root@laptop2:/home/bblab# cat /etc/wpa_supplicant/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
update_config=1
network={
ssid="guest_wifi_ssid"
key_mgmt=WPA-EAP
eap=PEAP
identity="myusername"
password="mypassword"
phase2="auth=MSCHAPV2"
eapol_flags=0
}

Bring up interface.

root@laptop2:/home/bblab# ifup wlan0
Internet Systems Consortium DHCP Client 4.3.1
Copyright 2004-2014 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/wlan0/18:cf:5e:26:83:86
Sending on   LPF/wlan0/18:cf:5e:26:83:86
Sending on   Socket/fallback
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 3
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 8
DHCPREQUEST on wlan0 to 255.255.255.255 port 67
DHCPOFFER from 100.95.254.1
DHCPACK from 100.95.254.1
bound to 100.95.254.2 -- renewal in 1376 seconds.