You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

372 lines
9.5 KiB

#!/bin/bash
## Depends lxc-scripts installed
##
## Install
##
HOST_EXTERNAL_DEVICE=${HOST_EXTERNAL_DEVICE:-eth0}
version_gt() { test "$(echo "$@" | tr " " "\n" | sort -V | head -n 1)" != "$1"; }
shorewall_candidate_version=$(echo $(apt-cache policy shorewall | grep "Candidate:" | cut -f 2 -d :))
## Support for docker introduced in 5.0.6
if version_gt "$shorewall_candidate_version" 5.0.5; then
apt-get install -y shorewall
else
(
VERSION="5.0.7.2-1"
cd /tmp &&
wget http://ftp.fr.debian.org/debian/pool/main/s/shorewall-core/shorewall-core_${VERSION}_all.deb &&
wget http://ftp.fr.debian.org/debian/pool/main/s/shorewall/shorewall_${VERSION}_all.deb &&
dpkg -i shorewall-core_${VERSION}_all.deb shorewall_${VERSION}_all.deb &&
rm shorewall-core_${VERSION}_all.deb shorewall_${VERSION}_all.deb
) || {
echo "Failed to install shorewall."
exit 1
}
fi
case $(lsb_release -is) in
Debian)
case $(lsb_release -rs) in
10)
## we had trouble with ``nft`` shorewall
update-alternatives --set iptables /usr/sbin/iptables-legacy
;;
esac
;;
esac
apt-get install -y dnsutils </dev/null
##
## Configuration
##
cat <<EOF > /etc/shorewall/README
Important notes gathered through time:
# Shorewall duties on our host
- block any access from outside to local ports if not mentionned
explicitely in shorewall.
- connect external ports to LXC (dockers has its own means)
- This uses ``/var/lib/lxc/*/shorewall`` files
- let mosh connect correctly
- ensure a correct access from Host/LXC/Docker to server's services.
For instance, an Host/LXC/Docker should be able to as if it was
external: ``curl https://myhostwebsite``. This is called routeback
and requires some special rules.
# Shorewall restarting and cache
Some process in shorewall seems to be using cache in some ways in
recent version that implies that it won't take actions if files are
not changed. A simple 'touch FILE' seems to be enough. Notice the
'Compiling' lines appearing in ``shorewall restart``.
It's always good to double-check in ``iptables -nL`` that some rules
actually seem to match your intention.
Don't forget that ``iptables-save`` is probably the best way to get
the full rules printed on stdout.
# Debian, ovh kernels and iptables-nft
Starting from Debian10, iptables by default uses iptables-nft... which
works well with default debian kernel. OVH kernels DO NOT provide
necessary kernel and we must:
update-alternatives --set iptables /usr/sbin/iptables-legacy
Note that transition is a little tricky because BOTH ways can have
their tables simultaneously. Use ``iptables-nft -nL`` and
``iptables-legacy -nL`` to check.
For now, we had little success to properly have the ``nft`` version
working properly on debian kernel. So even on debian kernel, we switch
here to iptables-legacy if on debian system.
# Interaction with docker's iptables rules
This is configured in ``shorewall.conf``, thanks to a simple::
DOCKER=Yes
# Route back
Be sure to check in /var/lib/lxc/*/shorewall definitions, they
must include special stances (see in next section).
On the side of shorewall, all network interface should be declared in
``/etc/shorewall/interfaces``.
# lxc ``shorewall`` files
Prefer the usage of ``ports`` files. If you insist on having a better
control of rules per LXC, you can use ``shorewall`` files.
They should be located in /var/lib/lxc/*/shorewall. This is a standard
redirection from external host port 10022 to lxc's port 22, on port
tcp::
DNAT net lan:%%IP%%:22 tcp 10022
#DNAT net lan:%%IP%%:22 udp 10022
Routeback (access of the same service from Host/LXC/Docker on the external
address) is given by these additional rules::
DNAT lan lan:www:80 tcp 80 - %%HOST_INTERNET_IP%%
DNAT lan lan:www:443 tcp 443 - %%HOST_INTERNET_IP%%
DNAT fw lan:www:80 tcp 80 - %%HOST_INTERNET_IP%%
DNAT fw lan:www:443 tcp 443 - %%HOST_INTERNET_IP%%
# lxc ``ports`` files
They should be located in /var/lib/lxc/*/ports. This is a standard
redirection from external host port 10022 to lxc's port 22, on both
tcp and udp::
10022:22 ## Normal port
# 10023:23 ## This is commented !
Note that comments are supported also.
EOF
cat <<EOF > /etc/shorewall/zones
fw firewall
net ipv4
lan ipv4
EOF
cat <<EOF > /etc/shorewall/macro.Mosh
#######################################################################################################
# DO NOT REMOVE THE FOLLOWING LINE
##############################################################################################################################################################
#ACTION SOURCE DEST PROTO DPORT SPORT ORIGDEST RATE USER MARK CONNLIMITTIME HEADERS SWITCH HELPER
#
PARAM - - udp 60000:61000
EOF
cat <<EOF > /etc/shorewall/interfaces
#ZONE INTERFACE BROADCAST OPTIONS
net $HOST_EXTERNAL_DEVICE
## Uncomment to enable vpn setup
#vpn tun0 detect
## All interfaces that require route back should be listed
## here:
lan lxcbr0 - routeback
BEGIN SHELL
ifconfig=\$(ifconfig)
echo "BEGIN DOCKER adding networks rules:" >&2
for docker_net in \$(docker network list -f driver=bridge -q); do
gws=\$(docker network inspect "\$docker_net" --format "{{range .IPAM.Config}}{{.Gateway}}{{\"\n\"}}{{end}}") || continue
for gw in \$gws; do
if=\$(printf "%s" "\$ifconfig" | egrep "\$gw" -B 1 | head -n 1 | cut -f 1 -d " ")
echo " lan \$if - routeback" >&2
echo "lan \$if - routeback"
done
done
echo "END DOCKER" >&2
true
END SHELL
EOF
cat <<EOF > /etc/shorewall/policy
#SOURCE DEST RULE LOG
fw all ACCEPT
lan all ACCEPT
net all DROP info
all all DROP info
EOF
cat <<EOF > /etc/shorewall/rules
SSH/ACCEPT net fw
Ping/ACCEPT net fw
Mosh(ACCEPT) net fw
BEGIN SHELL
host_ip="\$(/sbin/ifconfig $HOST_EXTERNAL_DEVICE 2> /dev/null | sed "s/^.*inet //g" | grep ^[0-9] | sed "s/ .*$//g")"
for name in \$(lxc-ls-running); do
ip=\$(dig +short A "\$name")
[ -e "/var/lib/lxc/\$name/shorewall" ] &&
cat /var/lib/lxc/\$name/shorewall |
sed -r "s/%%HOST_INTERNET_IP%%/\$host_ip/g" |
sed -r "s/%%IP%%/\$ip/g"
if [ -e "/var/lib/lxc/\$name/ports" ]; then
for ports in \$(cat /var/lib/lxc/\$name/ports | sed -r 's/#.*\$//g'); do
lxc_port=\${ports#*:}
ext_port=\${ports%:*}
echo "LXC \$name: redirection from \$host_ip:\$ext_port -> \$ip:\$lxc_port" >&2
for proto in tcp udp; do
for zone in net lan fw; do
echo "DNAT \$zone lan:\$ip:\$lxc_port \$proto \$ext_port - \$host_ip"
done
done
done
fi
done
true
END SHELL
EOF
cat <<EOF > /etc/shorewall/masq
$HOST_EXTERNAL_DEVICE lxcbr0
EOF
cat <<EOF > /etc/shorewall/start
## correct a bug that prevent DHCP packet to be correctly sent between
## LXC, preventing them to receive an IP.
. /etc/default/lxc
if [ -d "/sys/class/net/\$LXC_BRIDGE" ] && [ "\$(cat /sys/class/net/\$LXC_BRIDGE/operstate)" = "up" ]; then
source_file=
if [ -e /etc/init/lxc-net.conf ]; then
source_file=/etc/init/lxc-net.conf
elif [ -e /usr/lib/x86_64-linux-gnu/lxc/lxc-net ]; then
source_file=/usr/lib/x86_64-linux-gnu/lxc/lxc-net
fi
if [ "\$source_file" ]; then
code=\$(egrep '^\s+iptables.*\s+-j\s+' \$source_file | grep -v '\-D' | sed -r 's/^\s+[^-]+/run_iptables /g')
echo "Adding LXC rules:"
echo "\$code"
eval "\$code"
fi
fi
EOF
##
## lxc-scripts
##
[ -d "/opt/apps/lxc-scripts" ] || {
echo "Error: required 'lxc-scripts' not installed." >&2
exit 1
}
apt-get install -y moreutils ## needed because ``ts`` is used in this script
ln -sf /opt/apps/lxc-scripts/etc/cron.d/lxc-shorewall-repair /etc/cron.d/lxc-shorewall-repair
cat <<EOF > /etc/logrotate.d/lxc-shorewall-repair
/var/log/lxc-shorewall-repair.log {
weekly
missingok
dateext
dateyesterday
dateformat _%Y-%m-%d
extension .log
rotate 52
compress
delaycompress
notifempty
create 640 root root
sharedscripts
}
EOF
##
## LOGS
##
mkdir -p /var/log/shorewall
chgrp syslog /var/log/shorewall
chmod g+w /var/log/shorewall
cat <<EOF > /etc/rsyslog.d/shorewall.conf
:msg, contains, "Shorewall:" /var/log/shorewall/main.log
& ~
if \$msg contains 'net-fw DROP IN=' then {
action(type="omfile" file="/var/log/shorewall/net-fw.log")
stop
}
EOF
cat <<EOF > /etc/logrotate.d/shorewall
/var/log/shorewall/init.log
/var/log/shorewall/net-fw.log
/var/log/shorewall/main.log
{
weekly
missingok
dateext
dateyesterday
dateformat _%Y-%m-%d
extension .log
rotate 52
compress
delaycompress
notifempty
create 640 root root
sharedscripts
postrotate
reload rsyslog >/dev/null 2>&1 || true
endscript
}
EOF
## Init logs
sed -ri 's%^(STARTUP_LOG=).*$%\1/var/log/shorewall/init.log%g' /etc/shorewall/shorewall.conf
service rsyslog restart
##
## Final settings
##
## Activate support for docker
sed -ri 's/^DOCKER=No$/DOCKER=Yes/g' /etc/shorewall/shorewall.conf
sed -ri 's/^IP_FORWARDING=Keep$/IP_FORWARDING=On/g' /etc/shorewall/shorewall.conf