Last active
March 1, 2022 12:47
-
-
Save mizhka/5c770e6f2b3335147eecb8299d8b383d to your computer and use it in GitHub Desktop.
Jail+vnet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# dhcpd.conf | |
# option definitions common to all supported networks... | |
option subnet-mask 255.255.255.0; | |
default-lease-time 600; | |
max-lease-time 7200; | |
subnet 192.168.20.0 netmask 255.255.255.0 { | |
range 192.168.20.2 192.168.20.40; | |
option domain-name-servers 192.168.20.1; | |
option routers 192.168.20.1; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
ORIGIN="tank/guests/vm/jails/basepg@base" | |
TARGET="tank/guests/vm/jails" | |
JAILNAME="tmp`date +%Y%m%d`" | |
# Check if dataset exists | |
zfs get name ${TARGET}/${JAILNAME} > /dev/null 2>&1 | |
if [ $? -ne 0 ] | |
then | |
echo ">>> Create ZFS dataset ${TARGET}/${JAILNAME}" | |
zfs clone ${ORIGIN} ${TARGET}/${JAILNAME} || exit 1 | |
fi | |
echo ">>> Register new temp jail in jail.conf" | |
grep -qxF "${JAILNAME} {}" /etc/jail.conf || printf "${JAILNAME} {}\n" >> /etc/jail.conf | |
jls -j ${JAILNAME} > /dev/null 2>&1 | |
if [ $? -ne 0 ] | |
then | |
echo ">>> Start jail" | |
jail -vc ${JAILNAME} || exit 3 | |
fi | |
echo ">>> Go to shell" | |
jexec -l ${JAILNAME} zsh || exit 4 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Environment discovery | |
EXTERNAL_IF=`netstat -r4n | grep defa | cut -f4 -w` | |
EXTERNAL_IP=`ifconfig $EXTERNAL_IF | grep inet | cut -f3 -w` | |
# Extra settings | |
KLDMODS="ng_ipfw ng_ether ng_nat ng_eiface" | |
NG_IFPREFIX="ng-" | |
VERBOSE="yes" | |
# Input parameters | |
INTERNAL_IP="192.168.20.1" | |
INTERNAL_IF="${NG_IFPREFIX}jailgw" | |
NG_NATNAME="jail_nat0" | |
NG_BRGNAME="jail_bridge0" | |
print ( ) | |
{ | |
if [ "$VERBOSE" = "yes" ] ; then | |
echo ">>>> " $* | |
fi | |
} | |
print_error ( ) | |
{ | |
echo "Stopped at:" $* | |
exit 1 | |
} | |
# Load kernel modules | |
load_kld ( ) | |
{ | |
local _kldmod | |
print "Loading kernel modules" | |
for _kldmod in ${KLDMODS}; do | |
print "... Loading" ${_kldmod} | |
kldload -n ${_kldmod} | |
done | |
print "All kernel module loaded" | |
} | |
init_ipfw_nat ( ) | |
{ | |
local _name _in _out _ext_ip _ext_if _int_ip _int_if | |
_name=$1 | |
_ext_ip=$2 | |
_ext_if=$3 | |
_int_ip=$4 | |
_int_if=$5 | |
_in=100 | |
_out=110 | |
ngctl info ${_name}: > /dev/null 2>&1 && return | |
print "[NAT] start configuration of $_name from $_int_ip/$_int_if to $_ext_ip/$_ext_if" | |
print "... netgraph" | |
ngctl mkpeer ipfw: nat ${_in} in || print_error init_ipfw_nat ${LINENO} | |
ngctl name ipfw:${_in} ${_name} || print_error init_ipfw_nat ${LINENO} | |
ngctl connect ipfw: ${_name}: ${_out} out || print_error init_ipfw_nat ${LINENO} | |
ngctl msg ${_name}: setaliasaddr ${_ext_ip} || print_error init_ipfw_nat ${LINENO} | |
print "... ipfw" | |
destroy_ipfw_rules | |
ipfw -q add 200 allow ip from any to $_int_ip in via $_int_if || print_error init_ipfw_nat ${LINENO} | |
ipfw -q add 300 netgraph $_out all from any to any in via $_int_if || print_error init_ipfw_nat ${LINENO} | |
ipfw -q add 400 netgraph $_in all from any to any in via $_ext_if || print_error init_ipfw_nat ${LINENO} | |
ipfw -q add 500 allow ip from any to any || print_error init_ipfw_nat ${LINENO} | |
print "[NAT] done" | |
} | |
destroy_ipfw_rules ( ) | |
{ | |
ipfw -q delete 200 > /dev/null 2>&1 | |
ipfw -q delete 300 > /dev/null 2>&1 | |
ipfw -q delete 400 > /dev/null 2>&1 | |
ipfw -q delete 500 > /dev/null 2>&1 | |
} | |
destroy_ng_node ( ) | |
{ | |
ngctl shutdown $1: > /dev/null 2>&1 | |
} | |
init_jail_bridge ( ) | |
{ | |
local _bridge _int_if _int_ip _ext_if _oldname _ether | |
_bridge=$1 | |
_ext_if=$2 | |
_int_ip=$3 | |
_int_if=$4 | |
_ether="6a:61:69:6c:00:aa" | |
# Make sure the interface has been bridged | |
ngctl info ${_bridge}: > /dev/null 2>&1 && return | |
# Create bridge | |
ngctl mkpeer $_ext_if: bridge lower link0 || print_error init_jail_bridge ${LINENO} | |
ngctl name $_ext_if:lower ${_bridge} || print_error init_jail_bridge ${LINENO} | |
ngctl mkpeer ${_bridge}: eiface link1 ether || print_error init_jail_bridge ${LINENO} | |
# Disconnect from external interface | |
ngctl rmhook ${_bridge}: link0 || print_error init_jail_bridge ${LINENO} | |
_oldname=`ngctl show -n ${_bridge}:link1 | cut -f3 -w` | |
ngctl name ${_bridge}:link1 ${_int_if} || print_error init_jail_bridge ${LINENO} | |
ifconfig ${_oldname} name ${_int_if} > /dev/null || print_error init_jail_bridge ${LINENO} | |
ifconfig ${_int_if} inet alias ${_int_ip} > /dev/null || print_error init_jail_bridge ${LINENO} | |
ifconfig ${_int_if} ether ${_ether} || print_error create_interface ${LINENO} | |
print "Let packets continue with after being (de)aliased" | |
sysctl net.inet.ip.fw.one_pass=0 | |
sysctl net.inet.ip.forwarding=1 | |
} | |
create_interface ( ) | |
{ | |
local _num _name _link _ifname _oldname _ether _bridge | |
_num=2 | |
_name=$1 | |
_ifname="${NG_IFPREFIX}${_name}" | |
_bridge=$2 | |
# Silently exit if interface exists (job is done before) | |
ngctl msg "$_ifname:" getifname > /dev/null 2>&1 && \ | |
echo ">>>> Interface already exists" && return | |
while ngctl msg ${_bridge}: getstats $_num > /dev/null 2>&1 | |
do | |
_num=$(( $_num + 1 )) | |
done | |
_link="link${_num}" | |
# 6a:61:69:6c means "jail" | |
_ether="6a:61:69:6c:00:${_num}" | |
print "Create interface ${_ifname} with MAC ${_ether}" | |
ngctl mkpeer ${_bridge}: eiface ${_link} ether || print_error create_interface ${LINENO} | |
_oldname=`ngctl show -n ${_bridge}:${_link} | cut -f3 -w` | |
print "... Adjust names (netgraph) ${_oldname} -> ${_ifname}" | |
ngctl name ${_bridge}:${_link} ${_ifname} || print_error create_interface ${LINENO} | |
print "... Adjust names (if) ${_oldname} -> ${_ifname}" | |
ifconfig ${_oldname} name ${_ifname} > /dev/null || print_error create_interface ${LINENO} | |
print "... Set MAC address: ${_ether}" | |
ifconfig ${_ifname} ether ${_ether} || print_error create_interface ${LINENO} | |
print "Done" | |
} | |
delete_interface ( ) | |
{ | |
local _ifname _name | |
_name=$1 | |
_ifname="${NG_IFPREFIX}${_name}" | |
ngctl shutdown ${_ifname}: 2> /dev/null | |
} | |
init ( ) | |
{ | |
load_kld | |
init_jail_bridge ${NG_BRGNAME} ${EXTERNAL_IF} ${INTERNAL_IP} ${INTERNAL_IF} | |
init_ipfw_nat ${NG_NATNAME} ${EXTERNAL_IP} ${EXTERNAL_IF} ${INTERNAL_IP} ${INTERNAL_IF} | |
dhcpd ${INTERNAL_IF} | |
} | |
# MAIN | |
if [ "$1" = "create" ]; then | |
shift | |
# Make sure the interface has been bridged | |
ngctl info ${NG_BRGNAME}: > /dev/null 2>&1 || init | |
create_interface $1 ${NG_BRGNAME} | |
exit 0 | |
fi | |
if [ "$1" = "delete" ]; then | |
shift | |
delete_interface $* | |
exit 0 | |
fi | |
if [ "$1" = "init" ]; then | |
shift | |
init | |
exit 0 | |
fi | |
if [ "$1" = "deinit" ]; then | |
shift | |
pkill -f "dhcpd ${INTERNAL_IF}" | |
destroy_ng_node ${NG_NATNAME} | |
destroy_ng_node ${NG_BRGNAME} | |
destroy_ng_node ${INTERNAL_IF} | |
destroy_ipfw_rules | |
exit 0 | |
fi | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment