High availability Pi-hole cluster with Nginx load balancing

This is a quick write up for the hardware and software config for the high availability Pi-hole cluster with Nginx load balancing.


List of components used:

Name Part Number Quantity Link
raspbery pi single board computers (with cases and SD card) 3
USB A male to micro usb cables 3 https://amzn.to/2x9OdK6
6″ Ethernet patch cables 4 https://amzn.to/2KCi7K4
gigabit switch that has 5V input AM-SG205 1 https://amzn.to/2VGYGGy
5V 10A amp power supply Mean Well LRS-50-5 1 https://amzn.to/3aFPkic
Wire https://amzn.to/2Y2wv6q
Crimp ferrules https://amzn.to/3aH4a8c
Double Stick tape https://amzn.to/35eHUSg
panel mount Ethernet connector 1 https://amzn.to/2VGYMOq
usb to power PCB 2 Order from OSH Park
dupont female to female connector (for display) 18 https://amzn.to/3cPOkKa
PiOLED 0.91inch 3 https://amzn.to/2zyjJlV
1U rack mount case

Setup notes:

To configure the load balancer:

Add this to nginx.conf (make sure to change IPs to match your two pihole pi)

stream {
upstream dns_servers {
server fail_timeout=60s;
server fail_timeout=60s;
server {
listen 53 udp;
listen 53; #tcp
proxy_pass dns_servers;
error_log /var/log/nginx/dns.log info;
proxy_responses 1;
proxy_timeout 1s;

to restart nginix run this:

sudo /etc/init.d/nginx restart

See this page for details https://www.nginx.com/blog/load-balancing-dns-traffic-nginx-plus/

Rack Mounting RTL-SDR


This post talks about rack mounting a RTL-SDR reciever attached to a raspberry pi into a 1U case. The donor case used was a used kramer broadcast 1110 balanced audio distributor, but any 1U case should work.

Parts Needed:

    • 1U Case
    • 5V 3A power supply (Mean Well RS-15-5)
    • Raspberry Pi
    • Class 10 SD Card
    • rtl-sdr receiver with antenna
    • Short 6″ ethernet patch cable
    • panel mount ethernet jack (“search ebay for “ip68 ethernet”)
    • Screws, wire, fuses, switches, etc…


Configuring the Raspberry PI:

    1. Get the Raspbian “lite” image from  https://www.raspberrypi.org/downloads/raspbian/
    2. Install the image based on this guide: https://www.raspberrypi.org/documentation/installation/installing-images/README.md
    3. Find the SD card on the computer and add an empty file to it with the file name “ssh” (no extension). This will enable ssh on boot
    4. Power up the raspberry pi with ethernet connected.
    5. Find the address of the pi by port scanning with a tool like Nmap or looking at your routers DHCP allocation table.
    6. Use a tool like Putty to ssh into the pi on port 23. User name “pi” Password: “raspberry”
    7. Its a good idea to change the password when you log in using the passwd utility
    8. Optional: since this is going to be a headless install it would be a good idea to lower the video memory using  raspi-config.
    9. Now run these commands to get Osmocom rtl-sdr up and running on the pi:
      sudo apt-get update
      sudo apt-get install git cmake build-essential libusb-1.0 libpulse-dev libx11-dev
      git clone git://git.osmocom.org/rtl-sdr.git
      cd rtl-sdr
      mkdir build
      cd build
      cmake ../ -DINSTALL_UDEV_RULES=ON
      sudo make install
      sudo ldconfig
  1. Now you should be able to run rtl_tcp -a IpAddressOfPiGoesHere If an error pop up like Failed to open rtlsdr device #0. run sudo rmmod dvb_usb_rtl28xxu rtl2832 This will prevent the pi from loading the stock drivers for the dongle.
  2. The pi now can be used as a remote rtl-sdr server

Network Attached GPIO with HP Jetdirect

The goal of this is to create some network attached GPIO with some of the HP Jetdirects in my junk box. Here are some of the web sites used to figure this out:

As far as hardware the project was started with a Jetdirect 300x this was replaced with a 170x. The 300x has 10/100 base t which is why it was initially chosen. This was later replaced with the 170x which is only 10 base t. If you are looking to buy hardware, shoot for the 170x. The 300x, at least the one tested, does not appear to be as stable as the 170x.

The Jetdirects did not come with a power supply. The power connector was a somewhat weird diameter. Sourcing the power supply on Ebay proved more time consuming and expensive than desired. The search did lead to this listing which is hilarious.  Just picture a person driving with a wired network and a printer in their car. No one probably ever buys this…


The easiest solution for this was to pop open the case and solder some wires to the power connectors. That was also a problem since HP was nice enough to use some super tiny Torx security bits. A quick trip to the hardware store and the screws were no match for my new set of security screwdriver bits.

These wires were then attached to a surplus 12v wall wart.


For testing a PCB was created and the design was sent to https://macrofab.com/.


The original PCB did not have the connection on the DB25 connector between pins 1,  10, 13 and 15. This was added later on with some red 30 awg wire wrap wire.

The first problem that was encountered was finding the Jetdirect’s IP address. Usually this would be a simple task. All that would be required is holding down a button on startup and the jet direct would print out a configuration page that lists its IP address. This would be easy other than the fact that I no longer own a printer with a parallel port interface. The device is supposed to have a default IP of so that was tried first. After some reading it appears that if the device is power cycled while holding the
“test”button and releasing after 5 seconds it will go into reset and have factory defaults. After this was accomplished it was possible to ping, telnet and connect to the device using a web browser.


The telnet interface looked somewhat primitive so I opted for the web interface. The web interface failed to load in chrome so IE was tried. IE gave this lovely error:


After updating Java and adding the IP to the trusted sites in the java control panel, the web interface still did not work.


After some reading this is due to stricter security in the newer versions of Java. The work around for this was to use the telnet interface.


The jet direct’s default IP address of was not convenient so it was changed to be in the 192.168.1.xxx range. This was done by issuing the command ip: (or whatever IP you want) hitting enter then typing quit. After that wait one minute and power cycle the Jetdirect. The Jetdirect should now show up hopefully at the new IP. One other setting also needs to be set to gain control of the Jetdirect’s parallel port. The “set cmnty name” setting also needs to be set. This can be done by sending set-cmnty-name: private then typing quit.

One more thing needs to be done to trick the Jetdirect into thinking it has a printer attached. This is setting the npPortCentronicsHandshaking value in the jet direct. This was done with SNMPGetSet available here: http://www.fileguru.com/SNMPGetSet/download. The register is set by putting the value of into the OID box at the bottom of the form. Once that is done hit the SNMPGet button. The returned value should be 3.


To set the value change the value in the box to 2. After changing the value of 2 make sure that you set the value type to ANS1_INT. Then press the SNMPSet Button.  If you do not change the value type the setting will not save.  You can confirm the setting was saved by pressing the SNMPGet button again.


If everything is working correctly the Jetdirect should now be able to be controlled. To verify everything is working correctly first check to see if the Jetdirect will open port 9100. This can be done from a Unix shell with netcat. Command nc -vz 9100 you should see  [tcp/*] succeeded! if everything is working. If that does not work try port 23. If you can connect on port 23 but not on 9100 the Jetdirect does not think a printer is connected. Check your wiring especially on pins 1,  10, 13 and 15.

If everything works the fun begins. A printf "\xFF" | nc 9100 should turn on all the leds.

A sample program was constructed in C# to simulate the Knight Rider dash or a Cylon.

Here is the code: https://github.com/mdunakin/JetDirectDemo

Here is a video of the code running:

Network Caller ID (NCID) Install On Raspberry PI

This guide will walk through how to install network caller ID (NCID) on a headless raspberry pi. The primary goal of this is to create a blacklist to prevent unwanted spam telephone calls.


Hardware needed:

  1. Raspberry Pi, a model b was used but any should work
  2. SD Card, any larger than 4gb should work
  3. 5V power supply. The modem appears to take a large amount of current. The first 1 amp power supply was unstable so it was replaced with a 2 amp version
  4. Modem, a Zoom 56K USB Modem Model 3095 was used. This was sourced from Ebay.
  5. Phone cord
  6. A splitter. http://amzn.to/2fyT9hP to put the modem in parallel to the phone

How to install NCID:

  1. Grab an image of the Rasbian operating system from https://www.raspberrypi.org/downloads/ and install it to an SD card using this guide https://www.raspberrypi.org/documentation/installation/installing-images/
  2. SSH into the PI using putty http://www.putty.org/ User Name pi Password raspberry
  3. Grab a copy of the NCID source code from here https://sourceforge.net/projects/ncid/files/latest/download using wget. Sourceforge can be a little strange so you may have to poke around to find the direct link
  4. Un-tar the archive using tar -zxvf ncid-X.XX.X-src.tar.gz (replace the X.XX.X with version number)
  5. Run sudo-apt get update then grab a copy of sudo apt-get install libpcap0.8*
  6. Navigate to the folder with the build scripts and run sudo make ubuntu-install
  7. Open the config file with sudo nano /etc/ncid/ncidd.conf
  8. Make the following changes to the configuration file:
    set ignore1 = 1
    set hangup = 1
    set ttyport = /dev/ttyACM0
    set lockfile = /var/lock/LCK..ttyACM0
    # Make sure your modem is located here
  9. open nano /etc/ncid/ncidd.alias
  10. Comment out this line with a “#” #alias LINE - = POTS
  11. Make the  NCID daemon automatically start up sudo update-rc.d ncidd defaults
  12. The blacklist is located here and should be edited /etc/ncid/ncidd.blacklist
  13. Finally run sudo invoke-rc.d ncidd restart to get the service running. This also appears to need to be run after editing the blacklist.