Newer
Older
#!/bin/bash
#
# .---. . .
# | | |
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
#
# Freedom in the Cloud
#
# Firewall functions
#
# Copyright (C) 2014-2017 Bob Mottram <bob@freedombone.net>
#
# 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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
function firewall_block_bad_ip_ranges {
if [ $INSTALLING_MESH ]; then
return
fi
if [[ $(is_completed $FUNCNAME) == "1" ]]; then
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
mark_completed $FUNCNAME
}
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 "VPN=" $FIREWALL_CONFIG; then
echo "VPN=1194" >> $FIREWALL_CONFIG
fi
if [ $INSTALLING_MESH ]; then
mesh_firewall
return
fi
if grep -q "RELATED" /etc/firewall.conf; then
# recreate the firewall to remove RELATED
sed -i "/firewall/d" $COMPLETION_FILE
fi
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
function firewall_drop_telnet {
if [[ $(is_completed $FUNCNAME) == "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
mark_completed $FUNCNAME
}
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
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' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_keepalive_probes = 9' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_keepalive_intvl = 75' >> /etc/sysctl.conf
echo 'net.ipv4.tcp_keepalive_time = 7200' >> /etc/sysctl.conf
fi
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
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
}
function mesh_firewall {
FIREWALL_FILENAME=${rootdir}/etc/systemd/system/meshfirewall.service
MESH_FIREWALL_SCRIPT=${rootdir}/usr/bin/mesh-firewall
echo '#!/bin/bash' > $MESH_FIREWALL_SCRIPT
echo 'iptables -P INPUT ACCEPT' >> $MESH_FIREWALL_SCRIPT
echo 'ip6tables -P INPUT ACCEPT' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -F' >> $MESH_FIREWALL_SCRIPT
echo 'ip6tables -F' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -t nat -F' >> $MESH_FIREWALL_SCRIPT
echo 'ip6tables -t nat -F' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -X' >> $MESH_FIREWALL_SCRIPT
echo 'ip6tables -X' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -P INPUT DROP' >> $MESH_FIREWALL_SCRIPT
echo 'ip6tables -P INPUT DROP' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -A INPUT -i lo -j ACCEPT' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT' >> $MESH_FIREWALL_SCRIPT
echo '' >> $MESH_FIREWALL_SCRIPT
echo '# Make sure incoming tcp connections are SYN packets' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP' >> $MESH_FIREWALL_SCRIPT
echo '' >> $MESH_FIREWALL_SCRIPT
echo '# Drop packets with incoming fragments' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -A INPUT -f -j DROP' >> $MESH_FIREWALL_SCRIPT
echo '' >> $MESH_FIREWALL_SCRIPT
echo '# Drop bogons' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -A INPUT -p tcp --tcp-flags ALL FIN,PSH,URG -j DROP' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP' >> $MESH_FIREWALL_SCRIPT
echo '' >> $MESH_FIREWALL_SCRIPT
echo '# Incoming malformed NULL packets:' >> $MESH_FIREWALL_SCRIPT
echo 'iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP' >> $MESH_FIREWALL_SCRIPT
echo '' >> $MESH_FIREWALL_SCRIPT
echo "iptables -A INPUT -p tcp --dport $TOX_PORT -j ACCEPT" >> $MESH_FIREWALL_SCRIPT
echo "iptables -A INPUT -i $WIFI_INTERFACE -p udp --dport $ZERONET_PORT -j ACCEPT" >> $MESH_FIREWALL_SCRIPT
echo "iptables -A INPUT -i $WIFI_INTERFACE -p tcp --dport $ZERONET_PORT -j ACCEPT" >> $MESH_FIREWALL_SCRIPT
echo "iptables -A INPUT -i $WIFI_INTERFACE -p udp --dport $TRACKER_PORT -j ACCEPT" >> $MESH_FIREWALL_SCRIPT
echo "iptables -A INPUT -i $WIFI_INTERFACE -p tcp --dport $TRACKER_PORT -j ACCEPT" >> $MESH_FIREWALL_SCRIPT
echo "iptables -A INPUT -i $WIFI_INTERFACE -p udp --dport 1900 -j ACCEPT" >> $MESH_FIREWALL_SCRIPT
chmod +x $MESH_FIREWALL_SCRIPT
echo '[Unit]' > $FIREWALL_FILENAME
echo 'Description=Mesh Firewall' >> $FIREWALL_FILENAME
echo '' >> $FIREWALL_FILENAME
echo '[Service]' >> $FIREWALL_FILENAME
echo 'Type=oneshot' >> $FIREWALL_FILENAME
echo 'ExecStart=/usr/bin/mesh-firewall' >> $FIREWALL_FILENAME
echo 'RemainAfterExit=no' >> $FIREWALL_FILENAME
echo '' >> $FIREWALL_FILENAME
echo 'TimeoutSec=30' >> $FIREWALL_FILENAME
echo '' >> $FIREWALL_FILENAME
echo '[Install]' >> $FIREWALL_FILENAME
echo 'WantedBy=multi-user.target' >> $FIREWALL_FILENAME
chroot "$rootdir" systemctl enable meshfirewall
firewall_port=$2
firewall_protocol="$3"
if ! grep -q "${firewall_name}=${firewall_port}" $FIREWALL_CONFIG; then
echo "${firewall_name}=${firewall_port}" >> $FIREWALL_CONFIG
if [ ! ${firewall_protocol} ]; then
iptables -C INPUT -p udp --dport ${firewall_port} -j ACCEPT
if [ ! "$?" = "0" ]; then
iptables -A INPUT -p udp --dport ${firewall_port} -j ACCEPT
fi
iptables -C INPUT -p tcp --dport ${firewall_port} -j ACCEPT
if [ ! "$?" = "0" ]; then
iptables -A INPUT -p tcp --dport ${firewall_port} -j ACCEPT
fi
else
if [[ "${firewall_protocol}" == *"udp"* ]]; then
iptables -C INPUT -p udp --dport ${firewall_port} -j ACCEPT
if [ ! "$?" = "0" ]; then
iptables -A INPUT -p udp --dport ${firewall_port} -j ACCEPT
fi
fi
if [[ "${firewall_protocol}" == *"tcp"* ]]; then
iptables -C INPUT -p tcp --dport ${firewall_port} -j ACCEPT
if [ ! "$?" = "0" ]; then
iptables -A INPUT -p tcp --dport ${firewall_port} -j ACCEPT
fi
function firewall_add_range {
firewall_name=$(echo "$1" | sed "s| |-|g")
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
iptables -C INPUT -p udp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
if [ ! "$?" = "0" ]; then
iptables -A INPUT -p udp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
fi
iptables -C INPUT -p tcp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
if [ ! "$?" = "0" ]; then
iptables -A INPUT -p tcp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
fi
else
if [[ "${firewall_protocol}" == *"udp"* ]]; then
iptables -C INPUT -p udp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
if [ ! "$?" = "0" ]; then
iptables -A INPUT -p udp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
fi
fi
if [[ "${firewall_protocol}" == *"tcp"* ]]; then
iptables -C INPUT -p tcp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
if [ ! "$?" = "0" ]; then
iptables -A INPUT -p tcp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
fi
fi
fi
save_firewall_settings
fi
}
function firewall_remove {
firewall_port=$1
firewall_protocol="$2"
if [ ! -f $FIREWALL_CONFIG ]; then
return
fi
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
fi
fi
sed -i "/=${firewall_port}/d" $FIREWALL_CONFIG
save_firewall_settings
fi
}
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)
echo -n "|"
if [ $(echo -n "$hexnum" | wc -c) -lt 2 ]; then
echo -n "0"
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
echo "${blocked_domain}" >> $FIREWALL_DOMAINS
hexstr=$(domain_to_hex_string $blocked_domain)
iptables -C INPUT -p udp --dport 53 -m string --hex-string "$hexstr" --algo bm -j DROP
if [ ! "$?" = "0" ]; 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
echo "${blocked_domain}" >> $FIREWALL_DOMAINS
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
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
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
iptables -C INPUT -s $blocked_ip -j DROP
if [ ! "$?" = "0" ]; then
iptables -A INPUT -s $blocked_ip -j DROP
iptables -A OUTPUT -s $blocked_ip -j DROP
echo "${blocked_ip}" >> $FIREWALL_DOMAINS
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
save_firewall_settings
fi
}
function firewall_refresh_blocklist {
if [ ! -f /root/${PROJECT_NAME}-firewall-domains.cfg ]; then
return
fi
while read blocked_domain; do
firewall_block_domain $blocked_domain
done </root/${PROJECT_NAME}-firewall-domains.cfg
}
function firewall_unblock_domain {
unblocked_domain="$1"
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
fi
}
function firewall_drop_spoofed_packets {
if [[ $(is_completed $FUNCNAME) == "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
mark_completed $FUNCNAME
}
function firewall_rate_limits {
if [[ $(is_completed $FUNCNAME) == "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
mark_completed $FUNCNAME
}