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
- Log into your Synology NAS admin GUI as administrator.
- Install Java, version 1.7.0, using the Java Manager Package in the Package Center of you Synology NAS.
- Enable SSH in Control Panel / Terminal & SNMP / Terminal. Tick Enable SSH Service.
- 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).
Installing NxFilter
Get the latest NxFilter binaires as ZIP file from their website (nxfilter-v.v.v-p1.zip).
Deploying to a local user
- I suggest to create and use a specific local user account for the NxFilter installation on your Synology NAS to keep things separated.
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.
- Log into the created NxFilter account, upload and unzip the binaries in to the home folder.
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)
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:
- Setup the port redirection, with root privileges
- Start NxFilter with user privileges
- 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
- Download NxFilter
- Learning about UpStart
- About using UpStart by majikshoe
- Answer on unix.stackexchange.com about iptables and kernel modules
- Post by the author of NxFilter in a Google Group
- Question on Stackoverflow about binding to non-privileged ports