Enable iptables based ratelimit for cloudron auth services

The goal here is to simply add a rate limit to prevent brute
force password attacks.

Covered services includes:
    (public) http, https, ssh, smtp, msa, imap, sieve
    (private) postgres, redis, mysql, ldap, mongodb. msa

The private limits are higher because some apps will create
a db connection for each page request.  Some apps like mailtrain
will send out lots of emails etc.

Note that apps that use SSO are ratelimited by the ldap limit.

Part of #187
This commit is contained in:
Girish Ramakrishnan
2017-03-28 23:53:27 -07:00
parent 39e827be04
commit 4d000e377f

View File

@@ -46,6 +46,7 @@ if [[ "${arg_provider}" == "caas" ]]; then
else
iptables -A CLOUDRON -p tcp -m tcp -m multiport --dports 25,80,22,443,587,993,4190 -j ACCEPT
fi
iptables -t filter -A CLOUDRON -p icmp --icmp-type echo-request -j ACCEPT
iptables -t filter -A CLOUDRON -p icmp --icmp-type echo-reply -j ACCEPT
iptables -t filter -A CLOUDRON -p udp --sport 53 -j ACCEPT
@@ -60,6 +61,58 @@ if ! iptables -t filter -C INPUT -j CLOUDRON 2>/dev/null; then
iptables -t filter -I INPUT -j CLOUDRON
fi
# Setup rate limit chain (the recent info is at /proc/net/xt_recent)
iptables -t filter -N CLOUDRON_RATELIMIT || true
iptables -t filter -F CLOUDRON_RATELIMIT # empty any existing rules
# log dropped incoming. keep this at the end of all the rules
iptables -t filter -N CLOUDRON_RATELIMIT_LOG || true
iptables -t filter -F CLOUDRON_RATELIMIT_LOG # empty any existing rules
iptables -t filter -A CLOUDRON_RATELIMIT_LOG -m limit --limit 2/min -j LOG --log-prefix "IPTables RateLimit: " --log-level 7
iptables -t filter -A CLOUDRON_RATELIMIT_LOG -j DROP
# http https
for port in 80 443; do
iptables -A CLOUDRON_RATELIMIT -p tcp --dport ${port} -m state --state NEW -m recent --set --name "public-${port}"
iptables -A CLOUDRON_RATELIMIT -p tcp --dport ${port} -m state --state NEW -m recent --update --name "public-${port}" --seconds 5 --hitcount 250 -j CLOUDRON_RATELIMIT_LOG
done
# ssh smtp ssh msa imap sieve
for port in 22 202; do
iptables -A CLOUDRON_RATELIMIT -p tcp --dport ${port} -m state --state NEW -m recent --set --name "public-${port}"
iptables -A CLOUDRON_RATELIMIT -p tcp --dport ${port} -m state --state NEW -m recent --update --name "public-${port}" --seconds 10 --hitcount 10 -j CLOUDRON_RATELIMIT_LOG
done
# TODO: move docker platform rules to platform.js so it can be specialized to rate limit only when destination is the mail container
# docker translates (dnat) 25, 587, 993, 4190 in the PREROUTING step
for port in 2525 4190 9993; do
iptables -A CLOUDRON_RATELIMIT -p tcp ! -s 172.18.0.0/16 -d 172.18.0.0/16 --dport ${port} -m state --state NEW -m recent --set --name "public-${port}"
iptables -A CLOUDRON_RATELIMIT -p tcp ! -s 172.18.0.0/16 -d 172.18.0.0/16 --dport ${port} -m state --state NEW -m recent --update --name "public-${port}" --seconds 10 --hitcount 10 -j CLOUDRON_RATELIMIT_LOG
done
# ldap, imap, sieve
for port in 3002 4190 9993; do
iptables -A CLOUDRON_RATELIMIT -p tcp -s 172.18.0.0/16 -d 172.18.0.0/16 --dport ${port} -m state --state NEW -m recent --set --name "private-${port}"
iptables -A CLOUDRON_RATELIMIT -p tcp -s 172.18.0.0/16 -d 172.18.0.0/16 --dport ${port} -m state --state NEW -m recent --update --name "private-${port}" --seconds 10 --hitcount 10 -j CLOUDRON_RATELIMIT_LOG
done
# cloudron docker network: smtp mysql postgresql redis mongodb
for port in 2525 3306 5432 6379 27017; do
iptables -A CLOUDRON_RATELIMIT -p tcp -s 172.18.0.0/16 -d 172.18.0.0/16 --dport ${port} -m state --state NEW -m recent --set --name "private-${port}"
iptables -A CLOUDRON_RATELIMIT -p tcp -s 172.18.0.0/16 -d 172.18.0.0/16 --dport ${port} -m state --state NEW -m recent --update --name "private-${port}" --seconds 5 --hitcount 250 -j CLOUDRON_RATELIMIT_LOG
done
# For ssh, http, https
if ! iptables -t filter -C INPUT -j CLOUDRON_RATELIMIT 2>/dev/null; then
iptables -t filter -I INPUT 1 -j CLOUDRON_RATELIMIT
fi
# For smtp, imap etc routed via docker/nat
if ! iptables -t filter -C FORWARD -j CLOUDRON_RATELIMIT 2>/dev/null; then
iptables -t filter -I FORWARD 1 -j CLOUDRON_RATELIMIT
fi
# so it gets restored across reboot
mkdir -p /etc/iptables && iptables-save > /etc/iptables/rules.v4