| #!/bin/sh |
| . /etc/utils.sh |
| |
| trap ": >/tmp/run/firewall.init" EXIT |
| |
| register_experiment NoSIPConntrack |
| register_experiment McDoleCast |
| |
| flush() |
| { |
| for t in filter mangle nat; do |
| ip46tables -t $t -F |
| ip46tables -t $t -X |
| done |
| } |
| |
| if ! is-network-box; then |
| # no iptables needed on non-network boxes |
| exit 0 |
| fi |
| |
| case "$1" in |
| start|restart|reload) |
| if ! is-windcharger; then |
| modprobe -a \ |
| iptable_filter \ |
| iptable_nat \ |
| ipt_tcp \ |
| ipt_udp \ |
| ipt_conntrack \ |
| ipt_pkttype \ |
| ipt_limit \ |
| ipt_LOG \ |
| ipt_REJECT \ |
| ipt_MASQUERADE \ |
| \ |
| nf_nat_ftp \ |
| nf_nat_tftp \ |
| nf_nat_pptp \ |
| nf_nat_irc \ |
| nf_nat_proto_gre \ |
| nf_nat_h323 \ |
| nf_nat_rtsp \ |
| \ |
| nf_conntrack_ftp \ |
| nf_conntrack_tftp \ |
| nf_conntrack_pptp \ |
| nf_conntrack_irc \ |
| nf_conntrack_proto_gre \ |
| nf_conntrack_h323 \ |
| nf_conntrack_rtsp \ |
| \ |
| ip6table_filter \ |
| ip6t_tcp \ |
| ip6t_udp \ |
| nf_conntrack_ipv6 \ |
| ip6t_pkttype \ |
| ip6t_limit \ |
| ip6t_LOG \ |
| ip6t_REJECT |
| if ! experiment NoSIPConntrack; then |
| modprobe -a \ |
| nf_nat_sip \ |
| nf_conntrack_sip |
| fi |
| fi |
| |
| # Flush all existing rules when starting or reloading. |
| flush |
| |
| if is-ptp; then |
| ip46tables -P INPUT DROP |
| ip46tables -P OUTPUT ACCEPT |
| ip46tables -P FORWARD DROP |
| |
| # Accept established and related connections. |
| ip46tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT |
| |
| # ping and path MTU discovery (PMTUD) |
| iptables -A INPUT -p icmp --icmp-type 8/0 -j ACCEPT |
| iptables -A INPUT -p icmp --icmp-type 3/4 -j ACCEPT |
| iptables -A INPUT -p icmp --icmp-type 11/0 -j ACCEPT |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT |
| |
| if [ -e /tmp/DEBUG ]; then |
| ip46tables -A INPUT -p tcp --dport 8080 -j ACCEPT |
| fi |
| |
| # adding a new chain "vlan-input", which will be updated later when |
| # more interfaces are created in S40Network |
| ip46tables -N vlan-input |
| ip46tables -A INPUT -j vlan-input |
| |
| if [ -e /sys/class/net/craft0 ]; then |
| ip46tables -A INPUT -i craft0 -p tcp --dport 22 -j ACCEPT |
| ip46tables -A INPUT -i craft0 -p tcp --dport 80 -j ACCEPT |
| ip46tables -A INPUT -i craft0 -p tcp --dport 443 -j ACCEPT |
| # Reject everything else that comes in on the craft port. Any new rules |
| # must be added above the REJECT. |
| ip46tables -A INPUT -i craft0 -j REJECT |
| fi |
| |
| # multicast (fiber TV, EAS) |
| ip46tables -A INPUT -m pkttype --pkt-type multicast -j ACCEPT |
| |
| # Allow all incoming connections to the loopback interface. |
| ip46tables -A INPUT -i lo -j ACCEPT |
| |
| # cwmpd ACS kick |
| ip46tables -A INPUT -p tcp --dport 7547 -j ACCEPT # cwmpd |
| |
| # DHCPv4 client |
| iptables -A INPUT -p udp --sport 67:68 --dport 67:68 -j ACCEPT |
| # DHCP6 client |
| ip6tables -A INPUT -p udp --sport 547 --dport 546 -j ACCEPT |
| |
| # TODO(cgibson): Revisit allowing SSH access on all but the craft port |
| # pre-launch and also the SSH keying strategy: http://b/27072881 |
| ip46tables -A INPUT -p tcp --dport 22 -j ACCEPT |
| |
| # IPv6 addressing |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-advertisement -j ACCEPT |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-solicitation -j ACCEPT |
| |
| # Log packets which weren't explicitly accepted by above rules |
| ip46tables -N log |
| ip46tables -A log -m pkttype -m limit \ |
| --pkt-type unicast \ |
| --limit 1/second \ |
| -j LOG --log-prefix "FW: " |
| ip46tables -A INPUT -j log |
| fi |
| |
| if [ -e /sys/class/net/wan0 ]; then |
| # Do these first to reduce race conditions |
| if [ -e /tmp/NFS ]; then |
| # Workaround because we can't have a temporary network dropout |
| # when NFS booted. |
| ip46tables -P INPUT ACCEPT |
| else |
| ip46tables -P INPUT DROP |
| fi |
| ip46tables -P FORWARD DROP |
| |
| # captive-portal-filter and captive-portal-input contain rules that should |
| # always be applied to the br1 (captive portal) interface, regardless of |
| # what services we're trying to provide with it. |
| ip46tables -N captive-portal-guests |
| ip46tables -N captive-portal-filter |
| ip46tables -N captive-portal-ntp |
| ip46tables -N captive-portal-input |
| ip46tables -N acs-captive-portal-input |
| ip46tables -N sniproxy-input |
| ip46tables -N acs-captive-portal-filter |
| ip46tables -N acsrules-filter-forward |
| ip46tables -N MINIUPNPD |
| ip46tables -N wan-input |
| ip46tables -N wan-forward |
| ip46tables -N log |
| |
| ip46tables -t nat -N captive-portal-guests-nat |
| ip46tables -t nat -N acs-captive-portal-nat |
| iptables -t nat -N acsrules-nat-prerouting |
| iptables -t nat -N acsrules-nat-postrouting |
| ip46tables -t nat -N sniproxy-nat |
| iptables -t nat -N MINIUPNPD |
| ip46tables -t nat -N wan-nat |
| |
| for ifc in "wan0+" "frob+"; do |
| ip46tables -A INPUT -i "$ifc" -j wan-input |
| ip46tables -A FORWARD -i "$ifc" -j wan-forward |
| ip46tables -t nat -A PREROUTING -i "$ifc" -j wan-nat |
| |
| ip46tables -A FORWARD -i br0 -o "$ifc" -j ACCEPT |
| done |
| |
| ip46tables -A FORWARD -i br1 -o wan0+ -j captive-portal-guests |
| ip46tables -A FORWARD -i br1 -o wan0+ -j captive-portal-filter |
| ip46tables -A FORWARD -i br1 -o wan0+ -j captive-portal-ntp |
| |
| for ifc in lo br0; do |
| ip46tables -A INPUT -i "$ifc" -j ACCEPT |
| done |
| |
| ip46tables -A INPUT -i br1 -j captive-portal-input |
| ip46tables -A INPUT -i br1 -j acs-captive-portal-input |
| ip46tables -A INPUT -i br1 -j sniproxy-input |
| |
| # multicast (fiber TV, EAS) |
| ip46tables -A wan-input -m pkttype --pkt-type multicast -j ACCEPT |
| ip46tables -A wan-forward -m pkttype --pkt-type multicast -j ACCEPT |
| ip46tables -t nat -A wan-nat -m pkttype --pkt-type multicast -j ACCEPT |
| |
| # Forwarding |
| ip46tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT |
| ip46tables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT |
| |
| # igmp group membership control |
| ip46tables -A wan-input -p igmp -j ACCEPT |
| |
| # ping and PMTUD |
| iptables -A INPUT -p icmp --icmp-type 8/0 -j ACCEPT |
| iptables -A INPUT -p icmp --icmp-type 3/4 -j ACCEPT |
| iptables -A INPUT -p icmp --icmp-type 11/0 -j ACCEPT |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type echo-request -j ACCEPT |
| # RFC4890 says RFC4380 requires forwarding ipv6 ping requests |
| ip6tables -A wan-forward -p icmpv6 --icmpv6-type echo-request -j ACCEPT |
| |
| # Incoming connections |
| # TODO(apenwarr): Whitelist ports here too for added safety. |
| if [ -e /tmp/NFS ]; then |
| # Workaround because netfilter conntracking loaded *after* the NFS |
| # session was established. |
| ip46tables -A wan-input -p tcp --sport 2049 -j ACCEPT |
| fi |
| |
| # Outgoing connections |
| # TODO(apenwarr): Add a whitelist on OUTPUT for -o wan0. |
| # In particular we should have one for samba ports. |
| |
| # TODO(apenwarr): Remove this when we have real port forwarding controls. |
| if [ -e /tmp/DEBUG ]; then |
| ip46tables -A wan-input -p tcp --dport 22 -j ACCEPT # ssh |
| ip46tables -A wan-forward -p tcp --dport 22 -j ACCEPT # ssh for lan clients |
| ip46tables -A wan-input -p tcp --dport 5001 -j ACCEPT # iperf |
| ip46tables -A wan-input -p udp --dport 5001 -j ACCEPT # iperf |
| ip46tables -A wan-input -p udp --dport 4948 -j ACCEPT # isoping |
| fi |
| |
| # Open incoming ports for McDoleCast |
| if experiment McDoleCast; then |
| ip46tables -A wan-input -p tcp --dport 31098 -j ACCEPT # sagesrv |
| ip46tables -A wan-input -p tcp --dport 32825 -j ACCEPT # marjoram |
| fi |
| # cwmpd ACS kick |
| ip46tables -A wan-input -p tcp --dport 7547 -j ACCEPT # cwmpd |
| ip6tables -A wan-forward -p tcp --dport 7547 -j ACCEPT # cwmpd |
| ip46tables -t nat -A wan-nat -p tcp --dport 7547 -j ACCEPT # cwmpd |
| |
| if [ -e /tmp/factory_status ]; then |
| ip46tables -A wan-input -p tcp --dport 8883 -j ACCEPT # factory web server |
| fi |
| |
| # active FTP out |
| ip46tables -A FORWARD -m conntrack --ctstate RELATED \ |
| -m helper --helper ftp -o wan0+ -p tcp --dport 1024: -j ACCEPT |
| ip46tables -A wan-forward -m conntrack --ctstate RELATED \ |
| -m helper --helper ftp -p tcp --dport 1024: -j ACCEPT |
| |
| # add ACS-configured things |
| ip46tables -A FORWARD -i br1 -j acs-captive-portal-filter |
| ip46tables -A FORWARD -i wan0+ -j acsrules-filter-forward |
| ip46tables -t nat -A PREROUTING -i br1 -j captive-portal-guests-nat |
| ip46tables -t nat -A PREROUTING -i br1 -j acs-captive-portal-nat |
| iptables -t nat -A PREROUTING -i wan0+ -j acsrules-nat-prerouting |
| iptables -t nat -A POSTROUTING -o wan0+ -j acsrules-nat-postrouting |
| |
| # these are managed by sniproxy, if running |
| ip46tables -t nat -A PREROUTING -j sniproxy-nat -i br1 |
| |
| # these are managed by miniupnpd, if running |
| ip46tables -A FORWARD -i wan0+ ! -o wan0+ -j MINIUPNPD |
| iptables -t nat -A PREROUTING -i wan0+ -j MINIUPNPD |
| |
| # nat |
| ip46tables -t nat -A POSTROUTING -o wan0+ -j MASQUERADE |
| |
| # ipv6 addressing |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type router-advertisement -j ACCEPT |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type router-solicitation -j ACCEPT |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-advertisement -j ACCEPT |
| ip6tables -A INPUT -p icmpv6 --icmpv6-type neighbour-solicitation -j ACCEPT |
| # DHCP6 client |
| ip6tables -A INPUT -p udp --sport 547 --dport 546 -j ACCEPT |
| |
| # Log packets which weren't explicitly accepted by above rules |
| ip46tables -A log -m pkttype -m limit \ |
| --pkt-type unicast \ |
| --limit 1/second \ |
| -j LOG --log-prefix "FW: " |
| ip46tables -A INPUT -i wan0+ -j log |
| ip46tables -A FORWARD -i wan0+ -j log |
| |
| # Set the WAN 802.1q pbits |
| iptables -t mangle -A OUTPUT -o wan0.2 -p all -j CLASSIFY --set-class 0:2 |
| iptables -t mangle -A OUTPUT -o wan0.2 -p igmp -j CLASSIFY --set-class 0:6 |
| iptables -t mangle -A OUTPUT -o wan0.2 -p icmp -j CLASSIFY --set-class 0:6 |
| ip6tables -t mangle -A OUTPUT -o wan0.2 -p icmpv6 -j CLASSIFY --set-class 0:6 |
| # DHCP and DHCPv6 |
| iptables -t mangle -A OUTPUT -o wan0.2 -p udp --sport 68 --dport 67 -j CLASSIFY --set-class 0:6 |
| ip6tables -t mangle -A OUTPUT -o wan0.2 -p udp --sport 547 --dport 546 -j CLASSIFY --set-class 0:6 |
| |
| # Default DROP policy above is safe, but REJECT is friendlier. |
| # But you can't use REJECT as a policy, so add a catchall rule at the |
| # bottom. |
| ip46tables -A INPUT -j REJECT |
| ip46tables -A FORWARD -j REJECT |
| |
| # don't add any rules after the REJECTs above |
| |
| # parse acs state into acsrules chains |
| update-acs-iptables |
| |
| # Use iptables to mark packets to set the VLAN p-bits |
| # Bit(s) Definitions |
| # 0:4 class/priority of orig [and reply] connection. |
| # 5:7 VLAN P bits for orig [and reply] connection (if bit 15 = 1) |
| # |
| # 8 DSCP control bit |
| # 0: DSCP values will remain unchanged |
| # 1: do DSCP marking for orig [and reply] connection |
| # |
| # 9:14 DSCP value: DSCP value for orig [and reply] connection (if bit 8 # = 1) |
| # |
| # 15 if 0, copy VLAN P bits from ingress packet; |
| # if 1, set VLAN P bits for orig and reply connection |
| # |
| # 16:20 class/priority of reply connection |
| # 21:23 VLAN P bits for reply connection (if bit 15 = 1) |
| # |
| # 24 DSCP control bit |
| # 0: DSCP values will remain unchanged |
| # 1: do DSCP marking for reply connection; |
| # |
| # 25:30 DSCP value for reply connection (if bit 24 = 1) |
| # 31 0: use bits 0-15 for reply connection |
| # 1: use bits 16-30 for reply connection |
| ip46tables -A POSTROUTING -t mangle -o wan0.2 -j CONNMARK --set-mark 0x8040 |
| fi |
| exit 0 |
| ;; |
| stop) |
| if [ -e /proc/sys/net/netfilter -a -e /sys/class/net/wan0 ]; then |
| flush |
| ip46tables -P INPUT ACCEPT |
| ip46tables -P FORWARD ACCEPT |
| fi |
| ;; |
| *) |
| echo "Usage: $0 {start|stop|restart}" |
| exit 1 |
| esac |