Howto disable Raspberry Pi Status LEDs with RaspberryMatic

I’m using a RaspberryPi 3 with RaspberryMatic distribution to control my HomeMatic thermostats. This distribution has a “heartbeat” functionality, which leds the green LED of the Pi light up in constant time intervals.

These LEDs are quite strong and disturb the sleep of my family. Therefore its time to disable these leds.

Connect via SSH to the RaspberryMatic installation. Edit or create the file /usr/local/etc/rc.local and add this content:

#!/bin/sh
echo none >/sys/class/leds/led0/trigger
echo none >/sys/class/leds/led1/trigger

Now make this script executeable:

chmod +x /usr/local/etc/rc.local

This script is executed on each start and disables the LEDs completely. No need to use some duct tape to mask the LEDs anymore 🙂

Configure DynDNS client ddclient for use with all-inkl

You can try ddclient, if you don’t have a Router or NAS, which updates a DynDNS account. I’m using it on Raspbian and all-inkl as hosting service.

Create a new dyndns account in kas.all-inkl.com. Go to Tools, DDNS Settings and create a new entry. You’ll need the information from this page for the configuration of ddclient.

On your Raspberry pi:

$ sudo apt-get update
$ sudo apt-get install ddclient

Select other as DDNS service provider. Use dyndns.kasserver.com/ as update server with dyndns2 as protocol. Configure username and password as provided by all-inkl. Use eth0 as network interface (we’ll change this later on) and add your DynDNS Domainname.

$ sudo nano /etc/ddclient.conf

Change the file accordingly to your needs:

# Configuration file for ddclient generated by debconf
#
# /etc/ddclient.conf

protocol=dyndns2
#use=if, if=eth0
use=web
web=checkip.dyndns.org/
web-skip='Current IP Address: '
daemon=900
syslog=yes
pid=/var/run/ddclient.pid
mail-failure='email@domain.com'
server=dyndns.kasserver.com
login='yourlogin'
password='yourpassword'
subdomain.domain.com

This config will use checkip.dyndns.org to get your currently used external IP address. If you’ll use eth0, it will probably report the internal IP address of your eth0 interface instead.

If it encounters any errors, it will send an failure email to the provided email.

Now reboot the service and you’re done

$ sudo service ddclient restart

Setup external USB disk as NTFS volume on Raspbian

I intend to use an external 2.5″ USB disk formatted as NTFS volume on my Raspberry Pi. Since its rather larger (5TB) I don’t want to use MBR but GPT instead. Here’s a short list of commands I’ve used to setup the disk.

Start by identifying the connected disk:

> lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    0  4.6T  0 disk
└─sda1        8:1    0  4.6T  0 part
mmcblk0     179:0    0 14.9G  0 disk
├─mmcblk0p1 179:1    0  1.5G  0 part
├─mmcblk0p2 179:2    0    1K  0 part
├─mmcblk0p5 179:5    0   32M  0 part
├─mmcblk0p6 179:6    0   69M  0 part /boot
├─mmcblk0p7 179:7    0  8.2G  0 part /
├─mmcblk0p8 179:8    0  512M  0 part
└─mmcblk0p9 179:9    0  4.5G  0 part

My disk is sda.

I now usually used fdisk as a partitioning tool. However, there’s a tool I can highly recommend. Its called parted and can be installed using:

sudo apt-get install parted

Since I’ll want to use ntfs as file system, I’ll need to install the ntfs drivers:

sudo apt-get install ntfs-3g

Now create a new GPT partition table:

> sudo parted /dev/sda mklabel gpt
Warning: The existing disk label on /dev/sda will be destroyed and all data on this disk will be lost. Do you want to continue?
Yes/No? yes
Information: You may need to update /etc/fstab.

Now create a new partition with ntfs. I’ll use all of the available space, so its from 0 to 100%:

> sudo parted -a opt /dev/sda mkpart primary ntfs 0% 100%
Information: You may need to update /etc/fstab.

Now format the disk in quick format with ntfs. It will label the partition as “SynoBackups”:

> sudo mkfs.ntfs -L SynoBackups -Q /dev/sda1
Cluster size has been automatically set to 4096 bytes.
Creating NTFS volume structures.
mkntfs completed successfully. Have a nice day.

This label is very helpful in identifying the partition, even when it is connected to a different USB port. Using a device like sda might point to a different drive, so its better to use the label. This is one of the big advantages of using gpt in comparison to mbr.

Let’s see the label in action:

sudo lsblk --fs
NAME        FSTYPE LABEL       UUID                                 MOUNTPOINT
sda
└─sda1      ntfs   SynoBackups 4EE12D1B5321171F
mmcblk0
├─mmcblk0p1 vfat   RECOVERY    525E-19E4
├─mmcblk0p2
├─mmcblk0p5 ext4   SETTINGS    ceb0ae64-8675-406b-8eed-2244c26814c8
├─mmcblk0p6 vfat   boot        8454-E385                            /boot
├─mmcblk0p7 ext4   root0       65678398-7f53-48ec-8452-c277500fb4e8 /
├─mmcblk0p8 vfat               AC0D-3FB1
└─mmcblk0p9 ext4               ff645116-fe34-43bf-a580-b89fa963085d

Note that there’s also a more specific id, the UUID. We will use this UUID later when we configure a default mount point in /etc/fstab.

Now we’ll try to mount the new partition. Create a folder to mount the partition and mount it manually:

sudo mkdir /mnt/backups
sudo mount -o defaults /dev/sda1 /mnt/backups

Verify that the disk is mounted and try to write some stuff to it:

> df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       8.0G  2.7G  4.9G  36% /
devtmpfs        457M     0  457M   0% /dev
tmpfs           462M     0  462M   0% /dev/shm
tmpfs           462M  6.2M  455M   2% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           462M     0  462M   0% /sys/fs/cgroup
/dev/mmcblk0p6   68M   23M   46M  33% /boot
/dev/sda1       4.6T  210M  4.6T   1% /mnt/backups

> sudo lsblk --fs
NAME        FSTYPE LABEL       UUID                                 MOUNTPOINT
sda
└─sda1      ntfs   SynoBackups 4EE12D1B5321171F                     /mnt/backups
mmcblk0
├─mmcblk0p1 vfat   RECOVERY    525E-19E4
├─mmcblk0p2
├─mmcblk0p5 ext4   SETTINGS    ceb0ae64-8675-406b-8eed-2244c26814c8
├─mmcblk0p6 vfat   boot        8454-E385                            /boot
├─mmcblk0p7 ext4   root0       65678398-7f53-48ec-8452-c277500fb4e8 /
├─mmcblk0p8 vfat               AC0D-3FB1
└─mmcblk0p9 ext4               ff645116-fe34-43bf-a580-b89fa963085d

> echo "success" | sudo tee /mnt/backups/file
success
> cat /mnt/backups/file
success
> rm /mnt/backups/file
> sudo umount /mnt/backups

Now we’ll add the partition to /etc/fstab so that it can be mounted automatically:

UUID=4EE12D1B5321171F   /mnt/backups    ntfs    defaults        0       2

See that I’m now using the UUID instead of /dev/sda to mount the ntfs volume to /mnt/backups. We can test the new setting:

> sudo mount -a
> df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/root       8.0G  2.7G  4.9G  36% /
devtmpfs        457M     0  457M   0% /dev
tmpfs           462M     0  462M   0% /dev/shm
tmpfs           462M  6.2M  455M   2% /run
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs           462M     0  462M   0% /sys/fs/cgroup
/dev/mmcblk0p6   68M   23M   46M  33% /boot
/dev/sda1       4.6T  210M  4.6T   1% /mnt/backups

I think this is a really nice change in mounting the volumes and will create a more stable configuration, regardless which USB port you’ve used to connect your drive.

Block SSH connections by origin of IP address

If you’re exposing services to the internet, you’ll notice a lot of connection attempts. To block those bots and scripts trying to login to your machine, you should use fail2ban.

However, you can also limit the range of allowed origins of the IP addresses. The company MaxMind provides a database of IP addresses and their origin contries. You can configure your machine in such a way that only certain country codes are allowed.

Start by installing the geoip client and database by using this apt command:

sudo apt-get install geoip-bin geoip-database

This database is updated automatically, when you’ve got your machine configured for auto updates.

The next step is to save this script to your machine in /usr/local//usr/local/bin/ipfilter.sh:

Edit the script to your needs, e.g. by limiting the number of allowed countries. Now make this script executable:

chmod +x /usr/local/bin/ipfilter.sh

It is time to test it. Try the command with a known IP in America and one from a local network or known IP from the allowed countries:

> /usr/local/bin/ipfilter.sh
Usage:  ipfilter.sh <ip>
> /usr/local/bin/ipfilter.sh 8.8.8.8
> echo $?
1
> /usr/local/bin/ipfilter.sh 192.168.1.1
> echo $?
0

Notice the different exit codes of the script. If the IP is from a country that is allowed or if it is from a local network, it will exit with 0, otherwise 1. We can use this script now to configure a filter for sshd in the /etc/hosts.allow and /etc/hosts.deny files.

Add to /etc/hosts.allow:

sshd: ALL: aclexec /usr/local/bin/ipfilter.sh %a

As documented in the hosts_options(5) man page, the standard output is redirected to /dev/null, so that there’s no chance for you to get the output from echo. And as you want the exit status to be taken into account, you should use aclexec instead of spawn. Indeed the man page says for aclexec: “The connection will be allowed or refused depending on whether the command returns a true or false exit status.”

https://unix.stackexchange.com/a/149057/298669

I’ve previously used “spawn” instead of “aclexec” but the IPs weren’t blocked. There were still connection attempts in the fail2ban log. By using aclexec, the exit code will be properly used for filtering.

Add to /etc/hosts.deny:

sshd: ALL

Please note the trailing newline. If this is the last entry in the hosts file, you’ll need to add a newline. Otherwise the role won’t be active.

Do a reboot of your machine and try to connect. You should still be able to connect 😉 Otherwise you’ll need to revert this changes locally, since you’ve successfully blocked yourself from accessing that machine.

You can have a look at the /var/log/auth.log and will see entries like this for example (blocking an IP from China/CN):

Sep 30 12:10:32 raspberrypi root: DENY sshd connection from 222.186.30.76 (CN)
Sep 30 12:10:32 raspberrypi sshd[886]: aclexec returned 1
Sep 30 12:10:32 raspberrypi sshd[886]: refused connect from 222.186.30.76 (222.186.30.76)

This should reduce the amount of blocked SSH connections attempts significantly, if configured to a smaller selection of countries.