-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1677 from holta/firewall-usability
Making IIAB's firewall (iptables) understandable to newbie implementers
- Loading branch information
Showing
6 changed files
with
212 additions
and
121 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,165 +1,210 @@ | ||
#!/bin/bash -x | ||
source {{ iiab_env_file }} | ||
|
||
# To customize your iptables firewall, it's best to edit: | ||
# /opt/iiab/iiab/roles/network/templates/gateway/iiab-gen-iptables | ||
# And then run: cd /opt/iiab/iiab; ./iiab-network | ||
|
||
{% if is_debuntu %} | ||
IPTABLES=/sbin/iptables | ||
IPTABLES_DATA=/etc/iptables.up.rules | ||
{% else %} | ||
IPTABLES=/usr/sbin/iptables | ||
IPTABLES_DATA=/etc/sysconfig/iptables | ||
{% endif %} | ||
LANIF=$IIAB_LAN_DEVICE | ||
WANIF=$IIAB_WAN_DEVICE | ||
MODE=`grep iiab_network_mode_applied {{ iiab_ini_file }} | gawk '{print $3}'` | ||
|
||
clear_fw() { | ||
$IPTABLES -F | ||
$IPTABLES -t nat -F | ||
$IPTABLES -X | ||
|
||
# first match wins | ||
# Always accept loopback traffic | ||
$IPTABLES -A INPUT -i lo -j ACCEPT | ||
|
||
# Always drop rpc | ||
$IPTABLES -A INPUT -p tcp --dport 111 -j DROP | ||
$IPTABLES -A INPUT -p udp --dport 111 -j DROP | ||
# mysql | ||
$IPTABLES -A INPUT -p tcp --dport 3306 -j DROP | ||
$IPTABLES -A INPUT -p udp --dport 3306 -j DROP | ||
# postgres - not needed listens on lo only | ||
$IPTABLES -A INPUT -p tcp --dport 5432 -j DROP | ||
$IPTABLES -A INPUT -p udp --dport 5432 -j DROP | ||
# couchdb | ||
$IPTABLES -A INPUT -p tcp --dport 5984 -j DROP | ||
$IPTABLES -A INPUT -p udp --dport 5984 -j DROP | ||
} | ||
|
||
if [ "x$WANIF" == "xnone" ] || [ "$MODE" == "Appliance" ]; then | ||
clear_fw | ||
# save the rule set | ||
{% if is_debuntu %} | ||
netfilter-persistent save | ||
{% else %} | ||
iptables-save > $IPTABLES_DATA | ||
{% endif %} | ||
exit 0 | ||
fi | ||
lan=$LANIF | ||
wan=$WANIF | ||
|
||
# Good thing we replace this file should be treated like squid below | ||
source {{ iiab_env_file }} | ||
lan=$IIAB_LAN_DEVICE | ||
wan=$IIAB_WAN_DEVICE | ||
echo -e "\nLAN: $lan" | ||
echo -e "WAN: $wan" | ||
#network_mode=`grep iiab_network_mode_applied {{ iiab_ini_file }} | gawk '{print $3}'` | ||
#echo -e "Network Mode: $network_mode\n" | ||
|
||
# "Good thing we replace this file; should be treated like Squid below" ? | ||
ports_externally_visible={{ ports_externally_visible }} | ||
#services_externally_visible={{ services_externally_visible }} | ||
gw_block_https={{ gw_block_https }} | ||
ssh_port={{ ssh_port }} | ||
gui_wan={{ gui_wan }} | ||
#gui_wan={{ gui_wan }} | ||
gui_port={{ gui_port }} | ||
iiab_gateway_enabled={{ iiab_gateway_enabled }} | ||
services_externally_visible={{ services_externally_visible }} | ||
block_DNS={{ block_DNS }} | ||
|
||
calibre_port={{ calibre_port }} | ||
calibreweb_port={{ calibreweb_port }} | ||
kiwix_port={{ kiwix_port }} | ||
cups_port={{ cups_port }} | ||
kalite_server_port={{ kalite_server_port }} | ||
kiwix_port={{ kiwix_port }} | ||
kolibri_http_port={{ kolibri_http_port }} | ||
cups_port={{ cups_port }} | ||
transmission_http_port={{ transmission_http_port }} | ||
transmission_peer_port={{ transmission_peer_port }} | ||
sugarizer_port={{ sugarizer_port }} | ||
nodered_port={{ nodered_port }} | ||
mosquitto_port={{ mosquitto_port }} | ||
minetest_port={{ minetest_port }} | ||
mosquitto_port={{ mosquitto_port }} | ||
nodered_port={{ nodered_port }} | ||
pbx_enabled={{ pbx_enabled }} | ||
pbx_signaling_ports_chan_sip={{ pbx_signaling_ports_chan_sip }} | ||
pbx_signaling_ports_chan_pjsip={{ pbx_signaling_ports_chan_pjsip }} | ||
pbx_data_ports={{ pbx_data_ports }} | ||
pbx_enabled={{ pbx_enabled }} | ||
samba_enabled={{ samba_enabled }} | ||
sugarizer_port={{ sugarizer_port }} | ||
transmission_http_port={{ transmission_http_port }} | ||
transmission_peer_port={{ transmission_peer_port }} | ||
|
||
samba_udp_ports={{ samba_udp_ports }} | ||
samba_tcp_mports={{ samba_tcp_mports }} | ||
|
||
block_DNS={{ block_DNS }} | ||
|
||
echo "LAN is $lan and WAN is $wan" | ||
# | ||
# delete all existing rules. | ||
# | ||
################################################################################ | ||
# # | ||
# IF YOU NEED TO CHANGE ports_externally_visible DO THAT IN: # | ||
# # | ||
# /etc/iiab/local_vars.yml # | ||
# # | ||
# This firewall variable must be an integer {0...5} as follows: # | ||
# # | ||
# 0 = none # | ||
# 1 = ssh only # | ||
# 2 = ssh + http-or-https (for Admin Console's box.lan/admin too) # | ||
# 3 = ssh + http-or-https + common IIAB services <-- THIS IS THE DEFAULT # | ||
# 4 = ssh + http-or-https + common IIAB services + Samba # | ||
# 5 = all but databases # | ||
# # | ||
# Then enable it with iptables by running: cd /opt/iiab/iiab; ./iiab-network # | ||
# # | ||
################################################################################ | ||
|
||
echo -e "\nports_externally_visible: "$ports_externally_visible"\n" | ||
if ! [ "$ports_externally_visible" -eq "$ports_externally_visible" ] 2> /dev/null; then | ||
echo "EXITING: an integer is required" | ||
exit 1 | ||
elif [ "$ports_externally_visible" -lt 0 ] || [ "$ports_externally_visible" -gt 5 ]; then | ||
echo "EXITING: it must be in the range {0...5}" | ||
exit 1 | ||
fi | ||
|
||
#if [ "$wan" != "none" ] && [ "$network_mode" != "Appliance" ]; then | ||
# Load iptables kernel modules | ||
/sbin/modprobe ip_tables | ||
/sbin/modprobe iptable_filter | ||
/sbin/modprobe ip_conntrack | ||
/sbin/modprobe iptable_nat | ||
clear_fw | ||
#fi | ||
|
||
# Delete all existing firewall rules | ||
$IPTABLES -F | ||
$IPTABLES -t nat -F | ||
$IPTABLES -X | ||
|
||
# FIRST MATCH WINS - establish iptable rules, starting at the top: | ||
# (verify the resulting rule set by running 'iptables -L -v') | ||
# New to iptables? Run/read 'man iptables' & 'man iptables-extensions' | ||
|
||
# Always accept loopback traffic | ||
$IPTABLES -A INPUT -i lo -j ACCEPT | ||
|
||
# Disable access to databases, on LAN-side and WAN-side | ||
# SunRPC | ||
$IPTABLES -A INPUT -p tcp --dport 111 -j DROP | ||
$IPTABLES -A INPUT -p udp --dport 111 -j DROP | ||
# MySQL | ||
$IPTABLES -A INPUT -p tcp --dport 3306 -j DROP | ||
$IPTABLES -A INPUT -p udp --dport 3306 -j DROP | ||
# PostgreSQL - not needed listens on lo only | ||
$IPTABLES -A INPUT -p tcp --dport 5432 -j DROP | ||
$IPTABLES -A INPUT -p udp --dport 5432 -j DROP | ||
# CouchDB | ||
$IPTABLES -A INPUT -p tcp --dport 5984 -j DROP | ||
$IPTABLES -A INPUT -p udp --dport 5984 -j DROP | ||
|
||
# Allow established connections, and those not coming from the outside | ||
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT | ||
$IPTABLES -A INPUT -m state --state NEW -i $lan -j ACCEPT | ||
$IPTABLES -A INPUT -m state --state NEW -i $lan -j ACCEPT | ||
|
||
# Allow mDNS | ||
# Allow mDNS from WAN-side too (ON PURPOSE? WHY OUT OF CURIOSITY?) | ||
$IPTABLES -A INPUT -p udp --dport 5353 -j ACCEPT | ||
|
||
#when run as gateway | ||
$IPTABLES -A INPUT -p tcp --dport $ssh_port -m state --state NEW -i $wan -j ACCEPT | ||
#if [ "$wan" != "none" ] && [ "$network_mode" != "Appliance" ]; then | ||
if [ "$wan" != "none" ]; then | ||
|
||
if [ "$gui_wan" == "True" ]; then | ||
$IPTABLES -A INPUT -p tcp --dport $gui_port -m state --state NEW -i $wan -j ACCEPT | ||
fi | ||
# 1 = ssh only | ||
if [ "$ports_externally_visible" -ge 1 ]; then | ||
$IPTABLES -A INPUT -p tcp --dport $ssh_port -m state --state NEW -i $wan -j ACCEPT | ||
fi | ||
|
||
# 2 = ssh + http-or-https (for Admin Console's box.lan/admin too) | ||
if [ "$ports_externally_visible" -ge 2 ]; then | ||
# For now this is implemented using Admin Console variable "gui_port" from: | ||
# https://github.com/iiab/iiab/blob/master/roles/0-init/tasks/main.yml#L87-L95 | ||
$IPTABLES -A INPUT -p tcp --dport $gui_port -m state --state NEW -i $wan -j ACCEPT | ||
fi | ||
|
||
if [ "$services_externally_visible" == "True" ]; then | ||
$IPTABLES -A INPUT -p tcp --dport $kiwix_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $kalite_server_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $kolibri_http_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $calibre_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $calibreweb_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $cups_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $sugarizer_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $nodered_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $mosquitto_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $transmission_http_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $transmission_peer_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p udp --dport $minetest_port -m state --state NEW -i $wan -j ACCEPT | ||
|
||
if [ "$pbx_enabled" == "True" ]; then | ||
$IPTABLES -A INPUT -p udp --dport $pbx_signaling_ports_chan_sip -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p udp --dport $pbx_signaling_ports_chan_pjsip -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p udp --dport $pbx_data_ports -m state --state NEW -i $wan -j ACCEPT | ||
# 3 = ssh + http-or-https + common IIAB services | ||
if [ "$ports_externally_visible" -ge 3 ]; then | ||
$IPTABLES -A INPUT -p tcp --dport $calibre_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $calibreweb_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $cups_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $kalite_server_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $kiwix_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $kolibri_http_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p udp --dport $minetest_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $mosquitto_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $nodered_port -m state --state NEW -i $wan -j ACCEPT | ||
|
||
if [ "$pbx_enabled" == "True" ]; then | ||
$IPTABLES -A INPUT -p udp --dport $pbx_signaling_ports_chan_sip -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p udp --dport $pbx_signaling_ports_chan_pjsip -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p udp --dport $pbx_data_ports -m state --state NEW -i $wan -j ACCEPT | ||
fi | ||
|
||
$IPTABLES -A INPUT -p tcp --dport $sugarizer_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $transmission_http_port -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp --dport $transmission_peer_port -m state --state NEW -i $wan -j ACCEPT | ||
fi | ||
|
||
if [ "$samba_enabled" == "True" ]; then | ||
# 4 = ssh + http-or-https + common IIAB services + Samba | ||
if [ "$ports_externally_visible" -ge 4 ]; then | ||
$IPTABLES -A INPUT -p udp --dport $samba_udp_ports -m state --state NEW -i $wan -j ACCEPT | ||
$IPTABLES -A INPUT -p tcp -m multiport --dports $samba_tcp_mports -m state --state NEW -i $wan -j ACCEPT | ||
fi | ||
fi | ||
|
||
if [ "$iiab_gateway_enabled" == "True" ]; then | ||
$IPTABLES -A POSTROUTING -t nat -o $wan -j MASQUERADE | ||
fi | ||
# Typically False, to keep client machines (e.g. students) off the Internet | ||
if [ "$iiab_gateway_enabled" == "True" ] && [ "$lan" == "none" ]; then | ||
$IPTABLES -A POSTROUTING -t nat -o $wan -j MASQUERADE | ||
fi | ||
|
||
$IPTABLES -A FORWARD -i $wan -o $lan -m state --state ESTABLISHED,RELATED -j ACCEPT | ||
# 3 or 4 IP forwarding rules | ||
$IPTABLES -A FORWARD -i $wan -o $lan -m state --state ESTABLISHED,RELATED -j ACCEPT | ||
# Block https traffic except if directed at server | ||
if [ "$gw_block_https" == "True" ]; then | ||
$IPTABLES -A FORWARD -p tcp ! -d {{ lan_ip }} --dport 443 -j DROP | ||
fi | ||
# Allow outgoing connections from the LAN side | ||
$IPTABLES -A FORWARD -i $lan -o $wan -j ACCEPT | ||
# Don't forward from the outside to the inside | ||
$IPTABLES -A FORWARD -i $wan -o $lan -j DROP | ||
# Enable routing (kernel IP forwarding) | ||
echo 1 > /proc/sys/net/ipv4/ip_forward | ||
|
||
# 5 = "all but databases" | ||
if [ "$ports_externally_visible" -lt 5 ]; then | ||
# Drop everything else arriving via WAN | ||
$IPTABLES -A INPUT -i $wan -j DROP | ||
fi | ||
|
||
#Block https traffic except if directed at server | ||
if [ "$gw_block_https" == "True" ]; then | ||
$IPTABLES -A FORWARD -p tcp ! -d {{ lan_ip }} --dport 443 -j DROP | ||
fi | ||
|
||
# Allow outgoing connections from the LAN side. | ||
$IPTABLES -A FORWARD -i $lan -o $wan -j ACCEPT | ||
|
||
# Don't forward from the outside to the inside. | ||
$IPTABLES -A FORWARD -i $wan -o $lan -j DROP | ||
$IPTABLES -A INPUT -i $wan -j DROP | ||
|
||
# TCP & UDP block of DNS port 53 if truly nec | ||
if [ "$block_DNS" == "True" ]; then | ||
$IPTABLES -t nat -A PREROUTING -i $lan -p tcp --dport 53 ! -d {{ lan_ip }} -j DNAT --to {{ lan_ip }}:53 | ||
$IPTABLES -t nat -A PREROUTING -i $lan -p udp --dport 53 ! -d {{ lan_ip }} -j DNAT --to {{ lan_ip }}:53 | ||
fi | ||
|
||
# If Squid enabled, as indicated by "HTTPCACHE_ON=True" in /etc/iiab/iiab.env | ||
if [ "$HTTPCACHE_ON" == "True" ]; then | ||
$IPTABLES -t nat -A PREROUTING -i $lan -p tcp --dport 80 ! -d {{ lan_ip }} -j DNAT --to {{ lan_ip }}:3128 | ||
$IPTABLES -t nat -A PREROUTING -i $lan -p tcp --dport 80 ! -d {{ lan_ip }} -j DNAT --to {{ lan_ip }}:3128 | ||
fi | ||
|
||
# Enable routing. | ||
echo 1 > /proc/sys/net/ipv4/ip_forward | ||
# save the whole rule set now | ||
# Save the whole rule set | ||
{% if is_debuntu %} | ||
netfilter-persistent save | ||
{% else %} | ||
iptables-save > $IPTABLES_DATA | ||
{% endif %} | ||
|
||
exit 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.