Inside a Nexa PER-1500

I was looking for double pole relays suitable for mains voltage and noticed that one such relay is almost as expensive as a Nexa receiver, which got me wondering how remote switches does it.

I had an unused Nexa PER-1500 that I chose to disassemble and found that it uses a single pole relay, which to me was a bit unexpected since then you won’t know if it will switch the live or neutral.

Debian Linux firewall with multiple external IPs through DHCP


  • Debian Linux
  • Multiple network interfaces connected to WAN (for example using a switch, might also be possible using bridge and dummy interfaces in Linux)
  • ISP that gives multiple IPs via DHCP

Configure the interfaces

File: /etc/network/interfaces , change the interface names to match yours.

# The loopback network interface
auto lo
iface lo inet loopback

# LAN Interface
allow-hotplug ens3
iface ens3 inet static
        up /sbin/ip rule add dev $IFACE table 10
        up /sbin/ip rule add dev $IFACE table 11

# WAN Interface 1
allow-hotplug ens5
iface ens5 inet manual
        up /sbin/dhclient -4 -v -pf /run/dhclient.$ -lf /var/lib/dhcp/dhclient.$IFACE.leases -I -df /var/lib/dhcp/dhclient6.$IFACE.leases $IFACE
        down /bin/kill $(cat /run/dhclient.$

# WAN Inetrface 2
allow-hotplug ens9
iface ens9 inet manual
        up /sbin/dhclient -4 -v -pf /run/dhclient.$ -lf /var/lib/dhcp/dhclient.$IFACE.leases -I -df /var/lib/dhcp/dhclient6.$IFACE.leases $IFACE
        down /bin/kill $(cat /run/dhclient.$

# WAN Interface 3
allow-hotplug ens10
iface ens10 inet manual
        up /sbin/dhclient -4 -v -pf /run/dhclient.$ -lf /var/lib/dhcp/dhclient.$IFACE.leases -I -df /var/lib/dhcp/dhclient6.$IFACE.leases $IFACE
        down /bin/kill $(cat /run/dhclient.$

Configure dhclient enter hooks to use multiple routing tables

File: /etc/dhcp/dhclient-enter-hooks.d/routing-tables , change the interface names to match yours.


if [ "$RUN" = "yes" ]; then
        if [ "$interface" = "ens5" ]; then
                echo "Main wan interface, not doing anything special" >> /tmp/dhclient-routing-tables.log
                if [ "$interface" = "ens9" ]; then
                elif [ "$interface" = "ens10" ]; then
                echo "Routing table $table" >> /tmp/dhclient-script.debug

                if [ -n $table ]; then
                        if [ x$reason = xBOUND ] || [ x$reason = xRENEW ] || \
                                [ x$reason = xREBIND ] || [ x$reason = xREBOOT ]; then
                                if [ x$new_routers != x ] && [ x$new_routers != x$old_routers ]; then
                                        for router in $old_routers; do
                                                echo "Removing default $router table $table" >> /tmp/dhclient-routing-tables.log
                                                /sbin/ip route delete $router dev $interface table $table
                                                /sbin/ip route delete default via $router dev $interface table $table

                                        for router in $new_routers; do
                                                echo "Adding default $router table $table" >> /tmp/dhclient-routing-tables.log
                                                /sbin/ip route add $router dev $interface table $table
                                                /sbin/ip route add default via $router dev $interface table $table

                                if [ x$new_ip_address != x$old_ip_address ]; then
                                        echo "ip rule add from $new_ip_address table $table" >> /tmp/dhclient-routing-tables.log
                                        /sbin/ip rule del from $old_ip_address table $table
                                        /sbin/ip rule add from $new_ip_address table $table

Automatically update firewall when dhclient runs

File: /etc/dhcp/dhclient-exit-hooks.d/firewall

# Reload firewall in case ip has changed or such

if [ "$RUN" = "yes" ]; then

Configure the NAT and firewall

File: /etc/


WAN2_IP=$(ip addr show dev $WAN2_INTERFACE | grep 'inet ' |awk '{print $2}' | cut -f1 -d'/')
WAN3_IP=$(ip addr show dev $WAN3_INTERFACE | grep 'inet ' |awk '{print $2}' | cut -f1 -d'/')

# Configure routing tables
ip rule delete fwmark 10 table 10
ip rule add fwmark 10 table 10
ip rule delete fwmark 11 table 11
ip rule add fwmark 11 table 11

ip route add dev ens3 table 10
ip route add dev ens3 table 11

# Configure firewall
iptables -F
iptables -F -t nat
iptables -F -t mangle
ip6tables -F

# Allow ICMP
iptables -A INPUT -p icmp -j ACCEPT
iptables -A FORWARD -p icmp -j ACCEPT
ip6tables -t filter -A INPUT -p icmpv6 -j ACCEPT
ip6tables -t filter -A FORWARD -p icmpv6 -j ACCEPT

# Allow SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow localhost
iptables -I INPUT -i lo -s -d -j ACCEPT
ip6tables -I INPUT -i lo -s ::1 -d ::1 -j ACCEPT

# Allow state
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT

# NAT Postrouting

# Allow to all from lan
iptables -A FORWARD -i $LAN_IF -o $WAN2_INTERFACE -s -j ACCEPT
iptables -A FORWARD -i $LAN_IF -o $WAN3_INTERFACE -s -j ACCEPT

# Special mangle for multiple routing tables
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j RETURN # return if already set
iptables -t mangle -A PREROUTING -i $WAN2_INTERFACE -j MARK --set-mark 10
iptables -t mangle -A PREROUTING -i $WAN3_INTERFACE -j MARK --set-mark 11

iptables -t mangle -A POSTROUTING -o $WAN2_INTERFACE -j MARK --set-mark 10
iptables -t mangle -A POSTROUTING -o $WAN3_INTERFACE -j MARK --set-mark 11
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

# HTTP/HTTPS on WAN2 to webserver
iptables -t nat -A PREROUTING -i $WAN2_INTERFACE -p tcp --dport 80 -j DNAT --to
iptables -t nat -A PREROUTING -i $WAN2_INTERFACE -p tcp --dport 443 -j DNAT --to
iptables -A FORWARD -p tcp --dport 80 -d -j ACCEPT
iptables -A FORWARD -p tcp --dport 443 -d -j ACCEPT

# Rest of WAN2 to
iptables -t nat -A POSTROUTING -o $WAN2_INTERFACE -s -j SNAT --to-source $WAN2_IP
iptables -t nat -A PREROUTING -i $WAN2_INTERFACE -j DNAT --to-destination
iptables -t mangle -A PREROUTING -s -j MARK --set-mark 10

# 1:1 NAT for WAN3
iptables -t nat -A POSTROUTING -o $WAN3_INTERFACE -s -j SNAT --to-source $UWAN3_IP
iptables -t nat -A PREROUTING -i $WAN3_INTERFACE -j DNAT --to-destination
iptables -t mangle -A PREROUTING -s -j MARK --set-mark 11
iptables -A FORWARD -p tcp --dport 22 -d -j ACCEPT

# Masquerading
iptables -t nat -A POSTROUTING -s -j MASQUERADE

# Log the rest
iptables -t filter -A INPUT -j LOG
ip6tables -t filter -A INPUT -j LOG
iptables -A FORWARD -j LOG
ip6tables -A FORWARD -j LOG

# Default drop
iptables -P INPUT DROP
iptables -P FORWARD DROP
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP

Make script executable:

# chmod +x /etc/

Create systemd service for firewall

File: /etc/systemd/system/firewall.service




Enable service:

# systemctl enable firewall

Enable forwarding

File: /etc/sysctl.conf

net.ipv4.conf.all.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2


Reboot the system and verify functionality.

Digoo DG-M1Z IP Camera settings

Cheap IP camera with 1920×1080 resolution.

It does NOT have a web interface.
It can only be managed via ONVIF (python-onvif is useful for this, also ONVIF Device Manager).

Zoneminder settings:
General -> Source type = Ffmpeg
Source -> Source path: rtsp://admin:20160404@<ip>:554/onvif1
Source -> Remote Method: RTP/Unicast
Capture width: 1920
Capture height: 1080

There is smearing on the bottom part of the image about half the time.
Most people on the internet recommends switching to TCP to avoid smearing, but I have been unable to get this camera working over TCP.

Jumbo frames on Quanta LB6M

Enable jumbo frames for layer2 traffic:

(FASTPATH Routing) #config

(FASTPATH Routing) (Config)#interface 0/1-0/28

(FASTPATH Routing) (Interface 0/1-0/28)#mtu 9216

(FASTPATH Routing) (Interface 0/1-0/28)#exit

(FASTPATH Routing) (Config)#exit

Enable jumbo frames for routed traffic:

(FASTPATH Routing) #show ip interface brief

Interface    State  IP Address      IP Mask         Method
----------   -----  --------------- --------------- -------
2/1          Up   Manual

(FASTPATH Routing) (Config)#interface 2/1

(FASTPATH Routing) (Interface 2/1)#ip mtu 9198

Remember to save your config:

(FASTPATH Routing) #write mem

This operation may take a few minutes.
Management interfaces will not be available during this time.

Are you sure you want to save? (y/n) y

Config file 'startup-config' created successfully .

Configuration Saved!

Raspberry Pi Dragino LoRa/GPS Hat + DS18B20 temperature sensor

Wanted to log the temperature with the LoRa gateway pi, but had to use another gpio since gpio4 was already in use for the Dragino LoRa/GPS Hat.

Just solder the DS18B20 sensor as in the image (the blue resistor is a 4k7 ohm pullup between data and +3v3).

And then add the following to /boot/config.txt


Reboot and you will find the sensor in /sys/bus/w1/devices/.

Multicore debugging with OpenOCD + GDB

When using openocd with a MCU with multiple targets, openocd will listen on multiple ports (one per core) for gdb to connect to.
So for example a LPC4370 with the following openocd config:

swj_newdap lpc4370 m4 -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x4ba00477
jtag newtap lpc4370 m0sub -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x0ba01477
jtag newtap lpc4370 m0app -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id 0x0ba01477

target create lpc4370.m4 cortex_m -chain-position lpc4370.m4
target create lpc4370.m0sub cortex_m -chain-position lpc4370.m0sub
target create lpc4370.m0app cortex_m -chain-position lpc4370.m0app

lpc4370.m4 configure -work-area-phys 0x10000000 \
                        -work-area-size 0x20000 -work-area-backup 0
lpc4370.m0sub configure -work-area-phys 0x18000000 \
                         -work-area-size 0x4800 -work-area-backup 0
lpc4370.m0app configure -work-area-phys 0x10080000 \
                         -work-area-size 0x92000 -work-area-backup 0
targets lpc4370.m4

The main m4 core will be available as usual by connecting with gdb> target remote localhost:3333 , and m0app will be debuggable by connecting with gdb> target remote localhost:3335 .

The m0app and m0sub cores are a bit special in that they must be started from the m4 core, and any attempts to start them from gdb will result in warnings and the core will still be in reset state, until started by the m4 core.

Enabling IPMI using ipmiutil

ipmiutil is available for Linux, Windows, Solaris, Mac OSX, and FreeBSD and can be downloaded from:

The following command will enable LAN access for IPMI on IP with gateway, username admin and password Password

ipmiutil lan –e –I -f 2 -G –u admin –p Password


To set shared LAN on Dell servers (useful if the servers does not have a DRAC card):

ipmiutil delloem lan set shared


Migrate live system from single disk to LVM on RAID 1 (on Debian Jessie)

This assumes that the two drives are /dev/sda and /dev/sdb.
Where /dev/sda is the existing drive and /dev/sdb is the new drive,
and that the system partition is sda1/sdb1.

Copy the partition table from /dev/sda to /dev/sdb

sfdisk -d /dev/sda | sfdisk --force /dev/sdb


Set the filesystem type to “fd” (Linux raid autodetect)

sfdisk --change-id /dev/sdb 1 fd


Zero the superblock to make sure that mdadm will not detect an existing volume

mdadm --zero-superblock /dev/sdb1


Create the RAID 1 with the new disk only

mdadm --create /dev/md0 --level=1 --raid-disks=2 missing /dev/sdb1


Add the raid to mdadm.conf so that it will be configured automatically on boot

mdadm --examine --scan >> /etc/mdadm/mdadm.conf


Create the physical volume on the new raid volume

pvcreate /dev/md0


Create a volume group on the new physical volume

vgcreate vg_hostname /dev/md0


Create a logical volume on then new volume group

lvcreate -L 100G -n root vg_hostname


Create an ext4 filesystem on the logical volume

mkfs.ext4 /dev/vg_hostname/root


Mount the new filesystem

mount /dev/vg_hostname/root /mnt


Copy the old system files

rsync -auxHAXSv --exclude=/dev/* --exclude=/proc/* --exclude=/sys/* --exclude=/tmp/* --exclude=/mnt/* --exclude=/afs/* / /mnt/


Modify /etc/fstab, the line for / should be

/dev/vg_hostname/root / ext4    errors=remount-ro 0       1


Create /etc/grub.d/09-lvm with contents:

exec tail -n +3 $0

menyentry 'New system' --class gnu-linux --class gnu --class os {
    insmod part_msdos
    insmod diskfilter
    insmod mdraid1x
    insmod lvm
    insmod ext2
    set root='lvm/vg_hostname-root'
    linux /boot/vmlinuz-$(uname -r) root=/dev/mapper/vg_hostname-root ro
    initrd /boot/initrd.img-$(uname -r)


Add the following to /etc/default/grub:



Update the grub configuration files:



Update the initramfs

update-initramfs -c -k $(uname -r) -u


Reboot and it should now boot from the LVM volume


Verify that we have booted from the LVM volume

# the output should contain the following
/dev/mapper/vg_hostname-root on / type ext4 (rw,relatime,errors=remount-ro,data=ordered)


If everything is ok we can continue with adding the old drive to the raid.

Change the partition type to Linux raid autodetect
sfdisk –change-id /dev/sda 1 fd 

Add the old drive to the raid:

mdadm --add /dev/md0 /dev/sda1


Update grub config files and initramfs

update-initramfs -c -k $(uname -r) -u


Install grub to the devices.

grub-install --recheck /dev/sda
grub-install --recheck /dev/sdb



This is the configuration for L2TP/IPSEC on Cisco ASA.
This assumes that there is an aaa-server configured named ad_vpn for vpn users.
When using aaa-server protocol ldap then only pap is valid authentication type.
If you use radius authentication instead of ldap then ms-chap-v2 authentication can be enabled.

ip local pool vpnclient mask

access-list vpnclient_splitTunnelAcl remark Internal
access-list vpnclient_splitTunnelAcl standard permit

group-policy vpnclient internal
group-policy vpnclient attributes
vpn-tunnel-protocol IPSec l2tp-ipsec
split-tunnel-policy tunnelspecified
split-tunnel-network-list value vpnclient_splitTunnelAcl
intercept-dhcp enable

tunnel-group DefaultRAGroup general-attributes
address-pool vpnclient
authentication-server-group ad_vpn
default-group-policy vpnclient
tunnel-group DefaultRAGroup ipsec-attributes
pre-shared-key *****
tunnel-group DefaultRAGroup ppp-attributes
authentication pap
no authentication chap
no authentication ms-chap-v1

crypto ipsec ikev1 transform-set l2tp1 esp-aes esp-sha-hmac
crypto ipsec ikev1 transform-set l2tp1 mode transport
crypto ipsec ikev1 transform-set l2tp2 esp-aes esp-md5-hmac
crypto ipsec ikev1 transform-set l2tp2 mode transport
crypto ipsec ikev1 transform-set aes-256-l2tp esp-aes-256 esp-sha-hmac
crypto ipsec ikev1 transform-set aes-256-l2tp mode transport

crypto dynamic-map SYSTEM_DEFAULT_CRYPTO_MAP 65535 set transform-set l2tp1 l2tp2 aes-256-l2tp
no crypto dynamic-map SYSTEM_DEFAULT_CRYPTO_MAP 65535 set pfs

crypto isakmp nat-traversal 20

crypto ikev1 policy 5
authentication pre-share
encryption 3des
hash sha
group 2
lifetime 86400
crypto ikev1 policy 10
authentication pre-share
encryption aes
hash sha
group 2
lifetime 86400

crypto ikev1 enable outside