<!--- Before asking, did you search first? Press 🔍 at the upper right to search. ---->
I am attempting to implement the protections found in this post. Where sys-net and sys-firewall are configured to drop any traffic that is not loopback.
I have little experience with Linux so my implementation may be flawed (following an LLM generated guide, with my own tweaks). The setup is as follows
I duplicated the TemplateVM debian-13-xfce as sys-net already uses it. In the template VM I have a service found at /etc/systemd/system/firewall-by-hostname.service. The intention of this service, as I understand it, is to run the /usr/local/sbin/check_hostname-firewall_rules.sh script before network services come online and apply the firewall rules if the hostname fits.
I’ve included the specific configs for what I’ve setup below.
My primary issue is the template vm seems to execute these steps successfully, I can check the systemd service after a boot with sudo journalctl -b -u firewall-by-hostname.serviceand see success entries and checking the firewall rules they’ve applied. However, when I run the sys-net qube based on the new template vm the same status check returns an error that the check_hostname-firewall_rules.sh script does not exist. Cding into the directory shows it’s empty. Why is the script not appearing in the sys-net qube?
My secondary question, will the current configuration perform the expected function of blocking all non-tor traffic? I’m concerned about the ct state established, related accept rule. Does this rule even make sense? Please remember the contents of the configs were generated by an LLM as I could not write my own, but I typed everything myself and tried to understand everything I could. Any help regarding implementing this desired quality would be much appreciated ![]()
The configuration for the service is below:
[Unit]
Description=Apply firewall rules based on hostname check
Before=network-pre.target
Wants=network-pre.target
DefaultDependencies=yes
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/check_hostname-firewall_rules.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
The contents of check_hostname-firewall_rules.sh are:
#!/bin/bash
# ======
# check_hostname-firewall_rules.sh
# Runs in boot before networking is established
# Check hostname for sys-net or sys-firewall and blocks outbound connections if it matches
# ======
set -euo pipefail
TARGET_HOSTNAMES=("sys-net" "sys-firewall" "localhost") # Localhost is for testing while on template vm
RULESET_FILE="/etc/nftables.conf"
CURRENT_HOSTNAME=$(hostname)
HOSTNAME_MATCHED=false
for target in "${TARGET_HOSTNAMES[@]}"; do
if [[ "${CURRENT_HOSTNAME}" == "${target}" ]]; then
HOSTNAME_MATCHED=true
break
fi
done
if [[ "${HOSTNAME_MATCHED}" != true ]]; then
echo "Hostname does not match, skipping firewall rules"
exit 0
fi
echo "Hostname matched, applying firewall rules"
if [[ -f "${RULESET_FILE" ]]; then
nft -f "${RULESET_FILE}"
echo "Firewall rules loaded"
else
echo "ERROR: Ruleset file not found" >&2
exit 1
fi
The config for the /etc/nftables.conf are
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy accept;
# Allow loopback
iif "lo" accept
# Allow established/related
ct state established, related accept
# Allow ICMP
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
}
chain forward {
# Drop forward traffic, I think
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy drop;
# Allow loopback
oif "lo" accept
# Allow established/related
ct state established, related accept
}
}