Experimenting with setting up a Squid web proxy on OPNsense

I’m experimenting with setting up a Squid web proxy on OPNsense, aiming to replicate the kind of setup we previously had on NS7, but without relying on multiple extra servers.

Right now I’ve got internet routing through OPNsense, and my goal is to integrate SSO so that when domain-joined users log in with their credentials, the proxy applies category-based filtering. I’ve added some custom logic to pull down a blacklist, expose categories via dropdown menus, and push the selection into Redis for performance. Antivirus/malware scanning is also layered on top.

For devices that can’t or don’t authenticate (like TVs, IoT gear, or guest clients that are explicitly allowed), the proxy should still provide antivirus and malware filtering, but skip the category filtering and instead allow unrestricted internet access.

I’ll post more details as I work through the remaining issues, but I thought I’d share one small win: since the samba-tool commands get quite long, I put together a wrapper script to make them easier to use. It’s been handy while iterating on this setup.

NS8 Samba Wrapper for Rocky Linux

This script provides a unified wrapper for managing Samba AD DC running inside an NS8 container.
It simplifies common operations like restarting the container, running samba-tool, opening a shell, and copying files in/out.


Installation

sudo tee /usr/local/bin/samba >/dev/null <<'EOF'
#!/usr/bin/env bash
# Unified wrapper for Samba DC in NS8 containers via runagent.

# --- Defaults (lowest precedence) ---
RUNAGENT_MODULE="${RUNAGENT_MODULE:-samba1}"
CONTAINER_NAME="${CONTAINER_NAME:-samba-dc}"
DEFAULT_AD_DOMAIN="${DEFAULT_AD_DOMAIN:-}"

# --- Load config (medium precedence) ---
if [ -r /etc/samba-wrapper.conf ]; then
  . /etc/samba-wrapper.conf
fi
if [ -r "${HOME}/.config/samba-wrapper.conf" ]; then
  . "${HOME}/.config/samba-wrapper.conf"
fi

# --- ENV vars (highest precedence) ---
tty_flags="-i"
if [ -t 0 ] && [ -t 1 ]; then
  tty_flags="-ti"
fi

in_dc() {
  runagent -m "$RUNAGENT_MODULE" podman exec $tty_flags "$CONTAINER_NAME" "$@"
}

prog="$(basename "$0")"
if [[ "$prog" == "samba-tool" ]]; then
  if [[ -n "${SAMBA_TOOL_LOCAL:-}" ]]; then
    exec /usr/bin/samba-tool "$@"
  fi
  exec in_dc samba-tool "$@"
fi

usage() {
  cat <<USAGE
Usage:
  samba restart                    # restart container
  samba start|stop                 # start/stop container
  samba status                     # brief status
  samba logs [-f]                  # container logs
  samba exec <cmd> [args...]       # run arbitrary command inside container
  samba sh                         # shell (bash if present, else sh)
  samba bash                       # force bash
  samba tool <args...>             # run "samba-tool <args>" inside container
  samba cp <c_path> <host_path>    # copy FROM container to host
  samba cpto <host_path> <c_path>  # copy FROM host to container
  samba domain-info [DOMAIN]       # run "samba-tool domain info DOMAIN"

Config precedence:
  1) ENV at call-time (highest)      
  2) ~/.config/samba-wrapper.conf
  3) /etc/samba-wrapper.conf
  4) Built-in defaults (lowest)

Current config:
  RUNAGENT_MODULE=$RUNAGENT_MODULE
  CONTAINER_NAME=$CONTAINER_NAME
  DEFAULT_AD_DOMAIN=$DEFAULT_AD_DOMAIN
USAGE
}

subcmd="$1"; shift || true
case "$subcmd" in
  restart)   exec runagent -m "$RUNAGENT_MODULE" podman restart "$CONTAINER_NAME";;
  start|stop) exec runagent -m "$RUNAGENT_MODULE" podman "$subcmd" "$CONTAINER_NAME";;
  status)    exec runagent -m "$RUNAGENT_MODULE" podman ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' --filter "name=${CONTAINER_NAME}";;
  logs)      exec runagent -m "$RUNAGENT_MODULE" podman logs "$@" "$CONTAINER_NAME";;
  exec)      exec in_dc "$@";;
  sh)        in_dc bash -l 2>/dev/null || exec in_dc sh -l;;
  bash)      exec in_dc bash;;
  tool)      exec in_dc samba-tool "$@";;
  domain-info)
    domain="$1"
    if [[ -z "$domain" ]]; then
      if [[ -z "$DEFAULT_AD_DOMAIN" ]]; then
        echo "Error: No domain specified and DEFAULT_AD_DOMAIN not set." >&2
        exit 1
      fi
      domain="$DEFAULT_AD_DOMAIN"
    fi
    exec in_dc samba-tool domain info "$domain"
    ;;
  cp)        exec runagent -m "$RUNAGENT_MODULE" podman cp "${CONTAINER_NAME}:$1" "$2";;
  cpto)      exec runagent -m "$RUNAGENT_MODULE" podman cp "$1" "${CONTAINER_NAME}:$2";;
  ""|-h|--help|help) usage;;
  *) echo "Unknown command: $subcmd" >&2; usage; exit 1;;
esac
EOF

sudo chmod +x /usr/local/bin/samba
if [ ! -e /usr/local/bin/samba-tool ]; then
  sudo ln -s /usr/local/bin/samba /usr/local/bin/samba-tool
fi

Config File

You can set defaults in /etc/samba-wrapper.conf (system-wide) or ~/.config/samba-wrapper.conf (per-user).

Example:

# /etc/samba-wrapper.conf

RUNAGENT_MODULE="samba1"
CONTAINER_NAME="samba-dc"
DEFAULT_AD_DOMAIN="example.lan"

Examples

# Different module/container
RUNAGENT_MODULE=samba2 CONTAINER_NAME=samba-dc-2 samba status

# Restart DC
samba restart

# Logs
samba logs -f

# Shell
samba bash
samba sh

# Samba-tool
samba tool domain level show
samba domain-info                # uses DEFAULT_AD_DOMAIN if set
samba domain-info your.domain.lan

# File copies
samba cp /tmp/somefile /root/somefile
samba cpto /root/local.conf /etc/samba/local.conf

# Use host samba-tool instead of container
SAMBA_TOOL_LOCAL=1 samba-tool --version
3 Likes