On Debian, iptables-restore is called on boot by installing the following package:
apt install iptables-persistent

IPv4

We set the default policy of the INPUT chain to DROP and
specify some rules, which are applied from top to bottom:

  1. Incoming packages on the loopback interface lo are accepted.
  2. ESTABLISHED connections or RELATED packages are accepted.
  3. ICMP traffic (e.g. incoming ping requests) is allowed.
  4. The number of SSH connection attempts is limited to 8 per 60 seconds.
    This slows down brute force password attacks significantly.
  5. A web server needs incoming packages on port 80 (http) and port 443 (https) to be accepted.

Rules for IPv4 are specified in /etc/iptables/rules.v4:

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

-A INPUT -i lo -j ACCEPT

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p icmp -j ACCEPT

-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
-A INPUT -p tcp --dport 22 -j ACCEPT

-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

COMMIT

Reload IPv4 rules

Restore rules from file:
iptables-restore < /etc/iptables/rules.v4

Verify loaded rules:
iptables -L

Network Address Translation (NAT)

The PREROUTING chain is used for port forwarding.

The rule in the POSTROUTING chain translates the source address of outgoing packages.
The reply will be forwarded by translating the destination address of incoming packages.
This is what ordinary IPv4 routers do.

Rules for the nat table can be part of /etc/iptables/rules.v4:

*filter
#...
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.0.100:80
-A POSTROUTING -s 192.168.0.0/255.255.255.0 -o ppp0 -j MASQUERADE
COMMIT

Forwarding of packages needs to be enabled:
echo 1 > /proc/sys/net/ipv4/ip_forward

Edit /etc/sysctl.conf to make this change persistent over reboots:

#...

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1

#...

IPv6

ICMPv6 is required for IPv6 to work correctly.

Rules for IPv6 are specified in /etc/iptables/rules.v6:

*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

-A INPUT -i lo -j ACCEPT

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p icmpv6 -j ACCEPT

-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
-A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 8 --rttl --name SSH -j DROP
-A INPUT -p tcp --dport 22 -j ACCEPT

-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

COMMIT

Reload IPv6 rules

Restore rules from file:
ip6tables-restore < /etc/iptables/rules.v6

Verify loaded rules:
ip6tables -L