How to temporarily open a TCP port in NixOS?

If you’re trying to avoid typing in a password just to enable or disable the firewall rule, you can use a script to temporarily enable the port.

# file: ~/bin/run-with-port

#!/usr/bin/env bash
# Usage: sudo run-with-port <port> <cmd> <args...>

set -ueo pipefail

open-port() {
  local port=$1
  iptables -A INPUT -p tcp --dport $port -j ACCEPT
}

close-port() {
  local port=${1:-0}
  iptables -D INPUT -p tcp --dport $port -j ACCEPT
}


if [[ -z "$1" ]]; then
  echo "Port not given" >&2
  exit 1
fi

PORT=$1
shift;  # Drop port argument

if [[ 0 -eq $# ]]; then
  echo "No command given" >&2
  exit 1
fi

open-port $PORT

# Ensure port closes if error occurs.
trap "close-port $PORT" EXIT

# Run the command as user, not root.
runuser -u $SUDO_USER -- "$@"

# Trap will close port.

I just wrote this, tested that it opens and closes the port, but not much more thoroughly than that.

You can update your sudoer config to allow running the run-with-port script without a password, and you now have:

  1. No need to type password to open port.
  2. Can run any single command while port is open.
  3. Port is closed after command stops, even if command errors.
4 Likes