Newer
Older
# _____ _ _
# | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# | __| _| -_| -_| . | . | | . | . | | -_|
# |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
FIREWALL_DOMAINS=$HOME/${PROJECT_NAME}-firewall-domains.cfg
iptables-save > /etc/firewall.conf
ip6tables-save > /etc/firewall6.conf
printf '#!/bin/sh\n' > /etc/network/if-up.d/iptables
printf 'iptables-restore < /etc/firewall.conf\n' >> /etc/network/if-up.d/iptables
printf 'ip6tables-restore < /etc/firewall6.conf\n' >> /etc/network/if-up.d/iptables
if [ -f /etc/network/if-up.d/iptables ]; then
chmod +x /etc/network/if-up.d/iptables
fi
function block_firefox_telemetry {
# This shouldn't be needed on a server, but we'll do it anyway
# to be on the safe side
# Within firefox source code see submit_telemetry_data.py
echo '127.0.0.1 telemetry.mozilla.org' >> /etc/hosts
return
fi
iptables -A INPUT -s $FIREFOX_TELEMETRY_IP -j DROP
iptables -A OUTPUT -s $FIREFOX_TELEMETRY_IP -j DROP
save_firewall_settings
}
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
return
fi
# There are various blocklists out there, but they're difficult
# to verify. Indiscriminately blocking ranges without evidence
# would be a bad idea.
# From Wikipedia and elsewhere: US military addresses
iptables -A INPUT -s 6.0.0.0/8 -j DROP
iptables -A OUTPUT -s 6.0.0.0/8 -j DROP
iptables -A INPUT -s 7.0.0.0/8 -j DROP
iptables -A OUTPUT -s 7.0.0.0/8 -j DROP
iptables -A INPUT -s 11.0.0.0/8 -j DROP
iptables -A OUTPUT -s 11.0.0.0/8 -j DROP
iptables -A INPUT -s 21.0.0.0/8 -j DROP
iptables -A OUTPUT -s 21.0.0.0/8 -j DROP
iptables -A INPUT -s 22.0.0.0/8 -j DROP
iptables -A OUTPUT -s 22.0.0.0/8 -j DROP
iptables -A INPUT -s 26.0.0.0/8 -j DROP
iptables -A OUTPUT -s 26.0.0.0/8 -j DROP
iptables -A INPUT -s 28.0.0.0/8 -j DROP
iptables -A OUTPUT -s 28.0.0.0/8 -j DROP
iptables -A INPUT -s 29.0.0.0/8 -j DROP
iptables -A OUTPUT -s 29.0.0.0/8 -j DROP
iptables -A INPUT -s 30.0.0.0/8 -j DROP
iptables -A OUTPUT -s 30.0.0.0/8 -j DROP
iptables -A INPUT -s 33.0.0.0/8 -j DROP
iptables -A OUTPUT -s 33.0.0.0/8 -j DROP
iptables -A INPUT -s 55.0.0.0/8 -j DROP
iptables -A OUTPUT -s 55.0.0.0/8 -j DROP
iptables -A INPUT -s 214.0.0.0/8 -j DROP
iptables -A OUTPUT -s 214.0.0.0/8 -j DROP
iptables -A INPUT -s 215.0.0.0/8 -j DROP
iptables -A OUTPUT -s 215.0.0.0/8 -j DROP
save_firewall_settings
function global_rate_limit {
if ! grep -q "tcp_challenge_ack_limit" /etc/sysctl.conf; then
echo 'net.ipv4.tcp_challenge_ack_limit = 999999999' >> /etc/sysctl.conf
if ! grep -q "net.ipv4.tcp_challenge_ack_limit = 999999999" /etc/sysctl.conf; then
sed -i 's|net.ipv4.tcp_challenge_ack_limit.*|net.ipv4.tcp_challenge_ack_limit = 999999999|g' /etc/sysctl.conf
sysctl -p -q
fi
# endure that ipv6 is enabled and can route
sed -i 's/net.ipv6.conf.all.disable_ipv6.*/net.ipv6.conf.all.disable_ipv6 = 0/g' /etc/sysctl.conf
#sed -i "s/net.ipv6.conf.all.accept_redirects.*/net.ipv6.conf.all.accept_redirects = 1/g" /etc/sysctl.conf
#sed -i "s/net.ipv6.conf.all.accept_source_route.*/net.ipv6.conf.all.accept_source_route = 1/g" /etc/sysctl.conf
sed -i "s/net.ipv6.conf.all.forwarding.*/net.ipv6.conf.all.forwarding=1/g" /etc/sysctl.conf
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
iptables -D INPUT -i ${FIREWALL_EIFACE} -m state --state NEW -p tcp --dport 1194 -j ACCEPT
iptables -D INPUT -i tun+ -j ACCEPT
iptables -D FORWARD -i tun+ -j ACCEPT
iptables -D FORWARD -i tun+ -o ${FIREWALL_EIFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -D FORWARD -i ${FIREWALL_EIFACE} -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o ${FIREWALL_EIFACE} -j MASQUERADE
iptables -D OUTPUT -o tun+ -j ACCEPT
save_firewall_settings
}
iptables -A INPUT -i ${FIREWALL_EIFACE} -m state --state NEW -p tcp --dport 1194 -j ACCEPT
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o ${FIREWALL_EIFACE} -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i ${FIREWALL_EIFACE} -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o ${FIREWALL_EIFACE} -j MASQUERADE
iptables -A OUTPUT -o tun+ -j ACCEPT
save_firewall_settings
}
if grep -q "RELATED" /etc/firewall.conf; then
# recreate the firewall to remove RELATED
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
if [[ $INSTALLED_WITHIN_DOCKER == "yes" ]]; then
# docker does its own firewalling
return
fi
iptables -P INPUT ACCEPT
ip6tables -P INPUT ACCEPT
iptables -F
ip6tables -F
iptables -t nat -F
ip6tables -t nat -F
iptables -X
ip6tables -X
iptables -P INPUT DROP
ip6tables -P INPUT DROP
iptables -P FORWARD DROP
ip6tables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
# Drop invalid packets
iptables -t mangle -A PREROUTING -m conntrack --ctstate INVALID -j DROP
# Make sure incoming tcp connections are SYN packets
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
iptables -t mangle -A PREROUTING -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
# Drop SYN packets with suspicious MSS value
iptables -t mangle -A PREROUTING -p tcp -m conntrack --ctstate NEW -m tcpmss ! --mss 536:65535 -j DROP
# Drop packets with incoming fragments
iptables -A INPUT -f -j DROP
# Drop bogons
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,SYN FIN,SYN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,RST FIN,RST -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags FIN,ACK FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,URG URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,FIN FIN -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ACK,PSH PSH -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL ALL -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL NONE -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,FIN,PSH,URG -j DROP
iptables -t mangle -A PREROUTING -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
# Incoming malformed NULL packets:
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
# telnet isn't enabled as an input and we can also
# drop any outgoing telnet, just in case
iptables -A OUTPUT -p tcp --dport telnet -j REJECT
iptables -A OUTPUT -p udp --dport telnet -j REJECT
function_check save_firewall_settings
save_firewall_settings
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
# Only allow ping for mesh installs
return
fi
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
function_check save_firewall_settings
save_firewall_settings
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
sed -i "s/#net.ipv4.tcp_syncookies.*/net.ipv4.tcp_syncookies=1/g" /etc/sysctl.conf
sed -i "s/#net.ipv4.conf.all.accept_redirects.*/net.ipv4.conf.all.accept_redirects = 0/g" /etc/sysctl.conf
sed -i "s/#net.ipv6.conf.all.accept_redirects.*/net.ipv6.conf.all.accept_redirects = 0/g" /etc/sysctl.conf
sed -i "s/#net.ipv4.conf.all.send_redirects.*/net.ipv4.conf.all.send_redirects = 0/g" /etc/sysctl.conf
sed -i "s/#net.ipv4.conf.all.accept_source_route.*/net.ipv4.conf.all.accept_source_route = 0/g" /etc/sysctl.conf
sed -i "s/#net.ipv6.conf.all.accept_source_route.*/net.ipv6.conf.all.accept_source_route = 0/g" /etc/sysctl.conf
sed -i "s/#net.ipv4.conf.default.rp_filter.*/net.ipv4.conf.default.rp_filter=1/g" /etc/sysctl.conf
sed -i "s/#net.ipv4.conf.all.rp_filter.*/net.ipv4.conf.all.rp_filter=1/g" /etc/sysctl.conf
sed -i "s/#net.ipv4.ip_forward.*/net.ipv4.ip_forward=0/g" /etc/sysctl.conf
sed -i "s/#net.ipv6.conf.all.forwarding.*/net.ipv6.conf.all.forwarding=0/g" /etc/sysctl.conf
sed -i "s/# net.ipv4.tcp_syncookies.*/net.ipv4.tcp_syncookies=1/g" /etc/sysctl.conf
sed -i "s/# net.ipv4.conf.all.accept_redirects.*/net.ipv4.conf.all.accept_redirects = 0/g" /etc/sysctl.conf
sed -i "s/# net.ipv6.conf.all.accept_redirects.*/net.ipv6.conf.all.accept_redirects = 0/g" /etc/sysctl.conf
sed -i "s/# net.ipv4.conf.all.send_redirects.*/net.ipv4.conf.all.send_redirects = 0/g" /etc/sysctl.conf
sed -i "s/# net.ipv4.conf.all.accept_source_route.*/net.ipv4.conf.all.accept_source_route = 0/g" /etc/sysctl.conf
sed -i "s/# net.ipv6.conf.all.accept_source_route.*/net.ipv6.conf.all.accept_source_route = 0/g" /etc/sysctl.conf
sed -i "s/# net.ipv4.conf.default.rp_filter.*/net.ipv4.conf.default.rp_filter=1/g" /etc/sysctl.conf
sed -i "s/# net.ipv4.conf.all.rp_filter.*/net.ipv4.conf.all.rp_filter=1/g" /etc/sysctl.conf
sed -i "s/# net.ipv4.ip_forward.*/net.ipv4.ip_forward=0/g" /etc/sysctl.conf
sed -i "s/# net.ipv6.conf.all.forwarding.*/net.ipv6.conf.all.forwarding=0/g" /etc/sysctl.conf
if ! grep -q "ignore pings" /etc/sysctl.conf; then
echo '# ignore pings' >> /etc/sysctl.conf
echo 'net.ipv4.icmp_echo_ignore_all = 1' >> /etc/sysctl.conf
#echo 'net.ipv6.icmp_echo_ignore_all = 1' >> /etc/sysctl.conf
fi
if ! grep -q "disable ipv6" /etc/sysctl.conf; then
echo '# disable ipv6' >> /etc/sysctl.conf
echo 'net.ipv6.conf.all.disable_ipv6 = 1' >> /etc/sysctl.conf
fi
if ! grep -q "net.ipv4.tcp_synack_retries" /etc/sysctl.conf; then
echo 'net.ipv4.tcp_synack_retries = 2' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_syn_retries = 1' >> /etc/sysctl.conf
fi
if ! grep -q "keepalive" /etc/sysctl.conf; then
{ echo '# keepalive';
echo 'net.ipv4.tcp_keepalive_probes = 9';
echo 'net.ipv4.tcp_keepalive_intvl = 75';
echo 'net.ipv4.tcp_keepalive_time = 7200'; } >> /etc/sysctl.conf
if ! grep -q "net.ipv4.conf.default.send_redirects" /etc/sysctl.conf; then
echo "net.ipv4.conf.default.send_redirects = 0" >> /etc/sysctl.conf
else
sed -i "s|# net.ipv4.conf.default.send_redirects.*|net.ipv4.conf.default.send_redirects = 0|g" /etc/sysctl.conf
sed -i "s|#net.ipv4.conf.default.send_redirects.*|net.ipv4.conf.default.send_redirects = 0|g" /etc/sysctl.conf
sed -i "s|net.ipv4.conf.default.send_redirects.*|net.ipv4.conf.default.send_redirects = 0|g" /etc/sysctl.conf
fi
if ! grep -q "net.ipv4.conf.all.secure_redirects" /etc/sysctl.conf; then
echo "net.ipv4.conf.all.secure_redirects = 0" >> /etc/sysctl.conf
else
sed -i "s|# net.ipv4.conf.all.secure_redirects.*|net.ipv4.conf.all.secure_redirects = 0|g" /etc/sysctl.conf
sed -i "s|#net.ipv4.conf.all.secure_redirects.*|net.ipv4.conf.all.secure_redirects = 0|g" /etc/sysctl.conf
sed -i "s|net.ipv4.conf.all.secure_redirects.*|net.ipv4.conf.all.secure_redirects = 0|g" /etc/sysctl.conf
fi
if ! grep -q "net.ipv4.conf.default.accept_source_route" /etc/sysctl.conf; then
echo "net.ipv4.conf.default.accept_source_route = 0" >> /etc/sysctl.conf
else
sed -i "s|# net.ipv4.conf.default.accept_source_route.*|net.ipv4.conf.default.accept_source_route = 0|g" /etc/sysctl.conf
sed -i "s|#net.ipv4.conf.default.accept_source_route.*|net.ipv4.conf.default.accept_source_route = 0|g" /etc/sysctl.conf
sed -i "s|net.ipv4.conf.default.accept_source_route.*|net.ipv4.conf.default.accept_source_route = 0|g" /etc/sysctl.conf
fi
if ! grep -q "net.ipv4.conf.default.secure_redirects" /etc/sysctl.conf; then
echo "net.ipv4.conf.default.secure_redirects = 0" >> /etc/sysctl.conf
else
sed -i "s|# net.ipv4.conf.default.secure_redirects.*|net.ipv4.conf.default.secure_redirects = 0|g" /etc/sysctl.conf
sed -i "s|#net.ipv4.conf.default.secure_redirects.*|net.ipv4.conf.default.secure_redirects = 0|g" /etc/sysctl.conf
sed -i "s|net.ipv4.conf.default.secure_redirects.*|net.ipv4.conf.default.secure_redirects = 0|g" /etc/sysctl.conf
fi
if ! grep -q "net.ipv4.conf.default.accept_redirects" /etc/sysctl.conf; then
echo "net.ipv4.conf.default.accept_redirects = 0" >> /etc/sysctl.conf
else
sed -i "s|# net.ipv4.conf.default.accept_redirects.*|net.ipv4.conf.default.accept_redirects = 0|g" /etc/sysctl.conf
sed -i "s|#net.ipv4.conf.default.accept_redirects.*|net.ipv4.conf.default.accept_redirects = 0|g" /etc/sysctl.conf
sed -i "s|net.ipv4.conf.default.accept_redirects.*|net.ipv4.conf.default.accept_redirects = 0|g" /etc/sysctl.conf
fi
if ! grep -q "kernel.randomize_va_space" /etc/sysctl.conf; then
echo "kernel.randomize_va_space=2" >> /etc/sysctl.conf
else
sed -i 's|kernel.randomize_va_space.*|kernel.randomize_va_space=2|g' /etc/sysctl.conf
fi
# Turn off the tcp_timestamps
if ! grep -q "net.ipv4.tcp_timestamps" /etc/sysctl.conf; then
echo "net.ipv4.tcp_timestamps=0" >> /etc/sysctl.conf
else
sed -i 's|net.ipv4.tcp_timestamps.*|net.ipv4.tcp_timestamps=0|g' /etc/sysctl.conf
fi
# shellcheck disable=SC2154
FIREWALL_FILENAME="${rootdir}/etc/systemd/system/meshfirewall.service"
MESH_FIREWALL_SCRIPT=${rootdir}/usr/bin/mesh-firewall
if ! grep -q 'telemetry.mozilla' "${rootdir}/etc/hosts"; then
echo '127.0.0.1 telemetry.mozilla.org' >> "${rootdir}/etc/hosts"
fi
if ! grep -q 'facebook' "${rootdir}/etc/hosts"; then
{ echo '127.0.0.1 www.facebook.com';
echo '127.0.0.1 facebook.com';
echo '127.0.0.1 static.ak.fbcdn.net';
echo '127.0.0.1 www.static.ak.fbcdn.net';
echo '127.0.0.1 login.facebook.com';
echo '127.0.0.1 www.login.facebook.com';
echo '127.0.0.1 fbcdn.net';
echo '127.0.0.1 www.fbcdn.net';
echo '127.0.0.1 fbcdn.com';
echo '127.0.0.1 www.fbcdn.com';
echo '127.0.0.1 static.ak.connect.facebook.com';
echo '127.0.0.1 www.static.ak.connect.facebook.com'; } >> "${rootdir}/etc/hosts"
if ! grep -q 'google' "${rootdir}/etc/hosts"; then
{ echo '127.0.0.1 www.google-analytics.com';
echo '127.0.0.1 google-analytics.com';
echo '127.0.0.1 ssl.google-analytics.com'; } >> "${rootdir}/etc/hosts"
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
{ echo '#!/bin/bash';
echo 'iptables -P INPUT ACCEPT';
echo 'ip6tables -P INPUT ACCEPT';
echo 'iptables -F';
echo 'ip6tables -F';
echo 'iptables -t nat -F';
echo 'ip6tables -t nat -F';
echo 'iptables -X';
echo 'ip6tables -X';
echo 'iptables -P INPUT DROP';
echo 'ip6tables -P INPUT DROP';
echo 'iptables -A INPUT -i lo -j ACCEPT';
echo 'ip6tables -A INPUT -i lo -j ACCEPT';
echo 'iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT';
echo 'ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT';
echo '';
echo '# Make sure incoming tcp connections are SYN packets';
echo 'iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP';
echo 'ip6tables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP';
echo '';
echo '# Drop packets with incoming fragments';
echo 'iptables -A INPUT -f -j DROP';
echo 'ip6tables -A INPUT -f -j DROP';
echo '';
echo '# Drop bogons';
echo 'iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP';
echo 'ip6tables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP';
echo 'iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP';
echo 'ip6tables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP';
echo 'iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP';
echo 'ip6tables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP';
echo '';
echo '# Incoming malformed NULL packets:';
echo 'iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP';
echo 'ip6tables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP';
echo '';
echo "iptables -A INPUT -p tcp --dport $TOX_PORT -j ACCEPT";
echo "ip6tables -A INPUT -p tcp --dport $TOX_PORT -j ACCEPT";
echo "iptables -A INPUT -p udp --dport $ZERONET_PORT -j ACCEPT";
echo "ip6tables -A INPUT -p udp --dport $ZERONET_PORT -j ACCEPT";
echo "iptables -A INPUT -p tcp --dport $ZERONET_PORT -j ACCEPT";
echo "ip6tables -A INPUT -p tcp --dport $ZERONET_PORT -j ACCEPT";
echo "iptables -A INPUT -p udp --dport $TRACKER_PORT -j ACCEPT";
echo "ip6tables -A INPUT -p udp --dport $TRACKER_PORT -j ACCEPT";
echo "iptables -A INPUT -p tcp --dport $TRACKER_PORT -j ACCEPT";
echo "ip6tables -A INPUT -p tcp --dport $TRACKER_PORT -j ACCEPT";
echo "iptables -A INPUT -p udp --dport 1900 -j ACCEPT";
echo "ip6tables -A INPUT -p udp --dport 1900 -j ACCEPT";
echo "iptables -A INPUT -s $FIREFOX_TELEMETRY_IP -j DROP";
echo "iptables -A OUTPUT -s $FIREFOX_TELEMETRY_IP -j DROP"; } > "$MESH_FIREWALL_SCRIPT"
chmod +x "$MESH_FIREWALL_SCRIPT"
{ echo '[Unit]';
echo 'Description=Mesh Firewall';
echo '';
echo '[Service]';
echo 'Type=oneshot';
echo 'ExecStart=/usr/bin/mesh-firewall';
echo 'RemainAfterExit=no';
echo '';
echo 'TimeoutSec=30';
echo '';
echo '[Install]';
echo 'WantedBy=multi-user.target'; } > "$FIREWALL_FILENAME"
chmod +x "$FIREWALL_FILENAME"
chroot "$rootdir" systemctl enable meshfirewall
firewall_name=$(string="$1" ; echo "${string// /-}")
if ! grep -q "${firewall_name}=${firewall_port}" "$FIREWALL_CONFIG"; then
echo "${firewall_name}=${firewall_port}" >> "$FIREWALL_CONFIG"
if [ ! "${firewall_protocol}" ]; then
if ! iptables -C INPUT -p udp --dport "${firewall_port}" -j ACCEPT; then
iptables -A INPUT -p udp --dport "${firewall_port}" -j ACCEPT
if ! iptables -C INPUT -p tcp --dport "${firewall_port}" -j ACCEPT; then
iptables -A INPUT -p tcp --dport "${firewall_port}" -j ACCEPT
else
if [[ "${firewall_protocol}" == *"udp"* ]]; then
if ! iptables -C INPUT -p udp --dport "${firewall_port}" -j ACCEPT; then
iptables -A INPUT -p udp --dport "${firewall_port}" -j ACCEPT
fi
if [[ "${firewall_protocol}" == *"tcp"* ]]; then
if ! iptables -C INPUT -p tcp --dport "${firewall_port}" -j ACCEPT; then
iptables -A INPUT -p tcp --dport "${firewall_port}" -j ACCEPT
firewall_name=$(string="$1" ; echo "${string// /-}")
firewall_port_start=$2
firewall_port_end=$3
firewall_protocol="$4"
if ! grep -q "${firewall_name}=${firewall_port_start}:${firewall_port_end}" "$FIREWALL_CONFIG"; then
echo "${firewall_name}=${firewall_port_start}:${firewall_port_end}" >> "$FIREWALL_CONFIG"
if [ ! "${firewall_protocol}" ]; then
if ! iptables -C INPUT -p udp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT; then
iptables -A INPUT -p udp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT
if ! iptables -C INPUT -p tcp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT; then
iptables -A INPUT -p tcp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT
else
if [[ "${firewall_protocol}" == *"udp"* ]]; then
if ! iptables -C INPUT -p udp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT; then
iptables -A INPUT -p udp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT
fi
if [[ "${firewall_protocol}" == *"tcp"* ]]; then
if ! iptables -C INPUT -p tcp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT; then
iptables -A INPUT -p tcp --dport "${firewall_port_start}":"${firewall_port_end}" -j ACCEPT
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
function firewall_handle_port_scans {
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
# only works for high frequency port scanning
# flooding of RST packets, smurf attack Rejection
iptables -A INPUT -p tcp -m tcp --tcp-flags RST RST -m limit --limit 2/second --limit-burst 2 -j ACCEPT
# Protecting portscans
# Attacking IP will be locked for 24 hours (3600 x 24 = 86400 Seconds)
iptables -A INPUT -m recent --name portscan --rcheck --seconds 86400 -j DROP
iptables -A FORWARD -m recent --name portscan --rcheck --seconds 86400 -j DROP
# Remove attacking IP after 24 hours
iptables -A INPUT -m recent --name portscan --remove
iptables -A FORWARD -m recent --name portscan --remove
# These rules add scanners to the portscan list, and log the attempt.
iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "portscan:"
iptables -A INPUT -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP
iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j LOG --log-prefix "portscan:"
iptables -A FORWARD -p tcp -m tcp --dport 139 -m recent --name portscan --set -j DROP
save_firewall_settings
mark_completed "${FUNCNAME[0]}"
}
function firewall_remove {
firewall_port=$1
firewall_protocol="$2"
if grep -q "=${firewall_port}" "$FIREWALL_CONFIG"; then
if [ ! "${firewall_protocol}" ]; then
iptables -D INPUT -p udp --dport "${firewall_port}" -j ACCEPT
iptables -D INPUT -p tcp --dport "${firewall_port}" -j ACCEPT
else
if [[ "${firewall_protocol}" == *"udp"* ]]; then
iptables -D INPUT -p udp --dport "${firewall_port}" -j ACCEPT
fi
if [[ "${firewall_protocol}" == *"tcp"* ]]; then
iptables -D INPUT -p tcp --dport "${firewall_port}" -j ACCEPT
function domain_to_hex_string {
domain="$1"
ctr=1
segment=$(echo "$domain" | awk -F '.' -v value="$ctr" '{print $value}')
while [ ${#segment} -gt 0 ]
do
characters=$(echo -n "$segment" | wc -c)
hexnum=$(echo "obase=16; $characters" | bc)
segment=$(echo "$domain" | awk -F '.' -v value="$ctr" '{print $value}')
done
echo ""
}
function firewall_block_domain {
blocked_domain="$1"
if [[ "$blocked_domain" == *'@'* ]]; then
# Don't try to block email/microblog addresses
if ! grep -q "$blocked_domain" "$FIREWALL_DOMAINS"; then
hexstr=$(domain_to_hex_string "$blocked_domain")
if ! iptables -C INPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP; then
iptables -A INPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -A INPUT -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -A OUTPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -A OUTPUT -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -I FORWARD -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -I FORWARD -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
save_firewall_settings
fi
# run the blocking rules now
if [ -f /usr/bin/gnusocial-firewall ]; then
/usr/bin/gnusocial-firewall
fi
if [ -f /usr/bin/postactiv-firewall ]; then
/usr/bin/postactiv-firewall
fi
if [ -f /usr/bin/pleroma-blocking ]; then
/usr/bin/pleroma-blocking
fi
function firewall_block_words {
blocked_words="$1"
if [ ! -f "$MUTED_WORDS" ]; then
touch "$MUTED_WORDS"
fi
if ! grep -q "$blocked_words" "$MUTED_WORDS"; then
echo "${blocked_words}" >> "$MUTED_WORDS"
# run the blocking rules now
if [ -f /usr/bin/gnusocial-firewall ]; then
/usr/bin/gnusocial-firewall
fi
if [ -f /usr/bin/postactiv-firewall ]; then
/usr/bin/postactiv-firewall
fi
if [ -f /usr/bin/pleroma-blocking ]; then
/usr/bin/pleroma-blocking
fi
fi
regenerate_webadmin_blocklist_muted_words
}
function firewall_block_ip {
blocked_ip="$1"
if [[ "$blocked_ip" == *'@'* ]]; then
# Don't try to block email/microblog addresses
return
fi
if ! grep -q "$blocked_ip" "$FIREWALL_DOMAINS"; then
if ! iptables -C INPUT -s "$blocked_ip" -j DROP; then
iptables -A INPUT -s "$blocked_ip" -j DROP
iptables -A OUTPUT -s "$blocked_ip" -j DROP
save_firewall_settings
fi
fi
}
function firewall_unblock_ip {
blocked_ip="$1"
if [[ "$blocked_ip" == *'@'* ]]; then
# Don't try to block email/microblog addresses
return
fi
if grep -q "$blocked_ip" "$FIREWALL_DOMAINS"; then
iptables -D INPUT -s "$blocked_ip" -j DROP
iptables -D OUTPUT -s "$blocked_ip" -j DROP
sed -i "/$blocked_ip/d" "$FIREWALL_DOMAINS"
echo "${blocked_ip}" >> "$FIREWALL_DOMAINS"
function firewall_refresh_blocklist {
if [ ! -f "/root/${PROJECT_NAME}-firewall-domains.cfg" ]; then
while read -r blocked_domain; do
firewall_block_domain "$blocked_domain"
done <"/root/${PROJECT_NAME}-firewall-domains.cfg"
function firewall_unblock_domain {
unblocked_domain="$1"
if grep -q "${unblocked_domain}" "$FIREWALL_DOMAINS"; then
if [[ "${unblocked_domain}" != *'@'* ]]; then
hexstr=$(domain_to_hex_string "$unblocked_domain")
iptables -D INPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -D INPUT -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -D OUTPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -D OUTPUT -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -D FORWARD -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
iptables -D FORWARD -p tcp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
save_firewall_settings
fi
sed -i "/${unblocked_domain}/d" "$FIREWALL_DOMAINS"
if grep -q " $unblocked_domain" /etc/hosts; then
sed -i "/ $unblocked_domain/d" /etc/hosts
fi
function firewall_unblock_words {
unblocked_words="$1"
if [ ! -f "$MUTED_WORDS" ]; then
touch "$MUTED_WORDS"
fi
if grep -q "${unblocked_words}" "$MUTED_WORDS"; then
sed -i "/${unblocked_domain}/d" "$MUTED_WORDS"
fi
regenerate_webadmin_blocklist_muted_words
}
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
iptables -t mangle -A PREROUTING -s 224.0.0.0/3 -j DROP
iptables -t mangle -A PREROUTING -s 169.254.0.0/16 -j DROP
iptables -t mangle -A PREROUTING -s 172.16.0.0/12 -j DROP
iptables -t mangle -A PREROUTING -s 192.0.2.0/24 -j DROP
iptables -t mangle -A PREROUTING -s 10.0.0.0/8 -j DROP
iptables -t mangle -A PREROUTING -s 240.0.0.0/5 -j DROP
iptables -t mangle -A PREROUTING -s 127.0.0.0/8 ! -i lo -j DROP
function_check save_firewall_settings
save_firewall_settings
if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
return
fi
# Limit connections per source IP
iptables -A INPUT -p tcp -m connlimit --connlimit-above 111 -j REJECT --reject-with tcp-reset
# Limit RST packets
iptables -A INPUT -p tcp --tcp-flags RST RST -m limit --limit 2/s --limit-burst 2 -j ACCEPT
iptables -A INPUT -p tcp --tcp-flags RST RST -j DROP
# Limit new TCP connections per second per source IP
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -m limit --limit 60/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p tcp -m conntrack --ctstate NEW -j DROP
# SSH brute-force protection
iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --set
iptables -A INPUT -p tcp --dport ssh -m conntrack --ctstate NEW -m recent --update --seconds 60 --hitcount 10 -j DROP
function_check save_firewall_settings
save_firewall_settings
function regenerate_webadmin_blocklist {
if [ ! -f "$FIREWALL_DOMAINS" ]; then
touch "$FIREWALL_DOMAINS"
fi
local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
if [ -f "$webadmin_install_dir/blocking_template.html" ]; then
cp "$webadmin_install_dir/blocking_template.html" "$webadmin_install_dir/blocking.html"
blockedlist=$(sed 's@[/\&]@\\&@g;s/$/\\/' "$FIREWALL_DOMAINS"; echo .)
sed -i "s|BLOCKEDLIST|$blockedlist|g" "$webadmin_install_dir/blocking.html"
chown www-data:www-data "$webadmin_install_dir/blocking.html"
fi
}
function regenerate_webadmin_blocklist_muted_words {
if [ ! -f "$MUTED_WORDS" ]; then
touch "$MUTED_WORDS"
fi
local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
if [ -f "$webadmin_install_dir/blocking_words_template.html" ]; then
cp "$webadmin_install_dir/blocking_words_template.html" "$webadmin_install_dir/blocking_words.html"
blockedlistwords=$(sed 's@[/\&]@\\&@g;s/$/\\/' "$MUTED_WORDS"; echo .)
blockedlistwords=${blockedlistwords%.}
sed -i "s|BLOCKEDWORDSLIST|$blockedlistwords|g" "$webadmin_install_dir/blocking_words.html"
chown www-data:www-data "$webadmin_install_dir/blocking_words.html"
fi
}