Add dynamic rdr

This commit is contained in:
pc
2020-02-01 15:58:02 +00:00
parent eb38963752
commit f65fe999cc
4 changed files with 173 additions and 3 deletions

View File

@@ -103,14 +103,21 @@ Create the firewall rules:
table <jails> persist
nat on $ext_if from <jails> to any -> ($ext_if)
## rdr example
## static rdr example
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
## dynamic rdr anchor (see below)
rdr-anchor "rdr/*"
block in all
pass out quick modulate state
antispoof for $ext_if inet
pass in inet proto tcp from any to any port ssh flags S/SA modulate state
# If you are using dynamic rdr also need to ensure that the external port
# range you are using is open
# pass in inet proto tcp any to any port <rdr-start>:<rdr-end>
- Make sure to change the `ext_if` variable to match your host system interface.
- Make sure to include the last line (`port ssh`) or you'll end up locked out.
@@ -121,7 +128,7 @@ to containers are:
nat on $ext_if from <jails> to any -> ($ext_if)
## rdr example
## static rdr example
## rdr pass inet proto tcp from any to any port {80, 443} -> 10.17.89.45
The `nat` routes traffic from the loopback interface to the external
@@ -131,6 +138,23 @@ The `rdr pass ...` will redirect traffic from the host firewall on port X to
the ip of Container Y. The example shown redirects web traffic (80 & 443) to the
containers at `10.17.89.45`.
## dynamic rdr anchor (see below)
rdr-anchor "rdr/*"
The `rdr-anchor "rdr/*"` anables dynamic rdr rules to be setup using the
`bastille rdr` command at runtime - eg.
bastille rdr <jail> --tcp 2001 22 # Redirects tcp port 2001 on host to 22 on jail
bastille rdr <jail> --udp 2053 53 # Same for udp
bastille rdr <jail> --list # List dynamic rdr rules
bastille rdr <jail> --clear # Clear dynamic rdr rules
Note that if you are rediirecting ports where the host is also listening
(eg. ssh) you should make sure that the host service is not listening on
the cloned interface - eg. for ssh set sshd_flags in rc.conf
sshd_flags="-o ListenAddress=<hostname>"
Finally, start up the firewall:
.. code-block:: shell

View File

@@ -0,0 +1,27 @@
===
rdr
===
`bastille rdr` allows yiou 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).
Note: you need to be careful if host services are configured to run
on all interfaces as by default thsi will
.. code-block:: shell
# bastille rdr --help
Usage: bastille rdr TARGET [--clear] | [--list] | [--tcp <host_port> <jail_port>] | [--udp <host_port> <jail_port>]
# 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
# bastille rdr dev1 --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 em0 inet proto udp from any to any port = 2053 -> 10.17.89.1 port 53
# bastille rdr dev1 --clear
nat cleared

View File

@@ -93,6 +93,7 @@ Available Commands:
import Import a specified container.
list List containers (running and stopped).
pkg Manipulate binary packages within targeted container(s). See pkg(8).
rdr Redirect host port to container port.
restart Restart a running container.
service Manage services within targeted container(s).
start Start a stopped container.
@@ -130,7 +131,7 @@ esac
# Filter out all non-commands
case "${CMD}" in
cmd|convert|cp|create|destroy|export|import|list|pkg|restart|start|stop|sysrc|template|verify)
cmd|convert|cp|create|destroy|export|import|list|pkg|rdr|restart|start|stop|sysrc|template|verify)
;;
update|upgrade)
;;

View File

@@ -0,0 +1,118 @@
#!/bin/sh
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# * Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
. /usr/local/share/bastille/colors.pre.sh
. /usr/local/etc/bastille/bastille.conf
usage() {
echo -e "${COLOR_RED}Usage: bastille rdr TARGET [--clear] | [--list] | [--tcp <host_port> <jail_port>] | [--udp <host_port> <jail_port>]${COLOR_RESET}"
exit 1
}
# Handle special-case commands first.
case "$1" in
help|-h|--help)
usage
;;
esac
if [ $# -lt 2 ]; then
usage
fi
TARGET="${1}"
shift
# Can only redirect to single jail
if [ "${TARGET}" = 'ALL' ]; then
echo -e "${COLOR_RED}Can only redirect to single jail${COLOR_RESET}"
exit 1
fi
# Check jail name valid
JAIL_NAME=$(jls -j "${TARGET}" name 2>/dev/null)
if [ -z "${JAIL_NAME}" ]; then
echo -e "${COLOR_RED}Jail not found: ${TARGET}${COLOR_RESET}"
exit 1
fi
# Check jail ip4 address valid
JAIL_IP=$(jls -j "${TARGET}" ip4.addr 2>/dev/null)
if [ -z "${JAIL_IP}" -o "${JAIL_IP}" = "-" ]; then
echo -e "${COLOR_RED}Jail IP not found: ${TARGET}${COLOR_RESET}"
exit 1
fi
# Check rdr-anchor is setup in pf.conf
if !(pfctl -sn | grep rdr-anchor | grep 'rdr/\*' >/dev/null); then
echo -e "${COLOR_RED}rdr-anchor not found in pf.conf${COLOR_RESET}"
exit 1
fi
# Check ext_if is setup in pf.conf
EXT_IF=$(grep '^[[:space:]]*ext_if[[:space:]]*=' /etc/pf.conf)
if [ -z "${JAIL_NAME}" ]; then
echo -e "${COLOR_RED}ext_if not defined in pf.conf${COLOR_RESET}"
exit 1
fi
while [ $# -gt 0 ]; do
case "$1" in
--list)
pfctl -a "rdr/${JAIL_NAME}" -Psn 2>/dev/null
shift
;;
--clear)
pfctl -a "rdr/${JAIL_NAME}" -Fn
shift
;;
--tcp)
if [ $# -lt 3 ]; then
usage
fi
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
printf '%s\nrdr on $ext_if inet proto tcp to port %d -> %s port %d\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
| pfctl -a "rdr/${JAIL_NAME}" -f-
shift 3
;;
--udp)
if [ $# -lt 3 ]; then
usage
fi
( pfctl -a "rdr/${JAIL_NAME}" -Psn;
printf '%s\nrdr on $ext_if inet proto udp to port %d -> %s port %d\n' "$EXT_IF" "$2" "$JAIL_IP" "$3" ) \
| pfctl -a "rdr/${JAIL_NAME}" -f-
shift 3
;;
*)
usage
;;
esac
done