Architecting a Bulletproof Home Lab DNS Stack: Pi-hole v6, DJB dnscache, and tinydns on Fedora Linux

Here is a comprehensive, production-ready technical blog post detailing the exact architecture, challenges, and step-by-step solutions we implemented to make this complex stack work.

Introduction

Building a robust, privacy-first home network infrastructure often leads to mixing modern ad-blocking utilities with legendary, hyper-secure routing daemons.

In this post, we walk through how to deploy Pi-hole v6 alongside a legacy Daniel J. Bernstein (DJB) DNS stack—comprising dnscache and tinydns—all running smoothly on a single Fedora Linux server. We will cover the port conflicts, firewall obstacles, and advanced loopback configurations required to bind this multi-layered pipeline together.


🛠️ The Architecture Blueprint

To achieve maximum ad-filtering, ultra-fast caching, and custom local hostname resolution without single points of failure or resource friction, we isolated every service onto its own dedicated loopback or interface channel on Port 53:

Service layerIP Address & PortCore System Role
Pi-hole v6 (FTL)192.168.0.15:53Network entry point (strips trackers & ads)
dnscache127.0.0.1:53Handles recursion, caching, and routing
tinydns127.0.0.2:53Authoritative database for local home records
Quad9 Fallback9.9.9.9 / 149.112.112.112Upstream internet resolver (threat filtering)

🛑 Problem 1: The Port 8080 Web Server Crash

The Symptom

The web panel failed to load on the local network. Both Apache (HTTPD) and the core Pi-hole processing daemon were crashing or throwing “Address already in use” errors.

The Technical Reality

Pi-hole v6 completely dropped legacy PHP and Lighttpd in favor of a high-performance web server compiled directly into the pihole-FTL binary. During installation, if it detects Apache sitting on port 80, it will automatically fallback to port 8080. This crashes any pre-existing proxy workflows trying to use port 8080 globally.

The Fix

To isolate the web platforms, we allowed pihole-FTL to manage network interface web calls globally on port 8080 while bypassing the Apache layer completely:

sudo pihole-FTL --config webserver.port "8080o"

(The trailing o is a strict Pi-hole v6 validation requirement representing Open HTTP).


🛑 Problem 2: Fedora Firewalld Reject Strings

The Symptom

wget or curl on the server terminal loaded the Pi-hole dashboard perfectly, but client browsers on the home network timed out. Inspecting /var/log/messages showed aggressive kernel rejections:

filter_IN_internal_REJECT: IN=enp8s0 OUT= ... PROTO=TCP DPT=8080 SYN

The Technical Reality

Fedora server deployments utilize targeted network profiles. Opening ports on the default public or FedoraServer firewall zones is ignored if your active LAN network card card interface (enp8s0) is bound to the internal zone.

The Fix

Explicitly map the network interface and drill open the web panel port (8080) and standard DNS processing service (53) on the true active zone:

sudo firewall-cmd --permanent --zone=internal --add-interface=enp8s0
sudo firewall-cmd --permanent --zone=internal --add-port=8080/tcp
sudo firewall-cmd --permanent --zone=internal --add-service=dns
sudo firewall-cmd --reload

🛑 Problem 3: The Port 53 Shared Socket Clash

The Symptom

Upon launching Pi-hole, the background FTL daemon crashed instantly. The debug logs threw a critical error:

CRIT: Error in dnsmasq configuration: failed to create listening socket for 127.0.0.1: Address in use

The Technical Reality

Operating systems cannot allocate a single port (53) to multiple daemons on a shared interface wrapper. Even if you modify the environment files (env/IP) of dnscache to 127.0.0.1 and tinydns to 127.0.0.2, Pi-hole v6 generates a wildcard loop bind (0.0.0.0:53) internally by default. This causes it to blindly try to claim the loopback addresses, colliding directly with the DJB components.

The Fix

  1. Define strict loopback limits for the DJB suite by writing your runtime environment targets:
    • TinyDNS (/etc/tinydns/env/IP): 127.0.0.2
    • dnscache (/etc/dnscache/env/IP): 127.0.0.1
  2. Open Pi-hole v6’s configuration folder processing toggle to respect manual configuration blocks:sudo pihole-FTL --config misc.etc_dnsmasq_d true
  3. Drop a custom hardware interface layout rule directly into Pi-hole’s embedded dnsmasq engine directory:sudo nano /etc/dnsmasq.d/99-single-ip-bind.conf Inject the following constraints to restrict the wildcard loop:listen-address=192.168.0.15 except-interface=lo bind-interfaces
  4. Restart the runtime sequence:sudo svc -t /service/tinydns /service/dnscache sudo systemctl restart pihole-FTL

🛑 Problem 4: The Green “Deny” Query Log Loop

The Symptom

The Pi-hole dashboard populated rows of local client lookups, but they were flagged in red with a status profile of Deny right next to a light green blocklist validation highlight.

The Technical Reality

A light green block row proves the target domain safely cleared your ad-filtering databases. However, because dnscache passes traffic upstream using your domain identity name string (thefabfarrows.com) instead of raw numerical client IPs, Pi-hole’s internal security matrix triggers an automated CORS / Host Header cross-site vulnerability block, intentionally denying the query.

The Fix

  1. Instruct the web panel engine to explicitly trust the domain origin alongside your core IP:sudo pihole-FTL --config webserver.domain "192.168.0.15,thefabfarrows.com" sudo systemctl restart pihole-FTL
  2. Break recursive mapping floods by navigating to your dashboard SettingsDNSAdvanced DNS Settings, and disabling the toggle for “Never forward reverse lookups for private IP spaces”. This isolates your in-addr.arpa translation loops from leaking out to public fallbacks.

🎯 The Final Result

By nesting our layers systematically:

  1. Client machines ask Pi-hole (192.168.0.15) for resolutions.
  2. Pi-hole evaluates domain parameters, silently stripping trackers and dropping malicious assets.
  3. Clean requests are forwarded to dnscache (127.0.0.1), which inspects its custom file trees.
  4. Local paths map straight to your authoritative TinyDNS database (127.0.0.2), while global lookups safely fallback to Quad9 (9.9.9.9).

The result is an ultra-secure, stable, and incredibly performant network topology.


SmokePing on Linux: The Best Way to Monitor Network Latency

Brief

If you’ve ever wondered why your internet feels slow even though a speed test looks fine, the culprit is often latency or packet loss rather than bandwidth. This is where SmokePing shines. It’s one of the most effective tools for continuously monitoring network performance and producing beautiful graphs that make problems easy to spot.

Whether you’re a home lab enthusiast, a system administrator, or running business-critical services, SmokePing can quickly reveal intermittent network issues that other monitoring tools often miss.

What is SmokePing?

SmokePing is an open-source network monitoring application that measures latency over time. Instead of simply checking whether a server is online, SmokePing records response times and packet loss, displaying them in easy-to-read graphs.

Its unique “smoke” visualization makes jitter (variation in latency) immediately obvious.

Why Use SmokePing?

SmokePing offers several advantages over traditional monitoring tools:

  • Continuous latency monitoring
  • Packet loss detection
  • Historical performance graphs
  • Multiple probe types
  • Email alerting
  • Lightweight resource usage
  • Web-based interface
  • Excellent troubleshooting capabilities

Typical uses include:

  • Monitoring internet connections
  • Checking VPN stability
  • Watching WAN links
  • Monitoring cloud servers
  • Comparing multiple ISPs
  • Tracking Wi-Fi performance

Installing SmokePing

On Debian or Ubuntu, installation is straightforward:

sudo apt update
sudo apt install smokeping apache2

On Fedora:

sudo dnf install smokeping

On RHEL or Rocky Linux, you may first need to enable the appropriate repositories before installing the package.

Basic Configuration

Most configuration files live under:

/etc/smokeping/

The main configuration file is typically:

/etc/smokeping/config.d/

A simple target might look like:

+ LocalNetwork

menu = Local Network
title = Local Network Devices

++ Router
menu = Router
title = Home Router
host = 192.168.1.1

++ GoogleDNS
menu = Google DNS
title = Google DNS
host = 8.8.8.8

You can monitor virtually anything that responds to ICMP pings.

Starting the Service

Enable SmokePing to start automatically:

sudo systemctl enable smokeping
sudo systemctl start smokeping

Verify it’s running:

sudo systemctl status smokeping

Viewing the Dashboard

Once installed, open your browser and navigate to the SmokePing web interface.

You’ll see graphs that update automatically every few minutes, allowing you to view:

  • Average latency
  • Minimum latency
  • Maximum latency
  • Packet loss
  • Jitter

The graphs become more useful over time as historical data accumulates.

Understanding the Graphs

SmokePing graphs contain a wealth of information:

Flat green line
Your connection is stable with consistent latency.

Tall “smoke”
The wider the smoke appears, the more jitter is occurring.

Red sections
These indicate packet loss.

Latency spikes
Often caused by congestion, overloaded routers, wireless interference, or ISP issues.

Over days or weeks, recurring patterns can help identify scheduled backups, ISP congestion, or network maintenance windows.

Monitoring Multiple Locations

One of SmokePing’s strengths is organizing hosts into groups.

For example:

Internet
    Google
    Cloudflare
    Quad9

Servers
    Web01
    Database01
    MailServer

Network
    Router
    Switch
    Firewall

This makes it easy to identify whether problems originate inside your network or farther upstream.

Best Practices

To get the most from SmokePing:

  • Monitor your gateway.
  • Monitor your ISP’s first hop.
  • Monitor public DNS servers.
  • Monitor your web servers.
  • Keep historical data for trend analysis.
  • Configure email alerts for excessive latency or packet loss.
  • Back up your configuration files.

Common Troubleshooting Tips

If graphs stop updating:

  • Verify the SmokePing service is running.
  • Check firewall rules that may block ICMP.
  • Ensure target hosts respond to ping requests.
  • Review SmokePing logs for configuration errors.
  • Confirm the web server is serving the generated graph images.

Final Thoughts

SmokePing remains one of the best open-source tools for visualizing network latency and packet loss. It is lightweight, reliable, and provides insights that are difficult to obtain from simple uptime checks or occasional speed tests.

Whether you’re diagnosing an unreliable internet connection, monitoring remote servers, or keeping an eye on your home lab, SmokePing gives you a clear picture of network health over time. Once you’ve used it to troubleshoot a difficult issue, you’ll likely consider it an essential part of your Linux monitoring toolkit.

How to Run ASSP As A Systemd Service With Systemctl

Running the Anti-Spam SMTP Proxy (ASSP) reliably on a modern Linux server requires a proper service manager. By default, ASSP needs to start as root to bind to privileged mail ports (like port 25), after which it forks and spawns its main worker processes under a non-privileged user like nobody.

Using a custom systemd service file allows Linux to seamlessly handle this handoff, manage automatic restarts on failure, and handle process tracking without dealing with legacy PID files.


The Complete systemd Service File

Create a new service unit configuration file using your preferred text editor:

sudo nano /etc/systemd/system/assp.service

Paste the following optimized configuration into the file:

[Unit]
Description=ASSP (Anti-Spam SMTP Proxy)
After=network.target

[Service]
Type=forking
WorkingDirectory=/usr/local/assp
ExecStart=/usr/bin/perl /usr/local/assp/assp.pl
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Why This Configuration Works

  • Type=forking: Crucial for ASSP. It tells systemd that the initial process (started as root) will spawn a child process and then exit. systemd will wait for this handoff to complete rather than assuming the application crashed.
  • Root Execution: By omitting a User= directive in the service file, systemd launches the Perl script as root. This gives ASSP the authority to bind to port 25 before it internally drops its own privileges down to the nobody process.
  • No PID File Required: Modern systemd uses Linux control groups (cgroups) to track process trees. It will automatically detect and monitor the spawned nobody worker process without needing a legacy PIDFile directive.
  • Automatic Restarts: The Restart=always and RestartSec=5 directives ensure that if ASSP experiences a memory leak or crash, the system will automatically spin it back up after 5 seconds.

Activating and Managing ASSP

Once your service file is saved, run the following sequence to notify the system manager, enable the boot hook, and launch the proxy:

# 1. Reload systemd to detect the new service file
sudo systemctl daemon-reload

# 2. Enable ASSP to start automatically on system boot
sudo systemctl enable assp

# 3. Start the ASSP proxy service immediately
sudo systemctl start assp

Verifying the Service Status

To ensure that systemd is accurately tracking the background process tree, check the service status:

sudo systemctl status assp

You should see an active (running) status, and the CGroup section at the bottom will display the active Perl processes running under the nobody user.

Monitoring Real-Time Logs

Because systemd manages the execution environment, all standard output from ASSP is sent straight to the system journal. You can follow live spam-filtering logs using journalctl:

sudo journalctl -u assp -f

Why Tailscale + Firewalld Is My Ultimate Remote Access Stack

Setting up secure remote access usually feels like a balancing act between security and sheer frustration. For a long time, my server setup relied on Fail2ban throwing up dynamic walls via traditional iptables. It worked, but it was messy, cluttered, and stopping the service felt like waiting for water to boil as thousands of rules were torn down one by one.

Recently, I made two major upgrades to my network architecture: migrating my firewall backend entirely to Firewalld (using optimized ipsets), and rolling out Tailscale for zero-config mesh networking.

Here is why this combination has completely transformed how I manage my servers and devices.


Clean Infrastructure: The Firewalld Advantage

If you are still managing raw iptables chains for services like Fail2ban, do yourself a favor and migrate to Firewalld. Moving my setup to Firewalld made overall server configuration infinitely easier.

Instead of dealing with an unreadable wall of text when checking active blocks, Firewalld handles everything through structured zones and clean, dynamic kernel ipsets. Fail2ban now behaves itself flawlessly in the background, keeping my main firewall rules clean and freeing up system resources.


Tailscale: Secure Networking That Just Clicks

Tailscale is built on top of WireGuard®, creating a secure, encrypted mesh network (a “Tailnet”) across your devices, no matter where they are in the world. You can download the client directly from the Tailscale Website.

There is no port forwarding required on your home router, and Firewalld makes it incredibly simple to handle your security permissions. To keep your network segmented, Firewalld allows you to isolate your virtual private network interface into its own strict, custom security perimeter.

Rather than dumping your mesh traffic into a generic, open “trusted” zone, you can create a custom zone that explicitly allows only the services you choose. Assuming your virtual mesh network interface is named vpn-mesh0, here are the three commands to lock it down:

bash

# 1. Create a dedicated firewall zone for your secure network mesh
sudo firewall-cmd --permanent --new-zone=tailmesh

# 2. Assign your virtual network interface directly to this new zone
sudo firewall-cmd --permanent --zone=tailmesh --add-interface=vpn-mesh0

# 3. Permit ONLY explicit services (e.g., SSH) through the mesh
sudo firewall-cmd --permanent --zone=tailmesh --add-service=ssh

# 4. Reload firewalld to activate the changes
sudo firewall-cmd --reload

Use code with caution.

By explicitly isolating the mesh traffic to its own zone, you enforce zero-trust security. Even if a client device on your network is compromised, the attacker cannot scan or access any unapproved ports on your server, keeping your environment perfectly locked down.


Smarter Connectivity: VPN On-Demand & Local WiFi Exceptions

A common issue with traditional VPNs is the “always-on” headache. You want your traffic encrypted when you are sitting in a sketchy coffee shop, but keeping the VPN tunnel active when you are at home or work can break local casting, slow down file transfers, or create routing loops.

Tailscale solves this beautifully by allowing you to configure VPN On-Demand with smart exceptions.

Using Tailscale’s client configurations (which you can dive deep into via the official Tailscale Documentation), you can set up smart triggers based on the Wi-Fi network you are currently connected to:

  • The Untrusted Network Trigger: The moment your phone or laptop connects to an open public Wi-Fi network, Tailscale automatically spins up your connection and routes your traffic through your home “Exit Node” for complete encryption.
  • The Trusted Local Exception: When you walk through your front door and connect to your home Wi-Fi, the client recognizes the SSID. It immediately disables the heavy routing or exit-node tunneling, granting you seamless, full-speed access to local network storage, smart home devices, and local media servers without unnecessary overhead.

The Verdict

By pairing Firewalld on the backend with Tailscale on the frontend, I’ve achieved the holy grail of homelabbing and system administration: total security without sacrificing convenience. The server stays tightly locked down and easy to manage, while my client devices adapt intelligently to whatever network environment I throw them into.

If you’re looking to simplify your remote access without cutting corners on your firewall, this is the blueprint to follow.


I Finally Dropped My Custom 1996 iptables Firewall Script—And Why It Was Time

Thirty years. That is how long my home network routing infrastructure relied on a monolithic shell script I wrote back in 1996. I crafted it back in the golden era of early Linux packet filtering, packed it with raw configuration lines, and tweaked it over decades as a hobby project to survive moving from ipfwadm to ipchains, and eventually to iptables.

It was a personal point of pride. Whenever I set up a new tool in my home lab, I didn’t click buttons; I opened a massive text file, added a manual tracking line, flushed the kernel tables, and reloaded the whole script.

But this week, on my Fedora router, the limitations finally caught up. It was time to pull the plug, learn the modern way of doing things, and migrate my entire home routing setup to firewalld and native nftables.

Here is the story of how I transitioned my home lab, the weird architectural traps I fell into, and how I built a modern, locked-down zone security posture.


The Catalyst: Tracking Down the Ghosts in the Logs

The transition started where all good home lab projects begin: digging through log streams. By default, firewalld drops packets silently. If you want to see what is actually happening behind the scenes, you have to tell it to start logging denied traffic.

I turned on global drop logging using this quick command:

bash

sudo firewall-cmd --set-log-denied=all

Use code with caution.

(Pro-tip: If your logs get too flooded later on after everything is working, you can easily turn this back off by running sudo firewall-cmd --set-log-denied=off).

With logging activated, my journalctl stream instantly exposed the ghosts haunting my network. My internal server was actively throwing network blocks:

text

filter_IN_internal_REJECT: IN=eth1 OUT= MAC=... SRC=10.0.10.55 DST=10.0.10.200 PROTO=TCP DPT=443 SYN

Use code with caution.

Because of these newly introduced blocks from the transition to firewalld, the computers inside my house suddenly couldn’t load local secure web pages, my email client setups were dropping synchronization steps, and my smart devices were choking on network discovery packets. While my legacy 1996 script had seamlessly allowed this internal traffic for years, firewalld‘s strict, out-of-the-box zone behaviors completely locked down the single machine from serving both functions until I configured it correctly.


Step 1: Restoring the Internet Gateway (Masquerading)

The first order of business was transforming my Fedora server into an efficient edge gateway router for the house. In the old days, this meant writing explicit POSTROUTING -o eth0 -j MASQUERADE loops.

With firewalld, we instead split the hardware interfaces into discrete logical security boundaries: external (the WAN modem link on eth0) and internal (the private LAN switch on eth1). To feed the household devices out to the web, we built a dedicated outbound routing policy:

bash

# Set up a clean outbound forwarding pipeline with NAT masquerading
sudo firewall-cmd --permanent --new-policy=internalToExternal
sudo firewall-cmd --permanent --policy=internalToExternal --add-ingress-zone=internal
sudo firewall-cmd --permanent --policy=internalToExternal --add-egress-zone=public
sudo firewall-cmd --permanent --policy=internalToExternal --set-target=ACCEPT
sudo firewall-cmd --permanent --policy=internalToExternal --add-masquerade
sudo firewall-cmd --reload

Use code with caution.

Suddenly, outbound data—including seamless features like Wi-Fi Calling on our phones—slid out to the internet natively without requiring a single manually defined high-number port mapping.


Step 2: Falling Into the “Policy Object” Trap

My first instinct as a hobbyist was to consolidate everything into elegant inter-zone Policy Objects. I attempted to route all inbound public web, mail, and application traffic through a custom externalToInternal forward policy.

The firewall immediately threw a massive architectural roadblock:
Error: INVALID_ZONE: 'forward-port' cannot be used because egress zone 'internal' has assigned interfaces

The lesson learned:firewalld Policy Objects completely forbid port-forwarding rules if the destination zone is attached to a real, physical network card. Policies are designed for virtual spaces (like isolated Docker networks or hypervisor VM bridges).

To achieve a pristine setup, the correct move was to put forwarding rules back onto the zone itself, but keep the raw underlying system ports completely closed off to the public router space.


Step 3: Embracing “Option B” (Strict Local Lockdown)

When configuring internal communication, I faced a fork in the road. Option A was a loose, blanket ACCEPT target for the whole internal network. Option B was a hardened, granular lockdown where only verified application services could move data.

I chose Option B.

Because firewalld drops negative priority policies when traffic is destined for the host itself, trying to manage local server loops through a policy wrapper caused endless rejections. The correct architectural solution was to map my application signatures directly onto our physical internal zone gate.

We stripped out manual numeric ports and used pre-configured service wrappers to expose exactly what we needed, keeping everything else locked tight against unauthorized lateral movement:

bash

# Lock down the internal gate to ONLY trusted local infrastructure services
sudo firewall-cmd --permanent --zone=internal --add-service=http
sudo firewall-cmd --permanent --zone=internal --add-service=https
sudo firewall-cmd --permanent --zone=internal --add-service=ssh
sudo firewall-cmd --permanent --zone=internal --add-service=dns
sudo firewall-cmd --permanent --zone=internal --add-service=smtp
sudo firewall-cmd --permanent --zone=internal --add-service=smtps
sudo firewall-cmd --permanent --zone=internal --add-service=imaps
sudo firewall-cmd --permanent --zone=internal --add-service=plex
sudo firewall-cmd --permanent --zone=internal --add-service=samba
sudo firewall-cmd --permanent --zone=internal --add-port=8123/tcp  # Home Assistant
sudo firewall-cmd --reload

Use code with caution.


The Final Verdict: A Pristine Architecture

After sweeping out legacy clutter (like default desktop samba-client wrappers and unneeded dhcpv6-client daemons on the inner switch interface), the firewall configuration achieved absolute stability.

Running a diagnostic audit prints out an incredibly clean, legible system baseline:

text

external (active)
  interfaces: eth0
  services: http https imaps smtp smtps ssh

internal (active)
  interfaces: eth1
  services: dns http https imaps plex samba smtp smtps ssh
  ports: 8123/tcp

Use code with caution.

Everything is fully persistent and gracefully survives cold reboots. Local devices can map storage drives over Samba, stream Plex, resolve local DNS queries, and view internal pages. Meanwhile, the public web interface remains blind to everything except our secure edge proxies—and public pings remain active to satisfy network path diagnostics and MTU discovery boundaries as recommended by universal best practices.

It took me thirty years to finally retire that old text script. But seeing a silent journalctl stream and a flawless, granular zone layout?

It was an awesome weekend project upgrade.

ASSP mod_inst.pl Error After Upgrading Fedora 42 to 43

I recently upgraded my system from Fedora 42 to Fedora 43 after Fedora 42 reached end-of-life.

When I started ASSP, I received errors indicating that the required Perl modules were incorrect or missing, so I decided to run mod_inst.pl again to reinstall the necessary modules.

I downloaded the latest mod_inst.pl from the ASSP website and ran it, but it immediately failed with the following error:

error calling required module LWP::Simple - Proxy must be specified as absolute URI; 'proxyuser' is not at /usr/local/share/perl5/5.42/LWP/Simple.pm line 30.

After spending quite a while searching for solutions, most references pointed towards issues with the proxy settings. However, my assp.cfg file had blank values for proxyserver, proxyuser, and proxypass, and this configuration had worked fine before the Fedora upgrade.

While debugging mod_inst.pl and mod_inst_ocr.pl, I noticed the following commented-out section around line 722:

###########################################
# please change the following to your needs
#
# uncomment and change the following line(s) if you use a HTTP-Proxy and ENV is not set
#$ENV{HTTP_proxy} = 'http://yourproxy:port';
#$ENV{HTTP_proxy_user} = 'proxy-user';
#$ENV{HTTP_proxy_pass} = 'proxy-user-password';
###########################################

To resolve the issue, I uncommented the HTTP_proxy line and set it to my proxy server:

$ENV{HTTP_proxy} = 'http://10.0.0.1:765';

After making this change, mod_inst.pl ran successfully and installed the required modules without any further errors.

This information may already exist somewhere in the documentation, but I couldn’t find it. Hopefully this helps anyone else who encounters the same issue after upgrading Fedora or Perl.


Installed Radicale3 for hosting my own calendar and contacts data

So I finally got around to installing something so I can host my own calendar and contacts so that data is not shared with the big four corporate companies.

As I just need basic calendar and contacts functionality I chose the open source project Radicale. As I have run Fedora to control the house and my private data since 1998 I firstly installed the Radicale rpm via DNF.

dnf install radicale

This should install radicale3 as that is the latest version at the time of writing this blog post.

I will be running it off a sub domain of my public domain so I have set that up in the DNS with my main domain hosting company.

I have used a sub domain with a reverse proxy rather than opening another port [5232] on the firewall. I initially set it up with the port open but then rethought my approach as its more secure than to open the port on the firewall.

One other good thing using a sub domain is that you just need to have the proxy settings for that host rather than using location settings with the pathing.

Apache virtual host looks like this

<VirtualHost *:443>
 
 ServerName <subdomain.domain>
 DocumentRoot <pathtodomain>

 ProxyRequests Off
 ProxyPreserveHost On

 <Proxy *>
 Order deny,allow
 Allow from all
 </Proxy>

 # Forward requests to the backend Radicale server
 ProxyPass / http://localhost:5232/
 ProxyPassReverse / http://localhost:5232/

 # Inform Radicale about its location behind the proxy
 RequestHeader set X-Script-Name /radicale

 SSLCertificateFile <path to public key>
 SSLCertificateKeyFile <path to private key>

</VirtualHost>

Set up the config file for radicale to use it locally running on localhost on port 5232 and I am using my dovecot server to authenticate the users.

Then you should just be able to surf to the subdomain and be presented with the login page of the radicale server. Login and add your collections for the calendars and contacts.

Then configuring all the clients should be pretty straight forward for PC, Mac, iOS and Android.

MMEncode is not available on Linux distros any more.

Not sure what happened to this or why but its no longer available. I used to have a script that used it to convert binary data to text for attachments on emails. Having searched high and low I came up with a new solution – use openssl.

You can do the same that you were doing with mmencode by doing the following

openssl base64 -e < $FILE

Enjoy.

MySQL pegging CPU after the leap second adjustment.

So I find that my MySQL database is running high on CPU all of a sudden. I optimize the tables etc and no difference. I hunt around the internet to find that there seems to be a problem with this years leap second adjustment which sends MySQL into orbit.

The solution reset the date

date -s "`date`"

and it dropped back to normal.

Credit goes to this lady here http://www.sheeri.com/content/mysql-and-leap-second-high-cpu-and-fix

BackupPC Has qw(…) Warnings Since Upgrading Perl

So since upgrading Perl I am presented with qw warnings coming out of the cron job checking that BackupPC is running.

Use of qw(...) as parentheses is deprecated at /usr/share/BackupPC/lib/BackupPC/Storage/Text.pm line 301.
Use of qw(...) as parentheses is deprecated at /usr/share/BackupPC/lib/BackupPC/Lib.pm line 1412.

The way to get rid of these warnings is to enclose qw in parentheses and Perl processes the foreach parameters without warnings.

Like so

Text.pm (Line 301)

#
# Promote BackupFilesOnly and BackupFilesExclude to hashes
#
foreach my $param (qw(BackupFilesOnly BackupFilesExclude)) {
next if ( !defined($conf->{$param}) || ref($conf->{$param}) eq "HASH" );
$conf->{$param} = [ $conf->{$param} ]
if ( ref($conf->{$param}) ne "ARRAY" );
$conf->{$param} = { "*" => $conf->{$param} };
}

Lib.pm (Line 1412)

foreach my $param (qw(BackupFilesOnly BackupFilesExclude)) {
next if ( !defined($conf->{$param}) );
if ( ref($conf->{$param}) eq "HASH" ) {