Newer
Older
#!/bin/bash
#
# .---. . .
# | | |
# |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-.
# | | (.-' (.-' ( | ( )| | | | )( )| | (.-'
# ' ' --' --' -' - -' ' ' -' -' -' ' - --'
#
# Freedom in the Cloud
#
# Firewall functions
#
# Copyright (C) 2014-2016 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/>.
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 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
else
sed -i 's|net.ipv4.tcp_challenge_ack_limit.*|net.ipv4.tcp_challenge_ack_limit = 999999999|g' /etc/sysctl.conf
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
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
# Make sure incoming tcp connections are SYN packets
iptables -A INPUT -p tcp ! --syn -m state --state NEW -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
# Incoming malformed NULL packets:
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
}
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 -A INPUT -p udp --dport ${firewall_port} -j ACCEPT
iptables -A INPUT -p tcp --dport ${firewall_port} -j ACCEPT
else
if [[ "${firewall_protocol}" == *"udp"* ]]; then
iptables -A INPUT -p udp --dport ${firewall_port} -j ACCEPT
fi
if [[ "${firewall_protocol}" == *"tcp"* ]]; then
iptables -A INPUT -p tcp --dport ${firewall_port} -j ACCEPT
fi
fi
save_firewall_settings
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 -A INPUT -p udp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
iptables -A INPUT -p tcp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
else
if [[ "${firewall_protocol}" == *"udp"* ]]; then
iptables -A INPUT -p udp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
fi
if [[ "${firewall_protocol}" == *"tcp"* ]]; then
iptables -A INPUT -p tcp --dport ${firewall_port_start}:${firewall_port_end} -j ACCEPT
fi
fi
save_firewall_settings
fi
}
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
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
}
# NOTE: deliberately no exit 0