Reading 14bit from an SI7021 temperature and humidity sensor

The Si7021-A20 is capable of providing up to 14bit resolution for temperature and up to 12bit for relative humidity, over an I2C connection. However, many examples on the internet only use 8bit. I tried to get the full resolution on a Raspberry Pi using Python, version 3.

I2C is a simple, serial protocol for interconnecting devices. It allows the transfer of small amounts of data between a master device and various slaved devices.

Prerequisites

You need to configure the I2C interface using raspi-config first. Then install some related tools:

sudo apt-get install python3-smbus
# at the time writing, i2c-tools are not available for python3 by default
sudo apt-get install -y i2c-tools

You can test, whether I2C is available and whethere a device is connected using the following command in the terminal:

sudo i2cdetect -y 1

You should get something like

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

This shows a single device connected at hardware address 0x40.

Getting data

Now here it gets tricky. Most of the examples on the internet did not work for me. Either they read the same data bytes twice or they produced an error, like in this raspberry forum thread.

I had success getting a single byte (8 bit) of information using the SMBus, but not more. I have asked a question on the Raspberry Pi Stackexchange. Look it up to find the corresponding script.

The solution

Joan at abyz.me.uk provides a complete Si7021.py python module with a class and a main function that allows to fully interface with the Si7021 sensor.

To use it, just download the ZIP and place the contained Si7021.py in a folder of your choice. Since the script requires pigpio as a daemon, you must install and start that first. The script runs for 10 seconds, takes repeated measurements and prints them out.

# installing pigpio first
sudo apt-get install pigpio python-pigpio python3-pigpio

# get the Si7021.py script
wget http://abyz.me.uk/rpi/pigpio/code/Si7021_py.zip
unzip Si7021_py.zip

# start the pigpiod daemon; -l disables the remote socket interface, it's not needed to read a local sensor
sudo pigpiod -l	
# start the main function in the module
python3 Si7021.py

# stop the daemon, if no longer used
sudo killall pigpiod

I have used the module in a simple script that just reads one value at maximum resolution, with a formatted output:

https://github.com/suterma/WeatherPress/blob/master/Si7021-singleread.py

import time
import Si7021
import pigpio

pi = pigpio.pi()

if not pi.connected:
   exit(0)
s = Si7021.sensor(pi)

# set the resolution
# 0 denotes the maxium available: Humidity 12 bits, Temperature 14 bits
# See the documentation for more details
s.set_resolution(0)

print("{:.3f} °C".format(s.temperature()))
print("{:.3f} %rH".format(s.humidity()))

s.cancel()
pi.stop()

This gives:

pi@raspberrypi:~ $ python3 Si7021-singleread.py 
27.303 °C
40.574 %rH

Now, these values actually represent a resolution of 12 and 14 bit, respectively.

Setting up a Raspberry Pi Zero W/WH, the headless way, with Wifi and VNC enabled

Many have covered this (at least partially), but here’s my ultimate, minimal, quick guide to all the necessary parts, using a Linux box.

Use the given commands in a Linux bash terminal.

Get the image

Download the latest Raspbian image. (Choose the “with desktop and recommended software” version, when e.g. you need the IDLE Python IDE. VNC is included in all versions)

In the terminal (with optional, manual hash comparison):

# get the latest full image
wget --output-document=raspbian_full_latest.zip 
https://downloads.raspberrypi.org/raspbian_full_latest
# optionally check the sha256 hash
sha256sum raspbian_full_latest.zip

Burn

Burn the image from the ZIP to the SD Card. Use the lsblk command to find out the device name.

In the terminal (assuming dev/sdb is the device name)

# get the device name
lsblk
# unzip and write, use proper device name for output
unzip -p raspbian_full_latest.zip | sudo dd of=/dev/sdb status=progress conv=fsync
# flush the write cache
sync

Reference: For Linux specifically, here’s the full guide for writing the image to the SD card.

ssh

Enable ssh by placing an empty file named ssh (without extension or dot) in the boot folder of the boot partition.

In the terminal

# change to the boot partition
cd /media/$USER/boot

# ssh marker file
touch ssh

Wifi

Pre-configure your Wifi by placing a file named wpa_supplicant.conf in the root folder of the root partition, with the following content (Replace country and placeholders as needed)

country=CH   
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
   ssid="NETWORK-NAME"
   psk="NETWORK-PASSWORD"
}

In the terminal

# wifi config file (Adapt country and placeholders)
touch wpa_supplicant.conf
echo 'country=CH   
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
   ssid="NETWORK-NAME"
   psk="NETWORK-PASSWORD"
}' > wpa_supplicant.conf
# flush the write cache
sync

Startup…

Now insert the SD card into you Raspberry Pi and connect power.

# see if it's there...  (use your name or ip)
ping raspberrypi-zero-wh
# ssh into the raspberry
ssh pi@raspberrypi-zero-wh

Housekeeping

On the Raspberry Pi, do a proper setup:

# change the password
passwd
# type your old and new password
# do housekeeping
sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get clean

Enabling the remote VNC server

There are 3 Ways to Run a Remote Desktop on Raspberry Pi, but I like the to do it with RealVNC.

If you chose to burn the “with desktop and recommended software” version of the image, everything on the Raspberry Pi should already be in place to run the VNC server. Otherwise, follow the VNC Guide in the official documentation to enable the VNC server.

To run the VNC server, in an ssh session to the Raspberry Pi:

vncserver :1

This should print a message like
New desktop is raspberrypi:1 (192.168.77.3:1)

Connecting

On your client device, download the VNC viewer, then connect using the IP address and Desktop id.

Go to File/New Connection, then use e.g. 192.168.77.3:1

Connecting to the Raspberry Pi desktop using VNC

LineageOS on a Samsung Galaxy Tab S2 9.7 Wi-Fi (2016)

Steps to install LineageOS on a Samsung Galaxy S2 Tablet

I just got this nice Samsung Galaxy Tab S2 Value Edition (9.70″, 32GB, White) with WiFi, and had a very easy time to load the latest LineageOs build on it.

If you want to do it yourself, exactly follow the installation instruction from the LineageOS website. The model identifier is gts210vewifi.

The steps involved are basically:

  • Enable OEM unlock in the settings
  • Flash a custom recovery image: TWRP from TeamWin
  • Sideload the LineageOS image
  • Optionally sideload the Google Apps via OpenGAapps

Since the required files tend to go away, I host them here for future reference:

https://drive.google.com/drive/folders/18Ga0ZengJuhvuT05P70n09k_9BRwmomh?usp=sharing

Getting rid of all the bloatware – on a SONY Xperia X Compact.

In a recent release of the german c’t magazine, under “Schlanker Roboter” they described the process of getting rid of the many bloatware that comes along with Android Smartphones today. I went with the method using adb.

Others have done that, too.

You’ll find most of the resources on how to do it online:

Be careful you may brick your phone – I almost did. Do yourself a favor and quickly create a backup first:

adb backup '-apk -shared -all -f backup-file.adb'
#start the server process on the desktop machine
adb start-server
#check whether your device is connected
adb devices
#start remote shell to the device
adb shell
#list all the packages
pm list packages
#list the packages with "sony" in their namespace
pm list packages | grep sony

These were quite a few, more than 300 in total, with some of my apps installed.  Those with “sony” were 171. 

First, get rid of the 3rd party apps (How would they think I’ll use them….)

pm uninstall -k --user 0  com.amazon.mShop.android.shopping
pm uninstall -k --user 0  com.facebook.services
pm uninstall -k --user 0  com.google.android.printservice.recommendation
pm uninstall -k --user 0 com.spotify.music
pm uninstall -k --user 0 com.facebook.katana
pm uninstall -k --user 0 com.facebook.system
pm uninstall -k --user 0 com.qti.vzw.ims.internal.tests
pm uninstall -k --user 0 com.scee.psxandroid
#CNE Service I do not use: https://www.qualcomm.com/news/onq/2013/07/02/qualcomms-cne-bringing-smarts-3g4g-wi-fi-seamless-interworking
pm uninstall -k --user 0  com.quicinc.cne.CNEService
pm uninstall -k --user 0  com.realvnc.android.remote
pm uninstall -k --user 0  com.s.antivirus
pm uninstall -k --user 0  com.facebook.appmanager

Then, otherwise unnecessary apps:

pm uninstall -k --user 0 com.sonyericsson.music
#by sonymobile
pm uninstall -k --user 0 com.sonymobile.assist
pm uninstall -k --user 0 com.sonymobile.assist.persistent
pm uninstall -k --user 0 com.sonymobile.android.externalkeyboardjp
pm uninstall -k --user 0 com.sonymobile.advancedwidget.topcontacts
pm uninstall -k --user 0 com.sonymobile.android.contacts
pm uninstall -k --user 0 com.sonymobile.android.contacts.res.overlay_305
pm uninstall -k --user 0 com.sonymobile.anondata
pm uninstall -k --user 0 com.sonymobile.demoappchecker
pm uninstall -k --user 0 com.sonymobile.dualshockmanager
pm uninstall -k --user 0 com.sonymobile.email
pm uninstall -k --user 0 com.sonymobile.getmore.client
pm uninstall -k --user 0 com.sonymobile.gettoknowit
pm uninstall -k --user 0 com.sonymobile.googleanalyticsproxy
pm uninstall -k --user 0 com.sonymobile.intelligent.backlight
pm uninstall -k --user 0 com.sonymobile.intelligent.gesture
pm uninstall -k --user 0 com.sonymobile.intelligent.iengine
pm uninstall -k --user 0 com.sonymobile.intelligent.observer
pm uninstall -k --user 0 com.sonymobile.lifelog
pm uninstall -k --user 0 com.sonymobile.music.googlelyricsplugin
pm uninstall -k --user 0 com.sonymobile.music.wikipediaplugin
pm uninstall -k --user 0 com.sonymobile.music.youtubekaraokeplugin
pm uninstall -k --user 0 com.sonymobile.music.youtubeplugin
pm uninstall -k --user 0 com.sonymobile.retaildemo
pm uninstall -k --user 0 com.sonymobile.styleportrait.addon.blue
pm uninstall -k --user 0 com.sonymobile.styleportrait.addon.bubble
pm uninstall -k --user 0 com.sonymobile.styleportrait.addon.daily
pm uninstall -k --user 0 com.sonymobile.styleportrait.addon.paint
pm uninstall -k --user 0 com.sonymobile.styleportrait.addon.red
pm uninstall -k --user 0 com.sonymobile.styleportrait.addon.star
pm uninstall -k --user 0 com.sonymobile.styleportrait.addon.sunshine
pm uninstall -k --user 0 com.sonymobile.styleportrait.addon.suntan
pm uninstall -k --user 0 com.sonymobile.themes.sou.cid14.black
pm uninstall -k --user 0 com.sonymobile.themes.sou.cid15.white
pm uninstall -k --user 0 com.sonymobile.themes.sou.cid16.blue
pm uninstall -k --user 0 com.sonymobile.themes.sou.cid17.pink
pm uninstall -k --user 0 com.sonymobile.xperialounge.services
pm uninstall -k --user 0 com.sonymobile.xperiaweather
pm uninstall -k --user 0 com.sonymobile.xperiaservices
pm uninstall -k --user 0 com.sonymobile.xperiatransfermobile
pm uninstall -k --user 0 com.sonyericsson.textinput.chinese
pm uninstall -k com.sonymobile.support

You may remove more of course, just be aware that some might be required by the system. By removing some other packages, I got my phone almost ‘bricked’, requiring a complete reset of the system using the Sony Xperia Companion software.

Limitations:

Unfortunately, some of the packages are installed for user 0 (zero), while others seem to require no user for uninstallation.  I did not find out why this is, on my phone there is only 1 user.

Also, uninstalling on some packages can not completely remove them from the phone, they are still showing in the app list on the device GUI.

Defecting from Samsung (Android) to an Apple iPhone

The longest time I have been a happy Samsung phone user, currently with the S4 mini, and liked the ability to flash custom ROM’s like CyanogenMod and it’s sucessor LineageOS. However, having a hard time to find a small (4”-screen) phone with a good camera, I am considering the Apple iPhone SE.

Will I be punished for leaving the Android ecosystem?

This article on howtogeek.com gave me hope. Read on how it went for me…

Step 1: Find replacements for my favourite apps in the Apple Store

OwnCloud client app: $0.99
PodKickerPro: not available. There is a preinstalled app and some alternatives.
Barcode Scanner +:  not available, but there are many alternatives
GoogleContacts: not available as app. TechRepublic has an article.
GoogleCalendar: not available as app, but Google has a note on how to sync with the device’s Apple Calendar. Some restrictions apply.
Threema: $2.99
GoogleAuthenticator: free, from Google
GarminConnect: free, from Garmin
Scanbot: freemium, $4.99 for the lite version

But hey, is there (a) Llama….?

Which, by luck and a hint, I did not forget to look up.

Sad thing is, the Apple App store does not have an app for automated task execution. Neither Llama, nor Tasker is available.  IFTTT will not be of help either, because it can not control local settings.

This is a show-stopper to me and too much of a punishment. No iPhone for me this time.

Step 2

Update

I eventually bought an Android again. This time it was a SONY device:

The SONY Xperia X Compact is the smallest Android device available today with a decent camera and good other specs. It’s already more than 2 years old, but with a 23MP camera sensor resolution and an optical stabilisator it beats even it’s “successors”.

As any Android device it’s full of bloatware – read on how to get rid of it.

WordPress for Kids

How to simplify and secure a WordPress installation for kid’s use?

This guide focuses on privacy, security and ease of use. Thus secure access is enforced, a login is required and some UI sugar will be set up. Here are some steps to follow, with detailed instructions below:

  • Enforce HTTPS
  • Use WordPress privately, with required login
  • Disable commenting
  • Customize the login page for better recognition

Installation & Configuration

    1. Install it using your preferred way
    2. Create an admin user for you and a kid’s account (with the author role). If you like, also create viewer accounts for read-only access.
    3. Enforce HTTPS and use HSTS
      Create a .htaccess file in the root folder with the following content:
 
# Redirect to HTTPS 
RewriteEngine On 
RewriteCond %{HTTPS} =off 
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [QSA,L,R=301] 

# enable HSTS 
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" 

Install Plugins

  1. Use the Force Login plugin, to restrict usage only to registered users. This will also immediately load the edit mode once your kid has logged in.
  2. Make sure, the Loginizer plugin is installed and activated. It has a harsh retry limit and is a very effective means of keeping bad guys out.
  3. Use the Login customizer plugin, to create a pleasant login screen for your kid.

Commenting Config

In Settings/Discussion

  • Uncheck “Allow people to post comments on new articles”

Just in case you once allow discussion on a specific post:

  • Check “

Tweaking the UI

  • Update the theme: TWENTY SEVENTEEN is a nice theme (currently the default). Use a nice header image in the theme, showing something the kid likes (but probably not a closeup image of themselves)

Tweak the login screen

  • To make your kid feel at home, even at the login screen, use an image there too. Unfortunately you can not just add CSS in the default customization editor to tweak the login screen.
  • However, by using the Login customizer plugin:
    Go to Appearance/Customize, then Login Customizer (new from the installed plugin), then Other/Custom CSS to fully tweak the style. However, you can also just use the CSS below (replace the image URL):
/* This CSS changes the default WordPress login page
 * It uses a custom image as faded background and tweaks the
 * other UI stuff accordingly */

/* use an image from the gallery */
body.login {
    background-image: url(https://yourdomain.tld/wp-content/uploads/2018/03/x.jpg);
    display: block;
    background-size: cover;
}

/* fade the image to black and keep behind the login form */
body.login::after {
    content: "";
    background: rgba(0, 0, 0, 0.6);
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    /* Image behind the login form */
    z-index: -1;
}

/* make the links more readable, by using a white background, as the rest of the login form, in front of the blackish image */
/*body.login div#login,*/
body.login p#backtoblog,
body.login p#nav {
    background-color: white;
}

/* keep the links visually attached to the form */
body.login p#nav,
body.login p#backtoblog {
    margin-top: 0;
    padding-top: 6px;
    padding-bottom: 6px;
}

body.login p#backtoblog {
    padding-bottom: 24px;
}

/* keep the wordpress logo decolorized to not infer with image colors */
body.login #login > h1 > a {
    filter: grayscale(100%) brightness(250%); 
}

Happy blogging!

WordPress and all plugins mentioned are free (or freemium), so consider donating to the respective authors.

Publishing a CSS User Style as Firefox Extension

To provide the FocusFinder User Style to Firefox users that do not have the Stylish or Stylus browser extension, I want to create a simple Firefox extension that just applies these CSS rules. How easy is this with the new WebExtensions API model? Well…

Very easy!

  1. Create your CSS and provide it as User Style.
  2. Create the extension skeleton using the First Example from the Add-ons topic on MDN docs as Template.
  3. Replace the javascript file from the example with the file obtained via “Install style as userscript” on the user style website.
  4. Try the extension out locally using the Firefox debugging mode.
  5. Package it as a simple ZIP file.
  6. Publish to addons.mozilla.org (AMO), by submitting it through the submission form.
  7. Enjoy!

Here is the Focus Finder Firefox Extension on the official Firefox Add-ons Page!

Resources

 

 

An embeddable single file QR code generator

As HTML/CSS/JavaScript exercise I created* a QR code generator, which is embeddable into any website. It’s even usable offline, because it’s just a single HTML file.

Try it

And here’s how you embed it, using a cached copy via the RawGit CDN:

<iframe src="https://cdn.rawgit.com/suterma/quirli/1.1.0/website/qr.frameable.inline.html" frameborder="0" scrolling="no" style="overflow: hidden;" width="100%" height="400px"></iframe>

You can also change the sizes or the frame border. The displayed QR code will adapt accordingly on page load. However, only one iframe per page is currently supported.

You may also take the qr.frameable.inline.html and host it on your own server, or just download it to your local file system for offline use.

API

The offered QR code generator supports two request query parameters:

  • text, to allow for a custom preset text. Requires URL encoding of the text.
  • readonly, to disallow text entry. This may be useful when you just want to present a QR code for a given text.

Here’s an example with a link, which uses the (URL encoded) URL of this post: https://cdn.rawgit.com/suterma/quirli/1.1.0/website/qr.frameable.inline.html?text=https%3A%2F%2Fqrys.ch%2Fan-embeddable-single-file-qr-code-generator%2F&readonly=true

Credits

* To be honest, I just tried to pull the right strings. The QR Code generator page presented here is based on the Javascript QR Encoder by tz@execpc.com, released under GPLv3. It also uses small bits of Bootstrap, jQuery and AngularJS.

Running NxFilter on a Synology DS115j NAS

To free up my other Raspberry Pi from being a DNS server and to use an already existing NAS on my local LAN, I decided to try to install NxFilter (my favourite DNS filtering solution) to a Synology DS115j NAS device. Here’s how I did it.

The DS115j is one of the more affordable models, running Version 5 of the Synology DiskStation Manager (DSM). Unfortunately it is not able to run Docker containers. Thus I decided to go down the native way with the Java Manager module.

However, to make it safe (that is, not running it as root) was a little more involved as I thought…

You will need to…

  • Install Java (with the Java Manager)
  • (at least temporarily) enable SSH on your NAS.
  • Add kernel modules for port redirection from Port 53 to a non-privileged port, to avoid running the DNS server as root.
  • Modify the Synology firewall to accept traffic for DNS and the NxFilter admin GUI.
  • Use UpStart jobs to start up NxFilter automatically after boot.
  • Use an upstream DNS server, also for queries originating from within the NAS.

Prerequisites

  1. Log into your Synology NAS admin GUI as administrator.
  2. Install Java, version 1.7.0, using the Java Manager Package in the Package Center of you Synology NAS.
  3. Enable SSH in Control Panel / Terminal & SNMP / Terminal. Tick Enable SSH Service.
  4. Add firewall rules in Control Panel / Security / Firewall. You must open a port for DNS and one for the admin GUI.
    Since I will later use port redirection for DNS, I use port 8053 instead of the default 53. In the below example I allow all local traffic to the alternative DNS Port 8053 (UDP) as well as the administration GUI port 8443 (TCP).

    Firewall rules for DNS, using alternative ports.

Installing NxFilter

Get the latest NxFilter binaires as ZIP file from their website (nxfilter-v.v.v-p1.zip).

Deploying to a local user

  1. I suggest to create and use a specific local user account for the NxFilter installation on your Synology NAS to keep things separated.

    Creating an “NxFilter” user account

    Name the user “NxFilter” and keep it the “users” System default group. There is no need to add any further access (not even for the FileStation), as this account is only used as a convenient, local container for the NxFilter files.

  2. Log into the created NxFilter account, upload and unzip the binaries in to the home folder.

    Deploying NxFilter

    Config stuff

To avoid avoid the necessity to run as root, you should use an alternative port for the NxFilter admin GUI as well as the DNS service.

To do so, edit the home/conf/cfg.default file and save it as cfg.properties file. (Hint: to use the convenient online text editor, first rename the file to cfg.default.txt)

Editing the NxFilter config file

Edit the port configuration to this, for example (with an added line for the DNS port):

http_port = 8080
https_port = 8443
dns_port = 8053

Run, NxFilter run!

You will need to start Nxfilter via the SSH console, which requires you to log in as root (using the administrator password)

ssh root@192.168.x.z

To have the port forwarding working, add the following kernel modules and add the rule:

insmod /lib/modules/nf_nat.ko 
insmod /lib/modules/iptable_nat.ko 
insmod /lib/modules/ipt_REDIRECT.ko 
iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 8053

Then try to run it testwise using the provided startup script

/volume1/homes/NxFilter/bin/startup.sh

This should produce the following log on the console:

Check the presence of the admin GUI at https://your-ip:8443/admin.jsp

Now let’s shut it down again for the moment.

/volume1/homes/NxFilter/bin/shutdown.sh

iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-port 8053

rmmod /lib/modules/ipt_REDIRECT.ko 
rmmod /lib/modules/iptable_nat.ko 
rmmod /lib/modules/nf_nat.ko

Using Upstart to keep it running

To keep the NxFilter DNS server automatically running over NAS reboots, you can create an Upstart job configuration, that will cause a job to run at startup and shutdown of the NAS.

However, the job needs to be split in 3 parts:

  1. Setup the port redirection, with root privileges
  2. Start NxFilter with user privileges
  3. Tear down the port redirection, with root privileges

Create an Upstart script

Create an nxfilter-setup.conf file in /etc/init/ with the following content:

description "Prepares the system to start the NxFilter DNS server on a non-privileged port at NAS startup"
author "marcel@codeministry.ch (hosted on qrys.ch)"
usage "Start NxFilter simply with 'start nxfilter'. The setup and teardown tasks will be invoked automatically."

# output is logged to a file in directory /var/log/upstart/
console log

# Only start this task when the nxfilter service job is starting
start on starting nxfilter

task

# Note: Running as root (the default) is a bad idea,
# but root is actually required to bind to Port 53 (for DNS)
# on the given Synology DS115j NAS.
# As solution this uses local port redirection
# to let the DNS server use one of the higher, non-privileged ports
# when serving DNS queries.

script
 # Since Synology DS115j NAS does not support nat tables out of the box we will add this first.
 insmod /lib/modules/nf_nat.ko 
 insmod /lib/modules/iptable_nat.ko 
 insmod /lib/modules/ipt_REDIRECT.ko 
 # Add port redirection to serve DNS queries on one of the non-privileged ports
 iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-port 8053
end script

Create an nxfilter.conf file in /etc/init/ with the following content:

description "Starts the NxFilter DNS server on a non-privileged port at NAS startup"
author "marcel@codeministry.ch (hosted on qrys.ch)"
usage "Start NxFilter simply with 'start nxfilter'. The setup and teardown tasks will be invoked automatically."

setuid "NxFilter"

# output is logged to a file in directory /var/log/upstart/
console log

# Starting this service job will also start the nxfilter-setup task job
# Only start this service after the httpd user process has started. It is a safe bet that the DNS is able to run now.
start on started httpd-user

# Stop the service gracefully if the network goes down.
# Stoppping this service job will also start the nxfilter-teardown task job
stop on stopping network-interface IFACE=eth0

script
 # Start the DNS server
 # Since Upstart does only use a minimalistic environment, provide the necessities here directly to the process
 exec env PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/syno/sbin:/usr/syno/bin:/usr/local/sbin:/usr/local/bin:/var/packages/JavaManager/target/Java/jre/bin" /volume1/homes/NxFilter/bin/startup.sh
end script

pre-stop script
 # Shut down the DNS server gracefully (otherwise it will get killed by the stop process)
 # Since Upstart does only use a minimalistic environment, provide the necessities here directly to the process
 exec env PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/syno/sbin:/usr/syno/bin:/usr/local/sbin:/usr/local/bin:/var/packages/JavaManager/target/Java/jre/bin" /volume1/homes/NxFilter/bin/shutdown.sh
end script

Create an nxfilter-teardown.conf file in /etc/init/ with the following content:

description "Reverts the changes made to the system to start the NxFilter DNS server on a non-privileged port at NAS startup"
author "marcel@codeministry.ch (hosted on qrys.ch)"
usage "Start NxFilter simply with 'start nxfilter'. The setup and teardown tasks will be invoked automatically."

# output is logged to a file in directory /var/log/upstart/
console log

# Only start this task job the nxfilter service job is stopped (and NxFilter is shut down)
start on stopped nxfilter

task

script
 # Remove the port redirection
 iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-port 8053

# Remove the NAT kernel modules (in reverse order)
 rmmod /lib/modules/ipt_REDIRECT.ko 
 rmmod /lib/modules/iptable_nat.ko 
 rmmod /lib/modules/nf_nat.ko 
end script

If you created the job configs in the NxFilter user’s home directory for convenience, now copy it in the right place:

cp /volume1/homes/NxFilter/nxfilter-setup.conf /etc/init/nxfilter-setup.conf
cp /volume1/homes/NxFilter/nxfilter.conf /etc/init/nxfilter.conf
cp /volume1/homes/NxFilter/nxfilter-teardown.conf /etc/init/nxfilter-teardown.conf

Reload the job configuration and check the existence of the job

initctl reload-configuration
initctl list | grep nxfilter

Testing the UpStart job

Try to run the job now

start nxfilter

Output must be for a running state like:

nxfilter start/running, process 19499

See the log:

cat /var/log/upstart/nxfilter.log

If everything is OK, this job will start your NxFilter instance after reboot.

reboot

About not being root

By default, binding to a lower port, like 53 for DNS, needs root access, which is a good thing. But this also means that the whole NxFilter process (including the whole Java JVM in this case) needs to be run with root permissions, which is considered bad practice.

Better, you set explicit permission for binding, but run it without being root. However, the NAS in question seems not to support any of the conventional ways of doing this, like using authbind or setcap. But there’s another way.

Using iptables & kernel modules

iptables allows for all kind of redirecting and manipulating traffic. The solution here however requires only to change the destination port of an incoming DNS query packet. Thus I use the iptables directive as mentioned above.

However, on a Synology DS115j NAS the required nat table for port forwarding is not loaded by default, thus we also need insmod, as also was shown above.

Resources & Credits