How-To: eBlocker4 (beta) on Microsoft Hyper-V

This post describes how to deploy eBlocker4 in a Microsoft Hyper-V environment.
The guide is intended for administrators who want to run eBlocker as a virtual appliance and integrate it into an existing network using Hyper-V.

It covers the basic prerequisites, virtual machine configuration, and network setup required to get eBlocker 4 up and running. The focus is on a straightforward deployment using standard Hyper-V features, without assuming prior experience with eBlocker.

The steps outlined here are based on practical experience and are meant to serve as a reference or starting point for your own installation. Depending on your Hyper-V version and network design, minor adjustments may be necessary.

Tools:
– qemu-img-win-x64-2_3_0 -> extract with 7-zip
– 7-zip

Download eBlocker Image for VirtualBox:
https://eblocker.org/community/main-forum/eblockeros-4-beta-available-for-testing/#post-8547
https://eblocker.org/de/eblockeros-downloads/eBlockerVM-4.0.2-amd64-beta.ova

Extract the .ova image into a folder using 7-Zip

Open terminal with admin rights

qemu-img.exe convert eBlockerVM-disk001.vmdk -O vhdx -o subformat=dynamic eBlockerVM4.vhdx


Create new hyper-v machine Generation 1 and choose the eBlockerVM4.vhdx

Now you can start your virtual machine

Open the url for configuration. Follow the first steps from the Developer site.

Short configuration (if you only want some devices used by eBlocker):

Network: NetworkMode -> Expert -> Choose an fix IP Adress, name your Gateway DHCP Services: external

Network: IPv6 (BETA) -> deactivate


HTTPS -> HTTPS support activated

DNS Firewall: Use eBlocker as DNS server -> Custom list of external DNS servers -> name here your home DNS. Router, Pihole, etc.

Blocker: define your own filterlists
For example click on Domain Ad Blocker, Domain Tracker Blocker and Domain Malware Blocker. You can found some Lists here: https://firebog.net

Devices -> activate the device you want to use eBlocker

The device needs as Gateway and DNS the IP from your eBlocker. For domain blocking you don’t need to enroll SSL certificates on the device.

How-To: Raspberry Pi with Docker live Backup to NAS

Attached is a Bash script to live back up a Raspberry Pi running Docker to a QNAP NAS.

NAS configuration:

First, create a shared folder on your NAS and a user account with appropriate permissions.

Share name: NetBackup

NAS IP used in the example: 10.1.1.10.

Username in example: YOURNASSHAREUSER

Password in example: YOURSHAREUSERPASSWORD

So your NAS configuration is done.

Raspberry Pi Configuration:

# packages

sudo apt update
sudo apt install -y cifs-utils pigz

# mountpoint and access (edit your credentials)

sudo mkdir -p /mnt/qnap
echo -e "username=YOURNASSHAREUSER\npassword=YOURSHAREUSERPASSWORD\ndomain=WORKGROUP" | sudo tee /etc/cifs-creds-qnap >/dev/null
sudo chmod 600 /etc/cifs-creds-qnapCode-Sprache: JavaScript (javascript)

# persistent mount (edit your NAS IP)

echo "//10.1.1.10/NetBackup /mnt/qnap cifs _netdev,credentials=/etc/cifs-creds-qnap,iocharset=utf8,vers=3.0,serverino,nofail 0 0" | sudo tee -a /etc/fstabCode-Sprache: PHP (php)

# mount & check

sudo mount -a
ls -la /mnt/qnap

# folder create

sudo mkdir -p /mnt/qnap/rpi4/fullimages

# scriptfile create

sudo vi /usr/local/sbin/rpi_fullimage.sh

# copy script in scriptfile (edit Retention and device defaults)

sudo tee /usr/local/sbin/rpi_fullimage.sh >/dev/null <<'SH'
#!/usr/bin/env bash
set -euo pipefail

# ========= Einstellungen =========
TARGET_DIR="/mnt/qnap/rpi4/fullimages"   # Zielordner auf QNAP (NetBackup -> /mnt/qnap)
RETENTION_DAYS=180                       # Aufbewahrungsdauer in Tagen
BLOCK_SIZE="16M"                         # Lese-Blockgröße für dd
DEVICE_DEFAULT="/dev/mmcblk0"            # or /dev/sda if SDD over USB: df -h 

# ========= Hilfsfunktionen =========
abort() { echo "[FEHLER] $*" >&2; exit 1; }
info()  { echo "[*] $*"; }
ok()    { echo "[OK] $*"; }

# ========= Vorbedingungen =========
command -v pigz >/dev/null || abort "pigz fehlt. Installiere: sudo apt install -y pigz"
mountpoint -q /mnt/qnap || abort "QNAP nicht gemountet (/mnt/qnap). Prüfe /etc/fstab und 'sudo mount -a'."
mkdir -p "$TARGET_DIR"

DEV="$DEVICE_DEFAULT"
[ -b "$DEV" ] || abort "Blockgerät $DEV nicht gefunden. Bootest du evtl. von USB/NVMe? DEVICE_DEFAULT anpassen."

# Grobe Platzprüfung (mind. ~50% der Gerätegröße frei; gzip komprimiert stark)
FREE_KB=$(df -Pk "$TARGET_DIR" | awk 'NR==2{print $4}')
SECTORS=$(cat /sys/block/$(basename "$DEV")/size)
TOTAL_BYTES=$(( SECTORS * 512 ))
NEEDED_KB=$(( (TOTAL_BYTES / 2) / 1024 ))
[ "$FREE_KB" -ge "$NEEDED_KB" ] || abort "Zu wenig Platz auf QNAP. Frei: ${FREE_KB}KB, benötigt grob >= ${NEEDED_KB}KB."

DATE="$(date +%F_%H-%M-%S)"
IMG="${TARGET_DIR}/rpi4-${DATE}.img.gz"

# ========= Docker: laufende Container pausieren =========
DOCKER_AVAILABLE=true
command -v docker >/dev/null || DOCKER_AVAILABLE=false

RUNNING_IDS=""
if $DOCKER_AVAILABLE; then
  RUNNING_IDS="$(docker ps -q || true)"
  docker_restore() {
    if [ -z "$RUNNING_IDS" ]; then return 0; fi
    for id in $RUNNING_IDS; do
      st="$(docker inspect -f '{{.State.Status}}' "$id" 2>/dev/null || echo unknown)"
      [ "$st" = "paused" ] && docker unpause "$id" >/dev/null 2>&1 || true
      st="$(docker inspect -f '{{.State.Status}}' "$id" 2>/dev/null || echo unknown)"
      if [ "$st" = "exited" ] || [ "$st" = "created" ]; then docker start "$id" >/dev/null 2>&1 || true; fi
    done
  }
  trap 'docker_restore' EXIT
  [ -n "$RUNNING_IDS" ] && { info "Pausiere laufende Docker-Container…"; docker pause $RUNNING_IDS || true; }
fi

sync

# ========= Image erstellen (fsync am Zieldatei-dd) =========
info "Erzeuge Image von ${DEV} -> ${IMG}"
dd if="$DEV" bs="$BLOCK_SIZE" status=progress iflag=fullblock \
| pigz -c \
| dd of="$IMG" bs=4M status=progress conv=fsync

# ========= Prüfsumme =========
info "Erzeuge SHA256-Prüfsumme…"
sha256sum "$IMG" > "${IMG}.sha256"

# ========= Docker-Vorzustand wiederherstellen =========
if $DOCKER_AVAILABLE; then
  docker_restore
  trap - EXIT
fi

# ========= Aufräumen =========
info "Entferne Backups älter als ${RETENTION_DAYS} Tage…"
find "$TARGET_DIR" -type f -name "rpi4-*.img.gz" -mtime +$RETENTION_DAYS -delete
find "$TARGET_DIR" -type f -name "rpi4-*.img.gz.sha256" -mtime +$RETENTION_DAYS -delete

ok "Voll-Image abgeschlossen: $IMG"
SHCode-Sprache: PHP (php)

# make script executable

sudo chmod +x /usr/local/sbin/rpi_fullimage.sh

# run script (docker will suspend)

sudo /usr/local/sbin/rpi_fullimage.sh

After reboot if auto mount not work:

# mount & check

sudo mount -a
ls -la /mnt/qnap

# run script (docker will suspend)

sudo /usr/local/sbin/rpi_fullimage.sh

Backup restore (test first on an other drive):

# Linux

sha256sum -c rpi4-*.img.gz.sha256
lsblk
gunzip -c rpi4-*.img.gz | sudo dd of=/dev/sdX bs=16M status=progress conv=fsync
syncCode-Sprache: JavaScript (javascript)

# Mac

diskutil list
diskutil unmountDisk /dev/disk3
gunzip -c rpi4-*.img.gz | sudo dd of=/dev/rdisk3 bs=16m status=progress
diskutil eject /dev/disk3Code-Sprache: JavaScript (javascript)

# Windows / Mac / Linux

Raspberry Pi Imager oder balenaEtcher

How-To: Update Portainer on a Raspberry Pi (Docker)

This procedure updates Portainer to the latest version. It pulls portainer/portainer-ce:latest, stops/removes the old container, and recreates it with the same /data volume—your settings are preserved.

First things first: make a backup of your Portainer data.

Back up Docker volume (“portainer_data”)

mkdir -p backups && docker run --rm -v portainer_data:/data:ro -v "$PWD/backups:/backup" alpine sh -c "tar -czf /backup/portainer-data-$(date +%F_%H-%M-%S).tgz -C / data"
Code-Sprache: PHP (php)

Back up a bind mount

mkdir -p backups && tar -czf "backups/portainer-data-$(date +%F_%H-%M-%S).tgz" -C /srv/portainer data
Code-Sprache: JavaScript (javascript)

Quick integrity check

tar -tzf backups/portainer-data-*.tgz | head

Now let’s start…

Check your Portainer container name.
By default it’s portainer; if yours is different, adjust the commands accordingly.

docker volume ls

Stop and remove the container:

docker stop portainer
docker rm portainer

Pull latest container:

docker pull portainer/portainer-ce

Run the latest container:

docker run -d -p 8000:8000 -p 9000:9000 -p 9443:9443 \
   --name=portainer \
   -v /var/run/docker.sock:/var/run/docker.sock \
   -v portainer_data:/data \
   --restart=always \
   portainer/portainer-ceCode-Sprache: JavaScript (javascript)

done