From 381d09592b5e297fe51295e4ffb492b404fe1ab2 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 9 Dec 2024 16:53:37 -0700 Subject: [PATCH 001/100] Allow setting custom interface when doing "rdr" --- usr/local/share/bastille/rdr.sh | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 6bd7fbcd..1b25e930 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -81,16 +81,17 @@ check_jail_validity() { fi fi - # Check if rdr-anchor is defined in pf.conf if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then error_exit "rdr-anchor not found in pf.conf" fi # Check if ext_if is defined in pf.conf + # If EXT_IF is set, use it instead of the default if [ -n "${bastille_pf_conf}" ]; then - EXT_IF=$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf}) if [ -z "${EXT_IF}" ]; then + EXT_IF=$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf}) + else error_exit "bastille_network_pf_ext_if (${bastille_network_pf_ext_if}) not defined in pf.conf" fi fi @@ -98,8 +99,8 @@ check_jail_validity() { # function: write rule to rdr.conf persist_rdr_rule() { -if ! grep -qs "$1 $2 $3" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$1 $2 $3" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" +if ! grep -qs "$IF_NAME $1 $2 $3" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$IF_NAME $1 $2 $3" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" fi } @@ -107,8 +108,8 @@ persist_rdr_log_rule() { proto=$1;host_port=$2;jail_port=$3; shift 3; log=$@; -if ! grep -qs "$proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" +if ! grep -qs "$IF_NAME $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$IF_NAME $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" fi } @@ -142,6 +143,12 @@ fi } while [ $# -gt 0 ]; do + # Check if interface was specified, and use it instead of default + if echo "${1}" | ifconfig | grep -wo "${1}"; then + IF_NAME="${1}" + EXT_IF=ext_if="${1}" + shift + fi case "$1" in list) if [ "${TARGET}" = 'ALL' ]; then From dc9822a01317e652a8a4262138574369684d0a9c Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:01:17 -0700 Subject: [PATCH 002/100] also list interface when doing "list all" for published ports --- usr/local/share/bastille/list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index ebb28cc4..211f2f99 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -108,7 +108,7 @@ list_all(){ if [ "${JAIL_IP}" = "-" ]; then JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip6.addr 2> /dev/null); fi fi JAIL_HOSTNAME=$(/usr/sbin/jls -j ${JAIL_NAME} host.hostname 2> /dev/null) - JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s/%s:%s"",",$7,$14,$18 }' | sed "s/,$//") + JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s %s/%s:%s"",",$4,$7,$14,$18 }' | sed "s/,$//") JAIL_PATH=$(/usr/sbin/jls -j ${JAIL_NAME} path 2> /dev/null) if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then JAIL_RELEASE=$(jexec -l ${JAIL_NAME} freebsd-version -u 2> /dev/null) From 1c807bbef98507707815b30ffb55cdaf5644a4fc Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:26:44 -0700 Subject: [PATCH 003/100] Add docs about RDR multiple interfaces --- docs/chapters/subcommands/rdr.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index a65375a2..ac7af3c6 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -24,3 +24,17 @@ specify the interface they run on in rc.conf (or other config files) rdr on em0 inet proto udp from any to any port = 2053 -> 10.17.89.1 port 53 # bastille rdr dev1 clear nat cleared + +If you have a host with multiple interfaces, and you want to specify which +one to use, `bastille rdr` allows you to pass any interface to the command. +If you do not specify an interface, the default one will be used. + +.. code-block:: shell + + # bastille rdr em0 dev1 tcp 2001 22 + # bastille rdr dev1 list + rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 + # bastille rdr dev1 vtnet0 udp 2053 53 + # bastille rdr dev1 list + rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 + rdr on vtnet0 inet proto udp from any to any port = 2053 -> 10.17.89.1 port 53 From 2b6a7e83f940a564c34581696708641a2fba24c2 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 9 Dec 2024 17:58:55 -0700 Subject: [PATCH 004/100] add new interface option to docs --- docs/chapters/subcommands/rdr.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index ac7af3c6..8a6e2fd0 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -14,7 +14,7 @@ specify the interface they run on in rc.conf (or other config files) .. code-block:: shell # bastille rdr --help - Usage: bastille rdr TARGET [clear] | [list] | [tcp ] | [udp ] + Usage: bastille rdr TARGET [clear] | [list] | [ tcp ] | [ udp ] # bastille rdr dev1 tcp 2001 22 # bastille rdr dev1 list rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 From bafa183b08a92fc27f96c011e5ff402f7add804e Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:27:08 -0700 Subject: [PATCH 005/100] remove unecessary "echo" --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 1b25e930..92f6d4ab 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -144,7 +144,7 @@ fi while [ $# -gt 0 ]; do # Check if interface was specified, and use it instead of default - if echo "${1}" | ifconfig | grep -wo "${1}"; then + if ifconfig | grep -wo "${1}"; then IF_NAME="${1}" EXT_IF=ext_if="${1}" shift From eb65800a0cd5b345bd202fce911cb88f85ab35a4 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 9 Dec 2024 22:02:01 -0700 Subject: [PATCH 006/100] show output when creating rdr rule --- usr/local/share/bastille/rdr.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 92f6d4ab..24733628 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -124,6 +124,9 @@ if [ -n "$JAIL_IP6" ]; then printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$2" "$JAIL_IP6" "$3" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- fi +local interface="$( echo $EXT_IF | awk -F'"' '{print $2}')" +info "[${JAIL_NAME}]:" +info "Redirecting: ${1} port ${2} to ${3} on ${interface}" } # function: load rdr rule with log via pfctl @@ -139,14 +142,16 @@ if [ -n "$JAIL_IP6" ]; then printf '%s\nrdr pass %s on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "${bastille_network_pf_ext_if}" "$proto" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- fi - +local interface="$( echo $EXT_IF | awk -F'"' '{print $2}')" +info "[${JAIL_NAME}]:" +info "Redirecting: ${1} port ${2} to ${3} on ${interface}" } while [ $# -gt 0 ]; do # Check if interface was specified, and use it instead of default if ifconfig | grep -wo "${1}"; then IF_NAME="${1}" - EXT_IF=ext_if="${1}" + EXT_IF=ext_if=\"${1}\" shift fi case "$1" in From 622d84b6be69f6f505ca31ab708e262da425f30a Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:45:06 -0700 Subject: [PATCH 007/100] allow specifying IP to redirect traffic to This is for the folks who have multiple IP addresses on a single interface. --- usr/local/share/bastille/rdr.sh | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 24733628..666d0666 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -99,8 +99,8 @@ check_jail_validity() { # function: write rule to rdr.conf persist_rdr_rule() { -if ! grep -qs "$IF_NAME $1 $2 $3" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$IF_NAME $1 $2 $3" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" +if ! grep -qs "$IF_NAME $RDR_DST $1 $2 $3" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$IF_NAME $RDR_DST $1 $2 $3" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" fi } @@ -108,25 +108,28 @@ persist_rdr_log_rule() { proto=$1;host_port=$2;jail_port=$3; shift 3; log=$@; -if ! grep -qs "$IF_NAME $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$IF_NAME $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" +if ! grep -qs "$IF_NAME $RDR_DST $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$IF_NAME $RDR_DST $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" fi } - # function: load rdr rule via pfctl load_rdr_rule() { ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$2" "$JAIL_IP" "$3" ) \ + printf '%s\nrdr pass on $%s inet proto %s from any to %s port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$RDR_DST" "$2" "$JAIL_IP" "$3" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- if [ -n "$JAIL_IP6" ]; then ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$2" "$JAIL_IP6" "$3" ) \ + printf '%s\nrdr pass on $%s inet proto %s from any to %s port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$RDR_DST" "$2" "$JAIL_IP6" "$3" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- fi local interface="$( echo $EXT_IF | awk -F'"' '{print $2}')" info "[${JAIL_NAME}]:" -info "Redirecting: ${1} port ${2} to ${3} on ${interface}" +if [ "${RDR_DST}" != "any" ]; then + info "Redirecting: ${1} port ${2} to ${3} on ${interface}:${RDR_DST}" +else + info "Redirecting: ${1} port ${2} to ${3} on ${interface}" +fi } # function: load rdr rule with log via pfctl @@ -149,11 +152,19 @@ info "Redirecting: ${1} port ${2} to ${3} on ${interface}" while [ $# -gt 0 ]; do # Check if interface was specified, and use it instead of default + # Set default RDR rule to "any to any" + RDR_DST="any" if ifconfig | grep -wo "${1}"; then - IF_NAME="${1}" - EXT_IF=ext_if=\"${1}\" + IF_NAME="${1}" + EXT_IF=ext_if=\"${1}\" + shift + # Check if IP was specified for given interface + if ifconfig | grep -o "inet ${1}"; then + RDR_DST="${1}" shift + fi fi + case "$1" in list) if [ "${TARGET}" = 'ALL' ]; then From 471a91ca248bc91af85fab4fd59548f3e215c54d Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 10 Dec 2024 18:46:36 -0700 Subject: [PATCH 008/100] print IP in addition to interface when listing RDR --- usr/local/share/bastille/list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 211f2f99..e7d09e2c 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -108,7 +108,7 @@ list_all(){ if [ "${JAIL_IP}" = "-" ]; then JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip6.addr 2> /dev/null); fi fi JAIL_HOSTNAME=$(/usr/sbin/jls -j ${JAIL_NAME} host.hostname 2> /dev/null) - JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s %s/%s:%s"",",$4,$7,$14,$18 }' | sed "s/,$//") + JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s:%s %s/%s:%s"",",$4,$11,$7,$14,$18 }' | sed "s/,$//") JAIL_PATH=$(/usr/sbin/jls -j ${JAIL_NAME} path 2> /dev/null) if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then JAIL_RELEASE=$(jexec -l ${JAIL_NAME} freebsd-version -u 2> /dev/null) From 035855bf018d8e1b4eb4b3153d6bd2ea43ab06f1 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 10:57:07 -0700 Subject: [PATCH 009/100] major rewrite to allow setting TO+FROM --- usr/local/share/bastille/rdr.sh | 131 ++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 42 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 666d0666..3028ac03 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -53,6 +53,9 @@ JAIL_NAME="" JAIL_IP="" JAIL_IP6="" EXT_IF="" +RDR_IF="" +RDR_SRC="" +RDR_DST="" shift check_jail_validity() { @@ -99,71 +102,108 @@ check_jail_validity() { # function: write rule to rdr.conf persist_rdr_rule() { -if ! grep -qs "$IF_NAME $RDR_DST $1 $2 $3" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$IF_NAME $RDR_DST $1 $2 $3" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + local if="${1}" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" +if ! grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" fi } persist_rdr_log_rule() { -proto=$1;host_port=$2;jail_port=$3; -shift 3; + local if="${1}" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" +shift 6; log=$@; -if ! grep -qs "$IF_NAME $RDR_DST $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$IF_NAME $RDR_DST $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" +if ! grep -qs "$if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" fi } # function: load rdr rule via pfctl load_rdr_rule() { -( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass on $%s inet proto %s from any to %s port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$RDR_DST" "$2" "$JAIL_IP" "$3" ) \ + local if=ext_if=\"${1}\" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" +( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; + printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- if [ -n "$JAIL_IP6" ]; then - ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass on $%s inet proto %s from any to %s port %s -> %s port %s\n' "$EXT_IF" "${bastille_network_pf_ext_if}" "$1" "$RDR_DST" "$2" "$JAIL_IP6" "$3" ) \ +( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- fi -local interface="$( echo $EXT_IF | awk -F'"' '{print $2}')" info "[${JAIL_NAME}]:" -if [ "${RDR_DST}" != "any" ]; then - info "Redirecting: ${1} port ${2} to ${3} on ${interface}:${RDR_DST}" -else - info "Redirecting: ${1} port ${2} to ${3} on ${interface}" -fi +info "Redirecting:" +info "${src}:${host_port} -> ${dst}:${jail_port} on ${1}" } # function: load rdr rule with log via pfctl load_rdr_log_rule() { -proto=$1;host_port=$2;jail_port=$3; -shift 3; + local if=ext_if=\"${1}\" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" +shift 6; log=$@ ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass %s on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "${bastille_network_pf_ext_if}" "$proto" "$host_port" "$JAIL_IP" "$jail_port" ) \ + printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- if [ -n "$JAIL_IP6" ]; then ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass %s on $%s inet proto %s to port %s -> %s port %s\n' "$EXT_IF" "$log" "${bastille_network_pf_ext_if}" "$proto" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f- fi -local interface="$( echo $EXT_IF | awk -F'"' '{print $2}')" info "[${JAIL_NAME}]:" -info "Redirecting: ${1} port ${2} to ${3} on ${interface}" +info "Redirecting:" +info "${src}:${host_port} -> ${dst}:${jail_port} on ${1}" } + while [ $# -gt 0 ]; do - # Check if interface was specified, and use it instead of default - # Set default RDR rule to "any to any" + while getopts "i:s:d:" opt; do + case $opt in + i) if ifconfig | grep -ow "${OPTARG}:"; then + RDR_IF="${OPTARG}" + else + error_exit "$OPTARG is not a valid interface on this system." + fi + ;; + s) RDR_SRC="$OPTARG" + ;; + d) if ifconfig | grep -ow "inet ${OPTARG}"; then + RDR_DST="$OPTARG" + else + error_exit "$OPTARG is not an IP on this system." + fi + ;; + *) usage ;; + esac + done + shift $((OPTIND - 1)) + + # Set default interface, source, and destination if not set by options + if [ -z $RDR_IF ]; then + RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" + fi + if [ -z $RDR_SRC ]; then + RDR_SRC="any" + fi + if [ -z $RDR_DST ]; then RDR_DST="any" - if ifconfig | grep -wo "${1}"; then - IF_NAME="${1}" - EXT_IF=ext_if=\"${1}\" - shift - # Check if IP was specified for given interface - if ifconfig | grep -o "inet ${1}"; then - RDR_DST="${1}" - shift - fi - fi + fi case "$1" in list) @@ -195,9 +235,9 @@ while [ $# -gt 0 ]; do usage elif [ $# -eq 3 ]; then check_jail_validity - persist_rdr_rule $1 $2 $3 - load_rdr_rule $1 $2 $3 - shift 3 + persist_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 + load_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 + shift "$#" else case "$4" in log) @@ -211,16 +251,16 @@ while [ $# -gt 0 ]; do done if [ $2 == "(" ] && [ $last == ")" ] ; then check_jail_validity - persist_rdr_log_rule $proto $host_port $jail_port "$@" - load_rdr_log_rule $proto $host_port $jail_port "$@" + persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift $# else usage fi elif [ $# -eq 1 ]; then check_jail_validity - persist_rdr_log_rule $proto $host_port $jail_port "$@" - load_rdr_log_rule $proto $host_port $jail_port "$@" + persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift 1 else usage @@ -233,7 +273,14 @@ while [ $# -gt 0 ]; do fi ;; *) - usage + if [ $# -gt 5 ]; then + check_jail_validity + persist_rdr_rule "$@" + load_rdr_rule "$@" + shift $# + else + usage + fi ;; esac done From d21b5166d76164e797ad3c61addbc1f3c30cdde5 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:05:47 -0700 Subject: [PATCH 010/100] add usage command with new switches --- usr/local/share/bastille/rdr.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 3028ac03..0304af4d 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -32,7 +32,17 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille rdr TARGET [clear|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )]" + error_notify "Usage: bastille rdr TARGET [options(s)] [clear|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )]" + + cat << EOF + Options: + + -i [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -d [destination ip ] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + +EOF + exit 1 } # Handle special-case commands first. From f627aadac2105b702a44eb9ee4221111f45fbe28 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:06:16 -0700 Subject: [PATCH 011/100] spacing --- usr/local/share/bastille/rdr.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 0304af4d..c3d81196 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -37,9 +37,9 @@ usage() { cat << EOF Options: - -i [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. - -s [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. - -d [destination ip ] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -i [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -d [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. EOF exit 1 From 7f1be3d480fb9fa843937fb0de478b12e78c5ce4 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:06:33 -0700 Subject: [PATCH 012/100] more spacing --- usr/local/share/bastille/rdr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index c3d81196..f2a2c118 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -37,8 +37,8 @@ usage() { cat << EOF Options: - -i [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. - -s [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -i [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. -d [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. EOF From 2cff4048d18abfdef7fa8a15d75aa6d5510471b9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:35:14 -0700 Subject: [PATCH 013/100] document new changes to rdr --- docs/chapters/subcommands/rdr.rst | 61 +++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index 8a6e2fd0..0b86c640 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -14,27 +14,64 @@ specify the interface they run on in rc.conf (or other config files) .. code-block:: shell # bastille rdr --help - Usage: bastille rdr TARGET [clear] | [list] | [ tcp ] | [ udp ] + Usage: bastille rdr TARGET [options(s)] [clear|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )] + Options: + + -i [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -d [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + # bastille rdr dev1 tcp 2001 22 + [jail1]: + Redirecting: + tcp any:2001 -> any:22 on em0 + # bastille rdr dev1 list rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 + # bastille rdr dev1 udp 2053 53 + [jail1]: + Redirecting: + udp any:2001 -> any:22 on em0 + # bastille rdr dev1 list - rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 - rdr on em0 inet proto udp from any to any port = 2053 -> 10.17.89.1 port 53 + rdr pass on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 + rdr pass on em0 inet proto udp from any to any port = 2053 -> 10.17.89.1 port 53 + # bastille rdr dev1 clear nat cleared -If you have a host with multiple interfaces, and you want to specify which -one to use, `bastille rdr` allows you to pass any interface to the command. -If you do not specify an interface, the default one will be used. +Bastille included 3 options for the three following scenarios. +- Setting a non-default interface on which to create the rdr rule. +- Limiting the source IP on the rdr rule. +- Limiting the destination IP on the rdr rule. .. code-block:: shell - # bastille rdr em0 dev1 tcp 2001 22 + # bastille rdr dev1 -i vtnet0 udp 2001 22 + [jail1]: + Redirecting: + tcp any:8000 -> any:80 on vtnet0 + + # bastille rdr dev1 -s 192.168.0.1 tcp 8080 81 + [jail1]: + Redirecting: + tcp 192.168.0.1:8080 -> any:81 on em0 + + # bastille rdr dev1 -d 192.168.0.84 tcp 8082 82 + [jail1]: + Redirecting: + tcp any:8082 -> 192.168.0.84:82 on em0 + + # bastille rdr dev1 -i vtnet0 -d 192.168.0.45 tcp 9000 9000 + [jail1]: + Redirecting: + tcp any:9000 -> 192.168.0.45:9000 on vtnet0 + # bastille rdr dev1 list - rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 - # bastille rdr dev1 vtnet0 udp 2053 53 - # bastille rdr dev1 list - rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 - rdr on vtnet0 inet proto udp from any to any port = 2053 -> 10.17.89.1 port 53 + rdr pass on vtnet0 inet proto udp from any to any port = 2001 -> 10.17.89.1 port 22 + rdr pass on em0 inet proto tcp from 192.168.0.1 to any port = 8080 -> 10.17.89.1 port 81 + rdr pass on em0 inet proto tcp from any to 192.168.0.84 port = 8082 -> 10.17.89.1 port 82 + rdr pass on vtnet0 inet proto tcp from any to 192.168.0.45 port = 9000 -> 10.17.89.1 port 9000 + +The options can be used together, as seen above. From 4b5655470a663df9d62f2bb9568ae4f3640d9c2b Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:36:10 -0700 Subject: [PATCH 014/100] add protocol to printed info --- usr/local/share/bastille/rdr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index f2a2c118..92733ada 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -155,7 +155,7 @@ if [ -n "$JAIL_IP6" ]; then fi info "[${JAIL_NAME}]:" info "Redirecting:" -info "${src}:${host_port} -> ${dst}:${jail_port} on ${1}" +info "${proto} ${src}:${host_port} -> ${dst}:${jail_port} on ${1}" } # function: load rdr rule with log via pfctl @@ -178,7 +178,7 @@ if [ -n "$JAIL_IP6" ]; then fi info "[${JAIL_NAME}]:" info "Redirecting:" -info "${src}:${host_port} -> ${dst}:${jail_port} on ${1}" +info "${proto} ${src}:${host_port} -> ${dst}:${jail_port} on ${1}" } From 5b7b848b12599ff617b845d30dbc01b52601bd80 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:37:16 -0700 Subject: [PATCH 015/100] revert listing of IP and interface --- usr/local/share/bastille/list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index e7d09e2c..ebb28cc4 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -108,7 +108,7 @@ list_all(){ if [ "${JAIL_IP}" = "-" ]; then JAIL_IP=$(/usr/sbin/jls -j ${JAIL_NAME} ip6.addr 2> /dev/null); fi fi JAIL_HOSTNAME=$(/usr/sbin/jls -j ${JAIL_NAME} host.hostname 2> /dev/null) - JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s:%s %s/%s:%s"",",$4,$11,$7,$14,$18 }' | sed "s/,$//") + JAIL_PORTS=$(pfctl -a "rdr/${JAIL_NAME}" -Psn 2> /dev/null | awk '{ printf "%s/%s:%s"",",$7,$14,$18 }' | sed "s/,$//") JAIL_PATH=$(/usr/sbin/jls -j ${JAIL_NAME} path 2> /dev/null) if [ "${IS_FREEBSD_JAIL}" -eq 1 ]; then JAIL_RELEASE=$(jexec -l ${JAIL_NAME} freebsd-version -u 2> /dev/null) From 9ce301b7323cc12e721666300b3146e6b4951bd3 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:38:53 -0700 Subject: [PATCH 016/100] spacing --- docs/chapters/subcommands/rdr.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index 0b86c640..d87147ad 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -41,10 +41,11 @@ specify the interface they run on in rc.conf (or other config files) # bastille rdr dev1 clear nat cleared -Bastille included 3 options for the three following scenarios. -- Setting a non-default interface on which to create the rdr rule. -- Limiting the source IP on the rdr rule. -- Limiting the destination IP on the rdr rule. +Bastille includes 3 options for the three following scenarios. + + - Setting a non-default interface on which to create the rdr rule. + - Limiting the source IP on the rdr rule. + - Limiting the destination IP on the rdr rule. .. code-block:: shell From ac8d71bb94b1627f6bd7684633ec99c0a0b27f46 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:40:33 -0700 Subject: [PATCH 017/100] Update rdr.rst --- docs/chapters/subcommands/rdr.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index d87147ad..463b0a26 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -41,11 +41,11 @@ specify the interface they run on in rc.conf (or other config files) # bastille rdr dev1 clear nat cleared -Bastille includes 3 options for the three following scenarios. +`bastille rdr` includes 3 options. - - Setting a non-default interface on which to create the rdr rule. - - Limiting the source IP on the rdr rule. - - Limiting the destination IP on the rdr rule. +-i - Set a non-default interface on which to create the rdr rule. +-s - Limit the source IP on the rdr rule. +-d - Limit the destination IP on the rdr rule. .. code-block:: shell From 02e76f5d5f92c6347e8131720348d35a9c065132 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:40:56 -0700 Subject: [PATCH 018/100] Update rdr.rst --- docs/chapters/subcommands/rdr.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index 463b0a26..85224192 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -43,9 +43,9 @@ specify the interface they run on in rc.conf (or other config files) `bastille rdr` includes 3 options. --i - Set a non-default interface on which to create the rdr rule. --s - Limit the source IP on the rdr rule. --d - Limit the destination IP on the rdr rule. + -i - Set a non-default interface on which to create the rdr rule. + -s - Limit the source IP on the rdr rule. + -d - Limit the destination IP on the rdr rule. .. code-block:: shell From 356840a065a5243e6df259109d8be1873782c3a6 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:41:19 -0700 Subject: [PATCH 019/100] Update rdr.rst --- docs/chapters/subcommands/rdr.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index 85224192..96aa6dcd 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -43,9 +43,11 @@ specify the interface they run on in rc.conf (or other config files) `bastille rdr` includes 3 options. - -i - Set a non-default interface on which to create the rdr rule. - -s - Limit the source IP on the rdr rule. - -d - Limit the destination IP on the rdr rule. +-i - Set a non-default interface on which to create the rdr rule. + +-s - Limit the source IP on the rdr rule. + +-d - Limit the destination IP on the rdr rule. .. code-block:: shell From a52b53d6561f21082e96ed9c657c01f044e43cfd Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:43:08 -0700 Subject: [PATCH 020/100] spacing --- docs/chapters/subcommands/rdr.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index 96aa6dcd..e22196f1 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -2,7 +2,7 @@ rdr === -`bastille rdr` allows you to configure dynamic rdr rules for your containers +bastille rdr allows you to configure dynamic rdr rules for your containers without modifying pf.conf (assuming you are using the `bastille0` interface for a private network and have enabled `rdr-anchor 'rdr/*'` in /etc/pf.conf as described in the Networking section). @@ -41,13 +41,11 @@ specify the interface they run on in rc.conf (or other config files) # bastille rdr dev1 clear nat cleared -`bastille rdr` includes 3 options. +The rdr command includes 3 additional options. --i - Set a non-default interface on which to create the rdr rule. - --s - Limit the source IP on the rdr rule. - --d - Limit the destination IP on the rdr rule. + -i | - Set a non-default interface on which to create the rdr rule. + -s | - Limit the source IP on the rdr rule. + -d | - Limit the destination IP on the rdr rule. .. code-block:: shell From e5acf6f10385596a9c495e7827c80fe204f0c492 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:09:09 -0700 Subject: [PATCH 021/100] spacing --- docs/chapters/subcommands/rdr.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index e22196f1..fda13d0e 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -41,11 +41,11 @@ specify the interface they run on in rc.conf (or other config files) # bastille rdr dev1 clear nat cleared -The rdr command includes 3 additional options. +The `rdr` command includes 3 additional options: - -i | - Set a non-default interface on which to create the rdr rule. - -s | - Limit the source IP on the rdr rule. - -d | - Limit the destination IP on the rdr rule. +- **-i** | Set a non-default interface on which to create the `rdr` rule. +- **-s** | Limit the source IP on the `rdr` rule. +- **-d** | Limit the destination IP on the `rdr` rule. .. code-block:: shell From 8f3ad2f97271fc7c83f841e0171d5e83fdb0a911 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:13:05 -0700 Subject: [PATCH 022/100] change to -ge 6 --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 92733ada..a8bdb479 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -283,7 +283,7 @@ while [ $# -gt 0 ]; do fi ;; *) - if [ $# -gt 5 ]; then + if [ $# -ge 6 ]; then check_jail_validity persist_rdr_rule "$@" load_rdr_rule "$@" From 74eab248ca9401c473395cf6c393cb711481273e Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 15:56:31 -0700 Subject: [PATCH 023/100] add error notify to pfctl commands/add better info commands --- usr/local/share/bastille/rdr.sh | 71 +++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index a8bdb479..f06cdab5 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -62,7 +62,6 @@ TARGET="${1}" JAIL_NAME="" JAIL_IP="" JAIL_IP6="" -EXT_IF="" RDR_IF="" RDR_SRC="" RDR_DST="" @@ -98,16 +97,6 @@ check_jail_validity() { if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then error_exit "rdr-anchor not found in pf.conf" fi - - # Check if ext_if is defined in pf.conf - # If EXT_IF is set, use it instead of the default - if [ -n "${bastille_pf_conf}" ]; then - if [ -z "${EXT_IF}" ]; then - EXT_IF=$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf}) - else - error_exit "bastille_network_pf_ext_if (${bastille_network_pf_ext_if}) not defined in pf.conf" - fi - fi } # function: write rule to rdr.conf @@ -139,27 +128,40 @@ fi # function: load rdr rule via pfctl load_rdr_rule() { + local if_name="${1}" local if=ext_if=\"${1}\" local src="${2}" local dst="${3}" local proto="${4}" local host_port="${5}" local jail_port="${6}" -( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; +# Create IPv4 rdr rule +if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f- -if [ -n "$JAIL_IP6" ]; then -( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f- + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_notify "Failed to create IPv4 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" +else + info "[${JAIL_NAME}]:" + info "Redirecting IPv4:" + info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" +fi +# Create IPv6 rdr rule (if ip6.addr is enabled) +if [ -n "$JAIL_IP6" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_notify "Failed to create IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + info "Redirecting IPv6:" + info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi fi -info "[${JAIL_NAME}]:" -info "Redirecting:" -info "${proto} ${src}:${host_port} -> ${dst}:${jail_port} on ${1}" } # function: load rdr rule with log via pfctl load_rdr_log_rule() { + local if_name="${1}" local if=ext_if=\"${1}\" local src="${2}" local dst="${3}" @@ -168,17 +170,28 @@ load_rdr_log_rule() { local jail_port="${6}" shift 6; log=$@ -( pfctl -a "rdr/${JAIL_NAME}" -Psn; +# Create IPv4 rule with log +if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f- -if [ -n "$JAIL_IP6" ]; then - ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f- + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_notify "Failed to create logged IPv4 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" +else + info "[${JAIL_NAME}]:" + info "Redirecting logged IPv4:" + info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" +fi +# Create IPv6 rdr rule with log (if ip6.addr is enabled) +if [ -n "$JAIL_IP6" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_notify "Failed to create logged IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + info "Redirecting logged IPv6:" + info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi fi -info "[${JAIL_NAME}]:" -info "Redirecting:" -info "${proto} ${src}:${host_port} -> ${dst}:${jail_port} on ${1}" } From 53b47306f53b3241fdb9ec3abb12e3196a1d3a82 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:10:11 -0700 Subject: [PATCH 024/100] better error handling --- usr/local/share/bastille/rdr.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index f06cdab5..1a625cf7 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -174,7 +174,7 @@ log=$@ if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_notify "Failed to create logged IPv4 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + error_notify "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" info "Redirecting logged IPv4:" @@ -185,7 +185,7 @@ if [ -n "$JAIL_IP6" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_notify "Failed to create logged IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + error_notify "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" info "Redirecting logged IPv6:" @@ -296,11 +296,16 @@ while [ $# -gt 0 ]; do fi ;; *) - if [ $# -ge 6 ]; then + if [ $# -eq 6 ]; then check_jail_validity persist_rdr_rule "$@" load_rdr_rule "$@" shift $# + elif [ $# -ge 7 ] && [ "${7}" = "log" ]; then + check_jail_validity + persist_rdr_log_rule "$@" + load_rdr_log_rule "$@" + shift $# else usage fi From 4984f684e112fe43774f70181b8c98d855e67dd7 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:40:21 -0700 Subject: [PATCH 025/100] Update docs --- docs/chapters/subcommands/rdr.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index fda13d0e..e922701b 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -23,7 +23,7 @@ specify the interface they run on in rc.conf (or other config files) # bastille rdr dev1 tcp 2001 22 [jail1]: - Redirecting: + Redirecting IPv4: tcp any:2001 -> any:22 on em0 # bastille rdr dev1 list @@ -51,22 +51,22 @@ The `rdr` command includes 3 additional options: # bastille rdr dev1 -i vtnet0 udp 2001 22 [jail1]: - Redirecting: + Redirecting IPv4: tcp any:8000 -> any:80 on vtnet0 # bastille rdr dev1 -s 192.168.0.1 tcp 8080 81 [jail1]: - Redirecting: + Redirecting IPv4: tcp 192.168.0.1:8080 -> any:81 on em0 # bastille rdr dev1 -d 192.168.0.84 tcp 8082 82 [jail1]: - Redirecting: + Redirecting IPv4: tcp any:8082 -> 192.168.0.84:82 on em0 # bastille rdr dev1 -i vtnet0 -d 192.168.0.45 tcp 9000 9000 [jail1]: - Redirecting: + Redirecting IPv4: tcp any:9000 -> 192.168.0.45:9000 on vtnet0 # bastille rdr dev1 list From 6945781e15fa708be522bc7314a2c0c0da9738b5 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:41:18 -0700 Subject: [PATCH 026/100] Add / --- docs/chapters/subcommands/rdr.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index e922701b..9febbd24 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -24,7 +24,7 @@ specify the interface they run on in rc.conf (or other config files) # bastille rdr dev1 tcp 2001 22 [jail1]: Redirecting IPv4: - tcp any:2001 -> any:22 on em0 + tcp/any:2001 -> any:22 on em0 # bastille rdr dev1 list rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 @@ -32,7 +32,7 @@ specify the interface they run on in rc.conf (or other config files) # bastille rdr dev1 udp 2053 53 [jail1]: Redirecting: - udp any:2001 -> any:22 on em0 + udp/any:2001 -> any:22 on em0 # bastille rdr dev1 list rdr pass on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 @@ -52,22 +52,22 @@ The `rdr` command includes 3 additional options: # bastille rdr dev1 -i vtnet0 udp 2001 22 [jail1]: Redirecting IPv4: - tcp any:8000 -> any:80 on vtnet0 + tcp/any:8000 -> any:80 on vtnet0 # bastille rdr dev1 -s 192.168.0.1 tcp 8080 81 [jail1]: Redirecting IPv4: - tcp 192.168.0.1:8080 -> any:81 on em0 + tcp/192.168.0.1:8080 -> any:81 on em0 # bastille rdr dev1 -d 192.168.0.84 tcp 8082 82 [jail1]: Redirecting IPv4: - tcp any:8082 -> 192.168.0.84:82 on em0 + tcp/any:8082 -> 192.168.0.84:82 on em0 # bastille rdr dev1 -i vtnet0 -d 192.168.0.45 tcp 9000 9000 [jail1]: Redirecting IPv4: - tcp any:9000 -> 192.168.0.45:9000 on vtnet0 + tcp/any:9000 -> 192.168.0.45:9000 on vtnet0 # bastille rdr dev1 list rdr pass on vtnet0 inet proto udp from any to any port = 2001 -> 10.17.89.1 port 22 From 492b64b302bdeee410b832fafe8bea7f202fa221 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 11 Dec 2024 18:28:10 -0700 Subject: [PATCH 027/100] fix help usage command --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 1a625cf7..f6e9f4d5 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille rdr TARGET [options(s)] [clear|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )]" + error_notify "Usage: bastille rdr TARGET [options(s)] [clear|list|(tcp|udp)] host_port jail_port [log ['(' logopts ')'] ] )]" cat << EOF Options: From 449a0ae8e182f7ac97b6805fc241a62ce474a081 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 07:41:23 -0700 Subject: [PATCH 028/100] add check when setting source IP + supress echo output --- usr/local/share/bastille/rdr.sh | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index f6e9f4d5..ad158f8d 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -99,6 +99,29 @@ check_jail_validity() { fi } +check_rdr_ip_validity() { + local ip="$1" + local ip6=$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') + if [ -n "${ip6}" ]; then + info "Valid: (${ip6})." + else + local IFS + if echo "${ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then + TEST_IP=$(echo "${ip}" | cut -d / -f1) + IFS=. + set ${TEST_IP} + for quad in 1 2 3 4; do + if eval [ \$$quad -gt 255 ]; then + error_exit "Invalid: (${TEST_IP})" + fi + done + info "Valid: (${ip})." + else + error_exit "Invalid: (${ip})." + fi + fi +} + # function: write rule to rdr.conf persist_rdr_rule() { local if="${1}" @@ -198,15 +221,16 @@ fi while [ $# -gt 0 ]; do while getopts "i:s:d:" opt; do case $opt in - i) if ifconfig | grep -ow "${OPTARG}:"; then + i) if ifconfig | grep -owq "${OPTARG}:"; then RDR_IF="${OPTARG}" else error_exit "$OPTARG is not a valid interface on this system." fi ;; - s) RDR_SRC="$OPTARG" + s) check_rdr_ip_validity "${OPTARG}" + RDR_SRC="$OPTARG" ;; - d) if ifconfig | grep -ow "inet ${OPTARG}"; then + d) if ifconfig | grep -owq "inet ${OPTARG}"; then RDR_DST="$OPTARG" else error_exit "$OPTARG is not an IP on this system." From 606d8da0def35d0c33554ab068e8fc9fccc6f7fc Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:55:56 -0700 Subject: [PATCH 029/100] only persist rdr rule if it can be properly loaded, else exit --- usr/local/share/bastille/rdr.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index ad158f8d..cd8c180c 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -162,7 +162,7 @@ load_rdr_rule() { if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_notify "Failed to create IPv4 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + error_exit "Failed to create IPv4 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" info "Redirecting IPv4:" @@ -173,7 +173,7 @@ if [ -n "$JAIL_IP6" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_notify "Failed to create IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + error_exit "Failed to create IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" info "Redirecting IPv6:" @@ -197,7 +197,7 @@ log=$@ if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_notify "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" info "Redirecting logged IPv4:" @@ -208,7 +208,7 @@ if [ -n "$JAIL_IP6" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_notify "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" info "Redirecting logged IPv6:" @@ -282,8 +282,8 @@ while [ $# -gt 0 ]; do usage elif [ $# -eq 3 ]; then check_jail_validity - persist_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 load_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 + persist_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 shift "$#" else case "$4" in @@ -298,16 +298,16 @@ while [ $# -gt 0 ]; do done if [ $2 == "(" ] && [ $last == ")" ] ; then check_jail_validity - persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift $# else usage fi elif [ $# -eq 1 ]; then check_jail_validity - persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift 1 else usage @@ -322,13 +322,13 @@ while [ $# -gt 0 ]; do *) if [ $# -eq 6 ]; then check_jail_validity - persist_rdr_rule "$@" load_rdr_rule "$@" + persist_rdr_rule "$@" shift $# elif [ $# -ge 7 ] && [ "${7}" = "log" ]; then check_jail_validity - persist_rdr_log_rule "$@" load_rdr_log_rule "$@" + persist_rdr_log_rule "$@" shift $# else usage From 7ab9188b3a94b8f065e60a02c092b73e909c2a07 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:23:21 -0700 Subject: [PATCH 030/100] Use case command instead of getopts to remain consistent --- usr/local/share/bastille/rdr.sh | 67 +++++++++++++++++---------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index cd8c180c..9fb5e782 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -217,42 +217,43 @@ if [ -n "$JAIL_IP6" ]; then fi } +# Set defaults +RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" +RDR_SRC="any" +RDR_DST="any" while [ $# -gt 0 ]; do - while getopts "i:s:d:" opt; do - case $opt in - i) if ifconfig | grep -owq "${OPTARG}:"; then - RDR_IF="${OPTARG}" - else - error_exit "$OPTARG is not a valid interface on this system." - fi - ;; - s) check_rdr_ip_validity "${OPTARG}" - RDR_SRC="$OPTARG" - ;; - d) if ifconfig | grep -owq "inet ${OPTARG}"; then - RDR_DST="$OPTARG" - else - error_exit "$OPTARG is not an IP on this system." - fi - ;; - *) usage ;; - esac - done - shift $((OPTIND - 1)) - - # Set default interface, source, and destination if not set by options - if [ -z $RDR_IF ]; then - RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" - fi - if [ -z $RDR_SRC ]; then - RDR_SRC="any" - fi - if [ -z $RDR_DST ]; then - RDR_DST="any" - fi - case "$1" in + -i|--interface) + if [ -z "${2}" ]; then + error_exit "Must specify an interface with [-i|--interface]" + fi + if ifconfig | grep -owq "${1}:"; then + RDR_IF="${2}" + shift 2 + else + error_exit "${2} is not a valid interface." + fi + ;; + -s|--source) + if [ -z "${2}" ]; then + error_exit "Must specify a source IP/subnet with [-s|--source]" + fi + check_ip_validity "${2}" + RDR_SRC="${2}" + shift 2 + ;; + -d|--destination) + if [ -z "${2}" ]; then + error_exit "Must specify a destination IP with [-d|--destination]" + fi + if ifconfig | grep -owq "inet ${2}"; then + RDR_DST="${2}" + shift 2 + else + error_exit "${2} is not an IP on this system." + fi + ;; list) if [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do From 4377e1413a2c24566acc55fdeb6b739e6baf2bed Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:25:08 -0700 Subject: [PATCH 031/100] help message conform to case command --- usr/local/share/bastille/rdr.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 9fb5e782..3dae1c6d 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -37,9 +37,9 @@ usage() { cat << EOF Options: - -i [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. - -s [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. - -d [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s | --source [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -d | --destination [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. EOF exit 1 From c6547e97cf684aafce6c7ba4adaad6af1ee83cae Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:26:04 -0700 Subject: [PATCH 032/100] help message docs --- docs/chapters/subcommands/rdr.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index 9febbd24..e3be96ad 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -17,9 +17,9 @@ specify the interface they run on in rc.conf (or other config files) Usage: bastille rdr TARGET [options(s)] [clear|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )] Options: - -i [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. - -s [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. - -d [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s | --source [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -d | --destination [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. # bastille rdr dev1 tcp 2001 22 [jail1]: From ab54842061291e77f217fbeedd1e130d5d2897e1 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:39:08 -0700 Subject: [PATCH 033/100] error handling + add reset command to remove all rdr rules --- usr/local/share/bastille/rdr.sh | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 3dae1c6d..912ba80e 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -221,6 +221,7 @@ fi RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" RDR_SRC="any" RDR_DST="any" +OPTION="0" while [ $# -gt 0 ]; do case "$1" in @@ -230,6 +231,7 @@ while [ $# -gt 0 ]; do fi if ifconfig | grep -owq "${1}:"; then RDR_IF="${2}" + OPTION="1" shift 2 else error_exit "${2} is not a valid interface." @@ -241,6 +243,7 @@ while [ $# -gt 0 ]; do fi check_ip_validity "${2}" RDR_SRC="${2}" + OPTION="1" shift 2 ;; -d|--destination) @@ -249,12 +252,16 @@ while [ $# -gt 0 ]; do fi if ifconfig | grep -owq "inet ${2}"; then RDR_DST="${2}" + OPTION="1" shift 2 else error_exit "${2} is not an IP on this system." fi ;; list) + if [ "${OPTION}" -eq 1 ];then + error_exit "Command \"${1}\" cannot be used with options." + fi if [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" @@ -267,6 +274,9 @@ while [ $# -gt 0 ]; do shift ;; clear) + if [ "${OPTION}" -eq 1 ];then + error_exit "Command \"${1}\" cannot be used with options." + fi if [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" @@ -278,6 +288,23 @@ while [ $# -gt 0 ]; do fi shift ;; + reset) + if [ "${OPTION}" -eq 1 ];then + error_exit "Command \"${1}\" cannot be used with options." + fi + if [ "${TARGET}" = 'ALL' ]; then + for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do + echo "${JAIL_NAME} redirects:" + pfctl -a "rdr/${JAIL_NAME}" -Fn + rm -f "${bastille_jailsdir}"/"${JAIL__NAME}"/rdr.conf + done + else + check_jail_validity + pfctl -a "rdr/${JAIL_NAME}" -Fn + rm -f "${bastille_jailsdir}"/"${JAIL__NAME}"/rdr.conf + fi + shift + ;; tcp|udp) if [ $# -lt 3 ]; then usage @@ -321,7 +348,10 @@ while [ $# -gt 0 ]; do fi ;; *) - if [ $# -eq 6 ]; then + if [ "${OPTION}" -eq 1 ];then + usage + fi + if [ $# -eq 6 ] && [ "${4}" = "tcp" ] || [ "${4}" = "udp" ]; then check_jail_validity load_rdr_rule "$@" persist_rdr_rule "$@" From 9b6261346b0688e23b9548c28ec8698585f4b919 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:39:43 -0700 Subject: [PATCH 034/100] Update rdr.rst - add reset to help --- docs/chapters/subcommands/rdr.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index e3be96ad..cf2488ac 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -14,7 +14,7 @@ specify the interface they run on in rc.conf (or other config files) .. code-block:: shell # bastille rdr --help - Usage: bastille rdr TARGET [options(s)] [clear|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )] + Usage: bastille rdr TARGET [options(s)] [clear|reset|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )] Options: -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. From 20a291c689fdb78117bc0d45842e47b6e8678faa Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:40:32 -0700 Subject: [PATCH 035/100] add reset to help command --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 912ba80e..c966c022 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille rdr TARGET [options(s)] [clear|list|(tcp|udp)] host_port jail_port [log ['(' logopts ')'] ] )]" + error_notify "Usage: bastille rdr TARGET [options(s)] [clear|reset|list|(tcp|udp)] host_port jail_port [log ['(' logopts ')'] ] )]" cat << EOF Options: From d6cbbf2ac6dd683cb8c256c86bafc96ef5992e7c Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:42:52 -0700 Subject: [PATCH 036/100] quick fix --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index c966c022..5699f4c2 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -229,7 +229,7 @@ while [ $# -gt 0 ]; do if [ -z "${2}" ]; then error_exit "Must specify an interface with [-i|--interface]" fi - if ifconfig | grep -owq "${1}:"; then + if ifconfig | grep -owq "${2}:"; then RDR_IF="${2}" OPTION="1" shift 2 From 3f97dd7e58bc8732514aa8d9fb611cd69bfc2e14 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 18:52:46 -0700 Subject: [PATCH 037/100] split options and regular case commands --- usr/local/share/bastille/rdr.sh | 74 ++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 5699f4c2..2e28f237 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -223,41 +223,49 @@ RDR_SRC="any" RDR_DST="any" OPTION="0" -while [ $# -gt 0 ]; do - case "$1" in - -i|--interface) - if [ -z "${2}" ]; then - error_exit "Must specify an interface with [-i|--interface]" - fi - if ifconfig | grep -owq "${2}:"; then - RDR_IF="${2}" - OPTION="1" - shift 2 - else - error_exit "${2} is not a valid interface." - fi - ;; - -s|--source) - if [ -z "${2}" ]; then - error_exit "Must specify a source IP/subnet with [-s|--source]" - fi - check_ip_validity "${2}" - RDR_SRC="${2}" +# Check for options +case "$1" in + -i|--interface) + if [ -z "${2}" ]; then + error_exit "Must specify an interface with [-i|--interface]" + fi + if ifconfig | grep -owq "${2}:"; then + RDR_IF="${2}" OPTION="1" shift 2 - ;; - -d|--destination) - if [ -z "${2}" ]; then - error_exit "Must specify a destination IP with [-d|--destination]" - fi - if ifconfig | grep -owq "inet ${2}"; then - RDR_DST="${2}" - OPTION="1" - shift 2 - else - error_exit "${2} is not an IP on this system." - fi - ;; + else + error_exit "${2} is not a valid interface." + fi + ;; + -s|--source) + if [ -z "${2}" ]; then + error_exit "Must specify a source IP/subnet with [-s|--source]" + fi + check_ip_validity "${2}" + RDR_SRC="${2}" + OPTION="1" + shift 2 + ;; + -d|--destination) + if [ -z "${2}" ]; then + error_exit "Must specify a destination IP with [-d|--destination]" + fi + if ifconfig | grep -owq "inet ${2}"; then + RDR_DST="${2}" + OPTION="1" + shift 2 + else + error_exit "${2} is not an IP on this system." + fi + ;; +esac + +if [ $# -lt 2 ]; then + usage +fi + +while [ $# -gt 0 ]; do + case "$1" in list) if [ "${OPTION}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." From 216a4a5412b0858ec34ce8162162abf9d6feb7bd Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:41:52 -0700 Subject: [PATCH 038/100] spacing --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 2e28f237..fc6faf84 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -257,7 +257,7 @@ case "$1" in else error_exit "${2} is not an IP on this system." fi - ;; + ;; esac if [ $# -lt 2 ]; then From ae9a33a50e92315e0c6c20cb4512014502a551dd Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 20:23:50 -0700 Subject: [PATCH 039/100] error handling --- usr/local/share/bastille/rdr.sh | 68 +++++++++++++++++---------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index fc6faf84..c60529d5 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -224,40 +224,44 @@ RDR_DST="any" OPTION="0" # Check for options -case "$1" in - -i|--interface) - if [ -z "${2}" ]; then - error_exit "Must specify an interface with [-i|--interface]" - fi - if ifconfig | grep -owq "${2}:"; then - RDR_IF="${2}" +while [ "$#" -gt 0 ]; do + case "$1" in + -i|--interface) + if [ -z "${2}" ]; then + error_exit "Must specify an interface with [-i|--interface]" + fi + if ifconfig | grep -owq "${2}:"; then + RDR_IF="${2}" + OPTION="1" + shift 2 + else + error_exit "${2} is not a valid interface." + fi + ;; + -s|--source) + if [ -z "${2}" ]; then + error_exit "Must specify a source IP/subnet with [-s|--source]" + fi + check_rdr_ip_validity "${2}" + RDR_SRC="${2}" OPTION="1" shift 2 - else - error_exit "${2} is not a valid interface." - fi - ;; - -s|--source) - if [ -z "${2}" ]; then - error_exit "Must specify a source IP/subnet with [-s|--source]" - fi - check_ip_validity "${2}" - RDR_SRC="${2}" - OPTION="1" - shift 2 - ;; - -d|--destination) - if [ -z "${2}" ]; then - error_exit "Must specify a destination IP with [-d|--destination]" - fi - if ifconfig | grep -owq "inet ${2}"; then - RDR_DST="${2}" - OPTION="1" - shift 2 - else - error_exit "${2} is not an IP on this system." - fi - ;; + ;; + -d|--destination) + if [ -z "${2}" ]; then + error_exit "Must specify a destination IP with [-d|--destination]" + fi + if ifconfig | grep -owq "inet ${2}"; then + RDR_DST="${2}" + OPTION="1" + shift 2 + else + error_exit "${2} is not an IP on this system." + fi + ;; + *) + break + ;; esac if [ $# -lt 2 ]; then From ebf9c8955512cd79f42a4f2564fdf330c3138e2b Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 12 Dec 2024 20:26:06 -0700 Subject: [PATCH 040/100] missing done --- usr/local/share/bastille/rdr.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index c60529d5..919a7be9 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -262,7 +262,8 @@ while [ "$#" -gt 0 ]; do *) break ;; -esac + esac +done if [ $# -lt 2 ]; then usage From 3a16c047d2dcfb704c989bb266add1855ecb6ecb Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 13 Dec 2024 06:57:03 -0700 Subject: [PATCH 041/100] merge case commands, better error handling --- usr/local/share/bastille/rdr.sh | 38 ++++++++++++++------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 919a7be9..fb0b4ea5 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -227,8 +227,8 @@ OPTION="0" while [ "$#" -gt 0 ]; do case "$1" in -i|--interface) - if [ -z "${2}" ]; then - error_exit "Must specify an interface with [-i|--interface]" + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage fi if ifconfig | grep -owq "${2}:"; then RDR_IF="${2}" @@ -239,8 +239,8 @@ while [ "$#" -gt 0 ]; do fi ;; -s|--source) - if [ -z "${2}" ]; then - error_exit "Must specify a source IP/subnet with [-s|--source]" + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage fi check_rdr_ip_validity "${2}" RDR_SRC="${2}" @@ -248,8 +248,8 @@ while [ "$#" -gt 0 ]; do shift 2 ;; -d|--destination) - if [ -z "${2}" ]; then - error_exit "Must specify a destination IP with [-d|--destination]" + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage fi if ifconfig | grep -owq "inet ${2}"; then RDR_DST="${2}" @@ -259,21 +259,11 @@ while [ "$#" -gt 0 ]; do error_exit "${2} is not an IP on this system." fi ;; - *) - break - ;; - esac -done - -if [ $# -lt 2 ]; then - usage -fi - -while [ $# -gt 0 ]; do - case "$1" in list) if [ "${OPTION}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." + elif [ -n "${2}" ]; then + usage fi if [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do @@ -289,7 +279,9 @@ while [ $# -gt 0 ]; do clear) if [ "${OPTION}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." - fi + elif [ -n "${2}" ]; then + usage + fi if [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" @@ -303,18 +295,20 @@ while [ $# -gt 0 ]; do ;; reset) if [ "${OPTION}" -eq 1 ];then - error_exit "Command \"${1}\" cannot be used with options." + error_exit "Command \"${1}\" cannot be used with options." + elif [ -n "${2}" ]; then + usage fi if [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" pfctl -a "rdr/${JAIL_NAME}" -Fn - rm -f "${bastille_jailsdir}"/"${JAIL__NAME}"/rdr.conf + rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf done else check_jail_validity pfctl -a "rdr/${JAIL_NAME}" -Fn - rm -f "${bastille_jailsdir}"/"${JAIL__NAME}"/rdr.conf + rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf fi shift ;; From 29bd130b24a9c78fc2b9f8c79844e579409f0944 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 13 Dec 2024 07:31:58 -0700 Subject: [PATCH 042/100] final revision --- usr/local/share/bastille/rdr.sh | 237 ++++++++++++++++---------------- 1 file changed, 116 insertions(+), 121 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index fb0b4ea5..531c2962 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -107,114 +107,114 @@ check_rdr_ip_validity() { else local IFS if echo "${ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then - TEST_IP=$(echo "${ip}" | cut -d / -f1) - IFS=. - set ${TEST_IP} - for quad in 1 2 3 4; do - if eval [ \$$quad -gt 255 ]; then - error_exit "Invalid: (${TEST_IP})" - fi - done - info "Valid: (${ip})." + TEST_IP=$(echo "${ip}" | cut -d / -f1) + IFS=. + set ${TEST_IP} + for quad in 1 2 3 4; do + if eval [ \$$quad -gt 255 ]; then + error_exit "Invalid: (${TEST_IP})" + fi + done + info "Valid: (${ip})." else - error_exit "Invalid: (${ip})." - fi + error_exit "Invalid: (${ip})." + fi fi } # function: write rule to rdr.conf persist_rdr_rule() { - local if="${1}" - local src="${2}" - local dst="${3}" - local proto="${4}" - local host_port="${5}" - local jail_port="${6}" -if ! grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" -fi + local if="${1}" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" + if ! grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + fi } persist_rdr_log_rule() { - local if="${1}" - local src="${2}" - local dst="${3}" - local proto="${4}" - local host_port="${5}" - local jail_port="${6}" -shift 6; -log=$@; -if ! grep -qs "$if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" -fi + local if="${1}" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" + shift 6; + log=$@; + if ! grep -qs "$if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + fi } # function: load rdr rule via pfctl load_rdr_rule() { - local if_name="${1}" - local if=ext_if=\"${1}\" - local src="${2}" - local dst="${3}" - local proto="${4}" - local host_port="${5}" - local jail_port="${6}" -# Create IPv4 rdr rule -if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; - printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_exit "Failed to create IPv4 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" -else - info "[${JAIL_NAME}]:" - info "Redirecting IPv4:" - info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" -fi -# Create IPv6 rdr rule (if ip6.addr is enabled) -if [ -n "$JAIL_IP6" ]; then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_exit "Failed to create IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" - else - info "[${JAIL_NAME}]:" - info "Redirecting IPv6:" - info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" - fi -fi + local if_name="${1}" + local if=ext_if=\"${1}\" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" + # Create IPv4 rdr rule + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; + printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create IPv4 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + info "Redirecting IPv4:" + info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi + # Create IPv6 rdr rule (if ip6.addr is enabled) + if [ -n "$JAIL_IP6" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + info "Redirecting IPv6:" + info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi + fi } # function: load rdr rule with log via pfctl load_rdr_log_rule() { - local if_name="${1}" - local if=ext_if=\"${1}\" - local src="${2}" - local dst="${3}" - local proto="${4}" - local host_port="${5}" - local jail_port="${6}" -shift 6; -log=$@ -# Create IPv4 rule with log -if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" -else - info "[${JAIL_NAME}]:" - info "Redirecting logged IPv4:" - info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" -fi -# Create IPv6 rdr rule with log (if ip6.addr is enabled) -if [ -n "$JAIL_IP6" ]; then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" - else - info "[${JAIL_NAME}]:" - info "Redirecting logged IPv6:" - info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" - fi -fi + local if_name="${1}" + local if=ext_if=\"${1}\" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" + shift 6; + log=$@ + # Create IPv4 rule with log + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + info "Redirecting logged IPv4:" + info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi + # Create IPv6 rdr rule with log (if ip6.addr is enabled) + if [ -n "$JAIL_IP6" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + info "Redirecting logged IPv6:" + info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi + fi } # Set defaults @@ -229,10 +229,9 @@ while [ "$#" -gt 0 ]; do -i|--interface) if [ -z "${2}" ] || [ -z "${3}" ]; then usage - fi - if ifconfig | grep -owq "${2}:"; then + elif ifconfig | grep -owq "${2}:"; then RDR_IF="${2}" - OPTION="1" + OPTION="1" shift 2 else error_exit "${2} is not a valid interface." @@ -241,19 +240,19 @@ while [ "$#" -gt 0 ]; do -s|--source) if [ -z "${2}" ] || [ -z "${3}" ]; then usage + else + check_rdr_ip_validity "${2}" + RDR_SRC="${2}" + OPTION="1" + shift 2 fi - check_rdr_ip_validity "${2}" - RDR_SRC="${2}" - OPTION="1" - shift 2 ;; -d|--destination) if [ -z "${2}" ] || [ -z "${3}" ]; then usage - fi - if ifconfig | grep -owq "inet ${2}"; then + elif ifconfig | grep -owq "inet ${2}"; then RDR_DST="${2}" - OPTION="1" + OPTION="1" shift 2 else error_exit "${2} is not an IP on this system." @@ -262,10 +261,9 @@ while [ "$#" -gt 0 ]; do list) if [ "${OPTION}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." - elif [ -n "${2}" ]; then + elif [ -n "${2}" ]; then usage - fi - if [ "${TARGET}" = 'ALL' ]; then + elif [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null @@ -279,10 +277,9 @@ while [ "$#" -gt 0 ]; do clear) if [ "${OPTION}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." - elif [ -n "${2}" ]; then + elif [ -n "${2}" ]; then usage - fi - if [ "${TARGET}" = 'ALL' ]; then + elif [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" pfctl -a "rdr/${JAIL_NAME}" -Fn @@ -296,10 +293,9 @@ while [ "$#" -gt 0 ]; do reset) if [ "${OPTION}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." - elif [ -n "${2}" ]; then + elif [ -n "${2}" ]; then usage - fi - if [ "${TARGET}" = 'ALL' ]; then + elif [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" pfctl -a "rdr/${JAIL_NAME}" -Fn @@ -357,19 +353,18 @@ while [ "$#" -gt 0 ]; do *) if [ "${OPTION}" -eq 1 ];then usage - fi - if [ $# -eq 6 ] && [ "${4}" = "tcp" ] || [ "${4}" = "udp" ]; then - check_jail_validity - load_rdr_rule "$@" - persist_rdr_rule "$@" - shift $# + elif [ $# -eq 6 ] && [ "${4}" = "tcp" ] || [ "${4}" = "udp" ]; then + check_jail_validity + load_rdr_rule "$@" + persist_rdr_rule "$@" + shift $# elif [ $# -ge 7 ] && [ "${7}" = "log" ]; then - check_jail_validity - load_rdr_log_rule "$@" - persist_rdr_log_rule "$@" - shift $# + check_jail_validity + load_rdr_log_rule "$@" + persist_rdr_log_rule "$@" + shift $# else - usage + usage fi ;; esac From 0ce5c27d8e902de8fea37eea30fbcce19bc3b2b0 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 13 Dec 2024 07:41:27 -0700 Subject: [PATCH 043/100] add small info to reset command --- usr/local/share/bastille/rdr.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 531c2962..8cc9b04e 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -299,12 +299,16 @@ while [ "$#" -gt 0 ]; do for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do echo "${JAIL_NAME} redirects:" pfctl -a "rdr/${JAIL_NAME}" -Fn - rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf + if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then + info "[${JAIL_NAME}]: rdr.conf removed." + fi done else check_jail_validity pfctl -a "rdr/${JAIL_NAME}" -Fn - rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf + if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then + info "[${JAIL_NAME}]: rdr.conf removed." + fi fi shift ;; From 744dd10a1c4cd5d0994ee72df96af801f761085c Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 13 Dec 2024 07:43:03 -0700 Subject: [PATCH 044/100] remove . --- usr/local/share/bastille/rdr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 8cc9b04e..9eab2cc8 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -300,14 +300,14 @@ while [ "$#" -gt 0 ]; do echo "${JAIL_NAME} redirects:" pfctl -a "rdr/${JAIL_NAME}" -Fn if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then - info "[${JAIL_NAME}]: rdr.conf removed." + info "[${JAIL_NAME}]: rdr.conf removed" fi done else check_jail_validity pfctl -a "rdr/${JAIL_NAME}" -Fn if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then - info "[${JAIL_NAME}]: rdr.conf removed." + info "[${JAIL_NAME}]: rdr.conf removed" fi fi shift From 1fcdfa4e9bf0941afaa8fb7018246226c597a55c Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:49:36 -0700 Subject: [PATCH 045/100] add "ports" command to list jails and their published ports --- usr/local/share/bastille/list.sh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index ebb28cc4..d2fd2f89 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|(import|export|backup)]" + error_exit "Usage: bastille list [-j|-a] [release [-p]|template|(jail|container)|log|limit|ports|(import|export|backup)]" } if [ "${1}" = help -o "${1}" = "-h" -o "${1}" = "--help" ]; then @@ -202,12 +202,28 @@ list_import(){ ls "${bastille_backupsdir}" | grep -v ".sha256$" } +list_ports(){ + if [ -d "${bastille_jailsdir}" ]; then + JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") + for _JAIL in ${JAIL_LIST}; do + if [ -f "${bastille_jailsdir}/${_JAIL}/rdr.conf" ]; then + _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1":"$4"//"$2":"$5" -> "$3":"$6}')" + info "[${_JAIL}]:" + echo "${_PORTS}" + fi + done + fi +} + if [ $# -gt 0 ]; then # Handle special-case commands first. case "${1}" in all|-a|--all) list_all ;; + port|ports) + list_ports + ;; release|releases) list_release ;; From 8bf734210597210782e90a2137c6c39dadc1e7a9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:52:01 -0700 Subject: [PATCH 046/100] remove / to stay consistent --- usr/local/share/bastille/list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index d2fd2f89..a10dc532 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -207,7 +207,7 @@ list_ports(){ JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") for _JAIL in ${JAIL_LIST}; do if [ -f "${bastille_jailsdir}/${_JAIL}/rdr.conf" ]; then - _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1":"$4"//"$2":"$5" -> "$3":"$6}')" + _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1":"$4"/"$2":"$5" -> "$3":"$6}')" info "[${_JAIL}]:" echo "${_PORTS}" fi From e6ae0ebf20d27e2f6be4e749142c370900a81c17 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:56:33 -0700 Subject: [PATCH 047/100] too much green, minimize color and info when redirecting --- usr/local/share/bastille/rdr.sh | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 9eab2cc8..431acf4d 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -165,8 +165,7 @@ load_rdr_rule() { error_exit "Failed to create IPv4 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" - info "Redirecting IPv4:" - info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi # Create IPv6 rdr rule (if ip6.addr is enabled) if [ -n "$JAIL_IP6" ]; then @@ -176,8 +175,7 @@ load_rdr_rule() { error_exit "Failed to create IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" - info "Redirecting IPv6:" - info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi fi } @@ -200,8 +198,7 @@ load_rdr_log_rule() { error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" - info "Redirecting logged IPv4:" - info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi # Create IPv6 rdr rule with log (if ip6.addr is enabled) if [ -n "$JAIL_IP6" ]; then @@ -211,8 +208,7 @@ load_rdr_log_rule() { error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" - info "Redirecting logged IPv6:" - info "${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi fi } From 7cb3e4a8b9407adfdb6186684be71d5111a9a3d0 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 10:46:50 -0700 Subject: [PATCH 048/100] fix ip6 rule syntax --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 431acf4d..a87d6020 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -170,7 +170,7 @@ load_rdr_rule() { # Create IPv6 rdr rule (if ip6.addr is enabled) if [ -n "$JAIL_IP6" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass on $%s inet proto %s to port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then error_exit "Failed to create IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else From 9d37a15703a8a1c1b4095c600251bd562388135b Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 10:49:48 -0700 Subject: [PATCH 049/100] revert/ persist first then load rule --- usr/local/share/bastille/rdr.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index a87d6020..80edcb1c 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -227,7 +227,7 @@ while [ "$#" -gt 0 ]; do usage elif ifconfig | grep -owq "${2}:"; then RDR_IF="${2}" - OPTION="1" + OPTION="1" shift 2 else error_exit "${2} is not a valid interface." @@ -239,7 +239,7 @@ while [ "$#" -gt 0 ]; do else check_rdr_ip_validity "${2}" RDR_SRC="${2}" - OPTION="1" + OPTION="1" shift 2 fi ;; @@ -248,7 +248,7 @@ while [ "$#" -gt 0 ]; do usage elif ifconfig | grep -owq "inet ${2}"; then RDR_DST="${2}" - OPTION="1" + OPTION="1" shift 2 else error_exit "${2} is not an IP on this system." @@ -313,8 +313,8 @@ while [ "$#" -gt 0 ]; do usage elif [ $# -eq 3 ]; then check_jail_validity - load_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 + load_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 shift "$#" else case "$4" in @@ -329,16 +329,16 @@ while [ "$#" -gt 0 ]; do done if [ $2 == "(" ] && [ $last == ")" ] ; then check_jail_validity - load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" - persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift $# else usage fi elif [ $# -eq 1 ]; then check_jail_validity - load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift 1 else usage @@ -355,13 +355,13 @@ while [ "$#" -gt 0 ]; do usage elif [ $# -eq 6 ] && [ "${4}" = "tcp" ] || [ "${4}" = "udp" ]; then check_jail_validity - load_rdr_rule "$@" persist_rdr_rule "$@" + load_rdr_rule "$@" shift $# elif [ $# -ge 7 ] && [ "${7}" = "log" ]; then check_jail_validity - load_rdr_log_rule "$@" persist_rdr_log_rule "$@" + load_rdr_log_rule "$@" shift $# else usage From 031f47f39484da2f349900ab6d9460ffad14a55b Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 10:53:33 -0700 Subject: [PATCH 050/100] fix ipv6 (inet > inet6) --- usr/local/share/bastille/rdr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 80edcb1c..2fda0b0c 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -170,7 +170,7 @@ load_rdr_rule() { # Create IPv6 rdr rule (if ip6.addr is enabled) if [ -n "$JAIL_IP6" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + printf '%s\nrdr pass on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then error_exit "Failed to create IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else @@ -203,7 +203,7 @@ load_rdr_log_rule() { # Create IPv6 rdr rule with log (if ip6.addr is enabled) if [ -n "$JAIL_IP6" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ + printf '%s\nrdr pass %s on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else From 5b4cb721e59c47ce8532a5504158f10650f67ce2 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 12:44:59 -0700 Subject: [PATCH 051/100] add support for dual/ipv4/ipv6 options --- usr/local/share/bastille/rdr.sh | 162 +++++++++++++++++++------------- 1 file changed, 96 insertions(+), 66 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 2fda0b0c..f51ad914 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -40,6 +40,7 @@ usage() { -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. -s | --source [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. -d | --destination [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -t | --type [ipv4|ipv6] | -- Specify IP type. Must be used if -s or -d are used. Defaults to both. EOF exit 1 @@ -62,9 +63,6 @@ TARGET="${1}" JAIL_NAME="" JAIL_IP="" JAIL_IP6="" -RDR_IF="" -RDR_SRC="" -RDR_DST="" shift check_jail_validity() { @@ -124,55 +122,60 @@ check_rdr_ip_validity() { # function: write rule to rdr.conf persist_rdr_rule() { - local if="${1}" - local src="${2}" - local dst="${3}" - local proto="${4}" - local host_port="${5}" - local jail_port="${6}" - if ! grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + local inet="${1}" + local if="${2}" + local src="${3}" + local dst="${4}" + local proto="${5}" + local host_port="${6}" + local jail_port="${7}" + if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$inet $if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" fi } persist_rdr_log_rule() { - local if="${1}" - local src="${2}" - local dst="${3}" - local proto="${4}" - local host_port="${5}" - local jail_port="${6}" - shift 6; + local inet="${1}" + local if="${2}" + local src="${3}" + local dst="${4}" + local proto="${5}" + local host_port="${6}" + local jail_port="${7}" + shift 7; log=$@; - if ! grep -qs "$if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then + echo "$inet $if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" fi } # function: load rdr rule via pfctl load_rdr_rule() { - local if_name="${1}" - local if=ext_if=\"${1}\" - local src="${2}" - local dst="${3}" - local proto="${4}" - local host_port="${5}" - local jail_port="${6}" + local inet="${1}" + local if_name="${2}" + local if=ext_if=\"${2}\" + local src="${3}" + local dst="${4}" + local proto="${5}" + local host_port="${6}" + local jail_port="${7}" # Create IPv4 rdr rule - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; - printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_exit "Failed to create IPv4 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" - else - info "[${JAIL_NAME}]:" - echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + if [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; + printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi fi # Create IPv6 rdr rule (if ip6.addr is enabled) - if [ -n "$JAIL_IP6" ]; then + if [ -n "$JAIL_IP6" ] && [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_exit "Failed to create IPv6 rdr rule \"${1} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + error_exit "Failed to create IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" @@ -182,26 +185,29 @@ load_rdr_rule() { # function: load rdr rule with log via pfctl load_rdr_log_rule() { - local if_name="${1}" - local if=ext_if=\"${1}\" - local src="${2}" - local dst="${3}" - local proto="${4}" - local host_port="${5}" - local jail_port="${6}" - shift 6; + local inet="${1}" + local if_name="${2}" + local if=ext_if=\"${2}\" + local src="${3}" + local dst="${4}" + local proto="${5}" + local host_port="${6}" + local jail_port="${7}" + shift 7; log=$@ # Create IPv4 rule with log - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; - printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then - error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" - else - info "[${JAIL_NAME}]:" - echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + if [ "${inet} = "ipv4" ] || [ "${inet} = "dual" ]; then + if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ + | pfctl -a "rdr/${JAIL_NAME}" -f-; then + error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" + else + info "[${JAIL_NAME}]:" + echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + fi fi # Create IPv6 rdr rule with log (if ip6.addr is enabled) - if [ -n "$JAIL_IP6" ]; then + if [ -n "$JAIL_IP6" ] && [ "${inet} = "ipv6" ] || [ "${inet} = "dual" ]; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then @@ -218,6 +224,11 @@ RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${basti RDR_SRC="any" RDR_DST="any" OPTION="0" +RDR_INET="dual" +OPTION_IF=0 +OPTION_SRC=0 +OPTION_DST=0 +OPTION_TYPE=0 # Check for options while [ "$#" -gt 0 ]; do @@ -226,8 +237,8 @@ while [ "$#" -gt 0 ]; do if [ -z "${2}" ] || [ -z "${3}" ]; then usage elif ifconfig | grep -owq "${2}:"; then + OPTION_IF=1 RDR_IF="${2}" - OPTION="1" shift 2 else error_exit "${2} is not a valid interface." @@ -238,8 +249,8 @@ while [ "$#" -gt 0 ]; do usage else check_rdr_ip_validity "${2}" + OPTION_SRC=1 RDR_SRC="${2}" - OPTION="1" shift 2 fi ;; @@ -248,14 +259,25 @@ while [ "$#" -gt 0 ]; do usage elif ifconfig | grep -owq "inet ${2}"; then RDR_DST="${2}" - OPTION="1" + OPTION_DST=1 shift 2 else error_exit "${2} is not an IP on this system." fi ;; + -t|--type) + if [ -z "${2}" ] || [ -z "${3}" ]; then + usage + elif [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then + usage + else + OPTION_TYPE=1 + RDR_INET="${2}" + shift 2 + fi + ;; list) - if [ "${OPTION}" -eq 1 ];then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage @@ -271,7 +293,7 @@ while [ "$#" -gt 0 ]; do shift ;; clear) - if [ "${OPTION}" -eq 1 ];then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage @@ -287,7 +309,7 @@ while [ "$#" -gt 0 ]; do shift ;; reset) - if [ "${OPTION}" -eq 1 ];then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage @@ -311,10 +333,12 @@ while [ "$#" -gt 0 ]; do tcp|udp) if [ $# -lt 3 ]; then usage + elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_TYPE}" -ne 1 ];then + error_exit "[-t|--type] must be set when using [-s|--source] or [-d|--destination]" elif [ $# -eq 3 ]; then check_jail_validity - persist_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 - load_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 + persist_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 + load_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 shift "$#" else case "$4" in @@ -329,16 +353,16 @@ while [ "$#" -gt 0 ]; do done if [ $2 == "(" ] && [ $last == ")" ] ; then check_jail_validity - persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" - load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift $# else usage fi elif [ $# -eq 1 ]; then check_jail_validity - persist_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" - load_rdr_log_rule $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" + load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift 1 else usage @@ -353,12 +377,18 @@ while [ "$#" -gt 0 ]; do *) if [ "${OPTION}" -eq 1 ];then usage - elif [ $# -eq 6 ] && [ "${4}" = "tcp" ] || [ "${4}" = "udp" ]; then + fi + if [ "${1}" = "dual" ] || [ "${1}" = "ipv4" ] || [ "${1}" = "ipv6" ]; then + RDR_INET="${1}" + else + usage + fi + if [ $# -eq 7 ] && [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; then check_jail_validity persist_rdr_rule "$@" load_rdr_rule "$@" shift $# - elif [ $# -ge 7 ] && [ "${7}" = "log" ]; then + elif [ $# -ge 8 ] && [ "${8}" = "log" ]; then check_jail_validity persist_rdr_log_rule "$@" load_rdr_log_rule "$@" From 2059560dbdb9624c1fcf29bc9b68ce96bcbdcc09 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 16:18:41 -0700 Subject: [PATCH 052/100] list stack when listing ports --- usr/local/share/bastille/list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index a10dc532..d9b281f4 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -207,7 +207,7 @@ list_ports(){ JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") for _JAIL in ${JAIL_LIST}; do if [ -f "${bastille_jailsdir}/${_JAIL}/rdr.conf" ]; then - _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1":"$4"/"$2":"$5" -> "$3":"$6}')" + _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1 $2":"$5"/"$3":"$6" -> "$4":"$7}')" info "[${_JAIL}]:" echo "${_PORTS}" fi From 981268cf8b3e66e1799c8b7dfeb2f646efe6d0b0 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 16:20:20 -0700 Subject: [PATCH 053/100] document -t --- docs/chapters/subcommands/rdr.rst | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index cf2488ac..f02ed621 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -20,19 +20,19 @@ specify the interface they run on in rc.conf (or other config files) -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. -s | --source [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. -d | --destination [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -t | --type [ipv4|ipv6] | -- Specify IP type. Must be used if -s or -d are used. Defaults to both. + # bastille rdr dev1 tcp 2001 22 [jail1]: - Redirecting IPv4: - tcp/any:2001 -> any:22 on em0 + IPv4 tcp/any:2001 -> any:22 on em0 # bastille rdr dev1 list rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 # bastille rdr dev1 udp 2053 53 [jail1]: - Redirecting: - udp/any:2001 -> any:22 on em0 + IPv4 udp/any:2001 -> any:22 on em0 # bastille rdr dev1 list rdr pass on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 @@ -51,23 +51,19 @@ The `rdr` command includes 3 additional options: # bastille rdr dev1 -i vtnet0 udp 2001 22 [jail1]: - Redirecting IPv4: - tcp/any:8000 -> any:80 on vtnet0 + IPv4 tcp/any:8000 -> any:80 on vtnet0 # bastille rdr dev1 -s 192.168.0.1 tcp 8080 81 [jail1]: - Redirecting IPv4: - tcp/192.168.0.1:8080 -> any:81 on em0 + IPv4 tcp/192.168.0.1:8080 -> any:81 on em0 # bastille rdr dev1 -d 192.168.0.84 tcp 8082 82 [jail1]: - Redirecting IPv4: - tcp/any:8082 -> 192.168.0.84:82 on em0 + IPv4 tcp/any:8082 -> 192.168.0.84:82 on em0 # bastille rdr dev1 -i vtnet0 -d 192.168.0.45 tcp 9000 9000 [jail1]: - Redirecting IPv4: - tcp/any:9000 -> 192.168.0.45:9000 on vtnet0 + IPv4 tcp/any:9000 -> 192.168.0.45:9000 on vtnet0 # bastille rdr dev1 list rdr pass on vtnet0 inet proto udp from any to any port = 2001 -> 10.17.89.1 port 22 From 1f899b73a7071c75070f523c66e76549fb7236b9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 16:30:08 -0700 Subject: [PATCH 054/100] add space to list command --- usr/local/share/bastille/list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index d9b281f4..3f74d29f 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -207,7 +207,7 @@ list_ports(){ JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") for _JAIL in ${JAIL_LIST}; do if [ -f "${bastille_jailsdir}/${_JAIL}/rdr.conf" ]; then - _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1 $2":"$5"/"$3":"$6" -> "$4":"$7}')" + _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1" "$2":"$5"/"$3":"$6" -> "$4":"$7}')" info "[${_JAIL}]:" echo "${_PORTS}" fi From bd2a2e1a4ed27e2fdb8d64cfd7bd0573e1ee56b5 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 16:42:44 -0700 Subject: [PATCH 055/100] Typo --- docs/chapters/subcommands/rdr.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index f02ed621..b3be77f2 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -14,7 +14,7 @@ specify the interface they run on in rc.conf (or other config files) .. code-block:: shell # bastille rdr --help - Usage: bastille rdr TARGET [options(s)] [clear|reset|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )] + Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )] Options: -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. From afd7ea7f8f418a56a3cbf0634d4168ba1da3ef91 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 16:43:35 -0700 Subject: [PATCH 056/100] Typo --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index f51ad914..54cc2649 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -32,7 +32,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille rdr TARGET [options(s)] [clear|reset|list|(tcp|udp)] host_port jail_port [log ['(' logopts ')'] ] )]" + error_notify "Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp)] host_port jail_port [log ['(' logopts ')'] ] )]" cat << EOF Options: From 85fecea04f2c4c645466a6ea870966bb56e9df2d Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 14 Dec 2024 18:42:28 -0700 Subject: [PATCH 057/100] var rename for clarity --- usr/local/share/bastille/rdr.sh | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 54cc2649..dae0f00d 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -48,9 +48,9 @@ EOF # Handle special-case commands first. case "$1" in -help|-h|--help) - usage - ;; + help|-h|--help) + usage + ;; esac if [ $# -lt 2 ]; then @@ -80,10 +80,11 @@ check_jail_validity() { # Check if jail ip4 address (ip4.addr) is valid (non-VNET only) if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then JAIL_IP=$(/usr/sbin/jls -j "${TARGET}" ip4.addr 2>/dev/null) - if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then + if [ -z "${JAIL_IP}" ] || [ "${JAIL_IP}" = "-" ]; then error_exit "Jail IP not found: ${TARGET}" fi fi + # Check if jail ip6 address (ip6.addr) is valid (non-VNET only) if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then if [ "$(bastille config $TARGET get ip6)" != 'disable' ] && [ "$(bastille config $TARGET get ip6)" != 'not set' ]; then @@ -97,6 +98,7 @@ check_jail_validity() { fi } +# function: check if IP is valid check_rdr_ip_validity() { local ip="$1" local ip6=$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') @@ -228,7 +230,7 @@ RDR_INET="dual" OPTION_IF=0 OPTION_SRC=0 OPTION_DST=0 -OPTION_TYPE=0 +OPTION_INET_TYPE=0 # Check for options while [ "$#" -gt 0 ]; do @@ -258,8 +260,8 @@ while [ "$#" -gt 0 ]; do if [ -z "${2}" ] || [ -z "${3}" ]; then usage elif ifconfig | grep -owq "inet ${2}"; then + OPTION_DST=1 RDR_DST="${2}" - OPTION_DST=1 shift 2 else error_exit "${2} is not an IP on this system." @@ -271,13 +273,13 @@ while [ "$#" -gt 0 ]; do elif [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then usage else - OPTION_TYPE=1 + OPTION_INET_TYPE=1 RDR_INET="${2}" shift 2 fi ;; list) - if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_TYPE}" -eq 1 ];then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage @@ -293,7 +295,7 @@ while [ "$#" -gt 0 ]; do shift ;; clear) - if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_TYPE}" -eq 1 ];then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage @@ -309,7 +311,7 @@ while [ "$#" -gt 0 ]; do shift ;; reset) - if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_TYPE}" -eq 1 ];then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage @@ -333,7 +335,7 @@ while [ "$#" -gt 0 ]; do tcp|udp) if [ $# -lt 3 ]; then usage - elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_TYPE}" -ne 1 ];then + elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_INET_TYPE}" -ne 1 ];then error_exit "[-t|--type] must be set when using [-s|--source] or [-d|--destination]" elif [ $# -eq 3 ]; then check_jail_validity From 71b1f8ce1d1410144afe2175a99d3b10c7566c7a Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 15 Dec 2024 08:55:46 -0700 Subject: [PATCH 058/100] simply print rdr file when listing ports --- usr/local/share/bastille/list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 3f74d29f..21b7db01 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -207,7 +207,7 @@ list_ports(){ JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") for _JAIL in ${JAIL_LIST}; do if [ -f "${bastille_jailsdir}/${_JAIL}/rdr.conf" ]; then - _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf | awk '{print $1" "$2":"$5"/"$3":"$6" -> "$4":"$7}')" + _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf)" info "[${_JAIL}]:" echo "${_PORTS}" fi From a717b09d0fdb050e0a21fb0d5b513ea4d430af76 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 15 Dec 2024 08:57:02 -0700 Subject: [PATCH 059/100] print less info --- usr/local/share/bastille/rdr.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index dae0f00d..f1842f85 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -169,7 +169,7 @@ load_rdr_rule() { error_exit "Failed to create IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" - echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv4 ${proto}/${host_port}:${jail_port} on ${if_name}" fi fi # Create IPv6 rdr rule (if ip6.addr is enabled) @@ -180,7 +180,7 @@ load_rdr_rule() { error_exit "Failed to create IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" - echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv6 ${proto}/${host_port}:${jail_port} on ${if_name}" fi fi } @@ -205,7 +205,7 @@ load_rdr_log_rule() { error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" - echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv4 ${proto}/${host_port}:${jail_port} on ${if_name}" fi fi # Create IPv6 rdr rule with log (if ip6.addr is enabled) @@ -216,7 +216,7 @@ load_rdr_log_rule() { error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${JAIL_NAME}]:" - echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv6 ${proto}/${host_port}:${jail_port} on ${if_name}" fi fi } From 0c80326e3a305f4150a8b990699b50f630495ed9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 16 Dec 2024 09:34:54 -0700 Subject: [PATCH 060/100] fix quotes --- usr/local/share/bastille/rdr.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index c127c904..68560d66 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -101,7 +101,7 @@ check_jail_validity() { # function: check if IP is valid check_rdr_ip_validity() { local ip="$1" - local ip6=$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)') + local ip6="$(echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)')" if [ -n "${ip6}" ]; then info "Valid: (${ip6})." else @@ -198,7 +198,7 @@ load_rdr_log_rule() { shift 7; log=$@ # Create IPv4 rule with log - if [ "${inet} = "ipv4" ] || [ "${inet} = "dual" ]; then + if { [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; }; then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then @@ -209,7 +209,7 @@ load_rdr_log_rule() { fi fi # Create IPv6 rdr rule with log (if ip6.addr is enabled) - if [ -n "$JAIL_IP6" ] && [ "${inet} = "ipv6" ] || [ "${inet} = "dual" ]; then + if [ -n "$JAIL_IP6" ] && { [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; };then if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; printf '%s\nrdr pass %s on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ | pfctl -a "rdr/${JAIL_NAME}" -f-; then From fd4c5111b50caae001ca55a8729c95f9e7f41003 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 16 Dec 2024 23:00:20 -0700 Subject: [PATCH 061/100] cleanup --- usr/local/share/bastille/rdr.sh | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index ae7d6b3b..7e46390f 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -225,7 +225,6 @@ load_rdr_log_rule() { RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" RDR_SRC="any" RDR_DST="any" -OPTION="0" RDR_INET="dual" OPTION_IF=0 OPTION_SRC=0 @@ -260,7 +259,7 @@ while [ "$#" -gt 0 ]; do if [ -z "${2}" ] || [ -z "${3}" ]; then usage elif ifconfig | grep -owq "inet ${2}"; then - OPTION_DST=1 + OPTION_DST=1 RDR_DST="${2}" shift 2 else @@ -279,9 +278,9 @@ while [ "$#" -gt 0 ]; do fi ;; list) - if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ]; then error_exit "Command \"${1}\" cannot be used with options." - elif [ -n "${2}" ]; then + elif [ -n "${2}" ]; then usage elif [ "${TARGET}" = 'ALL' ]; then for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do @@ -295,7 +294,7 @@ while [ "$#" -gt 0 ]; do shift ;; clear) - if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ]; then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage @@ -311,7 +310,7 @@ while [ "$#" -gt 0 ]; do shift ;; reset) - if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ]; then error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage @@ -335,7 +334,7 @@ while [ "$#" -gt 0 ]; do tcp|udp) if [ $# -lt 3 ]; then usage - elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_INET_TYPE}" -ne 1 ];then + elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_INET_TYPE}" -ne 1 ]; then error_exit "[-t|--type] must be set when using [-s|--source] or [-d|--destination]" elif [ $# -eq 3 ]; then check_jail_validity From 6f0d318fd3356e468acc6dd74df8713568dcc8dc Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:43:22 -0700 Subject: [PATCH 062/100] rdr: Add debug option, code cleanup --- usr/local/share/bastille/rdr.sh | 261 +++++++++++++++----------------- 1 file changed, 122 insertions(+), 139 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 7e46390f..2f4fb6cd 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -32,82 +32,52 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp)] host_port jail_port [log ['(' logopts ')'] ] )]" - + error_notify "Usage: bastille rdr [option(s)] TARGET [clear|reset|list|(tcp|udp)] HOST_PORT JAIL_PORT [log ['(' logopts ')'] ] )]" cat << EOF Options: - -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. - -s | --source [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. - -d | --destination [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. - -t | --type [ipv4|ipv6] | -- Specify IP type. Must be used if -s or -d are used. Defaults to both. + -d | --destination [destination ip] Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -i | --interface [interface] Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s | --source [source ip] Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -t | --type [ipv4|ipv6] Specify IP type. Must be used if -s or -d are used. Defaults to both. + -x | --debug Enable debug mode. EOF exit 1 } -# Handle special-case commands first. -case "$1" in - help|-h|--help) - usage - ;; -esac - -if [ $# -lt 2 ]; then - usage -fi - -bastille_root_check - -TARGET="${1}" -JAIL_NAME="" -JAIL_IP="" -JAIL_IP6="" -shift - check_jail_validity() { - # Can only redirect to single jail - if [ "${TARGET}" = 'ALL' ]; then - error_exit "Can only redirect to a single jail." - fi - # Check if jail name is valid - JAIL_NAME=$(/usr/sbin/jls -j "${TARGET}" name 2>/dev/null) - if [ -z "${JAIL_NAME}" ]; then - error_exit "Jail not found: ${TARGET}" - fi - - # Check if jail ip4 address (ip4.addr) is valid (non-VNET only) - if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then - JAIL_IP=$(/usr/sbin/jls -j "${TARGET}" ip4.addr 2>/dev/null) - if [ -z "${JAIL_IP}" ] || [ "${JAIL_IP}" = "-" ]; then - error_exit "Jail IP not found: ${TARGET}" + if [ "$( bastille config ${TARGET} get vnet )" != 'enabled' ]; then + _ip4_interfaces="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')" + _ip6_interfaces="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')" + # Check if jail ip4.addr is valid (non-VNET only) + if [ "${_ip4_interfaces}" != "not set" ] && [ "${_ip4_interfaces}" != "disable" ]; then + JAIL_IP="$(bastille config ${TARGET} get ip4.addr | awk '{print $1}' | awk -F"|" '{print $2}')" fi + # Check if jail ip6.addr is valid (non-VNET only) + if [ "${_ip6_interfaces}" != "not set" ] && [ "${_ip6_interfaces}" != "disable" ]; then + JAIL_IP6="$(bastille config ${TARGET} get ip6.addr | awk '{print $1}' | awk -F"|" '{print $2}')" + fi + else + error_exit "VNET jails do not support rdr." fi - # Check if jail ip6 address (ip6.addr) is valid (non-VNET only) - if [ "$(bastille config $TARGET get vnet)" != 'enabled' ]; then - if [ "$(bastille config $TARGET get ip6)" != 'disable' ] && [ "$(bastille config $TARGET get ip6)" != 'not set' ]; then - JAIL_IP6=$(/usr/sbin/jls -j "${TARGET}" ip6.addr 2>/dev/null) - fi - fi - # Check if rdr-anchor is defined in pf.conf if ! (pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then error_exit "rdr-anchor not found in pf.conf" fi } -# function: check if IP is valid check_rdr_ip_validity() { - local ip4="$1" - local ip6="$(echo "${ip4}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)')" + local ip="${1}" + local ip6="$( echo "${ip}" | grep -E '^(([a-fA-F0-9:]+$)|([a-fA-F0-9:]+\/[0-9]{1,3}$)|SLAAC)' )" if [ -n "${ip6}" ]; then info "Valid: (${ip6})." else local IFS - if echo "${ip4}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then - TEST_IP=$(echo "${ip4}" | cut -d / -f1) + if echo "${ip}" | grep -Eq '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))?$'; then + TEST_IP=$(echo "${ip}" | cut -d / -f1) IFS=. set ${TEST_IP} for quad in 1 2 3 4; do @@ -115,14 +85,13 @@ check_rdr_ip_validity() { error_exit "Invalid: (${TEST_IP})" fi done - info "Valid: (${ip4})." + info "Valid: (${ip})." else - error_exit "Invalid: (${ip4})." + error_exit "Invalid: (${ip})." fi fi } -# function: write rule to rdr.conf persist_rdr_rule() { local inet="${1}" local if="${2}" @@ -131,8 +100,8 @@ persist_rdr_rule() { local proto="${5}" local host_port="${6}" local jail_port="${7}" - if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$inet $if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then + echo "$inet $if $src $dst $proto $host_port $jail_port" >> "${bastille_jailsdir}/${TARGET}/rdr.conf" fi } @@ -146,12 +115,11 @@ persist_rdr_log_rule() { local jail_port="${7}" shift 7; log=$@; - if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf"; then - echo "$inet $if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${JAIL_NAME}/rdr.conf" + if ! grep -qs "$inet $if $src $dst $proto $host_port $jail_port $log" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then + echo "$inet $if $src $dst $proto $host_port $jail_port $log" >> "${bastille_jailsdir}/${TARGET}/rdr.conf" fi } -# function: load rdr rule via pfctl load_rdr_rule() { local inet="${1}" local if_name="${2}" @@ -162,30 +130,31 @@ load_rdr_rule() { local host_port="${6}" local jail_port="${7}" # Create IPv4 rdr rule - if [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null; + # shellcheck disable=SC2193 + if { [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; } then + if ! ( pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null; printf '%s\nrdr pass on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then + | pfctl -a "rdr/${TARGET}" -f-; then error_exit "Failed to create IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else - info "[${JAIL_NAME}]:" + info "[${TARGET}]:" echo "IPv4 ${proto}/${host_port}:${jail_port} on ${if_name}" fi fi # Create IPv6 rdr rule (if ip6.addr is enabled) - if [ -n "$JAIL_IP6" ] && [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + # shellcheck disable=SC2193 + if [ -n "${JAIL_IP6}" ] && { [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; } then + if ! ( pfctl -a "rdr/${TARGET}" -Psn; printf '%s\nrdr pass on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then + | pfctl -a "rdr/${TARGET}" -f-; then error_exit "Failed to create IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else - info "[${JAIL_NAME}]:" - echo "IPv6 ${proto}/${host_port}:${jail_port} on ${if_name}" + info "[${TARGET}]:" + echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi fi } -# function: load rdr rule with log via pfctl load_rdr_log_rule() { local inet="${1}" local if_name="${2}" @@ -198,30 +167,32 @@ load_rdr_log_rule() { shift 7; log=$@ # Create IPv4 rule with log - if { [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; }; then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + # shellcheck disable=SC2193 + if { [ "${inet}" = "ipv4" ] || [ "${inet}" = "dual" ]; } then + if ! ( pfctl -a "rdr/${TARGET}" -Psn; printf '%s\nrdr pass %s on $%s inet proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then + | pfctl -a "rdr/${TARGET}" -f-; then error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else - info "[${JAIL_NAME}]:" - echo "IPv4 ${proto}/${host_port}:${jail_port} on ${if_name}" + info "[${TARGET}]:" + echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi fi # Create IPv6 rdr rule with log (if ip6.addr is enabled) - if [ -n "$JAIL_IP6" ] && { [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; };then - if ! ( pfctl -a "rdr/${JAIL_NAME}" -Psn; + # shellcheck disable=SC2193 + if [ -n "${JAIL_IP6}" ] && { [ "${inet}" = "ipv6" ] || [ "${inet}" = "dual" ]; } then + if ! ( pfctl -a "rdr/${TARGET}" -Psn; printf '%s\nrdr pass %s on $%s inet6 proto %s from %s to %s port %s -> %s port %s\n' "$if" "$log" "${bastille_network_pf_ext_if}" "$proto" "$src" "$dst" "$host_port" "$JAIL_IP6" "$jail_port" ) \ - | pfctl -a "rdr/${JAIL_NAME}" -f-; then + | pfctl -a "rdr/${TARGET}" -f-; then error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else - info "[${JAIL_NAME}]:" - echo "IPv6 ${proto}/${host_port}:${jail_port} on ${if_name}" + info "[${TARGET}]:" + echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" fi fi } -# Set defaults +# Handle options. RDR_IF="$(grep "^[[:space:]]*${bastille_network_pf_ext_if}[[:space:]]*=" ${bastille_pf_conf} | awk -F'"' '{print $2}')" RDR_SRC="any" RDR_DST="any" @@ -230,14 +201,13 @@ OPTION_IF=0 OPTION_SRC=0 OPTION_DST=0 OPTION_INET_TYPE=0 - -# Check for options while [ "$#" -gt 0 ]; do - case "$1" in + case "${1}" in + -h|--help|help) + usage + ;; -i|--interface) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - elif ifconfig | grep -owq "${2}:"; then + if ifconfig | grep -owq "${2}:"; then OPTION_IF=1 RDR_IF="${2}" shift 2 @@ -246,19 +216,13 @@ while [ "$#" -gt 0 ]; do fi ;; -s|--source) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - else - check_rdr_ip_validity "${2}" - OPTION_SRC=1 - RDR_SRC="${2}" - shift 2 - fi + check_rdr_ip_validity "${2}" + OPTION_SRC=1 + RDR_SRC="${2}" + shift 2 ;; -d|--destination) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - elif ifconfig | grep -owq "inet ${2}"; then + if ifconfig | grep -owq "inet ${2}"; then OPTION_DST=1 RDR_DST="${2}" shift 2 @@ -267,92 +231,113 @@ while [ "$#" -gt 0 ]; do fi ;; -t|--type) - if [ -z "${2}" ] || [ -z "${3}" ]; then - usage - elif [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then - usage + if [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then + error_exit "[-t|--type] must be [ipv4|ipv6]" else OPTION_INET_TYPE=1 RDR_INET="${2}" shift 2 fi ;; + -*) + error_exit "Unknown option: \"${1}\"" + ;; + *) + break + ;; + esac +done + +if [ "$#" -lt 2 ]; then + usage +fi + +TARGET="${1}" +JAIL_IP="" +JAIL_IP6="" +shift + +bastille_root_check +set_target_single "${TARGET}" + +while [ "$#" -gt 0 ]; do + case "${1}" in list) - if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ]; then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." - elif [ -n "${2}" ]; then + elif [ -n "${2}" ]; then usage elif [ "${TARGET}" = 'ALL' ]; then - for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${JAIL_NAME} redirects:" - pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null + for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do + echo "${_jail} redirects:" + pfctl -a "rdr/${_jail}" -Psn 2>/dev/null done else check_jail_validity - pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null + pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null fi shift ;; clear) - if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ]; then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." - elif [ -n "${2}" ]; then + elif [ -n "${2}" ]; then usage elif [ "${TARGET}" = 'ALL' ]; then - for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${JAIL_NAME} redirects:" - pfctl -a "rdr/${JAIL_NAME}" -Fn + for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do + echo "${_jail} redirects:" + pfctl -a "rdr/${_jail}" -Fn done else check_jail_validity - pfctl -a "rdr/${JAIL_NAME}" -Fn + pfctl -a "rdr/${TARGET}" -Fn fi shift ;; reset) - if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ]; then + if [ "${OPTION_IF}" -eq 1 ] || [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ];then error_exit "Command \"${1}\" cannot be used with options." - elif [ -n "${2}" ]; then + elif [ -n "${2}" ]; then usage elif [ "${TARGET}" = 'ALL' ]; then - for JAIL_NAME in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${JAIL_NAME} redirects:" - pfctl -a "rdr/${JAIL_NAME}" -Fn - if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then - info "[${JAIL_NAME}]: rdr.conf removed" - fi + for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do + echo "${_jail} redirects:" + pfctl -a "rdr/${_jail}" -Fn + if rm -f "${bastille_jailsdir}"/"${_jail}"/rdr.conf; then + info "[${_jail}]: rdr.conf removed" + fi done else check_jail_validity - pfctl -a "rdr/${JAIL_NAME}" -Fn - if rm -f "${bastille_jailsdir}"/"${JAIL_NAME}"/rdr.conf; then - info "[${JAIL_NAME}]: rdr.conf removed" - fi + pfctl -a "rdr/${TARGET}" -Fn + if rm -f "${bastille_jailsdir}"/"${_jail}"/rdr.conf; then + info "[${TARGET}]: rdr.conf removed" + fi fi shift ;; tcp|udp) - if [ $# -lt 3 ]; then + if [ "$#" -lt 3 ]; then usage - elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_INET_TYPE}" -ne 1 ]; then + elif [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] && [ "${OPTION_INET_TYPE}" -ne 1 ];then error_exit "[-t|--type] must be set when using [-s|--source] or [-d|--destination]" - elif [ $# -eq 3 ]; then + elif [ "$#" -eq 3 ]; then check_jail_validity persist_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 load_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 shift "$#" else - case "$4" in + case "${4}" in log) proto=$1 host_port=$2 jail_port=$3 shift 3 - if [ $# -gt 3 ]; then + if [ "$#" -gt 3 ]; then for last in "$@"; do true done - if [ "$2" = "(" ] && [ "$last" = ")" ] ; then + if [ "${2}" = "(" ] && [ "${last}" = ")" ] ; then check_jail_validity persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" @@ -376,23 +361,21 @@ while [ "$#" -gt 0 ]; do fi ;; *) - if [ "${OPTION_SRC}" -eq 1 ] || [ "${OPTION_DST}" -eq 1 ] || [ "${OPTION_INET_TYPE}" -eq 1 ] || [ "${OPTION_IF}" -eq 1 ]; then - usage - elif [ "${1}" = "dual" ] || [ "${1}" = "ipv4" ] || [ "${1}" = "ipv6" ]; then + if [ "${1}" = "dual" ] || [ "${1}" = "ipv4" ] || [ "${1}" = "ipv6" ]; then RDR_INET="${1}" else usage fi - if [ $# -eq 7 ] && [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; then + if [ "$#" -eq 7 ] && { [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; } then check_jail_validity persist_rdr_rule "$@" load_rdr_rule "$@" - shift $# - elif [ $# -ge 8 ] && [ "${8}" = "log" ]; then + shift "$#" + elif [ "$#" -ge 8 ] && [ "${8}" = "log" ]; then check_jail_validity persist_rdr_log_rule "$@" load_rdr_log_rule "$@" - shift $# + shift "$#" else usage fi From ada6c2d61c7835b573a24fb84af2849c3a1b0d8b Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:03:00 -0700 Subject: [PATCH 063/100] rdr: correctly print default interface IP --- usr/local/share/bastille/rdr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 2f4fb6cd..225e62a2 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -53,11 +53,11 @@ check_jail_validity() { _ip6_interfaces="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')" # Check if jail ip4.addr is valid (non-VNET only) if [ "${_ip4_interfaces}" != "not set" ] && [ "${_ip4_interfaces}" != "disable" ]; then - JAIL_IP="$(bastille config ${TARGET} get ip4.addr | awk '{print $1}' | awk -F"|" '{print $2}')" + JAIL_IP="$(echo ${_ip4_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" fi # Check if jail ip6.addr is valid (non-VNET only) if [ "${_ip6_interfaces}" != "not set" ] && [ "${_ip6_interfaces}" != "disable" ]; then - JAIL_IP6="$(bastille config ${TARGET} get ip6.addr | awk '{print $1}' | awk -F"|" '{print $2}')" + JAIL_IP6="$(echo ${_ip6_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" fi else error_exit "VNET jails do not support rdr." From a169beb073ce6ac933b331c4935d1d12bb7ee7b4 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:55:36 -0700 Subject: [PATCH 064/100] rdr: do not allow rules to be duplicated between jails --- usr/local/share/bastille/rdr.sh | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 225e62a2..a7b57de2 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -47,7 +47,6 @@ EOF } check_jail_validity() { - if [ "$( bastille config ${TARGET} get vnet )" != 'enabled' ]; then _ip4_interfaces="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')" _ip6_interfaces="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')" @@ -92,6 +91,19 @@ check_rdr_ip_validity() { fi } +validate_rdr_rule() { + local if="${1}" + local src="${2}" + local dst="${3}" + local proto="${4}" + local host_port="${5}" + local jail_port="${6}" + if grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then + error_notify "Error: Ports already in use on this interface." + error_exit "See 'bastille list ports' or 'bastille rdr TARGET clear'." + fi +} + persist_rdr_rule() { local inet="${1}" local if="${2}" @@ -239,6 +251,10 @@ while [ "$#" -gt 0 ]; do shift 2 fi ;; + -x|--debug) + enable_debug + shift + ;; -*) error_exit "Unknown option: \"${1}\"" ;; @@ -323,6 +339,7 @@ while [ "$#" -gt 0 ]; do error_exit "[-t|--type] must be set when using [-s|--source] or [-d|--destination]" elif [ "$#" -eq 3 ]; then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 load_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 shift "$#" @@ -339,6 +356,7 @@ while [ "$#" -gt 0 ]; do done if [ "${2}" = "(" ] && [ "${last}" = ")" ] ; then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift $# @@ -347,6 +365,7 @@ while [ "$#" -gt 0 ]; do fi elif [ $# -eq 1 ]; then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" load_rdr_log_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $proto $host_port $jail_port "$@" shift 1 @@ -368,11 +387,13 @@ while [ "$#" -gt 0 ]; do fi if [ "$#" -eq 7 ] && { [ "${5}" = "tcp" ] || [ "${5}" = "udp" ]; } then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_rule "$@" load_rdr_rule "$@" shift "$#" elif [ "$#" -ge 8 ] && [ "${8}" = "log" ]; then check_jail_validity + validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_log_rule "$@" load_rdr_log_rule "$@" shift "$#" From b7c861f6f921bca5893006e479e24922dae17323 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 7 Jan 2025 22:58:54 -0700 Subject: [PATCH 065/100] rdr: clear > reset notify on duplicate jail rules --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index a7b57de2..0c323156 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -100,7 +100,7 @@ validate_rdr_rule() { local jail_port="${6}" if grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then error_notify "Error: Ports already in use on this interface." - error_exit "See 'bastille list ports' or 'bastille rdr TARGET clear'." + error_exit "See 'bastille list ports' or 'bastille rdr TARGET reset'." fi } From e5f56558287f2f94a7ffa107d29f8ccc737dd6fc Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 7 Jan 2025 23:15:02 -0700 Subject: [PATCH 066/100] rdr: Allow only a single target --- usr/local/share/bastille/rdr.sh | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 0c323156..0361a2fc 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -100,7 +100,7 @@ validate_rdr_rule() { local jail_port="${6}" if grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then error_notify "Error: Ports already in use on this interface." - error_exit "See 'bastille list ports' or 'bastille rdr TARGET reset'." + error_exit "See 'bastille list ports' or 'bastille rdr TARGET clear'." fi } @@ -283,11 +283,6 @@ while [ "$#" -gt 0 ]; do error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage - elif [ "${TARGET}" = 'ALL' ]; then - for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${_jail} redirects:" - pfctl -a "rdr/${_jail}" -Psn 2>/dev/null - done else check_jail_validity pfctl -a "rdr/${TARGET}" -Psn 2>/dev/null @@ -299,14 +294,10 @@ while [ "$#" -gt 0 ]; do error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage - elif [ "${TARGET}" = 'ALL' ]; then - for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${_jail} redirects:" - pfctl -a "rdr/${_jail}" -Fn - done else check_jail_validity - pfctl -a "rdr/${TARGET}" -Fn + echo "${_jail} redirects:" + pfctl -a "rdr/${_jail}" -Fn fi shift ;; @@ -315,19 +306,12 @@ while [ "$#" -gt 0 ]; do error_exit "Command \"${1}\" cannot be used with options." elif [ -n "${2}" ]; then usage - elif [ "${TARGET}" = 'ALL' ]; then - for _jail in $(ls "${bastille_jailsdir}" | sed "s/\n//g"); do - echo "${_jail} redirects:" - pfctl -a "rdr/${_jail}" -Fn - if rm -f "${bastille_jailsdir}"/"${_jail}"/rdr.conf; then - info "[${_jail}]: rdr.conf removed" - fi - done else check_jail_validity - pfctl -a "rdr/${TARGET}" -Fn - if rm -f "${bastille_jailsdir}"/"${_jail}"/rdr.conf; then - info "[${TARGET}]: rdr.conf removed" + echo "${_jail} redirects:" + pfctl -a "rdr/${_jail}" -Fn + if rm -f "${bastille_jailsdir}/${_jail}/rdr.conf"; then + info "[${_jail}]: rdr.conf removed" fi fi shift From 2da817e0d435475741d45b97e62c720d49058a6d Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 7 Jan 2025 23:16:35 -0700 Subject: [PATCH 067/100] list: use list command for jail list --- usr/local/share/bastille/list.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 0a6b6b3c..085ba0cb 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -224,11 +224,11 @@ list_import(){ list_ports(){ if [ -d "${bastille_jailsdir}" ]; then - JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") - for _JAIL in ${JAIL_LIST}; do - if [ -f "${bastille_jailsdir}/${_JAIL}/rdr.conf" ]; then - _PORTS="$(cat "${bastille_jailsdir}"/"${_JAIL}"/rdr.conf)" - info "[${_JAIL}]:" + JAIL_LIST="$(bastille list jails)" + for _jail in ${JAIL_LIST}; do + if [ -f "${bastille_jailsdir}/${_jail}/rdr.conf" ]; then + _PORTS="$(cat ${bastille_jailsdir}/${_jail}/rdr.conf)" + info "[${_jail}]:" echo "${_PORTS}" fi done From eee99a3b799a9abcce50091eb43baa86efb6969f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:25:15 -0700 Subject: [PATCH 068/100] rdr: fix _jail > TARGET + alphabetical option order --- usr/local/share/bastille/rdr.sh | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 0361a2fc..2af4bf54 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -47,6 +47,8 @@ EOF } check_jail_validity() { + + # Validate jail network type and set IP4/6 if [ "$( bastille config ${TARGET} get vnet )" != 'enabled' ]; then _ip4_interfaces="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')" _ip6_interfaces="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')" @@ -218,6 +220,15 @@ while [ "$#" -gt 0 ]; do -h|--help|help) usage ;; + -d|--destination) + if ifconfig | grep -owq "inet ${2}"; then + OPTION_DST=1 + RDR_DST="${2}" + shift 2 + else + error_exit "${2} is not an IP on this system." + fi + ;; -i|--interface) if ifconfig | grep -owq "${2}:"; then OPTION_IF=1 @@ -233,15 +244,6 @@ while [ "$#" -gt 0 ]; do RDR_SRC="${2}" shift 2 ;; - -d|--destination) - if ifconfig | grep -owq "inet ${2}"; then - OPTION_DST=1 - RDR_DST="${2}" - shift 2 - else - error_exit "${2} is not an IP on this system." - fi - ;; -t|--type) if [ "${2}" != "ipv4" ] && [ "${2}" != "ipv6" ]; then error_exit "[-t|--type] must be [ipv4|ipv6]" @@ -296,8 +298,8 @@ while [ "$#" -gt 0 ]; do usage else check_jail_validity - echo "${_jail} redirects:" - pfctl -a "rdr/${_jail}" -Fn + echo "${TARGET} redirects:" + pfctl -a "rdr/${TARGET}" -Fn fi shift ;; @@ -308,10 +310,10 @@ while [ "$#" -gt 0 ]; do usage else check_jail_validity - echo "${_jail} redirects:" - pfctl -a "rdr/${_jail}" -Fn + echo "${TARGET} redirects:" + pfctl -a "rdr/${TARGET}" -Fn if rm -f "${bastille_jailsdir}/${_jail}/rdr.conf"; then - info "[${_jail}]: rdr.conf removed" + info "[${TARGET}]: rdr.conf removed" fi fi shift From 685c8f9079d45c524ed3e177e66f155298df69a4 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:31:47 -0700 Subject: [PATCH 069/100] doc: rdr with multiple interfaces --- docs/chapters/subcommands/rdr.rst | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index b3be77f2..2a4f9927 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -2,7 +2,7 @@ rdr === -bastille rdr allows you to configure dynamic rdr rules for your containers +`bastille rdr` allows you to configure dynamic rdr rules for your containers without modifying pf.conf (assuming you are using the `bastille0` interface for a private network and have enabled `rdr-anchor 'rdr/*'` in /etc/pf.conf as described in the Networking section). @@ -17,11 +17,11 @@ specify the interface they run on in rc.conf (or other config files) Usage: bastille rdr TARGET [option(s)] [clear|reset|list|(tcp|udp host_port jail_port [log ['(' logopts ')'] ] )] Options: - -i | --interface [interface] | -- Set the interface to create the rdr rule on. Useful if you have multiple interfaces. - -s | --source [source ip] | -- Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. - -d | --destination [destination ip] | -- Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. - -t | --type [ipv4|ipv6] | -- Specify IP type. Must be used if -s or -d are used. Defaults to both. - + -i | --interface [interface] Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s | --source [source ip] Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -d | --destination [destination ip] Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -t | --type [ipv4|ipv6] Specify IP type. Must be used if -s or -d are used. Defaults to both. + -x | --debug Enable debug mode. # bastille rdr dev1 tcp 2001 22 [jail1]: @@ -41,11 +41,12 @@ specify the interface they run on in rc.conf (or other config files) # bastille rdr dev1 clear nat cleared -The `rdr` command includes 3 additional options: +The `rdr` command includes 4 additional options: - **-i** | Set a non-default interface on which to create the `rdr` rule. - **-s** | Limit the source IP on the `rdr` rule. - **-d** | Limit the destination IP on the `rdr` rule. +- **-t** | Specify network type. Can be "ipv4" or "ipv6". Default is "dual". .. code-block:: shell @@ -72,3 +73,6 @@ The `rdr` command includes 3 additional options: rdr pass on vtnet0 inet proto tcp from any to 192.168.0.45 port = 9000 -> 10.17.89.1 port 9000 The options can be used together, as seen above. + +If you have multiple interfaces assigned to your jail, `bastille rdr` will +only redirect using the default one. From 780f93ca1668820d4463330b20e6c81c21a066ef Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:07:25 -0700 Subject: [PATCH 070/100] rdr: spacing fix and usage message remove additional ] --- usr/local/share/bastille/rdr.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 4dc4b1a5..0320e19f 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -34,7 +34,7 @@ . /usr/local/etc/bastille/bastille.conf usage() { - error_notify "Usage: bastille rdr [option(s)] TARGET [clear|reset|list|(tcp|udp)] HOST_PORT JAIL_PORT [log ['(' logopts ')'] ] )]" + error_notify "Usage: bastille rdr [option(s)] TARGET [clear|reset|list|(tcp|udp)] HOST_PORT JAIL_PORT [log ['(' logopts ')'] ]" cat << EOF Options: @@ -49,7 +49,6 @@ EOF } check_jail_validity() { - # Validate jail network type and set IP4/6 if [ "$( bastille config ${TARGET} get vnet )" != 'enabled' ]; then _ip4_interfaces="$(bastille config ${TARGET} get ip4.addr | sed 's/,/ /g')" From ba50618b51ca5f49e9c0b0997d4691f82ade75b4 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:09:29 -0700 Subject: [PATCH 071/100] docs: update rdr docs with code block for options --- docs/chapters/subcommands/rdr.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index 2a4f9927..72a9eefa 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -43,10 +43,12 @@ specify the interface they run on in rc.conf (or other config files) The `rdr` command includes 4 additional options: -- **-i** | Set a non-default interface on which to create the `rdr` rule. -- **-s** | Limit the source IP on the `rdr` rule. -- **-d** | Limit the destination IP on the `rdr` rule. -- **-t** | Specify network type. Can be "ipv4" or "ipv6". Default is "dual". +.. code-block:: shell + + -i | --interface [interface] Set the interface to create the rdr rule on. Useful if you have multiple interfaces. + -s | --source [source ip] Limit rdr to a source IP. Useful to only allow access from a certian IP or subnet. + -d | --destination [destination ip] Limit rdr to a destination IP. Useful if you have multiple IPs on one interface. + -t | --type [ipv4|ipv6] Specify IP type. Must be used if -s or -d are used. Defaults to both. .. code-block:: shell From 0696152aa4d2e19ffc16423918a5187706219e81 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:13:29 -0700 Subject: [PATCH 072/100] docs: rdr, fix info return block --- docs/chapters/subcommands/rdr.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/chapters/subcommands/rdr.rst b/docs/chapters/subcommands/rdr.rst index 72a9eefa..262f83b8 100644 --- a/docs/chapters/subcommands/rdr.rst +++ b/docs/chapters/subcommands/rdr.rst @@ -25,14 +25,14 @@ specify the interface they run on in rc.conf (or other config files) # bastille rdr dev1 tcp 2001 22 [jail1]: - IPv4 tcp/any:2001 -> any:22 on em0 + IPv4 tcp/2001:22 on em0 # bastille rdr dev1 list rdr on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 # bastille rdr dev1 udp 2053 53 [jail1]: - IPv4 udp/any:2001 -> any:22 on em0 + IPv4 udp/2053:53 on em0 # bastille rdr dev1 list rdr pass on em0 inet proto tcp from any to any port = 2001 -> 10.17.89.1 port 22 @@ -52,21 +52,21 @@ The `rdr` command includes 4 additional options: .. code-block:: shell - # bastille rdr dev1 -i vtnet0 udp 2001 22 + # bastille rdr dev1 -i vtnet0 udp 8000 80 [jail1]: - IPv4 tcp/any:8000 -> any:80 on vtnet0 + IPv4 tcp/8000:80 on vtnet0 # bastille rdr dev1 -s 192.168.0.1 tcp 8080 81 [jail1]: - IPv4 tcp/192.168.0.1:8080 -> any:81 on em0 + IPv4 tcp/8080:81 on em0 # bastille rdr dev1 -d 192.168.0.84 tcp 8082 82 [jail1]: - IPv4 tcp/any:8082 -> 192.168.0.84:82 on em0 + IPv4 tcp/8082:82 on em0 # bastille rdr dev1 -i vtnet0 -d 192.168.0.45 tcp 9000 9000 [jail1]: - IPv4 tcp/any:9000 -> 192.168.0.45:9000 on vtnet0 + IPv4 tcp/9000:9000 on vtnet0 # bastille rdr dev1 list rdr pass on vtnet0 inet proto udp from any to any port = 2001 -> 10.17.89.1 port 22 From cf3bb4e80939a55fda8913e8e77c85efa59114b6 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 11 Jan 2025 16:14:50 -0700 Subject: [PATCH 073/100] rdr: fix echo code on IPv6 redirection --- usr/local/share/bastille/rdr.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 0320e19f..38bb303e 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -165,7 +165,7 @@ load_rdr_rule() { error_exit "Failed to create IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${TARGET}]:" - echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv6 ${proto}/${host_port}:${jail_port} on ${if_name}" fi fi } @@ -190,7 +190,7 @@ load_rdr_log_rule() { error_exit "Failed to create logged IPv4 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${TARGET}]:" - echo "IPv4 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv4 ${proto}/${host_port}:${jail_port} on ${if_name}" fi fi # Create IPv6 rdr rule with log (if ip6.addr is enabled) @@ -202,7 +202,7 @@ load_rdr_log_rule() { error_exit "Failed to create logged IPv6 rdr rule \"${if_name} ${src} ${dst} ${proto} ${host_port} ${jail_port}\"" else info "[${TARGET}]:" - echo "IPv6 ${proto}/${src}:${host_port} -> ${dst}:${jail_port} on ${if_name}" + echo "IPv6 ${proto}/${host_port}:${jail_port} on ${if_name}" fi fi } From 0a837ee5be6c39dc98d6065d53a5b9272ebd9f94 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 12 Jan 2025 10:42:54 -0700 Subject: [PATCH 074/100] rdr: support old style interface --- usr/local/share/bastille/rdr.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 38bb303e..f936b587 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -55,11 +55,19 @@ check_jail_validity() { _ip6_interfaces="$(bastille config ${TARGET} get ip6.addr | sed 's/,/ /g')" # Check if jail ip4.addr is valid (non-VNET only) if [ "${_ip4_interfaces}" != "not set" ] && [ "${_ip4_interfaces}" != "disable" ]; then - JAIL_IP="$(echo ${_ip4_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" + if echo "&{_ip4_interfaces}" | grep -q "|"; then + JAIL_IP="$(echo ${_ip4_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" + else + JAIL_IP="${_ip4_interfaces}" + fi fi # Check if jail ip6.addr is valid (non-VNET only) if [ "${_ip6_interfaces}" != "not set" ] && [ "${_ip6_interfaces}" != "disable" ]; then - JAIL_IP6="$(echo ${_ip6_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" + if echo "&{_ip6_interfaces}" | grep -q "|"; then + JAIL_IP6="$(echo ${_ip6_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" + else + JAIL_IP6="${_ip6_interfaces}" + fi fi else error_exit "VNET jails do not support rdr." From 254f1718c071c35a7fc76d88e11a177063764b36 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 12 Jan 2025 11:07:36 -0700 Subject: [PATCH 075/100] rdr: update error_message to say reset instead of clear --- usr/local/share/bastille/rdr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index f936b587..2de8e259 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -111,7 +111,7 @@ validate_rdr_rule() { local jail_port="${6}" if grep -qs "$if $src $dst $proto $host_port $jail_port" "${bastille_jailsdir}/${TARGET}/rdr.conf"; then error_notify "Error: Ports already in use on this interface." - error_exit "See 'bastille list ports' or 'bastille rdr TARGET clear'." + error_exit "See 'bastille list ports' or 'bastille rdr TARGET reset'." fi } From bee05016f6a372eef2cc635feb30b9899d96cd0e Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 13 Jan 2025 08:17:54 -0700 Subject: [PATCH 076/100] rdr: trim subnet in case it is included behind ip --- usr/local/share/bastille/rdr.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 2de8e259..97897226 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -56,17 +56,17 @@ check_jail_validity() { # Check if jail ip4.addr is valid (non-VNET only) if [ "${_ip4_interfaces}" != "not set" ] && [ "${_ip4_interfaces}" != "disable" ]; then if echo "&{_ip4_interfaces}" | grep -q "|"; then - JAIL_IP="$(echo ${_ip4_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" + JAIL_IP="$(echo ${_ip4_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}' | sed -E 's#/[0-9]+$##g')" else - JAIL_IP="${_ip4_interfaces}" + JAIL_IP="$(echo ${_ip4_interfaces} | sed -E 's#/[0-9]+$##g')" fi fi # Check if jail ip6.addr is valid (non-VNET only) if [ "${_ip6_interfaces}" != "not set" ] && [ "${_ip6_interfaces}" != "disable" ]; then if echo "&{_ip6_interfaces}" | grep -q "|"; then - JAIL_IP6="$(echo ${_ip6_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}')" + JAIL_IP6="$(echo ${_ip6_interfaces} | awk '{print $1}' | awk -F"|" '{print $2}' | sed -E 's#/[0-9]+$##g')" else - JAIL_IP6="${_ip6_interfaces}" + JAIL_IP6="$(echo ${_ip6_interfaces} | sed -E 's#/[0-9]+$##g')" fi fi else From 4c2d6774a24daebe5837286e709e2401edb895d5 Mon Sep 17 00:00:00 2001 From: Paul Wilde <31094984+pswilde@users.noreply.github.com> Date: Thu, 13 Feb 2025 14:00:56 +0000 Subject: [PATCH 077/100] add initial startup delay option --- usr/local/etc/rc.d/bastille | 2 ++ 1 file changed, 2 insertions(+) diff --git a/usr/local/etc/rc.d/bastille b/usr/local/etc/rc.d/bastille index 9322c099..be5c1b0e 100755 --- a/usr/local/etc/rc.d/bastille +++ b/usr/local/etc/rc.d/bastille @@ -32,6 +32,7 @@ rcvar=${name}_enable : ${bastille_conf:="/usr/local/etc/bastille/bastille.conf"} : ${bastille_list:="ALL"} : ${bastille_rcorder:="NO"} +: ${bastille_startup_delay:=0} command=/usr/local/bin/${name} start_cmd="bastille_start" @@ -60,6 +61,7 @@ bastille_start() for _jail in ${bastille_ordered_list}; do echo "Starting Bastille Container: ${_jail}" ${command} start ${_jail} + sleep ${bastille_startup_delay} done } From 318df00ea8fb84ae84b55b4efb825ab66dd21673 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 13 Feb 2025 11:59:32 -0700 Subject: [PATCH 078/100] create: Fix VNeT template not applying when mixed with thick or thin jails --- usr/local/share/bastille/create.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index af06fd9a..f6125081 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -573,7 +573,8 @@ create_jail() { _ifconfig="${_ifconfig_inet} ${_ifconfig_inet6}" bastille template "${NAME}" ${bastille_template_vnet} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg GATEWAY6="${_gateway6}" --arg IFCONFIG="${_ifconfig}" fi - elif [ -n "${THICK_JAIL}" ]; then + fi + if [ -n "${THICK_JAIL}" ]; then if [ -n "${bastille_template_thick}" ]; then bastille template "${NAME}" ${bastille_template_thick} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" fi From 12e0782bb7aa331fc752a71de7a2814a1bb738fe Mon Sep 17 00:00:00 2001 From: Paul Wilde <31094984+pswilde@users.noreply.github.com> Date: Thu, 13 Feb 2025 20:01:13 +0000 Subject: [PATCH 079/100] Put sleep delay before starting jail instead of after --- usr/local/etc/rc.d/bastille | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/etc/rc.d/bastille b/usr/local/etc/rc.d/bastille index be5c1b0e..15420986 100755 --- a/usr/local/etc/rc.d/bastille +++ b/usr/local/etc/rc.d/bastille @@ -59,9 +59,9 @@ bastille_start() fi for _jail in ${bastille_ordered_list}; do + sleep ${bastille_startup_delay} echo "Starting Bastille Container: ${_jail}" ${command} start ${_jail} - sleep ${bastille_startup_delay} done } From cbe448c4d2ea49d33c7e4cbab9b27fc8585f4e6f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 13 Feb 2025 13:18:09 -0700 Subject: [PATCH 080/100] rdr: Remove old format after new format is loaded --- usr/local/share/bastille/rdr.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 97897226..2c6ec54f 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -337,6 +337,12 @@ while [ "$#" -gt 0 ]; do validate_rdr_rule $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 persist_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 load_rdr_rule $RDR_INET $RDR_IF $RDR_SRC $RDR_DST $1 $2 $3 + # Temp block to remove old format after new format is loaded the first time + while read rules; do + if [ "$(echo ${rules} | wc -w)" -lt 6 ]; then + sed -i '' "/^${rules}$/d" "${bastille_jailsdir}/${_jail}/rdr.conf" + fi + done < "${bastille_jailsdir}/${_jail}/rdr.conf" shift "$#" else case "${4}" in From 99abd0dfd1c66ff2e57daac8dc8a112e7b1ec9a7 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 14 Feb 2025 09:10:20 -0700 Subject: [PATCH 081/100] VNET: do not apply base template from VNET template --- usr/local/share/bastille/templates/default/vnet/Bastillefile | 5 ----- 1 file changed, 5 deletions(-) diff --git a/usr/local/share/bastille/templates/default/vnet/Bastillefile b/usr/local/share/bastille/templates/default/vnet/Bastillefile index 902fe6dd..95613485 100644 --- a/usr/local/share/bastille/templates/default/vnet/Bastillefile +++ b/usr/local/share/bastille/templates/default/vnet/Bastillefile @@ -1,8 +1,3 @@ -ARG BASE_TEMPLATE=default/base -ARG HOST_RESOLV_CONF=/etc/resolv.conf - -INCLUDE ${BASE_TEMPLATE} --arg HOST_RESOLV_CONF="${HOST_RESOLV_CONF}" - ARG EPAIR ARG GATEWAY ARG GATEWAY6 From cb7c5daf9787fb2b9f3932670a71477e32986883 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Fri, 14 Feb 2025 09:11:38 -0700 Subject: [PATCH 082/100] create: VNET template only does VNET config, not base template --- usr/local/share/bastille/create.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/create.sh b/usr/local/share/bastille/create.sh index f6125081..dc65d412 100644 --- a/usr/local/share/bastille/create.sh +++ b/usr/local/share/bastille/create.sh @@ -571,7 +571,7 @@ create_jail() { fi # Join together IPv4 and IPv6 parts of ifconfig _ifconfig="${_ifconfig_inet} ${_ifconfig_inet6}" - bastille template "${NAME}" ${bastille_template_vnet} --arg BASE_TEMPLATE="${bastille_template_base}" --arg HOST_RESOLV_CONF="${bastille_resolv_conf}" --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg GATEWAY6="${_gateway6}" --arg IFCONFIG="${_ifconfig}" + bastille template "${NAME}" ${bastille_template_vnet} --arg EPAIR="${uniq_epair}" --arg GATEWAY="${_gateway}" --arg GATEWAY6="${_gateway6}" --arg IFCONFIG="${_ifconfig}" fi fi if [ -n "${THICK_JAIL}" ]; then From 0c1456fd79ced156a0798b3094f6d9c625500078 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 15 Feb 2025 22:23:43 -0700 Subject: [PATCH 083/100] template: Exit when any ARG is not set --- usr/local/share/bastille/template.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 9e4f42b2..234eece3 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -266,7 +266,7 @@ for _jail in ${JAILS}; do _arg_name=$(get_arg_name "${_line}") _arg_value=$(get_arg_value "${_line}" "$@") if [ -z "${_arg_value}" ]; then - warn "No value provided for arg: ${_arg_name}" + error_exit "No value provided for arg: ${_arg_name}" fi ARG_REPLACEMENTS="${ARG_REPLACEMENTS} -e 's/\${${_arg_name}}/${_arg_value}/g'" done < "${bastille_template}/ARG" @@ -291,7 +291,7 @@ for _jail in ${JAILS}; do _arg_name=$(get_arg_name "${_args}") _arg_value=$(get_arg_value "${_args}" "$@") if [ -z "${_arg_value}" ]; then - warn "No value provided for arg: ${_arg_name}" + error_exit "No value provided for arg: ${_arg_name}" fi # Build a list of sed commands like this: -e 's/${username}/root/g' -e 's/${domain}/example.com/g' ARG_REPLACEMENTS="${ARG_REPLACEMENTS} -e 's/\${${_arg_name}}/${_arg_value}/g'" From fc8e9290b1421fa5bbffdc81ff2095b7c99bce74 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sat, 15 Feb 2025 22:28:06 -0700 Subject: [PATCH 084/100] =?UTF-8?q?template:=20Base=20-=20add=20=E2=80=9Cd?= =?UTF-8?q?aily=5Fstatus=5Fworld=5Fkernel=3DNO=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- usr/local/share/bastille/templates/default/base/Bastillefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/usr/local/share/bastille/templates/default/base/Bastillefile b/usr/local/share/bastille/templates/default/base/Bastillefile index 7418fba6..ad898446 100644 --- a/usr/local/share/bastille/templates/default/base/Bastillefile +++ b/usr/local/share/bastille/templates/default/base/Bastillefile @@ -1,6 +1,9 @@ ARG HOST_RESOLV_CONF=/etc/resolv.conf CMD touch /etc/rc.conf +CMD touch /etc/periodic.conf +CMD sysrc -f /etc/periodic.conf daily_status_world_kernel="NO" + SYSRC syslogd_flags="-ss" SYSRC sendmail_enable="NO" SYSRC sendmail_submit_enable="NO" From d23ba945c969d04afe39faee66d55f4cbed94773 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 16 Feb 2025 17:44:47 -0700 Subject: [PATCH 085/100] docs: Document missing template hooks --- docs/chapters/template.rst | 77 ++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 23 deletions(-) diff --git a/docs/chapters/template.rst b/docs/chapters/template.rst index e3a7d5f1..e6d10cdf 100644 --- a/docs/chapters/template.rst +++ b/docs/chapters/template.rst @@ -6,8 +6,8 @@ Looking for ready made CI/CD validated `Bastille Templates`_? Bastille supports a templating system allowing you to apply files, pkgs and execute commands inside the containers automatically. -Currently supported template hooks are: `CMD`, `CP`, `INCLUDE`, `LIMITS`, `MOUNT`, -`PKG`, `RDR`, `SERVICE`, `SYSRC`. +Currently supported template hooks are: `ARG`, `CMD`, `CONFIG`, `CP`, `INCLUDE`, +`LIMITS`, `MOUNT`, `OVERLAY`, `PKG`, `RDR`, `RENDER`, `RESTART`, `SERVICE`, `SYSRC`. Templates are created in `${bastille_prefix}/templates` and can leverage any of the template hooks. @@ -23,27 +23,55 @@ template hook commands. Template Automation Hooks ------------------------- -+---------+-------------------+-----------------------------------------+ -| HOOK | format | example | -+=========+===================+=========================================+ -| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh | -+---------+-------------------+-----------------------------------------+ -| CP | path(s) | etc root usr (one per line) | -+---------+-------------------+-----------------------------------------+ -| INCLUDE | template path/URL | http?://TEMPLATE_URL or project/path | -+---------+-------------------+-----------------------------------------+ -| LIMITS | resource value | memoryuse 1G | -+---------+-------------------+-----------------------------------------+ -| MOUNT | fstab syntax | /host/path container/path nullfs ro 0 0 | -+---------+-------------------+-----------------------------------------+ -| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop | -+---------+-------------------+-----------------------------------------+ -| RDR | tcp port port | tcp 2200 22 (hostport jailport) | -+---------+-------------------+-----------------------------------------+ -| SERVICE | service command | 'nginx start' OR 'postfix reload' | -+---------+-------------------+-----------------------------------------+ -| SYSRC | sysrc command(s) | nginx_enable=YES | -+---------+-------------------+-----------------------------------------+ ++-------------+---------------------+-----------------------------------------+ +| HOOK | format | example | ++=============+=====================+=========================================+ +| ARG | ARG=VALUE | MINECRAFT_MEMX="1024M" | ++-------------+---------------------+-----------------------------------------+ +| CMD | /bin/sh command | /usr/bin/chsh -s /usr/local/bin/zsh | ++-------------+---------------------+-----------------------------------------+ +| CONFIG | set property value | set allow.mlock 1 | ++-------------+---------------------+-----------------------------------------+ +| CP/OVERLAY | path(s) | etc root usr (one per line) | ++-------------+---------------------+-----------------------------------------+ +| INCLUDE | template path/URL | http?://TEMPLATE_URL or project/path | ++-------------+---------------------+-----------------------------------------+ +| LIMITS | resource value | memoryuse 1G | ++-------------+---------------------+-----------------------------------------+ +| MOUNT | fstab syntax | /host/path container/path nullfs ro 0 0 | ++-------------+---------------------+-----------------------------------------+ +| OVERLAY | path(s) | etc root usr (one per line) | ++-------------+---------------------+-----------------------------------------+ +| PKG | port/pkg name(s) | vim-console zsh git-lite tree htop | ++-------------+---------------------+-----------------------------------------+ +| RDR | tcp port port | tcp 2200 22 (hostport jailport) | ++-------------+---------------------+-----------------------------------------+ +| RENDER | /path/file.txt | /usr/local/etc/gitea/conf/app.ini | ++-------------+---------------------+-----------------------------------------+ +| RESTART | | (restart jail) | ++-------------+---------------------+-----------------------------------------+ +| SERVICE | service command | 'nginx start' OR 'postfix reload' | ++-------------+---------------------+-----------------------------------------+ +| SYSRC | sysrc command(s) | nginx_enable=YES | ++-------------+---------------------+-----------------------------------------+ + +Template Hook Descriptions +-------------------------- + +ARG - set an ARG value to be used in the template +CMD - run the specified command +CONFIG - set the specified property and value +CP/OVERLAY - copy specified files from template directory to specified path inside jail +INCLUDE - specify a template to include +LIMITS - set the specified resource value for the jail +MOUNT - mount specified files/directories inside the jail +PKG - install specified packages inside jail +RDR - redirect specified ports to the jail +RENDER - replace ARG values inside specified files inside the jail + if a directory is specified, ARGS will be replaced in all files underneath +RESTART - restart the jail +SERVICE - run 'service' command inside the jail with specified arguments +SYSRC - run 'sysrc' inside the jail with specified arguments Special Hook Cases ------------------ @@ -54,6 +82,9 @@ ie; (`\\"`) ARG will always treat an ampersand "\&" literally, without the need to escape it. Escaping it will cause errors. +Template Examples +----------------- + Place these uppercase template hook commands into a `Bastillefile` in any order and automate container setup as needed. From d552b44521a6463e52fd1b775a1d8f267f5ddcf9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 16 Feb 2025 17:47:58 -0700 Subject: [PATCH 086/100] Update template.rst --- docs/chapters/template.rst | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/chapters/template.rst b/docs/chapters/template.rst index e6d10cdf..36794f01 100644 --- a/docs/chapters/template.rst +++ b/docs/chapters/template.rst @@ -59,19 +59,30 @@ Template Hook Descriptions -------------------------- ARG - set an ARG value to be used in the template + CMD - run the specified command + CONFIG - set the specified property and value + CP/OVERLAY - copy specified files from template directory to specified path inside jail + INCLUDE - specify a template to include + LIMITS - set the specified resource value for the jail + MOUNT - mount specified files/directories inside the jail + PKG - install specified packages inside jail + RDR - redirect specified ports to the jail -RENDER - replace ARG values inside specified files inside the jail - if a directory is specified, ARGS will be replaced in all files underneath + +RENDER - replace ARG values inside specified files inside the jail. If a directory is specified, ARGS will be replaced in all files underneath + RESTART - restart the jail -SERVICE - run 'service' command inside the jail with specified arguments -SYSRC - run 'sysrc' inside the jail with specified arguments + +SERVICE - run `service` command inside the jail with specified arguments + +SYSRC - run `sysrc` inside the jail with specified arguments Special Hook Cases ------------------ From 34efac30177841b5711871a3d7186087d8c05106 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Sun, 16 Feb 2025 17:50:03 -0700 Subject: [PATCH 087/100] docs: Document INCLUDE to let users know to have the template bootstrapped --- docs/chapters/template.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/chapters/template.rst b/docs/chapters/template.rst index 36794f01..0e294885 100644 --- a/docs/chapters/template.rst +++ b/docs/chapters/template.rst @@ -66,7 +66,7 @@ CONFIG - set the specified property and value CP/OVERLAY - copy specified files from template directory to specified path inside jail -INCLUDE - specify a template to include +INCLUDE - specify a template to include. Make sure the template is bootstrapped, or you are using the template url LIMITS - set the specified resource value for the jail From 6f038eda21b699b8112304dae84e1b1895781055 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 17 Feb 2025 05:07:44 -0700 Subject: [PATCH 088/100] Revert "template: Exit when any ARG is not set" --- usr/local/share/bastille/template.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/template.sh b/usr/local/share/bastille/template.sh index 234eece3..9e4f42b2 100644 --- a/usr/local/share/bastille/template.sh +++ b/usr/local/share/bastille/template.sh @@ -266,7 +266,7 @@ for _jail in ${JAILS}; do _arg_name=$(get_arg_name "${_line}") _arg_value=$(get_arg_value "${_line}" "$@") if [ -z "${_arg_value}" ]; then - error_exit "No value provided for arg: ${_arg_name}" + warn "No value provided for arg: ${_arg_name}" fi ARG_REPLACEMENTS="${ARG_REPLACEMENTS} -e 's/\${${_arg_name}}/${_arg_value}/g'" done < "${bastille_template}/ARG" @@ -291,7 +291,7 @@ for _jail in ${JAILS}; do _arg_name=$(get_arg_name "${_args}") _arg_value=$(get_arg_value "${_args}" "$@") if [ -z "${_arg_value}" ]; then - error_exit "No value provided for arg: ${_arg_name}" + warn "No value provided for arg: ${_arg_name}" fi # Build a list of sed commands like this: -e 's/${username}/root/g' -e 's/${domain}/example.com/g' ARG_REPLACEMENTS="${ARG_REPLACEMENTS} -e 's/\${${_arg_name}}/${_arg_value}/g'" From a8a377f7c424b4cf70c6ff6c9865c50ea2073a7f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 17 Feb 2025 16:22:30 -0700 Subject: [PATCH 089/100] docs: Document issues when not including subnet mask on VNET jails --- docs/chapters/networking.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/chapters/networking.rst b/docs/chapters/networking.rst index d94bf27d..255d1024 100644 --- a/docs/chapters/networking.rst +++ b/docs/chapters/networking.rst @@ -120,6 +120,10 @@ container interfaces as they are started and stopped. These interface names match the pattern `eXb_bastilleX`. Internally to the containers these interfaces are presented as `vnet0`. +If you do not specify a subnet mask, you might have issues with jail to jail +networking, especially VLAN to VLAN. We recommend always adding a subnet to +VNET jail IPs when creating them to avoid these issues. + VNET also requires a custom devfs ruleset. Create the file as needed on the host system: From 1cff0763d91ea374080ebedb880dc0ca2da9a827 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 17 Feb 2025 16:41:22 -0700 Subject: [PATCH 090/100] docs: Redo upgrade instructions --- docs/chapters/upgrading.rst | 79 ++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 15 deletions(-) diff --git a/docs/chapters/upgrading.rst b/docs/chapters/upgrading.rst index b059fa0d..1621fe47 100644 --- a/docs/chapters/upgrading.rst +++ b/docs/chapters/upgrading.rst @@ -5,31 +5,80 @@ This document outlines upgrading jails hosted using Bastille. Bastille can "bootstrap" multiple versions of FreeBSD to be used by jails. All jails do not NEED to be the same version (even if they often are), the only requirement here is that the "bootstrapped" versions are less than or equal to the host version of FreeBSD. +To keep releases updated, use `bastille update RELEASE` + +To keep thick jails updated, use `bastille update TARGET` + To upgrade Bastille jails for a minor release (ie; 13.1→13.2) you can do the following: -1. ensure the new release version is bootstrapped and updated to the latest patch release: `bastille bootstrap 13.2-RELEASE update` -2. stop the jail(s) that need to be updated. -3. use `bastille edit TARGET fstab` to manually update the jail mounts from 13.1 to 13.2 release path. -4. start the jail(s) that were edited -5. upgrade complete! +Thick Jails +=========== + +1. ensure the new release version is bootstrapped and updated to the latest patch release: `bastille bootstrap 13.2-RELEASE` +2. update the release: `bastille update 13.2-RELEASE` +3. use `bastille upgrade TARGET 13.2-RELEASE` to upgrade the jail to 13.2-RELEASE +4. use `bastille upgrade TARGET 13.2-RELEASE update` to apply the updates +5. reboot the jail `bastille restart TARGET` +6. use `bastille upgrade TARGET 13.2-RELEASE update` to finish applying the upgrade +7. upgrade complete! + +Thin Jails +========== + +1. ensure the new release version is bootstrapped and updated to the latest patch release: `bastille bootstrap 13.2-RELEASE` +2. update the release: `bastille update 13.2-RELEASE` +3. stop the jail(s) that need to be updated. +4. use `bastille upgrade TARGET 13.2-RELEASE` to automatically change the mount points to 13.2-RELEASE +5. use `bastille etcupdate bootstrap 13.2-RELEASE` to bootstrap src for 13.2-RELEASE +6. use `bastille etcupdate TARGET update 13.2-RELEASE` to update the contents of /etc for 13.2-RELEASE +7. use `bastille etcupdate TARGET reslove` to resolve any conflicts +8. start the jail(s) +8. upgrade complete! To upgrade Bastille jails for a major release (ie; 12.4→13.2) you can do the following: -1. ensure the new version is bootstrapped and update to the latest patch release: `bastille bootstrap 13.2-RELEASE update` -2. stop the jail(s) that need to be updated. -3. use `bastille edit TARGET fstab` to manually update the jail mounts from 12.4 to 13.2 release path. -4. start the jail(s) that were edited -5. Force the reinstallation or upgrade of all installed packages (ABI change): `pkg upgrade -f` within each jail (or `bastille pkg ALL upgrade -f`) -6. restart the affected jail(s) -7. upgrade complete! +Thick Jails +=========== + +1. ensure the new release version is bootstrapped and updated to the latest patch release: `bastille bootstrap 13.2-RELEASE` +2. update the release: `bastille update 13.2-RELEASE` +3. use `bastille upgrade TARGET 13.2-RELEASE` to upgrade the jail to 13.2-RELEASE +4. use `bastille upgrade TARGET 13.2-RELEASE update` to apply the updates +5. reboot the jail `bastille restart TARGET` +6. use `bastille upgrade TARGET 13.2-RELEASE update` to finish applying the upgrade +7. force the reinstallation or upgrade of all installed packages (ABI change): `pkg upgrade -f` within each jail (or `bastille pkg ALL upgrade -f`) +8. upgrade complete! + +Thin Jails +========== + +1. ensure the new release version is bootstrapped and updated to the latest patch release: `bastille bootstrap 13.2-RELEASE` +2. update the release: `bastille update 13.2-RELEASE` +3. stop the jail(s) that need to be updated. +4. use `bastille upgrade TARGET 13.2-RELEASE` to automatically change the mount points to 13.2-RELEASE +5. use `bastille etcupdate bootstrap 13.2-RELEASE` to bootstrap src for 13.2-RELEASE +6. use `bastille etcupdate TARGET update 13.2-RELEASE` to update the contents of /etc for 13.2-RELEASE +7. use `bastille etcupdate TARGET reslove` to resolve any conflicts +8. start the jail(s) +9. force the reinstallation or upgrade of all installed packages (ABI change): `pkg upgrade -f` within each jail (or `bastille pkg ALL upgrade -f`) +10. upgrade complete! Revert Upgrade / Downgrade Process ---------------------------------- The downgrade process (not usually needed) is similar to the upgrade process only in reverse. -If you did a minor upgrade changing the release path from 13.1 to 13.2, stop the jail and revert that change. Downgrade complete. +Thick Jails +=========== -If you did a major upgrade changing the release path from 12.4 to 13.2, stop the jail and revert that change. The pkg reinstallation will also need to be repeated after the jail restarts on the previous release. +Thick jails should not be downgraded and is not supported in general on FreeBSD. + +Thin Jails +========== + +Not recommended, but you can run `bastille upgrade TARGET 13.1-RELEASE` to downgrade a thin jail. +Make sure to run `bastille etcupdate TARGET update 13.1-RELEASE` to keep the contents of /etc updated with each release. + +The pkg reinstallation will also need to be repeated after the jail restarts on the previous release. Old Releases ---------------------------------- @@ -40,4 +89,4 @@ After upgrading all jails from one release to the next you may find that you now `bastille destroy X.Y-RELEASE` to fully delete the release. -`bastille destroy force X.Y-RELEASE` to delete the cache directory as well. +`bastille destroy [-f|--force] X.Y-RELEASE` to delete the cache directory as well. From 5745f50204e9b92b8d522185697b6bd2ea8c72f5 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 17 Feb 2025 16:44:58 -0700 Subject: [PATCH 091/100] docs: Document having unbound enabled=network issues --- docs/chapters/networking.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/chapters/networking.rst b/docs/chapters/networking.rst index 255d1024..2befa4eb 100644 --- a/docs/chapters/networking.rst +++ b/docs/chapters/networking.rst @@ -309,3 +309,8 @@ At this point you'll likely be disconnected from the host. Reconnect the ssh session and continue. This step only needs to be done once in order to prepare the host. + +Things to Note +============== + +- If you are running "unbound" on your server, you will probably have issues with DNS resolution. From 7fd301e66c886077463a00683c1464374678e108 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Mon, 17 Feb 2025 16:51:58 -0700 Subject: [PATCH 092/100] docs: Document using local_unbound --- docs/chapters/networking.rst | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/docs/chapters/networking.rst b/docs/chapters/networking.rst index 2befa4eb..8b78b5db 100644 --- a/docs/chapters/networking.rst +++ b/docs/chapters/networking.rst @@ -310,7 +310,20 @@ ssh session and continue. This step only needs to be done once in order to prepare the host. -Things to Note -============== +local_unbound +============= -- If you are running "unbound" on your server, you will probably have issues with DNS resolution. +If you are running "local_unbound" on your server, you will probably have issues with DNS resolution. + +To resolve this, add the following configuration to local_unbound: + +.. code-block:: shell + + server: + interface: 0.0.0.0 + access-control: 192.168.0.0/16 allow + access-control: 10.17.90.0/24 allow + +Also, change the nameserver to the servers IP instead of 127.0.0.1 inside /etc/rc.conf + +Adjust the above "access-control" strings to fit your network. From dad0c5b85a869283eb65dbcae5f2e92aff3440d9 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 18 Feb 2025 08:47:36 -0700 Subject: [PATCH 093/100] docs: Add etcupdate.rst --- docs/chapters/subcommands/etcupdate.rst | 46 +++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 docs/chapters/subcommands/etcupdate.rst diff --git a/docs/chapters/subcommands/etcupdate.rst b/docs/chapters/subcommands/etcupdate.rst new file mode 100644 index 00000000..cec9a411 --- /dev/null +++ b/docs/chapters/subcommands/etcupdate.rst @@ -0,0 +1,46 @@ +========= +etcupdate +========= + +This command will update the contents of `/etc` inside a jail. It should be run after a jail upgrade + +First we need to bootstrap a release for `etcupdate` to use. + +.. code-block:: shell + + ishmael ~ # bastille etcupdate bootstrap 14.1-RELEASE + bastille_bootstrap_archives: base -> src + /usr/local/bastille/cache/14.1-RELEASE/MANIFES 1046 B 1134 kBps 00s + /usr/local/bastille/cache/14.1-RELEASE/src.txz 205 MB 2711 kBps 01m18s + bastille_bootstrap_archives: src -> base + Building tarball, please wait... + Etcupdate bootstrap complete: 14.1-RELEASE + +Next we can use the `update` command to apply the update to the jail. + +.. code-block:: shell + + ishmael ~ # bastille etcupdate ishmael update 14.1-RELEASE + +The output will show you which files were added, updated, changed, deleted, or have conflicts. +To automatically resolve the conflicts, run the `resolve` command. + +.. code-block:: shell + + ishmael ~ # bastille etcupdate ishmael resolve + +To show only the differences between the releases, use the `diff` command. + +.. code-block:: shell + + ishmael ~ # bastille etcupdate ishmael diff 14.1-RELEASE + +.. code-block:: shell + + ishmael ~ # bastille etcupdate help + Usage: bastille etcupdate [option(s)] [bootstrap|TARGET] [diff|resolve|update RELEASE] + Options: + + -d | --dry-run Show output, but do not apply. + -f | --force Force a re-bootstrap of a RELEASE. + -x | --debug Enable debug mode. From 86714b2ae0dac99550b1044a822bfef104775466 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 18 Feb 2025 09:03:17 -0700 Subject: [PATCH 094/100] etcupdate: Fix not bootstrapping when /usr/src is present but empty --- usr/local/share/bastille/etcupdate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/etcupdate.sh b/usr/local/share/bastille/etcupdate.sh index 1f0979be..2f625d41 100644 --- a/usr/local/share/bastille/etcupdate.sh +++ b/usr/local/share/bastille/etcupdate.sh @@ -46,7 +46,7 @@ EOF bootstrap_etc_release() { local _release="${1}" local _current="$(sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives | awk -F': ' '{print $2}')" - if ! ls -A "${bastille_releasesdir}/${_release}/usr/src" 2>/dev/null; then + if [ -z "$(ls -A "${bastille_releasesdir}/${_release}/usr/src")" ]; then sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives=src if ! bastille bootstrap "${_release}" > /dev/null; then sysrc -f /usr/local/etc/bastille/bastille.conf bastille_bootstrap_archives="${_current}" From 4aa9ca555fc4c2a306e3a9025f7339db67be79ee Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Tue, 18 Feb 2025 09:09:50 -0700 Subject: [PATCH 095/100] rdr: _jail > TARGET --- usr/local/share/bastille/rdr.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr/local/share/bastille/rdr.sh b/usr/local/share/bastille/rdr.sh index 2c6ec54f..b301e631 100644 --- a/usr/local/share/bastille/rdr.sh +++ b/usr/local/share/bastille/rdr.sh @@ -340,9 +340,9 @@ while [ "$#" -gt 0 ]; do # Temp block to remove old format after new format is loaded the first time while read rules; do if [ "$(echo ${rules} | wc -w)" -lt 6 ]; then - sed -i '' "/^${rules}$/d" "${bastille_jailsdir}/${_jail}/rdr.conf" + sed -i '' "/^${rules}$/d" "${bastille_jailsdir}/${TARGET}/rdr.conf" fi - done < "${bastille_jailsdir}/${_jail}/rdr.conf" + done < "${bastille_jailsdir}/${TARGET}/rdr.conf" shift "$#" else case "${4}" in From 53d37cde1a1614ff2b1a553322ac0ab95bae3657 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Wed, 19 Feb 2025 20:24:09 -0700 Subject: [PATCH 096/100] list: No color when searching for jails --- usr/local/share/bastille/list.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/share/bastille/list.sh b/usr/local/share/bastille/list.sh index 23f13d07..8655b858 100644 --- a/usr/local/share/bastille/list.sh +++ b/usr/local/share/bastille/list.sh @@ -208,7 +208,7 @@ list_template(){ list_jail(){ if [ -d "${bastille_jailsdir}" ]; then - JAIL_LIST=$(ls "${bastille_jailsdir}" | sed "s/\n//g") + JAIL_LIST=$(ls --color=never "${bastille_jailsdir}" | sed "s/\n//g") for _JAIL in ${JAIL_LIST}; do if [ -f "${bastille_jailsdir}/${_JAIL}/jail.conf" ]; then echo "${_JAIL}" From 3ac59c13545343f0e4246fb2dc336808cbb3125f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 20 Feb 2025 12:28:16 -0700 Subject: [PATCH 097/100] docs: Update "update" to allow for thick jails also --- docs/chapters/subcommands/update.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/chapters/subcommands/update.rst b/docs/chapters/subcommands/update.rst index 4beef655..e1a6bae4 100644 --- a/docs/chapters/subcommands/update.rst +++ b/docs/chapters/subcommands/update.rst @@ -2,8 +2,8 @@ update ====== -The `update` command targets a release instead of a container. Because every container is -based on a release, when the release is updated all the containers are automatically +The `update` command targets a release or a thick jail. Because thin jails are +based on a release, when the release is updated all the thin jails are automatically updated as well. If no updates are available, a message will be shown: @@ -20,8 +20,7 @@ If no updates are available, a message will be shown: No updates needed to update system to 11.4-RELEASE-p4. No updates are available to install. - -The older the release, however, the more updates will be available: +The older the release or jail, however, the more updates will be available: .. code-block:: shell @@ -38,4 +37,7 @@ The older the release, however, the more updates will be available: The following files will be added as part of updating to 13.2-RELEASE-p4: ...[snip]... -To be safe, you may want to restart any containers that have been updated live. +To be safe, you may want to restart any jails that have been updated live. + +If the jail is a thin jail, an error will be shown. If it is a thick jail, it will be updated just like +the release shown above. From 29855d7957d28a8e2aeef0d45fbba4b648072b30 Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 20 Feb 2025 12:39:41 -0700 Subject: [PATCH 098/100] docs: Add upgrade subcommand --- docs/chapters/subcommands/upgrade.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 docs/chapters/subcommands/upgrade.rst diff --git a/docs/chapters/subcommands/upgrade.rst b/docs/chapters/subcommands/upgrade.rst new file mode 100644 index 00000000..bbff8af4 --- /dev/null +++ b/docs/chapters/subcommands/upgrade.rst @@ -0,0 +1,16 @@ +======= +upgrade +======= + +The `upgrade` command targets a thick or thin jail. Thin jails will be updated by changing the +release mount point that it is based on. Thick jails will be upgraded normally. + +.. code-block:: shell + + ishmael ~ # bastille upgrade help + Usage: bastille upgrade [option(s)] TARGET [NEWRELEASE|install] + Options: + + -a | --auto Auto mode. Start/stop jail(s) if required. + -f | --force Force upgrade a jail. + -x | --debug Enable debug mode. From c701d6c17b0239dbbc137d089685782fff8a437f Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 20 Feb 2025 12:47:20 -0700 Subject: [PATCH 099/100] docs: Document ARGS more thouroughly --- docs/chapters/template.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/chapters/template.rst b/docs/chapters/template.rst index 0e294885..0c45bead 100644 --- a/docs/chapters/template.rst +++ b/docs/chapters/template.rst @@ -60,6 +60,15 @@ Template Hook Descriptions ARG - set an ARG value to be used in the template +ARGS will default to the value set inside the template, but can be changed by including `--arg ARG=VALUE` when +running the template. Multiple ARGS can also be specified as seen below. If no ARG value is given, the template +will show a warning, but will still continue. + +.. code-block:: shell + + ishmael ~ # bastille template azkaban sample/template --arg ARG=VALUE --arg ARG1=VALUE + + CMD - run the specified command CONFIG - set the specified property and value From 63c008b25e3d06fb32d521349e48ec63e6ff8d9d Mon Sep 17 00:00:00 2001 From: tschettervictor <85497460+tschettervictor@users.noreply.github.com> Date: Thu, 20 Feb 2025 12:48:26 -0700 Subject: [PATCH 100/100] Update upgrading.rst --- docs/chapters/upgrading.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/chapters/upgrading.rst b/docs/chapters/upgrading.rst index 1621fe47..1d9161eb 100644 --- a/docs/chapters/upgrading.rst +++ b/docs/chapters/upgrading.rst @@ -9,6 +9,10 @@ To keep releases updated, use `bastille update RELEASE` To keep thick jails updated, use `bastille update TARGET` +====================== +Minor Release Upgrades +====================== + To upgrade Bastille jails for a minor release (ie; 13.1→13.2) you can do the following: Thick Jails @@ -35,6 +39,10 @@ Thin Jails 8. start the jail(s) 8. upgrade complete! +====================== +Major Release Upgrades +====================== + To upgrade Bastille jails for a major release (ie; 12.4→13.2) you can do the following: Thick Jails