#!/bin/sh

# Last updated 9/20/2025
# Public interface is assumed to be eth0
# Private interface is assumed to be eth1

if [ -f "/etc/default/edge-firewall" ]; then
    echo "Sourcing /etc/default/edge-firewall"
    . /etc/default/edge-firewall
fi

# Insert connection-tracking modules
# (not needed if built into the kernel)
modprobe nf_conntrack
modprobe xt_LOG

# Enable broadcast echo Protection
echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

# Disable Source Routed Packets
echo 0 >/proc/sys/net/ipv4/conf/all/accept_source_route
echo 0 >/proc/sys/net/ipv4/conf/default/accept_source_route

# Enable TCP SYN Cookie Protection
echo 1 >/proc/sys/net/ipv4/tcp_syncookies

# Disable ICMP Redirect Acceptance
echo 0 >/proc/sys/net/ipv4/conf/default/accept_redirects

# Do not send Redirect Messages
echo 0 >/proc/sys/net/ipv4/conf/all/send_redirects
echo 0 >/proc/sys/net/ipv4/conf/default/send_redirects

# Drop Spoofed Packets coming in on an interface, where responses
# would result in the reply going out a different interface.
echo 1 >/proc/sys/net/ipv4/conf/all/rp_filter
echo 1 >/proc/sys/net/ipv4/conf/default/rp_filter

# Log packets with impossible addresses.
echo 1 >/proc/sys/net/ipv4/conf/all/log_martians
echo 1 >/proc/sys/net/ipv4/conf/default/log_martians

# be verbose on dynamic ip-addresses (not needed in case of static IP)
echo 2 >/proc/sys/net/ipv4/ip_dynaddr

# disable Explicit Congestion Notification
# too many routers are still ignorant
echo 0 >/proc/sys/net/ipv4/tcp_ecn

# enable ipv4 forwarding
echo 1 >/proc/sys/net/ipv4/ip_forward

IPT="iptables --wait"

# Set a known state
$IPT -P INPUT DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT DROP

# These lines are here in case rules are already in place and the
# script is ever rerun on the fly. We want to remove all rules and
# pre-existing user defined chains before we implement new rules.
$IPT -F
$IPT -X
$IPT -Z

$IPT -t nat -F

# Allow connections on loopback interface
$IPT -A INPUT -i lo -j ACCEPT

# Allow connnections on local network
if [ "$ALLOW_ETH0" = "yes" ]; then
    echo "Allowing eth0"
    $IPT -A INPUT -i eth0 -j ACCEPT
fi

# Allow connnections on private machine network
if [ "$ALLOW_ETH1" = "yes" -o "$ALLOW_PRIVATE_NAT" = "yes" ]; then
    echo "Allowing eth1"
    $IPT -A INPUT -i eth1 -j ACCEPT
fi

# Free output on any interface to any ip for any service
# (equal to -P ACCEPT)
$IPT -A OUTPUT -j ACCEPT

# Permit answers on already established connections
# and permit new connections related to established ones
# (e.g. port mode ftp)
$IPT -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow ping
$IPT -A INPUT -p icmp -j ACCEPT

# Allow tcp flags
$IPT -A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT

# Allow ssh
if [ "$ALLOW_SSH" = "yes" ]; then
    echo "Allowing ssh"
    $IPT -A INPUT -p tcp --dport 22 -j ACCEPT
fi

# Allow dns
if [ "$ALLOW_DNS" = "yes" ]; then
    echo "Allowing dns"
    $IPT -A INPUT -p udp --dport 53 -j ACCEPT
fi

# Allow http
if [ "$ALLOW_HTTP" = "yes" ]; then
    echo "Allowing http"
    $IPT -A INPUT -p tcp --dport 80 -j ACCEPT
fi

# Allow sntp
if [ "$ALLOW_SNTP" = "yes" ]; then
    echo "Allowing sntp"
    $IPT -A INPUT -p udp --port 123 -j ACCEPT
fi

# Allow https
if [ "$ALLOW_HTTPS" = "yes" ]; then
    echo "Allowing https"
    $IPT -A INPUT -p tcp --dport 443 -j ACCEPT
fi

# Allow mqtt
if [ "$ALLOW_MQTT" = "yes" ]; then
    echo "Allowing mqtt"
    $IPT -A INPUT -p tcp --dport 1883 -j ACCEPT
fi

# Allow Ignition
if [ "$ALLOW_IGNITION_HTTP" = "yes" ]; then
    echo "Allowing ignition http port 8088"
    $IPT -A INPUT -p tcp --dport 8088 -j ACCEPT
fi
if [ "$ALLOW_IGNITION_HTTPS" = "yes" ]; then
    echo "Allowing ignition https port 8043"
    $IPT -A INPUT -p tcp --dport 8043 -j ACCEPT
fi

# Allow mqtts
if [ "$ALLOW_MQTTS" ]; then
    echo "Allowing mqtts"
    $IPT -A INPUT -p tcp --dport 8883 -j ACCEPT
fi

# OpenVPN NAT
if [ "$ALLOW_EDGE_OPENVPN" = "yes" ]; then
    echo "Allowing edge openvpn server"
    $IPT -A INPUT -i tun+ -j ACCEPT
    $IPT -A POSTROUTING -t nat -o eth1 -j MASQUERADE
    $IPT -A FORWARD -i tun+ -j ACCEPT
    $IPT -A FORWARD -i tun+ -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
    $IPT -A FORWARD -i eth1 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
fi

# Private network NAT
if [ "$ALLOW_PRIVATE_NAT" = "yes" ]; then
    echo "Allowing private network NAT"
    $IPT -A POSTROUTING -t nat -o eth0 -j MASQUERADE
    $IPT -A FORWARD -i eth1 -j ACCEPT
    $IPT -A FORWARD -i eth1 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    $IPT -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
fi

# Log everything else
$IPT -A INPUT -j LOG --log-prefix "FIREWALL:INPUT "
