mirror of
https://codeberg.org/scip/jaildk.git
synced 2025-12-17 04:31:02 +01:00
added pf support
This commit is contained in:
126
README.md
126
README.md
@@ -418,6 +418,132 @@ which uses custom ipfw rules:
|
|||||||
|
|
||||||
`exec.prestart = "/jail/bin/jaildk ipfw $name"`
|
`exec.prestart = "/jail/bin/jaildk ipfw $name"`
|
||||||
|
|
||||||
|
Be aware, that the ipfw module will only be executed if the jail is
|
||||||
|
running so that we can properly determine the ip addresses of the
|
||||||
|
running jail. **Note**: this might change in the future.
|
||||||
|
|
||||||
|
### Using pf
|
||||||
|
|
||||||
|
Beside ipfw, Free supports
|
||||||
|
[pf](https://www.freebsd.org/doc/de_DE.ISO8859-1/books/handbook/firewalls-pf.html)
|
||||||
|
as well. You can use pf with `jaildk`. Unlike the ipfw module (see
|
||||||
|
above) it is a normal `install` module. That is it can be installed or
|
||||||
|
reloaded before the jail is running (i.e. like the mount module).
|
||||||
|
|
||||||
|
In order to use `pf` with a jail, enable and configure it according to
|
||||||
|
the FreeBSD handbook linked above. It is recommended to include
|
||||||
|
general block, scrup, state rules, communication to and fro localhost
|
||||||
|
etc and just leave everything which is related to your jail.
|
||||||
|
|
||||||
|
Just so that you know how such a global `/etc/pf.conf` file might look
|
||||||
|
like, here's a simple one:
|
||||||
|
```shell
|
||||||
|
# variables
|
||||||
|
ext = "em0"
|
||||||
|
me = "your ipv4 address here"
|
||||||
|
me5 = "your ipv6 address here/64"
|
||||||
|
loginports = "{ 22, 5222, 443 }"
|
||||||
|
icmp_types = "echoreq"
|
||||||
|
|
||||||
|
# tables. look at the contents of a table:
|
||||||
|
# pfctl -t bad_hosts -T show
|
||||||
|
# remove an entry from a table:
|
||||||
|
# pfctl -t bad_hosts -T delete $ip
|
||||||
|
table <bad_hosts> persist
|
||||||
|
|
||||||
|
# default policy
|
||||||
|
set block-policy drop
|
||||||
|
|
||||||
|
# optimize according to rfc's
|
||||||
|
set optimization aggressive
|
||||||
|
|
||||||
|
# normalisation
|
||||||
|
scrub in all
|
||||||
|
antispoof for $ext
|
||||||
|
|
||||||
|
# allow localhost
|
||||||
|
pass quick on $local
|
||||||
|
|
||||||
|
# additional default block rules w/ logging. to view the log:
|
||||||
|
# tcpdump -n -e -ttt -r /var/log/pflog
|
||||||
|
# to view live log:
|
||||||
|
# tcpdump -n -e -ttt -i pflog0
|
||||||
|
block in log on $ext
|
||||||
|
block in log on $ext inet6
|
||||||
|
|
||||||
|
# whoever makes it into those tables: you loose
|
||||||
|
block quick from <bad_hosts>
|
||||||
|
|
||||||
|
# allow outgoing established sessions
|
||||||
|
pass out keep state
|
||||||
|
pass out inet6 keep state
|
||||||
|
|
||||||
|
# allow troubleshooting
|
||||||
|
pass in on $ext inet proto icmp all icmp-type $icmp_types keep state
|
||||||
|
pass in on $ext inet proto udp from any to any port 33433 >< 33626 keep state
|
||||||
|
|
||||||
|
# allow all icmpv6
|
||||||
|
pass in quick inet6 proto icmp6 all keep state
|
||||||
|
|
||||||
|
# allow login but punish offenders
|
||||||
|
block quick from <bad*hosts>
|
||||||
|
pass in quick on $ext inet proto tcp from any to $me port $loginports \
|
||||||
|
flags S/SAFR keep state \
|
||||||
|
(max-src-conn-rate 10/60, \
|
||||||
|
overload <bad*hosts> flush global) label ServicesTCP
|
||||||
|
pass in quick on $ext inet6 proto tcp from any to $me6 port $loginports \
|
||||||
|
flags S/SAFR keep state \
|
||||||
|
(max-src-conn-rate 10/60, \
|
||||||
|
overload <bad_hosts> flush global) label ServicesTCP
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the ruleset with `service pf start`.
|
||||||
|
|
||||||
|
Now that everything is prepared you can create a pf.conf file for your
|
||||||
|
jail. Here's an example I use for a webserver jail, which includes a
|
||||||
|
git server:
|
||||||
|
```shell
|
||||||
|
ip = "jail ip4 addr"
|
||||||
|
ip6 = "jail ip6 addr"
|
||||||
|
loginports = "{ 22 }"
|
||||||
|
prodports = "{ 80, 443 }"
|
||||||
|
ext = "em0"
|
||||||
|
|
||||||
|
# dynamic block list
|
||||||
|
table <blocked>
|
||||||
|
|
||||||
|
# restrict foreigners
|
||||||
|
block quick from <blocked>
|
||||||
|
pass in quick on $ext inet proto tcp from any to $ip port $loginports \
|
||||||
|
flags S/SAFR keep state \
|
||||||
|
(max-src-conn-rate 10/60, \
|
||||||
|
overload <blocked> flush global) label ServicesTCP
|
||||||
|
|
||||||
|
# allow production traffic v4
|
||||||
|
pass in quick on $ext proto tcp from any to $ip port $prodports keep state
|
||||||
|
|
||||||
|
# allow production traffic v6
|
||||||
|
pass in quick inet6 proto tcp from any to $ip6 port $prodports keep state
|
||||||
|
```
|
||||||
|
|
||||||
|
That's it already. Now install the jail as usual. You can also install
|
||||||
|
the pf ruleset for the jail separately:
|
||||||
|
|
||||||
|
`jaildk install myjail start -r pf`
|
||||||
|
|
||||||
|
To take look at the rules, execute:
|
||||||
|
|
||||||
|
`jaildk install myjail status -r pf`
|
||||||
|
|
||||||
|
You can of course manipulate the ruleset manually. `jaildk` installs
|
||||||
|
rulesets into a jail specific anchor using the following naming
|
||||||
|
scheme: `/jail/<jail name>`. So, for example to view the rules, execute:
|
||||||
|
|
||||||
|
`pfctl -a /jail/myjail -s rules`
|
||||||
|
|
||||||
|
Manipulate a jail specific table:
|
||||||
|
|
||||||
|
`pfctl -a /jail/myjail -t blocked -T show`
|
||||||
|
|
||||||
## Getting help
|
## Getting help
|
||||||
|
|
||||||
|
|||||||
85
jaildk
85
jaildk
@@ -1,6 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
version=1.08
|
version=1.09
|
||||||
|
|
||||||
usage_jaildk() {
|
usage_jaildk() {
|
||||||
beg=`tput -T ${TERM:-cons25} md`
|
beg=`tput -T ${TERM:-cons25} md`
|
||||||
@@ -119,6 +119,58 @@ die_if_not_exist() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parse_jail_conf() {
|
||||||
|
#
|
||||||
|
# just in case we want or have to fetch variables out of
|
||||||
|
# /etc/jail.conf, this is the way to go. Call it like this:
|
||||||
|
#
|
||||||
|
# ip=`parse_jail_conf $jail ip4.addr`
|
||||||
|
#
|
||||||
|
# Output may be empty, so check before using. Multiple variables
|
||||||
|
# of the same type (like multiple ip addresses) will be returned
|
||||||
|
# comma separated.
|
||||||
|
jail=$1
|
||||||
|
search=$2
|
||||||
|
JAIL=''
|
||||||
|
list=''
|
||||||
|
|
||||||
|
# fetch 20 lines after "^$jail {", ignore comments
|
||||||
|
egrep -A20 "^$jail" jail.conf | egrep -v "^ *#" | \
|
||||||
|
# turn each line into an evaluable shell expression \
|
||||||
|
sed -e 's/ *{//g' -e 's/}//g' -e 's/ *= */=/g' -e 's/;$//' | \
|
||||||
|
# ignore empty lines \
|
||||||
|
egrep -v '^$' | while read LINE; do
|
||||||
|
if echo "$LINE" | egrep -q "="; then
|
||||||
|
case $JAIL in
|
||||||
|
$jail)
|
||||||
|
var=`echo "$LINE" | cut -d= -f1`
|
||||||
|
opt=`echo "$LINE" | cut -d= -f2 | sed -e 's/^"//' -e 's/"$//'`
|
||||||
|
case $var in
|
||||||
|
$search)
|
||||||
|
if test -z "$list"; then
|
||||||
|
list="$opt"
|
||||||
|
else
|
||||||
|
list="$list,$opt"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo $list
|
||||||
|
return
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
else
|
||||||
|
case $LINE in
|
||||||
|
\*) JAIL=any;;
|
||||||
|
*) JAIL="$LINE";;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
usage_build() {
|
usage_build() {
|
||||||
fin "Usage: $0 build <jail> [<start|stop|status>] [-b <base>] [-v <version>]
|
fin "Usage: $0 build <jail> [<start|stop|status>] [-b <base>] [-v <version>]
|
||||||
Mount <jail> to $j/build read-writable for maintenance. Options:
|
Mount <jail> to $j/build read-writable for maintenance. Options:
|
||||||
@@ -171,6 +223,33 @@ jaildk_build() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jaildk_rc_pf() {
|
||||||
|
jail=$1
|
||||||
|
mode=$2
|
||||||
|
conf=$j/etc/$jail/pf.conf
|
||||||
|
|
||||||
|
# FIXME: maybe we use parse_jail_conf() to fetch ip addresses,
|
||||||
|
# generate a config file containing pf macros, which the user
|
||||||
|
# needs to include in the jails pf.conf? On the other hand,
|
||||||
|
# there's not that much duplication in the config. So, maybe not.
|
||||||
|
if test -f $conf; then
|
||||||
|
case $mode in
|
||||||
|
start)
|
||||||
|
bold "Installing PF rules for jail $jail:"
|
||||||
|
pfctl -a /jail/$jail -f $conf -v
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
bold "PF rules for jail $jail:"
|
||||||
|
pfctl -a /jail/$jail -s rules -v
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
bold "Removing PF rules for jail $jail:"
|
||||||
|
pfctl -a /jail/$jail -f $conf -v -F all
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
jaildk_rc_mtree() {
|
jaildk_rc_mtree() {
|
||||||
jail=$1
|
jail=$1
|
||||||
mode=$2
|
mode=$2
|
||||||
@@ -1540,8 +1619,8 @@ jaildk_ipfw_delete() {
|
|||||||
JAILDIR=/jail
|
JAILDIR=/jail
|
||||||
|
|
||||||
# install modules
|
# install modules
|
||||||
RCSCRIPTS_START="jaildk_rc_mount jaildk_rc_rcoff jaildk_rc_ports jaildk_rc_mtree"
|
RCSCRIPTS_START="jaildk_rc_mount jaildk_rc_rcoff jaildk_rc_ports jaildk_rc_mtree jaildk_rc_pf"
|
||||||
RCSCRIPTS_STOP="jaildk_rc_rcoff jaildk_rc_mount jaildk_rc_ports"
|
RCSCRIPTS_STOP="jaildk_rc_pf jaildk_rc_rcoff jaildk_rc_mount jaildk_rc_ports"
|
||||||
|
|
||||||
# globals
|
# globals
|
||||||
j=$JAILDIR
|
j=$JAILDIR
|
||||||
|
|||||||
Reference in New Issue
Block a user