Skip to content

My config files for rolling entire infrastructures behind OpenBSD gateways which can only be accessed if on whitelists.

License

Notifications You must be signed in to change notification settings

emdnaia/OpenOCD

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 

Repository files navigation

OpenOCD

This project gets you:

  • OpenBSD: Static filtering of static IPs for SSH
  • OpenBSD: Dynamic filtering of dynamic IPs for VPN (Wireguard)
  • Linux: Dynamic filtering of dynamic IPs for VPN (Wireguard)
  • OpenBSD: Encrypted DNS via ODoH / DoT via Unbound + DNScrypt
  • OpenBSD: Adblocker skript to pull adlists for Unbound

Some steps

  1. Initial Setup: Start by configuring the OpenBSD gateway with the provided PF configuration to set up initial firewall rules.
  2. Dynamic IP Script: Implement the dynamic IP update script to maintain an up-to-date whitelist of IPs that can access the VPN.
  3. Cron Configuration: Schedule the provided cron jobs to automate the updating and maintenance tasks.
  4. DNS Encryption: Follow the DNS setup instructions to encrypt DNS queries, using either DoT or ODoH.
  5. Ad Blocking: Set up the ad blocker script to filter out unwanted ads.

Detailed Configuration Scripts and Commands

  • Dynamic IP Update Script (getpara.sh): This script resolves the current IP address for a specified FQDN and updates the PF table with any changes.

  • PF Configuration (pf.conf): Includes rules for blocking, allowing SSH from specific IPs, handling Wireguard traffic, and default deny policies.

  • Cron Jobs: Automates system updates, VPN renewals, and the dynamic IP update script. If on the go, reduce the cronjob size to refreshing every 2-5 minutes on getpara.sh, like this you can unlock a laptop on a hotspot in a train. The laptop would only need a dynamic dns client unlocking the public IP, which is also set to a maximum number kicking off the older ones.

  • DNS Configuration: Setup guides for DoT and ODoH, including configuration changes for dnscrypt-proxy.

  • Ad Blocker Script: Instructions and script for setting up ad blocking on OpenBSD using Unbound.

Some OpenBSD Cronjobs right away

  • add via crontab -e
@reboot /bin/sleep 30 && /usr/local/bin/wg-quick up wg0
@reboot /bin/sleep 30 && /usr/sbin/rcctl restart unbound

30 13 * * * /usr/sbin/syspatch -c 
32 13 * * * /usr/sbin/syspatch
35 13 * * * /usr/sbin/pkg_add -u

@reboot /bin/sleep 30 && /usr/local/getpara.sh
0 0,12 * * * /usr/local/getpara.sh

2 0 * * * /usr/sbin/rcctl restart unbound

Firewall: OpenBSD PF rules for static & dynamic ips

  • You edit the pf rules on /etc/pf.conf and check via pfctl -nf /etc/pf.conf and load them via pfctl -f /etc/pf.conf | non - webserver example
  • version A (more secure)
# $OpenBSD: pf.conf,v 1.55 2017/12/03 20:40:04 sthen Exp $
#
# See pf.conf(5) and /etc/examples/pf.conf

# Configuration Variables
dynamic_hosts_file="/usr/local/gotten-para"  # Location for dynamic hosts
wireguard_port="51820"                        # Your WireGuard VPN port
wireguard_net="10.0.0.0/24"                 # Your WireGuard VPN network
ssh_allowed_ips="{6.6.6.6/32, 7.7.7.7/32}"  # IPs allowed for SSH
wireguard_iface="wg0"                       # WireGuard interface identifier

# Block Ipv6 - remember hotspot leakage
block quick inet6

set skip on lo

# Block all incoming on vio0 but allow outgoing
block in on vio0 all

# NAT for outgoing traffic
match out on egress inet from !(egress:network) to any nat-to (egress:0)

# Allow SSH from specified IPs
pass in on vio0 proto tcp from $ssh_allowed_ips to (vio0) port 22 keep state
pass out quick on vio0 keep state

# Allow only IPs from <dynamic_hosts> to access WireGuard port on vio0
pass in on vio0 proto udp from <dynamic_hosts> to any port $wireguard_port keep state
pass out on vio0 proto udp to <dynamic_hosts> port $wireguard_port keep state

# Allow all on WireGuard interface
pass in on $wireguard_iface from $wireguard_net to any
pass out on $wireguard_iface from any to $wireguard_net

# By default, do not permit remote connections to X11
block return in on ! lo0 proto tcp to port 6000:6010

# Port build user does not need network
block return out log proto {tcp udp} user _pbuild
  • hypervisor forward example to -> pf firewall filtering forward to -> webserver
  • hypervisor forward via iptables:
## Variables
real_adapter_name="YOUR_ADAPTER_NAME"  # Replace this with the actual adapter name like eth0 or any placeholder
backend_server_ip="10.0.0.33"  # New IP instead of 10.9.3.33

## Forward port 443 from the real adapter to backend server on port 443
post-up iptables -t nat -A PREROUTING -i $real_adapter_name -p tcp --dport 443 -j DNAT --to $backend_server_ip:443
post-down iptables -t nat -D PREROUTING -i $real_adapter_name -p tcp --dport 443 -j DNAT --to $backend_server_ip:443

## Forward port 80 from the real adapter to backend server on port 80
post-up iptables -t nat -A PREROUTING -i $real_adapter_name -p tcp --dport 80 -j DNAT --to $backend_server_ip:80
post-down iptables -t nat -D PREROUTING -i $real_adapter_name -p tcp --dport 80 -j DNAT --to $backend_server_ip:80
  • version B (with webserver): pf then forwards to webserver that can be accessed from dynamic ips + static ips
  • dns is internal and can connect to the vpn
# $OpenBSD: pf.conf,v 1.55 2017/12/03 20:40:04 sthen Exp $
#
# See pf.conf(5) and /etc/examples/pf.conf

# Configuration Variables
dynamic_hosts_file="/usr/local/gotten-para"  # Location for dynamic hosts
wireguard_port="51820"                       # Your WireGuard VPN port
wireguard_net="10.0.0.0/24"                  # Your WireGuard VPN network
ssh_allowed_ips="{6.6.6.6/32, 7.7.7.7/32}"   # IPs allowed for SSH
wireguard_iface="wg0"                        # WireGuard interface identifier
final_backend_server="10.0.0.207"            # Final backend server IP
internal_dns_server="10.0.0.34"              # Internal DNS server IP
gateway_server="10.0.0.1"                    # Gateway server IP

# Block IPv6
block quick inet6

set skip on lo  # Skip loopback interface

# ---- Security Rules ----

# Block all inbound traffic except for explicitly allowed rules
block in on vio0 all

# Block X11 connections (optional security)
block return in on ! lo0 proto tcp to port 6000:6010

# Block network access for _pbuild user
block return out log proto {tcp udp} user _pbuild

# ---- NAT for Outgoing Traffic ----

# NAT outgoing traffic from non-egress networks (LAN/WireGuard)
match out on egress inet from !(egress:network) to any nat-to (egress:0)

# NAT for outgoing traffic from WireGuard network to external clients
match out on egress inet from $wireguard_net to any nat-to (egress:0)

# ---- Port Forwarding and Traffic Handling ----

# Allow access to port 80 (HTTP) from dynamic IPs and ssh_allowed_ips, and forward traffic to internal server
pass in log on vio0 proto tcp from <dynamic_hosts> to any port 80 rdr-to $final_backend_server port 80 keep state
pass in log on vio0 proto tcp from $ssh_allowed_ips to any port 80 rdr-to $final_backend_server port 80 keep state

# Allow access to port 443 (HTTPS) from dynamic IPs and ssh_allowed_ips, and forward traffic to internal server
pass in log on vio0 proto tcp from <dynamic_hosts> to any port 443 rdr-to $final_backend_server port 443 keep state
pass in log on vio0 proto tcp from $ssh_allowed_ips to any port 443 rdr-to $final_backend_server port 443 keep state

# ---- WireGuard-Specific Rules for Internal Traffic ----

# Allow intra-WireGuard traffic (e.g., from WireGuard clients accessing internal server)
pass in on $wireguard_iface proto tcp from $wireguard_net to $final_backend_server keep state
pass out on $wireguard_iface proto tcp from $final_backend_server to $wireguard_net keep state

# ---- SSH and DNS Access Rules ----

# Allow SSH from gateway_server
pass in on vio0 proto tcp from $gateway_server to (vio0) port 22 keep state
pass out quick on vio0 keep state

# Allow DNS requests from allowed SSH IPs
pass in on vio0 proto {udp tcp} from $ssh_allowed_ips to any port 53 keep state
pass out on vio0 proto {udp tcp} from any to any port 53 keep state

# ---- WireGuard-Specific DNS Rules ----

# Allow DNS requests from WireGuard clients (on WireGuard network) to internal DNS server
pass in on $wireguard_iface proto udp from $internal_dns_server to $wireguard_net port 53 keep state
pass out on $wireguard_iface proto udp from $wireguard_net to $internal_dns_server port 53 keep state

# ---- WireGuard-Specific Rules for External Access ----

# Only allow WireGuard access from dynamic IPs
pass in on vio0 proto udp from <dynamic_hosts> to any port $wireguard_port keep state
pass out on vio0 proto udp from (vio0) port $wireguard_port to <dynamic_hosts> keep state

# Allow DNS server to access WireGuard for traffic
pass in on vio0 proto udp from $internal_dns_server to (vio0) port $wireguard_port keep state
pass out on vio0 proto udp from (vio0) port $wireguard_port to $internal_dns_server keep state

# Allow all traffic between WireGuard interface (wg0) and WireGuard network
pass in on $wireguard_iface from $wireguard_net to any
pass out on $wireguard_iface from any to $wireguard_net

# ---- Ensure Return Traffic ----

# Ensure return traffic from internal server to WireGuard clients is handled properly
pass in on $wireguard_iface proto tcp from $final_backend_server to any keep state
pass out on vio0 proto tcp from $final_backend_server to any keep state

Skript to add the dynamic hosts

  • Important: All your clients will need to get FQDNs, and you can do that by adding for example containers in your home, work etc, that use tools like ddclient + any DYNDNS-hoster.
  • Next, Ensure you replace hoster1 + hoster2 with your actual domains to allow dynamic access from.
  • The script below will access the FQDN and add it to the firewall ruletable for access.

I've deployed the following script on /usr/local/getpara.sh it creates temp_gotten_para as well as gotten-para which contains the dynamic IPs to be added to the firewall for access.

#!/bin/sh

# FQDNs
FQDN1="myhost1.hoster1.org"
FQDN2="myhost2.hoster2.org"

# Define variables
WORK_DIR="/usr/local"
TEMP_IP_FILE="$WORK_DIR/temp_gotten_para"
FINAL_IP_FILE="$WORK_DIR/gotten-para"
LOG_FILE="$WORK_DIR/firewall_update.log"
MAX_IP_COUNT=2  # Adjusted if needed to allow more IPs
IP_RETENTION_DAYS=2

# Setup and cleanup environment
if [ ! -f "$TEMP_IP_FILE" ]; then
    echo "Creating $TEMP_IP_FILE as it does not exist."
    touch "$TEMP_IP_FILE"
fi

# Function to log messages with timestamps
log() {
    echo "$(date "+%Y-%m-%d %H:%M:%S") - $1" >> "$LOG_FILE"
}

# Function to validate an IP address
is_valid_ip() {
    local ip=$1
    if echo "$ip" | grep -Eq "^([0-9]{1,3}\.){3}[0-9]{1,3}$"; then
        return 0
    else
        return 1
    fi
}

# Function to resolve IP addresses and avoid duplicates
resolve_ip() {
    local FQDN=$1
    log "Resolving IP address for $FQDN"
    # Resolve the current IP address of the FQDN
    CURRENT_IP=$(dig +short $FQDN | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}')
    CURRENT_TIMESTAMP=$(date +%s)

    # Exit if no valid IP is resolved
    if [ -z "$CURRENT_IP" ] || ! is_valid_ip "$CURRENT_IP"; then
        log "No valid IP address found for $FQDN"
        return
    fi

    # Check if the IP already exists in the TEMP_IP_FILE to avoid duplicates
    if ! grep -q "$CURRENT_IP" "$TEMP_IP_FILE"; then
        # Append current IP with timestamp to TEMP_IP_FILE for processing
        echo "$CURRENT_TIMESTAMP $CURRENT_IP" >> "$TEMP_IP_FILE"
        log "Added IP $CURRENT_IP to $TEMP_IP_FILE"
    else
        log "IP $CURRENT_IP already exists in $TEMP_IP_FILE, not adding again."
    fi
}

# Ensure FINAL_IP_FILE exists
if [ ! -f "$FINAL_IP_FILE" ]; then
    echo "Creating $FINAL_IP_FILE as it does not exist."
    touch "$FINAL_IP_FILE"
fi

# Resolve IPs for both FQDNs
resolve_ip $FQDN1
resolve_ip $FQDN2

# Process TEMP_IP_FILE to ensure uniqueness, limit the number of IPs, and consider the retention period
log "Processing $TEMP_IP_FILE to update $FINAL_IP_FILE"
awk -v max_count=$MAX_IP_COUNT -v retention_days=$IP_RETENTION_DAYS -v current_time=$(date +%s) '{
    timestamp = $1
    ip = $2
    if (!seen[ip]++ && (current_time - timestamp) <= (retention_days * 86400)) {
        print ip
        if (++count >= max_count) exit
    }
}' "$TEMP_IP_FILE" | sort -u | tail -n $MAX_IP_COUNT > "$FINAL_IP_FILE"

# Cleanup old entries from TEMP_IP_FILE
log "Cleaning up old entries from $TEMP_IP_FILE"
awk -v current_time=$(date +%s) -v retention_days=$IP_RETENTION_DAYS '{
    timestamp = $1
    if ((current_time - timestamp) <= (retention_days * 86400)) {
        print $0
    }
}' "$TEMP_IP_FILE" > "${TEMP_IP_FILE}.tmp" && mv "${TEMP_IP_FILE}.tmp" "$TEMP_IP_FILE"

# Check if there are any changes
if [ "$(wc -l < "$FINAL_IP_FILE")" -eq 0 ]; then
    log "No changes."
else
    # Reload the PF table with the updated IP list
    log "Reloading PF table 'dynamic_hosts' with updated IP list from $FINAL_IP_FILE"
    pfctl -t dynamic_hosts -T replace -f "$FINAL_IP_FILE" && log "PF table 'dynamic_hosts' reloaded with updated IP list."

    # Output the contents of the PF table
    log "Contents of PF table 'dynamic_hosts':"
    pfctl -t dynamic_hosts -T show >> "$LOG_FILE"
fi

# Log completion message
log "Firewall update complete."

Wireguards

  • After you installed the package via pkg_add wireguard-tools,your gateways wg0.conf looks like this on /etc/wireguard/wg0.confand you can trigger restarts for the interface like wg-quick down wg0 && sleep 5 && wg-quick up wg0.
  • You generate client priv and pub keys via sh -c 'umask 077; wg genkey | tee privatekey | wg pubkey > publickey'
  • You can have your entire infrastructure within nested wireguards, increasing trust per interface

Server side:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = gateways-private-key

[Peer]
PublicKey = publickey-client1
AllowedIPs = 10.0.0.2/32

[Peer]
PublicKey = publickey-client-2
AllowedIPs = 10.0.0.3/32

Client side:

[Interface]
PrivateKey = client-private-key
#DNS=10.0.0.1
Address = 10.0.0.2/24
#ListenPort=

[Peer]
PublicKey =  server-pubkey
AllowedIPs = 10.0.0.0/24
Endpoint = public-gateway-ip:51820
PersistentKeepalive = 15
  • Congrats, You arere already done at this point, you only allow static IPs to connect, everything else is inside a VPN tunnel that only allows connecting from whitelisted fqdns!
  • Always room for improvement, add encrypted DNS, as well as an addblocker

Optional DNS

Option 1: ODOH via Cloudflare

  • You work on /etc/dnscrypt-proxy.toml

  • Use the Guide from here: SwaroopGiri: (https://github.com/SwaroopGiri/Pihole-with-Anonymized-ODOH)

  • The DNScrypt runs at 127.0.0.1@54, which Unbound at 127.0.0.1@53 will just forward requests to, while only accessible from Wireguard clients:

  • Here is how you add the dnscrypt proxy package and check paths, plus how to do restarts and enabling of it

pkg_add dnscrypt-proxy
pkg_info -L dnscrypt-proxy
...
rcctl enable dnscrypt_proxy
rcctl restart unbound
rcctl restart dnscrypt_proxy
  • Important settings from the guide :
server_names = ['odoh-cloudflare']
odoh_servers = true
require_dnssec = true   
require_nofilter = true # this parameter depends on your relay selected next
cache = false   
  • Enable sources:
[sources.odoh-servers]
   urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-servers.md', 'https://download.dnscrypt.info/resolvers-list/v3/odoh-servers.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/odoh-servers.md']
   cache_file = 'odoh-servers.md'
   minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
   refresh_delay = 24
   prefix = ''
[sources.odoh-relays]
   urls = ['https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/odoh-relays.md', 'https://download.dnscrypt.info/resolvers-list/v3/odoh-relays.md', 'https://ipv6.download.dnscrypt.info/resolvers-list/v3/odoh-relays.md']
   cache_file = 'odoh-relays.md'
   minisign_key = 'RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3'
   refresh_delay = 24
   prefix = ''
routes = [
     { server_name='odoh-cloudflare', via=['odohrelay-your-pick1', 'oodohrelay-your-pick2'] },
     { server_name='odohrelay-koki-ams', via=['odohrelay-koki-ams', 'odohrelay-koki-bcn'] }
 ]

Unbound for ODoH

  • We use Unbound for DNs, the config is at /var/unbound/etc/unbound.conf
  • The config is as simple as forwarding to the dnscrypt, uncomment the rest
server:
	interface: 0.0.0.0@53
	do-ip6: no
	access-control: 10.0.0.0/24 allow
	access-control: 0.0.0.0/0 refuse
	access-control: ::0/0 refuse
	
	forward-zone:
    		name: "."
        	forward-addr: 127.0.0.1@54

#Include the blocklist for ads
include: "/home/lowpriv_user/blacklist.conf"

Option 2: DOT via Quad9

  • We use Unbound for DoT and can skip dnscrypt, the config is at /var/unbound/etc/unbound.conf
# example config from: https://nurdletech.com/linux-notes/dns/unbound.html
server:
	interface: 0.0.0.0@53
	#interface: 127.0.0.1@5353	# listen on alternative port
	#interface: ::1
	do-ip6: no
#	do-udp: yes
#	do-tcp: yes
	
	auto-trust-anchor-file: "/var/unbound/db/root.key"
	tls-cert-bundle: "/etc/ssl/cert.pem"

	access-control: 10.0.0.0/24 allow
	access-control: 0.0.0.0/0 refuse
	access-control: ::0/0 refuse

	forward-zone:
    		name: "."
		forward-tls-upstream: yes		# use DNS-over-TLS forwarder
# 	hide-identity: yes
#	hide-version: yes

        # Cloudflare pick
	#	forward-addr: 1.1.1.1@53
	#	forward-addr: 2606:4700:4700::1111@853#cloudflare-dns.com
  	#       forward-addr: 1.1.1.1@853#cloudflare-dns.com
 	#	forward-addr: 2606:4700:4700::1001@853#cloudflare-dns.com
    	#	forward-addr: 1.0.0.1@853#cloudflare-dns.com
        # Quad9 pick
	       forward-addr: 2620:fe::fe@853#dns.quad9.net
	       forward-addr: 9.9.9.9@853#dns.quad9.net
	       forward-addr: 2620:fe::9@853#dns.quad9.net
	       forward-addr: 149.112.112.112@853#dns.quad9.net

 # Include the blocklist for ads
include: "/home/lowpriv_user/blacklist.conf"
  • In case you still need to generate the key:
unbound-anchor -a /var/unbound/db/root.key

Optional Linux side for dynamic IP adding

  • Here is the same /usr/local/getpara.sh but adjusted for Linux:
#!/bin/bash

# FQDNs
FQDN1="myhost1.mydnsprovider.com"
FQDN2="myhost2.mydnsprovider.com"

# Variables
WORK_DIR="/usr/local"
TEMP_IP_FILE="$WORK_DIR/temp_gotten_para"
FINAL_IP_FILE="$WORK_DIR/gotten-para"
LOG_FILE="$WORK_DIR/firewall_update.log"

MAX_IP_COUNT=2
IP_RETENTION_DAYS=2
IP_SET_NAME="dynamic_hosts"
PUBLIC_ZONE="public"
WIREGUARD_PORT="51820"  # WireGuard port for the public interface

# Setup and cleanup environment
> "$TEMP_IP_FILE"
> "$FINAL_IP_FILE"
touch "$LOG_FILE"
exec 3>&1 1>>"$LOG_FILE" 2>&1

log() {
    echo "$(date "+%Y-%m-%d %H:%M:%S") - $1"
}

execute_command() {
    echo "Executing command: ${*}" >&3
    "${@}"
    local status=$?
    if [ $status -ne 0 ]; then
        log "ERROR: Failed to execute: ${*}"
        exit $status
    else
        log "SUCCESS: Executed: ${*}"
    fi
}

ensure_files_exist() {
    touch "$1" 2>/dev/null || {
        log "Failed to touch $1. Check permissions."
        exit 1
    }
}

ensure_files_exist "$TEMP_IP_FILE"
ensure_files_exist "$FINAL_IP_FILE"

resolve_ip() {
    local FQDN=$1
    local CURRENT_IP=$(dig +short "$FQDN" | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}$')
    local CURRENT_TIMESTAMP=$(date +%s)

    if [ -z "$CURRENT_IP" ]; then
        log "No valid IP address found for $FQDN"
        return 1
    fi

    if ! grep -q "$CURRENT_TIMESTAMP $CURRENT_IP" "$TEMP_IP_FILE"; then
        echo "$CURRENT_TIMESTAMP $CURRENT_IP" >> "$TEMP_IP_FILE"
        log "Added IP $CURRENT_IP to $TEMP_IP_FILE"
    else
        log "Duplicate IP entry for $CURRENT_IP at $CURRENT_TIMESTAMP skipped"
    fi
}

if ! resolve_ip $FQDN1; then
    log "Failed to resolve $FQDN1"
fi

if ! resolve_ip $FQDN2; then
    log "Failed to resolve $FQDN2"
fi

log "Processing $TEMP_IP_FILE to update $FINAL_IP_FILE"
awk -v max_count=$MAX_IP_COUNT -v retention_days=$IP_RETENTION_DAYS -v current_time=$(date +%s) '{
    ip = $2
    timestamp = $1
    if (!seen[ip]++ && (current_time - timestamp) <= (retention_days * 86400)) {
        print ip
        if (++count >= max_count) exit
    }
}' "$TEMP_IP_FILE" | sort -u | tail -n $MAX_IP_COUNT > "$FINAL_IP_FILE"

if [ -s "$FINAL_IP_FILE" ]; then
    log "Final IP file contains valid entries."
else
    log "No valid IPs resolved. Exiting script."
    exit 0
fi

log "Current IP set entries before deletion:"
firewall-cmd --ipset=$IP_SET_NAME --get-entries >> "$LOG_FILE" 2>/dev/null || log "IP set not found."

if firewall-cmd --permanent --get-ipsets | grep -qw "$IP_SET_NAME"; then
    log "Deleting IP set $IP_SET_NAME"
    execute_command firewall-cmd --permanent --delete-ipset=$IP_SET_NAME
else
    log "IP set $IP_SET_NAME does not exist, creating a new one."
fi

execute_command firewall-cmd --permanent --new-ipset=$IP_SET_NAME --type=hash:ip

log "Adding IPs to the new IP set"
for ip in $(cat "$FINAL_IP_FILE"); do
    execute_command firewall-cmd --permanent --ipset=$IP_SET_NAME --add-entry=$ip
done

log "Enabling WireGuard service in the public zone"
if ! firewall-cmd --permanent --zone="$PUBLIC_ZONE" --query-port="$WIREGUARD_PORT"/udp; then
    execute_command firewall-cmd --permanent --zone="$PUBLIC_ZONE" --add-port="$WIREGUARD_PORT"/udp
fi

execute_command firewall-cmd --reload

log "Firewall and WireGuard rules updated with latest IPs."

exec 1>&3 3>&-
echo "Firewall update complete. See $LOG_FILE for details."

  • In case we wanna confirm para entries:
firewall-cmd --ipset=dynamic_hosts --get-entries
  • In case we wanna remove entries:
firewall-cmd --ipset=dynamic_hosts --get-entries | xargs -I{} firewall-cmd --permanent --ipset=dynamic_hosts --remove-entry={} && firewall-cmd --reload
  • We need to also add this to the cronjob of the Linux server, for example on reboot and 12 hours:
@reboot /bin/sleep 30 && /usr/local/getpara.sh
0 0,12 * * * /usr/local/getpara.sh

Optional Addblocking

  • Reference on the top to the original one, I only care about OpenBSD and want this to be ran on a lowpriv user for it!
  • Please add your own custom lists, I prefer to not show mine!
  • You could save this at /home/lowpriv_user/blocklister.sh with an own account on a user named lowpriv_user
  • Get the lowpriv_user to run this daily, unbound has an include for it.
#!/bin/sh


# This script is based on the version of 2020 Slawomir Wojciech Wojtczak (vermaden) found here:
# https://github.com/vermaden/scripts/blob/master/unbound-blacklist-fetch-huge.sh

# My version is smaller and doesn't need to be ran as root
# I am not leaking my favourite ad lists, there are plenty good ones


# SETTINGS
TYPE=always_nxdomain
TEMP="/home/lowpriv_user/unbound_temp"
ECHO=1
FILE="/home/lowpriv_user/blacklist.conf"
TEMP_FILE="/lowpriv_user/temp_blacklist.conf"

# Create temp directory
[ "${ECHO}" != "0" ] && echo "mkdir: create '${TEMP}' temp dir"
mkdir -p ${TEMP}

# FETCH add lists you can add multiple you like or use pihole or adguard, but why not make some pre filtering on a low priv user

[ "${ECHO}" != "0" ] && echo "fetch: ${TEMP}/lists-domains"
curl -s 'https://your-1st-list.txt' \
     'https://your-snd-list.txt' \
     'https://your-trd-list.txt' \
     'https://your-fourth-list.txt' \
     'https://your-fifth-list.txt/ ' \
     > "${TEMP}/lists-domains"


# GENERATE CONFIG
[ "${ECHO}" != "0" ] && echo "echo: add '${FILE}' header"
echo 'server:' > ${FILE}

[ "${ECHO}" != "0" ] && echo "echo: add '${FILE}' rules"
cat "${TEMP}/lists-domains" \
  | grep -v '^(.)*#' -E \
  | grep -v '^#' \
  | grep -v '^$' \
  | grep -v '^!' \
  | awk '{print $1}' \
  | sed -e s/$'\r'//g \
        -e 's/^\|\|//' \
        -e 's/\^$//' \
        -e 's/^\|//' \
        -e '/^\/.*\/$/d' \
        -e '/https?:\/\//d' \
        -e 's|\.$||g' \
        -e 's|^\.||g' \
  | grep -v -e '127.0.0.1' \
            -e '0.0.0.0' \
            -e '255.255.255.255' \
            -e '::' \
            -e 'localhost' \
            -e 'localhost.localdomain' \
            -e 'ip6-localhost' \
            -e 'ip6-loopback' \
            -e 'ip6-localnet' \
            -e 'ip6-mcastprefix' \
            -e 'ip6-allnodes' \
            -e 'ip6-allrouters' \
            -e 'broadcasthost' \
            -e 'ff02::' \
  | tr '[:upper:]' '[:lower:]' \
  | tr -d '\r' \
  | tr -d '#' \
  | sort -u \
  | sed 1,2d \
  | while read I; do
      echo "local-zone: \"${I}\" ${TYPE}"
    done > ${TEMP_FILE} 2>"${TEMP}/debug-errors.txt"

# Remove duplicate entries and ensure file starts with 'server:'
echo 'server:' > ${FILE}
sort ${TEMP_FILE} | uniq >> ${FILE}
rm -f ${TEMP_FILE}

# REMINDER FOR MANUAL ACTION
[ "${ECHO}" != "0" ] && echo "Reminder: Manually check the unbound configuration with 'unbound-checkconf ${FILE}' and, if valid, restart the unbound service with appropriate permissions."

# CLEAN
[ "${ECHO}" != "0" ] && echo "rm: remove '${TEMP}' temp dir BUT keep debug files"
rm -rf ${TEMP}/lists-domains

# UNSET
unset FILE
unset TYPE
unset TEMP
unset ECHO
unset UNAME
  • This should be now ran as the lowpriv_user in a crontab for getting the blocklists:
0 0 * * * /home/lowpriv_user/blocklister.sh

Much love if you read until here

About

My config files for rolling entire infrastructures behind OpenBSD gateways which can only be accessed if on whitelists.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published