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
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
|