lib/fault_tolerant_router/generate_iptables.rb
def generate_iptables
puts <<END
#Integrate with your existing "iptables-save" configuration, or adapt to work
#with any other iptables configuration system
*mangle
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:INPUT ACCEPT [0:0]
#New outbound connections: force a connection to use a specific uplink instead
#of participating in the multipath routing. This can be useful if you have an
#SMTP server that should always send emails originating from a specific IP
#address (because of PTR DNS records), or if you have some service that you want
#always to use a particular slow/fast uplink.
#
#Uncomment if needed.
#
#NB: these are just examples, you can add as many options as needed: -s, -d,
# --sport, etc.
END
UPLINKS.each do |uplink|
puts "##{uplink.description}"
puts "#[0:0] -A PREROUTING -i #{LAN_INTERFACE} -m conntrack --ctstate NEW -p tcp --dport XXX -j CONNMARK --set-mark #{uplink.fwmark}"
puts "#[0:0] -A PREROUTING -i #{DMZ_INTERFACE} -m conntrack --ctstate NEW -p tcp --dport XXX -j CONNMARK --set-mark #{uplink.fwmark}" if DMZ_INTERFACE
end
puts <<END
#Mark packets with the outgoing interface:
#
#- Established outbound connections: mark non-first packets (first packet will
# be marked as 0, as a standard unmerked packet, because the connection has not
# yet been marked with CONNMARK --set-mark)
#
#- New outbound connections: mark first packet, only effective if marking has
# been done in the section above
#
#- Inbound connections: mark returning packets (from LAN/DMZ to WAN)
[0:0] -A PREROUTING -i #{LAN_INTERFACE} -j CONNMARK --restore-mark
END
puts "[0:0] -A PREROUTING -i #{DMZ_INTERFACE} -j CONNMARK --restore-mark" if DMZ_INTERFACE
puts <<END
#New inbound connections: mark the connection with the incoming interface.
END
UPLINKS.each do |uplink|
puts "##{uplink.description}"
puts "[0:0] -A PREROUTING -i #{uplink.interface} -m conntrack --ctstate NEW -j CONNMARK --set-mark #{uplink.fwmark}"
end
puts <<END
#New outbound connections: mark the connection with the outgoing interface
#(chosen by the multipath routing).
END
UPLINKS.each do |uplink|
puts "##{uplink.description}"
puts "[0:0] -A POSTROUTING -o #{uplink.interface} -m conntrack --ctstate NEW -j CONNMARK --set-mark #{uplink.fwmark}"
end
puts <<END
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
#DNAT: WAN --> LAN/DMZ. The original destination IP (-d) can be any of the IP
#addresses assigned to the uplink interface. XXX.XXX.XXX.XXX can be any of your
#LAN/DMZ IPs.
#
#Uncomment if needed.
#
#NB: these are just examples, you can add as many options as you wish: -s,
# --sport, --dport, etc.
END
UPLINKS.each do |uplink|
puts "##{uplink.description}"
if uplink.type == :ppp
puts "#[0:0] -A PREROUTING -i #{uplink.interface} -j DNAT --to-destination XXX.XXX.XXX.XXX"
else
puts "#[0:0] -A PREROUTING -i #{uplink.interface} -d #{uplink.ip} -j DNAT --to-destination XXX.XXX.XXX.XXX"
end
end
puts <<END
#SNAT: LAN/DMZ --> WAN. Force an outgoing connection to use a specific source
#address instead of the default one of the outgoing interface. Of course this
#only makes sense if more than one IP address is assigned to the uplink
#interface.
#
#Uncomment if needed.
#
#NB: these are just examples, you can add as many options as needed: -d,
# --sport, --dport, etc.
END
UPLINKS.each do |uplink|
puts "##{uplink.description}"
puts "#[0:0] -A POSTROUTING -s XXX.XXX.XXX.XXX -o #{uplink.interface} -j SNAT --to-source YYY.YYY.YYY.YYY"
end
puts <<END
#SNAT: LAN --> WAN
END
UPLINKS.each do |uplink|
puts "##{uplink.description}"
if uplink.type == :ppp
puts "[0:0] -A POSTROUTING -o #{uplink.interface} -j MASQUERADE"
else
puts "[0:0] -A POSTROUTING -o #{uplink.interface} -j SNAT --to-source #{uplink.ip}"
end
end
puts <<END
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:LAN_WAN - [0:0]
:WAN_LAN - [0:0]
END
if DMZ_INTERFACE
puts ':DMZ_WAN - [0:0]'
puts ':WAN_DMZ - [0:0]'
end
puts <<END
#This is just a very basic example, add your own rules for the FORWARD chain.
[0:0] -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
END
UPLINKS.each do |uplink|
puts "[0:0] -A FORWARD -i #{LAN_INTERFACE} -o #{uplink.interface} -j LAN_WAN"
end
UPLINKS.each do |uplink|
puts "[0:0] -A FORWARD -i #{uplink.interface} -o #{LAN_INTERFACE} -j WAN_LAN"
end
if DMZ_INTERFACE
UPLINKS.each do |uplink|
puts "[0:0] -A FORWARD -i #{DMZ_INTERFACE} -o #{uplink.interface} -j DMZ_WAN"
end
UPLINKS.each do |uplink|
puts "[0:0] -A FORWARD -i #{uplink.interface} -o #{DMZ_INTERFACE} -j WAN_DMZ"
end
end
puts <<END
[0:0] -A LAN_WAN -j ACCEPT
[0:0] -A WAN_LAN -j REJECT
END
if DMZ_INTERFACE
puts '[0:0] -A DMZ_WAN -j ACCEPT'
puts '[0:0] -A WAN_DMZ -j ACCEPT'
end
puts <<END
COMMIT
END
end