Hardening of OpenHAB Guide

Cyber risks are consistently increasing. These affect the private and corporate world. House automation can be vulnerable against cyber attacks. This hardening of OpenHAB Guide shares some options to mitigate or reduce cyber risks for your home automation based on OpenHABian.

Hardening of OpenHAB Guide

Hardening of OpenHAB Guide

Index:

General Information

This Hardening of OpenHAB Guide is focusing on OpenHABian. However, since OpenHABian is based on Debian, it is likely to run on other linux distributions too, including Debian, Ubuntu, RedHat, openSUSE. 

Change your password!

The first thing, right after the initial installation, is changing your password. This because it is public known that the standard settings are

  • user: openhabian
  • password: openhabian

To change the password, you like to leverage on the below command. Also you like to consider some password best practices recommended by may cyber security experts. Password best practices:

  • Each character increases the complexity. This is why passwords typically have a minimum requirement of 8 characters. You like to go beyond 8 characters
  • There are 26 lowercase letters, but only 10 digits (0-9). You can see how “home” is more secure than “8394” against computer scripts running through possible combinations of characters.
  • Mixing numbers and letters, including upper & lowercase letters, as well as special characters increases the protection against pre-defined word lists a computer script could test against. Further, its a good protection against so called brute force attacks in which a computer script would randomly try passwords 

Example of a good password that you can recall. Think about: “Today I setup my OpenHAB and I like to secure it!”. This could become the password of:TIsmOHABaIltsi!

To change the password type:

passwd openhabian

Secure your SSH connection to OpenHAB

To have administrative access to your OpenHAB, you would like to leverage on SSH. There are different layers of security that you can achieve for securing the connection between your computer and OpenHAB. This Hardening of OpenHAB Guide leverages on the so called “key based SSH login”, whilst disabling remote login by password. SSH key based login is leveraging on certificates which is for a number of good reasons seen by cyber security experts as far more secure than allowing login by password. Additionally, if you leverage on login by SSH key, the user experience is far better. Finally, you like to leverage on a strong cryptographic standard. This Hardening of OpenHAB Guide leverages on Ed25519. Here’s the step by step guide:

Step 1, generate certificates on OpenHABian:

ssh-keygen -t ed25519 -C "Your@E-MailAddress.com"

The input/output should look similar like the below. Please note, not setting a passphrase allows an easier user experience for logging in, but is however also more risky as it potentially allows anyone to login that is able to steel your private key

openhabian@openHAB:~$ ssh-keygen -t ed25519 -C "Your@E-MailAddress.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/openhabian/.ssh/id_ed25519): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/openhabian/.ssh/id_ed25519
Your public key has been saved in /home/openhabian/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:iic0RyBXlhKNmvr7OxS8z95dcdRi8EmQRpsXG1J3zeE OpenHAB3
The key's randomart image is:
+--[ED25519 256]--+
|  . +=o.   .=+=o=|
|   oooo     oB.B+|
|   + ..    .o OE.|
|  o o.       + . |
| .  oo. S   . .  |
|.  .o+ .     o   |
| . .ooo     .    |
|  . .oo. . .     |
|  .oo+. . .      |
+----[SHA256]-----+

Step 2, generate certificates on your computer

In this Hardening of OpenHAB Guide we leverage on a Mac computer and we leverage on the Mac’s command line. If you run a Windows system you like to leverage on your favourite software.

Mike@Mac-Mini ~ % ssh-keygen -t ed25519 -C "Your@E-MailAddress.com"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/Users/Mike/.ssh/id_ed25519): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /users/Mike/id_ed25519
Your public key has been saved in /users/Mike/id_ed25519.pub
The key fingerprint is:
SHA256:D38BRm81OT5jE5AtD+eCHXG77tNNQUhnC1jGk7Bsw3g test
The key's randomart image is:
+--[ED25519 256]--+
|          ..OX*+ |
|         .+oBBX+.|
|         .oEoO++ |
|         .+o+ Oo |
|        S   .o.+.|
|         +   o  .|
|          o . .o.|
|           . .. o|
|              .. |
+----[SHA256]-----+

Step 3, copy your public certificate to the OpenHAB OpenHABian system

This step is now a simple copy and paste activity. You copy the content of your in step 2 generated id_ed25519.pub file into the authorized_key file on OpenHAB.

nano /home/openhabian/.ssh/authorized_keys

 Try to login by leveraging on SSH. For example, if your OpenHAB IP address is 192.168.1.100, than by typing the below

ssh openhabian@192.168.1.100

If all runs well, than you should be able to login without typing a password as SSH will be leveraging on your keys.

Step 4, Hardening of ssh.conf

A important step in this hardening process is to ensure the right configuration of SSH. SSH stores its configuration in ssh.conf. In this step 4 we now will be updating ssh.conf in a way in which your OpenHAB will allow login by SSH key only, but not anymore by passwords. With this you mitigate the high risks related to passwords (Password guessing, brute force attacks, etc.)

sudo vi /etc/ssh/sshd_config

Allow Only ed25519 Key Login

To activate login by the above created ed25519 key only change the following lines from

#HostKey /etc/ssh/ssh_host_ed25519_key
#AuthorizedKeysFile     .ssh/authorized_keys .ssh/authorized_keys2

to

HostKey /etc/ssh/ssh_host_ed25519_key
AuthorizedKeysFile     .ssh/authorized_keys 

Allow Only Key Login (no password login anymore)

To activate login by key only (no password anymore) set Password Authentication to no. Additionally, disallow login with empty passwords. Therefore, change the following lines from

#PasswordAuthentication yes 
#PermitEmptyPasswords no

to
PasswordAuthentication no
PermitEmptyPasswords no

Disable Root Login

You do not like that anyone logs into your OpenHAB remotely by leveraging on Root. Therefore, disallow root login. This you do by changing the below line from:

#PermitRootLogin prohibit-password

to:

PermitRootLogin no

Only Allow The More Secure Protocol 2

There are tow protocol versions of SSH, Protocol 1 and Protocol 2. Protocol 1 is legacy and Protocol 2 is more secure. Most likely, your sshd_config does not consist of a setting. You however can simply add the below line at the end of your sshd_config file:

Protocol 2

Protect Against Unattended Sessions

Leaving your OpenHAB unattended for a long time period carries security risks. Therefore you like to address the issue by setting a limit for keeping a session open if not used. In this example we set the limit to 180 second. SSH will close the session once idle for 180 seconds. Change from:

#ClientAliveInterval 6

to:

ClientAliveInterval 180

Allow Only Selected Users To Login By SSH

Allow only users you know to login into your OpenHAB system. By default the user is openhabian. In this example we allow only the “openhabian” user to login leveraging on SSH. Add the below line to the end of your sshd_config:

AllowUsers openhabian

Maximum Number Of Trying The Password

Even though we have allowed in the above only login by key, we still like to limit the number of passwords attempts to 3 tries. Change from:

#MaxAuthTries 6

to:
MaxAuthTries 3

Make The New Configuration Effective And Test It

Last step is to test your updated configuration. To do so, you keep your existing terminal open. Do not close it, because you will need it if your configuration does not work. We try the configuration in 2 steps. First, in the existing window we type and execute:

sudo systemctl restart sshd

2nd, in a new additional terminal window (open a new terminal window and keep the existing open) you type:

ssh openhabian@

“IP ADDRESS OF YOUR OPENHAB”

If you able to login, great. Your configuration works. If not, double check in the other Terminal window that you have not closed your configuration for potential mistakes.

Finally, you can test some of your configurations whether they work properly. Open a Terminal window and test whether login with Protocol 1 is possible (it should not be possible) and it should look like this:

testuser@Mac-mini ~ % ssh -1 openhabian@”IP ADDRESS OF YOUR OPENHAB”
SSH protocol v.1 is no longer supported
testuser@Mac-mini ~ %

Test whether you can login as root and if the root user as configured in the above is not allowed to login, than it should look like this:

testuser@Mac-mini ~ %  ssh root@"IP ADDRESS OF YOUR OPENHAB"
root@"IP ADDRESS OF YOUR OPENHAB": Permission denied (publickey).
testuser@Mac-mini ~ % 

Disable Wireless Interfaces (WiFi and Bluetooth)

NOTE: If you need for your Home Automation either Bluetooth or WiFi, than of course you should not deactivate these services!

In a typical setup, you most likely have connected your OpenHAB via Ethernet RJ 45 Cable. It therefore makes no sense to have the WiFi Wireless interface of your Raspberry OpenHAB running. The idea of hardening is to turn off what ever can be turned off, because this is a risk reduction. So lets switch off WiFi. Type on the command line:

sudo openhabian-config

  1. Select “System Settings”
  2. Select “WiFi setup”
  3. Deactivate WiFi

Additionally Disable Wireless Interfaces on Boot Level

To ensure the wireless devices are disabled at boot level, you on top of the above type in the command line:

sudo nano /boot/config.txt

Add at the end of the file the following lines (disable-bt = Bluetooth disable-wifi = Wireless LAN / WiFi):

# Disable wireless services (bt=bluetooth)
dtoverlay=disable-wifi
dtoverlay=disable-bt

Additionally Avoid Using Modprobe To Activate Wireless Interfaces

Modprobe allowed to load kernel modules into the Linux kernel. This way modprobe could potentially be used for re-activating wireless interfaces. To avoid this, we add the wireless interfaces to the blacklist. To do so, you type on the command line:

sudo nano /etc/modprobe.d/raspi-blacklist.conf

At the bottom of this file we add the following lines:

blacklist brcmfmac
blacklist brcmutil

To disable Bluetooth module from loading add the following lines on top of the above
blacklist hci_uart
blacklist btbcm
blacklist btintel
blacklist rfcom
blacklist btqca
blacklist btsdio
blacklist bluetooth

Finally, reboot the system by typing 

sudo reboot

Configure SMTP For Alerts

In an ideal world you like your OpenHAB Raspberry to tell you if there is something to know. For example, if there is anything not OK with the configuration, if there are any logs or security warnings, or if for example your disk is running full. For this reason we leverage on SMTP that allows the OpenHAB Raspberry to send you emails. In this example we leverage on Gmail.

First we install the necessary packages by executing the following command:

sudo apt install msmtp msmtp-mta

Once done, edit the msmtprc file copy & pasting the below. Please note, you need to update it with your Gmail mail address, username and password

 sudo nano /etc/msmtprc

Add the below values:
# Default values 
# Example configuration made by https://www.myhowto.blog
# Configuration leverages on Google Gmail
# Replace *youraddress@gmail.com* by your Gmail address
# Replace *yourPassword* by your real Gmail password
# Replace *yourUsername# by your real Gmail username
#
defaults
auth on
tls on

# Gmail
account gmail
host smtp.gmail.com
from youraddress@gmail.com

port 587
user yourUsername
password yourPassword

# Syslog logging with facility LOG_MAIL instead of the default LOG_USER.
syslog LOG_MAIL

# Set a default account
account default : gmail

Once done, you like to test whether your configuration is working. This can be done directly on the command line by typing:

 echo "This is a test email" | msmtp --debug youraddress@gmail.com

Configure Unattended Updates

NOTE: Automating system updates are important, especially if it comes to security updates. Also, having this sort of headless system updates are amazing for your personal freedom. One thing less to think about. However, such updates can potentially cause unexpected problems and incidents. It is therefore key that you are ware on this fact and that you not only automate updates, but also backup allowing you to restore the system for the case updates bring you new problems.

Install The Prerequisites

Lets ensure all packages needed to run updates automatically are installed. Therefore type on the command line:

sudo apt install unattended-upgrades apt-listchanges apticron

Configure Auto-Updates (Unattended Updates)

Next step is to configure unattended updates. For this we create a configuration file like the below. First, to create a configuration file, type:

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

Secondly, include the below content. Alternatively activate in your existing 50unattended-upgrades file the below content. In case you copy & paste the below and replace the original content, then create a backup of the original content. If the updates do not work, then the original content maybe helps to troubleshoot. Note, you should review it and update it by your needs. The obvious one’s that need your update are:

  • Email Address – (to get emails about updates sent; Please note, you need to have configured SMTP on your system. More about this can be found in the above chapter)
  • What you like to update (in this case: Debian and Debian-Security)
  • Allow (true) or disallow (false) to reboot automatically after updates are installed

// example configuration to update automatically OpenHAB Habian
// example configuration updates Debian, Debian-Security
// example configuration and further guidance can be found on https://www.myhowto.blog
Unattended-Upgrade::Origins-Pattern {
        // Codename based matching:
        // This will follow the migration of a release through different
        // archives (e.g. from testing to stable and later oldstable).
        // Software will be the latest available for the named release,
        // but the Debian release itself will not be automatically upgraded.
//      "origin=Debian,codename=${distro_codename}-updates";
//      "origin=Debian,codename=${distro_codename}-proposed-updates";
        "origin=Debian,codename=${distro_codename},label=Debian";
        "origin=Debian,codename=${distro_codename},label=Debian-Security";
        "origin=Debian,codename=${distro_codename}-security,label=Debian-Security";

        // Archive or Suite based matching:
        // Note that this will silently match a different release after
        // migration to the specified archive (e.g. testing becomes the
        // new stable).
//      "o=Debian,a=stable";
//      "o=Debian,a=stable-updates";
//      "o=Debian,a=proposed-updates";
//      "o=Debian Backports,a=${distro_codename}-backports,l=Debian Backports";
};

Unattended-Upgrade::Mail "yourUserName@gmail.com";
Unattended-Upgrade::Automatic-Reboot "true";

Once the above is configured, a further configuration is necessary. To do so, type:

sudo nano /etc/apt/apt.conf.d/20auto-upgrades

The content of the file should look like the below example

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::Verbose "1";
APT::Periodic::AutocleanInterval "7";

Test The Configuration

Lets test the configuration by executing the below comment:

sudo unattended-upgrade -d -v --dry-run

Unable Unattended Updates

Once the test was successful, enable unattended upgrades by using the below command on the command line:

sudo dpkg-reconfigure --priority=low unattended-upgrades

A window like the below will appear. To enable automatic updates confirm by saying “Yes”.

Hardening of OpenHAB Guide

Hardening of OpenHAB Guide – Activate unattended upgrades

Backup the OpenHAB Raspberry System – Google Cloud Option

Background

There are various options for backup. To back up to an USB stick, but then you have to deal with the USB stick and obviously, if the USB stick is in the same location as the OpenHAB Raspberry system, that the whole solution is still vulnerable against threats like fire, water or earthquake. The same applies for hard drive. Whilst in the past this sort of local solution backup was common practice, it is in my opinion not headless, as from time to time the backups need to be moved to other locations. Of course there are various other options and all of these options have advantages and disadvantages. The big question remains, where to store the backup!?

In this scenario we leverage on Google Cloud, because it is for free, cloud services provide a high availability, it’s simple to use and finally a headless solution can be enabled. Further, there is a good amount on free disk space on the Google Cloud available.

Connect to Google Cloud

There are various options to connect OpenHAB to the Google cloud. In this how to we leverage on the following How To Mount Google Drive on Raspberry

Leverage on rsync to backup to Google Cloud

In Linux there are plenty of options for copy and backup files. Rsync is quite common and can provide a great experience. Its a good maintained program that is used all over the places. Typically its fully integrated into Linux systems and OpenHABian has installed it by default.

So let’s create a simple rsync backup script and configure it to allow automated backup!

Simple rsync backup script

The below backup script basically syncs files to the Google Cloud drive. There is a couple of things you like to find out first, to make this run proberly. 

Figure out what you like to backup

The command of df -k gives you a good indication on available Filesystems. In our example its looking like this:

openhabian@OpenHAB:~ $ df -k
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/root       30384508 4865096  24241148  17% /
devtmpfs         4036076       0   4036076   0% /dev
tmpfs            4069868       0   4069868   0% /dev/shm
tmpfs            1627948    1544   1626404   1% /run
tmpfs               5120       0      5120   0% /run/lock
/dev/mmcblk0p1    258095   51464    206631  20% /boot
/dev/zram1        738048      36    684252   1% /opt/zram/zram1
overlay1          738048      36    684252   1% /var/lib/openhab/persistence
/dev/zram2        996780   25852    902116   3% /opt/zram/zram2
overlay2          996780   25852    902116   3% /var/log
tmpfs             813972       0    813972   0% /run/user/1000
GoogleDrive:    15728640 7448072   8280568  48% /home/openhabian/mnt/GoogleDrive>

We are interested in backup up the following drives:

  • /dev/root
  • /dev/mmcblk01p1     (<- This is the SD card)

For the rest of the drives, we are not interested as these are mainly temporary and these do not maintain the configuration files of OpenHAB.

Create a simple backup script

Since you now know what we like to backup to Google drive, you now create a simple backup script by the bellow commands and content.

Prepare the directory in which you like to store the backup script. Its Ok if you select another location, but keep in mind that in this case you maybe need to adjust the backup script.

openhabian@OpenHAB:~ $ mkdir /home/openhabian/backup-script
openhabian@OpenHAB:~ $ cd /home/openhabian/backup-script/

Now you create the script by enter the below in the command line:

openhabian@OpenHAB:~ $ vi openHAB-backup-script.sh

This will open a file that is called “openHAB-backup-script.sh”. Copy the below lines into this backup script file. Add to this script the below lines (please double check whether paths, filenames, etc. match for you):

###################
#
# Synchronize your openHAB files to Google Cloud (or another location)
#
# Simple backup script
#
# echo outputs into the file called openHAB-backup-script.log
# -&gt; you can change the directory and filename to something else
# -&gt; the default backup script stores logs into the /var/log/ directory
#
# The backup script leverages on rsync that by default is installed with OpenHABian
# More information on https://www.myhowto.blog
#
####################
#
#!/bin/sh
TODAY=$(date)
HOST=$(hostname)
echo "" &gt;&gt; /var/log/openHAB-backup-script.log
echo "" &gt;&gt; /var/log/openHAB-backup-script.log
echo "" &gt;&gt; /var/log/openHAB-backup-script.log
echo "" &gt;&gt; /var/log/openHAB-backup-script.log
echo "-----------------------------------------------------"  &gt;&gt; /var/log/openHAB-backup-script.log
echo "Date: $TODAY                     Host:$HOST"  &gt;&gt; /var/log/openHAB-backup-script.log
echo "-----------------------------------------------------"  &gt;&gt; /var/log/openHAB-backup-script.log
mkdir -p /home/openhabian/mnt/GoogleDrive/Backups/OpenHAB3
mkdir -p /home/openhabian/mnt/GoogleDrive/Backups/OpenHAB3/dev/root
mkdir -p /home/openhabian/mnt/GoogleDrive/Backups/OpenHAB3/dev/mmcblk01p1
echo "Syncing leveraging rsync to Google Cloud to directory /home/openhabian/mnt/GoogleDrive/Backups/OpenHAB3" &gt;&gt; /var/log/openHAB-backup-script.log
/usr/bin/rsync -av / /home/openhabian/mnt/GoogleDrive/Backups/OpenHAB3/  &gt;&gt; /var/log/openHAB-backup-script.log 2&gt;&amp;1
/usr/bin/rsync -av /boot /home/openhabian/mnt/GoogleDrive/Backups/OpenHAB3/boot  &gt;&gt; /var/log/openHAB-backup-script.log 2&gt;&amp;1
echo "End Syncing" &gt;&gt; /var/log/openHAB-backup-script.log

Automate the simple backup script

You of course like to have this headless. Therefore, lets automate the backup to the google drive. To do so, you first make the backup script executable and then create a cron job.

 Make it executable by executing the below command:

openhabian@OpenHAB:~ $ chmod +x /home/openhabian/openHAB-backup-script.sh

Next step, add it to the crontab by executing the below command

sudo crontab -e

If your system is newly setup and you never edited crontab, then it most likely will ask you which editor you like to use. Select your preferred editor, e.g.  nano or vim. Add (copy & paste)) the following lies at the end of the file. Note: double check paths and file names!

# The next line starts every night at 01:01am the automatic backup of the OpenHAB system. 
# The logs of the backup are stored in syslog
# More information on https://www.myhowto.blog
1 1 * * * /bin/bash /home/openhabian/backup-script/openHAB-backup-script.sh 2&gt;&amp;1 | /usr/bin/logger -t BACKUP_Script
# End of automated backup of the OpenHAB system.

Backup the OpenHAB Raspberry System – USB Drive Option

Background

There are various options for backup. Backing up to a USB Drive / Stick locally is probably one of the most common practices in private households. Please check also the Backup the OptionHAB Raspberry System – Google Cloud Option as an alternative to the classic backup solution.

In this scenario we leverage on another USB Drive / Stick. Please ensure that there is enough disk space on the backup USB Stick / Drive. Since we will backup in this “How To” scenario by a full image, the backup device should be in a minimum the same or a larger size than the systems USB Stick / Drive. In this example, the systems USB stick is 512GB whilst the 

Leverage on Rpi-clone to backup to the USB Stick / Drive

In Linux there are plenty of options for copy and backup files. Rpi-clone allows to clone a full USB drive / stick or an SD card to another one. In other words, its a 1:1 copy, bit by bit. 

So let’s install rpi-clone!

git clone https://github.com/billw2/rpi-clone.git 
cd rpi-clone 
sudo cp rpi-clone rpi-clone-setup /usr/local/sbin 
sudo rpi-clone-setup -t $(hostname -s)&nbsp;

Figure out your backup device (USB Stick / Device)

To figure out the backup device we leverage on the lsblk command. First, we send the command without the backup USB device plugged, secondly we fire the lsblk command with the USB device plugged. This clearly will indicate you which one is the backup device. Typically, USB devices are sda, sdb, sdc, (…), sdX. Once done, it should look like something like this:

openhabian@OpenHAB:~ $ sudo lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 476.9G  0 disk 
├─sda1   8:1    0   256M  0 part /boot
└─sda2   8:2    0 476.7G  0 part /
zram0  254:0    0     1G  0 disk [SWAP]
zram1  254:1    0   750M  0 disk /opt/zram/zram1
zram2  254:2    0     1G  0 disk /opt/zram/zram2
openhabian@OpenHAB:~ $ sudo lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 476.9G  0 disk 
├─sda1   8:1    0   256M  0 part /boot
└─sda2   8:2    0 476.7G  0 part /
sdb      8:16   0 465.7G  0 disk 
└─sdb1   8:17   0 465.7G  0 part 
zram0  254:0    0     1G  0 disk [SWAP]
zram1  254:1    0   750M  0 disk /opt/zram/zram1
zram2  254:2    0     1G  0 disk /opt/zram/zram2

In the above example we see, that after plugging the second USB device sdb and sdb1 are shown. This now tells us that

  • sda (incl. sda1 and sda2) is the system drive on which we have openHAB 3 running
  • sdb (incl. sdb1) is the backup USB stick that we plugged after the execution of the first lsblk command

Whatever the above information looks like, you like to note it down as you need it for the next steps. Eg. sda is where OpenHAB 3 sits on and sdb is the Backup USB stick / drive. Please note, In the next steps we will use sdb as the backup drive. You have to replace this by whatever is your backup USB drive / stick, otherwise you risk to lose your data. 

Make Ready The Backup USB Drive / Stick

Ensure your USB stick / drive is empty. In any case, ensure you have a backup of all data stored on your USB stick! The following step will delete all data on your USB stick!

sudo sfdisk --delete /dev/sdb

After execution of the above, you will notice that the USB stick has no partition anymore. You see this if you execute again lsblk. This is OK, don’t worry.

Lets Test The Backup

Again, the approach in this scenario is to make a full 1:1 backup of the OpenHAB 3 USB stick. For this reason, r-clone will copy byte-by-byte from the OpenHAB3 USB stick to the Backup USB Stick / Drive. Depending on the disk size you have (in this scenario wie have a 512 GB USB stick, this will take some time. Therefore, please be patient with your system. Don’t worry about the future, as we will in the next step create a script that does this backup over night – headless. 

openhabian@OpenHAB:~ $ cd ~/rpi-clone 
openhabian@OpenHAB:~ $ sudo rpi-clone sda

Booted disk: sda 512.1GB                   Destination disk: sdb 512.1GB
---------------------------------------------------------------------------
Part      Size    FS     Label           Part   Size  FS  Label  
1 /boot   256.0M  fat32  --                                      
2 root    476.7G  ext4   OpenHAB                                 
---------------------------------------------------------------------------
== Initialize: IMAGE partition table - partition number mismatch: 2 -&gt; 0 ==
1 /boot               (50.0M used)   : MKFS  SYNC to sdb1
2 root                (18.3G used)   : RESIZE  MKFS  SYNC to sdb2
---------------------------------------------------------------------------
Run setup script       : no.
Verbose mode           : no.
-----------------------:
** WARNING **          : All destination disk sdb data will be overwritten!
-----------------------:

Initialize and clone to the destination disk sdb?  (yes/no): y
Optional destination ext type file system label (16 chars max):

Create a simple backup script

We do not like to execute every night our own the rpi-clone command and watch how the system does the backup. You like to have a headless solution, hence lets create a script which backs up every night without even thinking about. OK, lets be honest, it makes sense from time to time to check whether all is running fine and if using the backup USB stick / device is working, but this should be the maximum effort. 

openhabian@OpenHAB:~ $ mkdir /home/openhabian/backup-script
openhabian@OpenHAB:~ $ cd /home/openhabian/backup-script/

Now you create the script:

openhabian@OpenHAB:~ $ vi openHAB-backup-script.sh

This will open a file that is called “openHAB-backup-script.sh”. Copy the below lines into this backup script file. Add to this script the below lines (please double check whether paths, filenames, etc. match for you):

###################
#
# Clone your openHAB disk to another disk (e.g. USB drive)
#
# Simple backup script
#
# echo outputs into the file called openHAB-backup-script.log
# -&gt; you can change the directory and filename to something else
# -&gt; the default backup script stores logs into the /var/log/ directory
#
# The backup script leverages on rpi-clone that you need to install on OpenHABian
# More information on https://www.myhowto.blog
#
####################
#
#!/bin/sh
TODAY=$(date)
HOST=$(hostname)
echo "" &gt;&gt; /var/log/openHAB-backup-script.log
echo "" &gt;&gt; /var/log/openHAB-backup-script.log
echo "" &gt;&gt; /var/log/openHAB-backup-script.log
echo "" &gt;&gt; /var/log/openHAB-backup-script.log
echo "-----------------------------------------------------"  &gt;&gt; /var/log/openHAB-backup-script.log
echo "Date: $TODAY                     Host:$HOST"  &gt;&gt; /var/log/openHAB-backup-script.log
echo "-----------------------------------------------------"  &gt;&gt; /var/log/openHAB-backup-script.log
echo "Cloning sda to sdb" &gt;&gt; /var/log/openHAB-backup-script.log
sudo /home/openhabian/rpi-clone/rpi-clone sdb -U -v &gt;&gt; /var/log/openHAB-backup-script.log 2&gt;&amp;1
echo "End cloning" &gt;&gt; /var/log/openHAB-backup-script.log

Automate the simple backup script

You of course like to have this headless. To do so, you first make the backup script executable and then create a cron job.

Make it executable by executing the below command:

openhabian@OpenHAB:~ $ chmod +x /home/openhabian/openHAB-backup-script.sh

Next step, add it to the crontab by executing the below command

sudo crontab -e

If your system is newly setup and you never edited crontab, then it most likely will ask you which editor you like to use. Select your preferred editor, e.g.  nano or vim. Add (copy & paste)) the following lies at the end of the file. Note: double check paths and file names!

# The next line starts every night at 01:01am the automatic backup of the OpenHAB system. 
# The logs of the backup are stored in syslog
# More information on https://www.myhowto.blog
1 1 * * * /bin/bash /home/openhabian/backup-script/openHAB-backup-script.sh 2&gt;&amp;1 | /usr/bin/logger -t BACKUP_Script
# End of automated backup of the OpenHAB system.

Fail2ban

Unfortunately, brute-forcing access to a system is common practice by criminals. By doing so, attackers try any possible way of usernames and passwords until they are able to login. File2ban allows to react on this and block IPs of attackers that try brute-force. This chapter explains how you install and configure File2ban on your OpenHAB system.

First, lets download the software package

 sudo apt install fail2ban

Secondly we configure File2ban. To start with, we copy an example configuration by executing the following command:

sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local

Now we adjust the example configuration by executing

sudo vi /etc/fail2ban/jail.local

The below is an example how I have adjusted jail.local. You should double check whether the items are OK to you. Have a specific focus on:

  • bantime – which is the time in which a potential attacker will be banned. This includes you, if for example you type the password to often wrongly
  • maxretry – defines how often it is possible to retry a wrong username/password combination. This includes you, if for example you type the password to often wrongly
  • Email – Allows email alerts. If you like to receive them, you should adjust this to your email address  (an example of an email configuration for your system allowing file2ban to email you can be found in the previous chapters)
  • Services – If you added services to your OpenHAB / openhabian system, than you maybe like to consider adding these services to your file2ban configuration as well. There are plenty of information in the internet about how to do this 

File2ban example configuration for OpenHAB:

 
# Common configuration for file2ban. Check the internet for more information that best fits your needs. 
# bantime sets the time in which a particular IP address will be unable to login 
# maxretry defines how often retrying is possible 
# port defines the service / port to be protected. This is in this file adjusted for OpenHAB 3, standard habian configuration 
# log path defines the path into which logs will be stored. This is in the below adjusted for OpenHAB 3, standard habian configuration 
# IF YOU LIKE TO RECEIVE EMAIL ALERTS, ADJUST THE EMAIL ADDRESS. 
# For OpenHAB system hardening you can find additional information on https://www.myhowto.blog 
#------ PLEASE READ CAREFULLY THE BELOW INSTRUCTIONS AND ADJUST WHERE NEEDED --------------#
#
# WARNING: heavily refactored in 0.9.0 release.  Please review and
#          customize settings for your setup.
#
# Changes:  in most of the cases you should not modify this
#           file, but provide customizations in jail.local file,
#           or separate .conf files under jail.d/ directory, e.g.:
#
# HOW TO ACTIVATE JAILS:
#
# YOU SHOULD NOT MODIFY THIS FILE.
#
# It will probably be overwritten or improved in a distribution update.
#
# Provide customizations in a jail.local file or a jail.d/customisation.local.
# For example to change the default bantime for all jails and to enable the
# ssh-iptables jail the following (uncommented) would appear in the .local file.
# See man 5 jail.conf for details.
#
# [DEFAULT]
# bantime = 1h
#
# [sshd]
# enabled = true
#
# See jail.conf(5) man page for more information

# Comments: use '#' for comment lines and ';' (following a space) for inline comments

[INCLUDES]

#before = paths-distro.conf
before = paths-debian.conf

# The DEFAULT allows a global definition of the options. They can be overridden
# in each jail afterwards.

[DEFAULT]

#
# MISCELLANEOUS OPTIONS
#

# "bantime.increment" allows to use database for searching of previously banned ip's to increase a 
# default ban time using special formula, default it is banTime * 1, 2, 4, 8, 16, 32...
#bantime.increment = true

# "bantime.rndtime" is the max number of seconds using for mixing with random time 
# to prevent "clever" botnets calculate exact time IP can be unbanned again:
#bantime.rndtime = 

# "bantime.maxtime" is the max number of seconds using the ban time can reach (doesn't grow further)
#bantime.maxtime = 

# "bantime.factor" is a coefficient to calculate exponent growing of the formula or common multiplier,
# default value of factor is 1 and with default value of formula, the ban time 
# grows by 1, 2, 4, 8, 16 ...
#bantime.factor = 1

# "bantime.formula" used by default to calculate next value of ban time, default value below,
# the same ban time growing will be reached by multipliers 1, 2, 4, 8, 16, 32...
#bantime.formula = ban.Time * (1&lt;&lt;(ban.Count if ban.Count&lt;20 else 20)) * banFactor
#
# more aggressive example of formula has the same values only for factor "2.0 / 2.885385" :
#bantime.formula = ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)

# "bantime.multipliers" used to calculate next value of ban time instead of formula, coresponding 
# previously ban count and given "bantime.factor" (for multipliers default is 1);
# following example grows ban time by 1, 2, 4, 8, 16 ... and if last ban count greater as multipliers count, 
# always used last multiplier (64 in example), for factor '1' and original ban time 600 - 10.6 hours
#bantime.multipliers = 1 2 4 8 16 32 64
# following example can be used for small initial ban time (bantime=60) - it grows more aggressive at begin,
# for bantime=60 the multipliers are minutes and equal: 1 min, 5 min, 30 min, 1 hour, 5 hour, 12 hour, 1 day, 2 day
#bantime.multipliers = 1 5 30 60 300 720 1440 2880

# "bantime.overalljails" (if true) specifies the search of IP in the database will be executed 
# cross over all jails, if false (dafault), only current jail of the ban IP will be searched
#bantime.overalljails = false

# --------------------

# "ignoreself" specifies whether the local resp. own IP addresses should be ignored
# (default is true). Fail2ban will not ban a host which matches such addresses.
#ignoreself = true

# "ignoreip" can be a list of IP addresses, CIDR masks or DNS hosts. Fail2ban
# will not ban a host which matches an address in this list. Several addresses
# can be defined using space (and/or comma) separator.
#ignoreip = 127.0.0.1/8 ::1

# External command that will take an tagged arguments to ignore, e.g. ,
# and return true if the IP is to be ignored. False otherwise.
#
# ignorecommand = /path/to/command 
ignorecommand =

# "bantime" is the number of seconds that a host is banned.
bantime  = 30m

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime  = 10m

# "maxretry" is the number of failures before a host get banned.
maxretry = 5

# "maxmatches" is the number of matches stored in ticket (resolvable via tag  in actions).
maxmatches = %(maxretry)s

# "backend" specifies the backend used to get files modification.
# Available options are "pyinotify", "gamin", "polling", "systemd" and "auto".
# This option can be overridden in each jail as well.
#
# pyinotify: requires pyinotify (a file alteration monitor) to be installed.
#              If pyinotify is not installed, Fail2ban will use auto.
# gamin:     requires Gamin (a file alteration monitor) to be installed.
#              If Gamin is not installed, Fail2ban will use auto.
# polling:   uses a polling algorithm which does not require external libraries.
# systemd:   uses systemd python library to access the systemd journal.
#              Specifying "logpath" is not valid for this backend.
#              See "journalmatch" in the jails associated filter config
# auto:      will try to use the following backends, in order:
#              pyinotify, gamin, polling.
#
# Note: if systemd backend is chosen as the default but you enable a jail
#       for which logs are present only in its own log files, specify some other
#       backend for that jail (e.g. polling) and provide empty value for
#       journalmatch. See https://github.com/fail2ban/fail2ban/issues/959#issuecomment-74901200
backend = auto

# "usedns" specifies if jails should trust hostnames in logs,
#   warn when DNS lookups are performed, or ignore all hostnames in logs
#
# yes:   if a hostname is encountered, a DNS lookup will be performed.
# warn:  if a hostname is encountered, a DNS lookup will be performed,
#        but it will be logged as a warning.
# no:    if a hostname is encountered, will not be used for banning,
#        but it will be logged as info.
# raw:   use raw value (no hostname), allow use it for no-host filters/actions (example user)
usedns = warn

# "logencoding" specifies the encoding of the log files handled by the jail
#   This is used to decode the lines from the log file.
#   Typical examples:  "ascii", "utf-8"
#
#   auto:   will use the system locale setting
logencoding = auto

# "enabled" enables the jails.
#  By default all jails are disabled, and it should stay this way.
#  Enable only relevant to your setup jails in your .local or jail.d/*.conf
#
# true:  jail will be enabled and log files will get monitored for changes
# false: jail is not enabled
enabled = false

# "mode" defines the mode of the filter (see corresponding filter implementation for more info).
mode = normal

# "filter" defines the filter to use by the jail.
#  By default jails have names matching their filter name
#
filter = %(__name__)s[mode=%(mode)s]

#
# ACTIONS
#

# Some options used for actions

# Destination email address used solely for the interpolations in
# jail.{conf,local,d/*} configuration files.
destemail = YOUReMailAdress@YourDomain.com

# Sender email address used solely for some actions
sender = YOUReMailAdress@YourDomain.com

# E-mail action. Since 0.8.1 Fail2Ban uses sendmail MTA for the
# mailing. Change mta configuration parameter to mail if you want to
# revert to conventional 'mail'.
mta = sendmail

# Default protocol
protocol = tcp

# Specify chain where jumps would need to be added in ban-actions expecting parameter chain
chain = &lt;known/chain&gt;

# Ports to be banned
# Usually should be overridden in a particular jail
port = 0:65535

# Format of user-agent https://tools.ietf.org/html/rfc7231#section-5.5.3
fail2ban_agent = Fail2Ban/%(fail2ban_version)s

#
# Action shortcuts. To be used to define action parameter

# Default banning action (e.g. iptables, iptables-new,
# iptables-multiport, shorewall, etc) It is used to define
# action_* variables. Can be overridden globally or per
# section within jail.local file
banaction = iptables-multiport
banaction_allports = iptables-allports

# The simplest action to take: ban only
action_ = %(banaction)s[port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban &amp; send an e-mail with whois report to the destemail.
action_mw = %(action_)s
            %(mta)s-whois[sender="%(sender)s", dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"]

# ban &amp; send an e-mail with whois report and relevant log lines
# to the destemail.
action_mwl = %(action_)s
             %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]

# See the IMPORTANT note in action.d/xarf-login-attack for when to use this action
#
# ban &amp; send a xarf e-mail to abuse contact of IP address and include relevant log lines
# to the destemail.
action_xarf = %(action_)s
             xarf-login-attack[service=%(__name__)s, sender="%(sender)s", logpath="%(logpath)s", port="%(port)s"]

# ban IP on CloudFlare &amp; send an e-mail with whois report and relevant log lines
# to the destemail.
action_cf_mwl = cloudflare[cfuser="%(cfemail)s", cftoken="%(cfapikey)s"]
                %(mta)s-whois-lines[sender="%(sender)s", dest="%(destemail)s", logpath="%(logpath)s", chain="%(chain)s"]

# Report block via blocklist.de fail2ban reporting service API
# 
# See the IMPORTANT note in action.d/blocklist_de.conf for when to use this action.
# Specify expected parameters in file action.d/blocklist_de.local or if the interpolation
# `action_blocklist_de` used for the action, set value of `blocklist_de_apikey`
# in your `jail.local` globally (section [DEFAULT]) or per specific jail section (resp. in 
# corresponding jail.d/my-jail.local file).
#
action_blocklist_de  = blocklist_de[email="%(sender)s", service="%(__name__)s", apikey="%(blocklist_de_apikey)s", agent="%(fail2ban_agent)s"]

# Report ban via badips.com, and use as blacklist
#
# See BadIPsAction docstring in config/action.d/badips.py for
# documentation for this action.
#
# NOTE: This action relies on banaction being present on start and therefore
# should be last action defined for a jail.
#
action_badips = badips.py[category="%(__name__)s", banaction="%(banaction)s", agent="%(fail2ban_agent)s"]
#
# Report ban via badips.com (uses action.d/badips.conf for reporting only)
#
action_badips_report = badips[category="%(__name__)s", agent="%(fail2ban_agent)s"]

# Report ban via abuseipdb.com.
#
# See action.d/abuseipdb.conf for usage example and details.
#
action_abuseipdb = abuseipdb

# Choose default action.  To change, just override value of 'action' with the
# interpolation to the chosen action shortcut (e.g.  action_mw, action_mwl, etc) in jail.local
# globally (section [DEFAULT]) or per specific section
action = %(action_)s

#
# JAILS
#

#
# SSH servers
#

[sshd]

# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
#mode   = normal
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

[dropbear]

port     = ssh
logpath  = %(dropbear_log)s
backend  = %(dropbear_backend)s

[selinux-ssh]

port     = ssh
logpath  = %(auditd_log)s

#
# HTTP servers
#

[apache-auth]

port     = http,https,8443
logpath  = %(apache_error_log)s

[apache-badbots]
# Ban hosts which agent identifies spammer robots crawling the web
# for email addresses. The mail outputs are buffered.
port     = http,https,8443
logpath  = %(apache_access_log)s
bantime  = 48h
maxretry = 1

[apache-noscript]

port     = http,https,8443
logpath  = %(apache_error_log)s

[apache-overflows]

port     = http,https,8443
logpath  = %(apache_error_log)s
maxretry = 2

[apache-nohome]

port     = http,https,8443
logpath  = %(apache_error_log)s
maxretry = 2

[apache-botsearch]

port     = http,https,8443
logpath  = %(apache_error_log)s
maxretry = 2

[apache-fakegooglebot]

port     = http,https,8443
logpath  = %(apache_access_log)s
maxretry = 1
ignorecommand = %(ignorecommands_dir)s/apache-fakegooglebot 

[apache-modsecurity]

port     = http,https,8443
logpath  = %(apache_error_log)s
maxretry = 2

[apache-shellshock]

port    = http,https,8443
logpath = %(apache_error_log)s
maxretry = 1

[openhab-auth]

filter = openhab
banaction = %(banaction_allports)s
logpath = /opt/openhab/logs/request.log

[nginx-http-auth]

port    = http,https,8443
logpath = %(nginx_error_log)s

# To use 'nginx-limit-req' jail you should have `ngx_http_limit_req_module` 
# and define `limit_req` and `limit_req_zone` as described in nginx documentation
# http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
# or for example see in 'config/filter.d/nginx-limit-req.conf'
[nginx-limit-req]
port    = http,https,8443
logpath = %(nginx_error_log)s

[nginx-botsearch]

port     = http,https,8443
logpath  = %(nginx_error_log)s
maxretry = 2

# Ban attackers that try to use PHP's URL-fopen() functionality
# through GET/POST variables. - Experimental, with more than a year
# of usage in production environments.

[php-url-fopen]

port    = http,https,8443
logpath = %(nginx_access_log)s
          %(apache_access_log)s

[suhosin]

port    = http,https,8443
logpath = %(suhosin_log)s

[lighttpd-auth]
# Same as above for Apache's mod_auth
# It catches wrong authentifications
port    = http,https,8443
logpath = %(lighttpd_error_log)s

#
# Webmail and groupware servers
#

[roundcube-auth]

port     = http,https,8443
logpath  = %(roundcube_errors_log)s
# Use following line in your jail.local if roundcube logs to journal.
#backend = %(syslog_backend)s

[openwebmail]

port     = http,https,8443
logpath  = /var/log/openwebmail.log

[horde]

port     = http,https,8443
logpath  = /var/log/horde/horde.log

[groupoffice]

port     = http,https,8443
logpath  = /home/groupoffice/log/info.log

[sogo-auth]
# Monitor SOGo groupware server
# without proxy this would be:
# port    = 20000
port     = http,https,8443
logpath  = /var/log/sogo/sogo.log

[tine20]

logpath  = /var/log/tine20/tine20.log
port     = http,https,8443

#
# Web Applications
#
#

[drupal-auth]

port     = http,https,8443
logpath  = %(syslog_daemon)s
backend  = %(syslog_backend)s

[guacamole]

port     = http,https,8443
logpath  = /var/log/tomcat*/catalina.out
#logpath  = /var/log/guacamole.log

[monit]
#Ban clients brute-forcing the monit gui login
port = 2812
logpath  = /var/log/monit
           /var/log/monit.log

[webmin-auth]

port    = 10000
logpath = %(syslog_authpriv)s
backend = %(syslog_backend)s

[froxlor-auth]

port    = http,https,8443
logpath  = %(syslog_authpriv)s
backend  = %(syslog_backend)s

#
# HTTP Proxy servers
#
#

[squid]

port     =  80,443,3128,8080
logpath = /var/log/squid/access.log

[3proxy]

port    = 3128
logpath = /var/log/3proxy.log

#
# FTP servers
#

[proftpd]

port     = ftp,ftp-data,ftps,ftps-data
logpath  = %(proftpd_log)s
backend  = %(proftpd_backend)s

[pure-ftpd]

port     = ftp,ftp-data,ftps,ftps-data
logpath  = %(pureftpd_log)s
backend  = %(pureftpd_backend)s

[gssftpd]

port     = ftp,ftp-data,ftps,ftps-data
logpath  = %(syslog_daemon)s
backend  = %(syslog_backend)s

[wuftpd]

port     = ftp,ftp-data,ftps,ftps-data
logpath  = %(wuftpd_log)s
backend  = %(wuftpd_backend)s

[vsftpd]
# or overwrite it in jails.local to be
# logpath = %(syslog_authpriv)s
# if you want to rely on PAM failed login attempts
# vsftpd's failregex should match both of those formats
port     = ftp,ftp-data,ftps,ftps-data
logpath  = %(vsftpd_log)s

#
# Mail servers
#

# ASSP SMTP Proxy Jail
[assp]

port     = smtp,465,submission
logpath  = /root/path/to/assp/logs/maillog.txt

[courier-smtp]

port     = smtp,465,submission
logpath  = %(syslog_mail)s
backend  = %(syslog_backend)s

[postfix]
# To use another modes set filter parameter "mode" in jail.local:
mode    = more
port    = smtp,465,submission
logpath = %(postfix_log)s
backend = %(postfix_backend)s

[postfix-rbl]

filter   = postfix[mode=rbl]
port     = smtp,465,submission
logpath  = %(postfix_log)s
backend  = %(postfix_backend)s
maxretry = 1

[sendmail-auth]

port    = submission,465,smtp
logpath = %(syslog_mail)s
backend = %(syslog_backend)s

[sendmail-reject]
# To use more aggressive modes set filter parameter "mode" in jail.local:
# normal (default), extra or aggressive
# See "tests/files/logs/sendmail-reject" or "filter.d/sendmail-reject.conf" for usage example and details.
#mode    = normal
port     = smtp,465,submission
logpath  = %(syslog_mail)s
backend  = %(syslog_backend)s

[qmail-rbl]

filter  = qmail
port    = smtp,465,submission
logpath = /service/qmail/log/main/current

# dovecot defaults to logging to the mail syslog facility
# but can be set by syslog_facility in the dovecot configuration.
[dovecot]

port    = pop3,pop3s,imap,imaps,submission,465,sieve
logpath = %(dovecot_log)s
backend = %(dovecot_backend)s

[sieve]

port   = smtp,465,submission
logpath = %(dovecot_log)s
backend = %(dovecot_backend)s

[solid-pop3d]

port    = pop3,pop3s
logpath = %(solidpop3d_log)s

[exim]
# see filter.d/exim.conf for further modes supported from filter:
#mode = normal
port   = smtp,465,submission
logpath = %(exim_main_log)s

[exim-spam]

port   = smtp,465,submission
logpath = %(exim_main_log)s

[kerio]

port    = imap,smtp,imaps,465
logpath = /opt/kerio/mailserver/store/logs/security.log

#
# Mail servers authenticators: might be used for smtp,ftp,imap servers, so
# all relevant ports get banned
#

[courier-auth]

port     = smtp,465,submission,imap,imaps,pop3,pop3s
logpath  = %(syslog_mail)s
backend  = %(syslog_backend)s

[postfix-sasl]

filter   = postfix[mode=auth]
port     = smtp,465,submission,imap,imaps,pop3,pop3s
# You might consider monitoring /var/log/mail.warn instead if you are
# running postfix since it would provide the same log lines at the
# "warn" level but overall at the smaller filesize.
logpath  = %(postfix_log)s
backend  = %(postfix_backend)s

[perdition]

port   = imap,imaps,pop3,pop3s
logpath = %(syslog_mail)s
backend = %(syslog_backend)s

[squirrelmail]

port = smtp,465,submission,imap,imap2,imaps,pop3,pop3s,http,https,socks
logpath = /var/lib/squirrelmail/prefs/squirrelmail_access_log

[cyrus-imap]

port   = imap,imaps
logpath = %(syslog_mail)s
backend = %(syslog_backend)s

[uwimap-auth]

port   = imap,imaps
logpath = %(syslog_mail)s
backend = %(syslog_backend)s

#
#
# DNS servers
#

# !!! WARNING !!!
#   Since UDP is connection-less protocol, spoofing of IP and imitation
#   of illegal actions is way too simple.  Thus enabling of this filter
#   might provide an easy way for implementing a DoS against a chosen
#   victim. See
#    http://nion.modprobe.de/blog/archives/690-fail2ban-+-dns-fail.html
#   Please DO NOT USE this jail unless you know what you are doing.
#
# IMPORTANT: see filter.d/named-refused for instructions to enable logging
# This jail blocks UDP traffic for DNS requests.
# [named-refused-udp]
#
# filter   = named-refused
# port     = domain,953
# protocol = udp
# logpath  = /var/log/named/security.log

# IMPORTANT: see filter.d/named-refused for instructions to enable logging
# This jail blocks TCP traffic for DNS requests.

[named-refused]

port     = domain,953
logpath  = /var/log/named/security.log

[nsd]

port     = 53
action_  = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
           %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
logpath = /var/log/nsd.log

#
# Miscellaneous
#

[asterisk]

port     = 5060,5061
action_  = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
           %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
logpath  = /var/log/asterisk/messages
maxretry = 10

[freeswitch]

port     = 5060,5061
action_  = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
           %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
logpath  = /var/log/freeswitch.log
maxretry = 10

# enable adminlog; it will log to a file inside znc's directory by default.
[znc-adminlog]

port     = 6667
logpath  = /var/lib/znc/moddata/adminlog/znc.log

# To log wrong MySQL access attempts add to /etc/my.cnf in [mysqld] or
# equivalent section:
# log-warnings = 2
#
# for syslog (daemon facility)
# [mysqld_safe]
# syslog
#
# for own logfile
# [mysqld]
# log-error=/var/log/mysqld.log
[mysqld-auth]

port     = 3306
logpath  = %(mysql_log)s
backend  = %(mysql_backend)s

# Log wrong MongoDB auth (for details see filter 'filter.d/mongodb-auth.conf')
[mongodb-auth]
# change port when running with "--shardsvr" or "--configsvr" runtime operation
port     = 27017
logpath  = /var/log/mongodb/mongodb.log

# Jail for more extended banning of persistent abusers
# !!! WARNINGS !!!
# 1. Make sure that your loglevel specified in fail2ban.conf/.local
#    is not at DEBUG level -- which might then cause fail2ban to fall into
#    an infinite loop constantly feeding itself with non-informative lines
# 2. Increase dbpurgeage defined in fail2ban.conf to e.g. 648000 (7.5 days)
#    to maintain entries for failed logins for sufficient amount of time
[recidive]

logpath  = /var/log/fail2ban.log
banaction = %(banaction_allports)s
bantime  = 1w
findtime = 1d

# Generic filter for PAM. Has to be used with action which bans all
# ports such as iptables-allports, shorewall

[pam-generic]
# pam-generic filter can be customized to monitor specific subset of 'tty's
banaction = %(banaction_allports)s
logpath  = %(syslog_authpriv)s
backend  = %(syslog_backend)s

[xinetd-fail]

banaction = iptables-multiport-log
logpath   = %(syslog_daemon)s
backend   = %(syslog_backend)s
maxretry  = 2

# stunnel - need to set port for this
[stunnel]

logpath = /var/log/stunnel4/stunnel.log

[ejabberd-auth]

port    = 5222
logpath = /var/log/ejabberd/ejabberd.log

[counter-strike]

logpath = /opt/cstrike/logs/L[0-9]*.log
tcpport = 27030,27031,27032,27033,27034,27035,27036,27037,27038,27039
udpport = 1200,27000,27001,27002,27003,27004,27005,27006,27007,27008,27009,27010,27011,27012,27013,27014,27015
action_  = %(default/action_)s[name=%(__name__)s-tcp, port="%(tcpport)s", protocol="tcp"]
           %(default/action_)s[name=%(__name__)s-udp, port="%(udpport)s", protocol="udp"]

[softethervpn]
port     = 500,4500
protocol = udp
logpath  = /usr/local/vpnserver/security_log/*/sec.log

[gitlab]
port    = http,https
logpath = /var/log/gitlab/gitlab-rails/application.log

[grafana]
port    = http,https
logpath = /var/log/grafana/grafana.log

[bitwarden]
port    = http,https
logpath = /home/*/bwdata/logs/identity/Identity/log.txt

[centreon]
port    = http,https
logpath = /var/log/centreon/login.log

# consider low maxretry and a long bantime
# nobody except your own Nagios server should ever probe nrpe
[nagios]

logpath  = %(syslog_daemon)s     ; nrpe.cfg may define a different log_facility
backend  = %(syslog_backend)s
maxretry = 1

[oracleims]
# see "oracleims" filter file for configuration requirement for Oracle IMS v6 and above
logpath = /opt/sun/comms/messaging64/log/mail.log_current
banaction = %(banaction_allports)s

[directadmin]
logpath = /var/log/directadmin/login.log
port = 2222

[portsentry]
logpath  = /var/lib/portsentry/portsentry.history
maxretry = 1

[pass2allow-ftp]
# this pass2allow example allows FTP traffic after successful HTTP authentication
port         = ftp,ftp-data,ftps,ftps-data
# knocking_url variable must be overridden to some secret value in jail.local
knocking_url = /knocking/
filter       = apache-pass[knocking_url="%(knocking_url)s"]
# access log of the website with HTTP auth
logpath      = %(apache_access_log)s
blocktype    = RETURN
returntype   = DROP
action       = %(action_)s[blocktype=%(blocktype)s, returntype=%(returntype)s,
                        actionstart_on_demand=false, actionrepair_on_unban=true]
bantime      = 1h
maxretry     = 1
findtime     = 1

[murmur]
# AKA mumble-server
port     = 64738
action_  = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
           %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]
logpath  = /var/log/mumble-server/mumble-server.log

[screensharingd]
# For Mac OS Screen Sharing Service (VNC)
logpath  = /var/log/system.log
logencoding = utf-8

[haproxy-http-auth]
# HAProxy by default doesn't log to file you'll need to set it up to forward
# logs to a syslog server which would then write them to disk.
# See "haproxy-http-auth" filter for a brief cautionary note when setting
# maxretry and findtime.
logpath  = /var/log/haproxy.log

[slapd]
port    = ldap,ldaps
logpath = /var/log/slapd.log

[domino-smtp]
port    = smtp,ssmtp
logpath = /home/domino01/data/IBM_TECHNICAL_SUPPORT/console.log

[phpmyadmin-syslog]
port    = http,https
logpath = %(syslog_authpriv)s
backend = %(syslog_backend)s

[zoneminder]
# Zoneminder HTTP/HTTPS web interface auth
# Logs auth failures to apache2 error log
port    = http,https
logpath = %(apache_error_log)s

[traefik-auth]
# to use 'traefik-auth' filter you have to configure your Traefik instance,
# see `filter.d/traefik-auth.conf` for details and service example.
port    = http,https
logpath = /var/log/traefik/access.log

 

 

Now lets activate the new file2ban configuration

To activate the new configuration, simply restart the service. This can be done by executing the below command:

 sudo service fail2ban restart

Logwatch

The Logwatch program allows to send system summaries of messages and logs to your e-mail. This is useful to see what’s going on and keep the system monitored via different channels. Its easy to be configured, hence lets get it done. 

Note, you need to have Email configured on your OpenHAB Openhabian system. See in the previous chapter how to do this.

First, and as usual, lets install logwatch, by the execution of the below command:

 

sudo apt install logwatch

 
Secondly, we configure logwatch by executing:

sudo vi /usr/share/logwatch/dist.conf/logwatch.conf

Now we add the following lines into this dlist.conf file:
# Logwatch configuration for OpenHAB openhabian
# Make sure you update the values as required by you and your system
# You like in a minimum to adjust the email address as well as the mailer
# An example for configuring a mailer on an OpenHAB openhabian system can be found at https://www.myhowto.blog
#
# Range defines the time periode
# Detail defines the detail level. You may like to start with "high" and downgrade it depending on your needs
# Format is whether you like to receive it as html or as text
#
mailer = "/usr/bin/msmtp YOUReMailAdress@YourDomain.com"
TmpDir = /tmp
MailFrom = YOUReMailAdress@YourDomain.com
Range = yesterday
Detail = high
Format = html

 Now lets see whether our configuration is working. To do so, enter the following to your command line:

 sudo /etc/cron.daily/00logwatch

Once executed successfully, you should receive an email that looks like the below picture.

Hardening of OpenHAB Guide - Logwatch Email

Hardening of OpenHAB Guide – Logwatch Email

 

SSH Login Notification

You like to be informed if someone logs in into your OpenHAB 3. This way you can easily control whether you were logging in or someone else. To get in a position for identifying whether someone logged into you OpenHAB 3 we leverage on eMail and the SSH Login notification option.

To be in a position to establish this control you leverage on the SMTP configuration made bin the previous chapter.

Once eMail (SMTP configuration) is configured, you create a login_notification by executing this command:

sudo nano /etc/ssh/login_notification.sh

Within the sudo /etc/ssh/login_notification.sh you add the below content. You of course exchange the email address of YOUReMailAdress@Domain.com by your email address.

#!/bin/sh

# This script is used to inform about SSH logins into the OpenHAB 3 system
# More information and a detailed how to can be found at https://www.myhowto.blog
# NOTE: Replace the email address by your email address
#
if [ "$PAM_TYPE" != "open_session" ]
then
        exit 0
else
        {
                echo "User: $PAM_USER"
                echo "Remote Host: $PAM_RHOST"
                echo "Service: $PAM_SERVICE"
                echo "TTY: $PAM_TTY"
                echo "Date: `date`"
                echo "Server: `uname -a`"
        } | echo "SSH Login on OpenHAB 3 Notification. User: $PAM_USER, has loged in on host $PAM_RHOST, hostname: `hostname`, using Service: $PAM_SERVICE, on TTY: $PAM_TTY, date: `date`, server information: `uname -a`" | msmtp YOUReMailAdress@Domain.com
fi
exit 0

Now make the executable

 sudo chmod +x  /etc/ssh/login_notification.sh

Update /etc/pam.d/sshd. Note: the value “optional” is added in the below. This means, if something fails you are still able to login. You like to start with this to test. If you want to increase the level of security and to further strengthen security on your system, then you can replace “optional” by “required”. However, be aware, that if you set “required” you will not be able to login anymore if something with the script execution fails.

 sudo vi /etc/pam.d/sshd

Add the following lines at the end of the file

# Get an Notification if someone logs in with SSH
# More details at https://www.myhowto.blog
session optional pam_exec.so seteuid /etc/ssh/login_notification.sh

Restart the SSHD service now

sudo systemctl restart sshd.service

Open a new terminal window, and login by SSH. If all worked well, you should have received a simple notification with key information about your login.

Additional Information

This is my first Hardening of OpenHAB Guide and I already have many ideas allowing to further harden the system. Since this blog is already very long, I am stopping here and will be issuing later an additional Hardening of OpenHAB Guide. Please join the myhowto.blog Twitter account to stay close and get notified about new guides.

Many items of the above are example configurations that were made on a newly installed openHAB openhabian system. In case your system is running since a while and you made changes to it, there maybe is one or the other element that does not work as nice for you as described in the above. In this case troubleshooting is required. Fortunately, there are plenty of guides and manuals in the internet. I summarise some important one’s for you allowing you to get additional information. 

Cool How To pages:

 

If you like to add commands or have updates to this Hardening of OpenHAB Guide, than please use the contact form. I am looking forward for your input.