Dear openwrt users,
mayby im a little bit paranoid but im scared of mine home firewall setup that its secure enough. and everything im scared of is that i dont understand so the last week or so im reading and try to build my own firewall for nftables, to learn more about the firewall to be more secure.
how i read it the nftables are amazing because if for some examples a connection is made from the lan network to the internet, the connecting keeps excisting and is accepted. but if the same connection is made from the internet trough the lan it will be blocked because noone asked for it, no matter what port. (dont know if thats possible in ip tables but i like this a lot feels secure).
ct state vmap { established : accept, related : accept, invalid : drop }
now see the picture for the home network setup (sorry for the bad drawing if been using paint for years and trying out linux for the last month or so):
The router has three lan ports (eth0 for wan eth1 lan and eth2 lan), eth1 is connected to server running proxmox that runs:
- minecraft server
- logging server
- website
- mailing
- rstp and ftp for iot camera's (hacked china stuff so that is really untrustworthy)
and eth2 is connected to a switch that is connected to:
- iptv
- IOT(light control device)
- second router as AP
i can create inside the switch different vlans for each device, but now the problem the wifi.
Some wifi devices are untrusted and only can use the rstp and ftp server to control them like:
- the china ip cameras
but some devices i trust like:
- mine laptop after some port knocking.
some IOT devices i trust more than the china ip camera's and need to get connected to the internet but nothing else like:
- printers (ntp)
- nest thermostat
- smart tv's
- mobile phones
- switch
- etc.
so the i tought of a setup for vlans or ipaddress ranges that get ranked and only can connect lower ranks, The problems:
-
If the ip address range is being used than no vlan is made only a lot of interfaces are made with diff ranges, the devices are setup by ranked, so they cant find each other. but if someone hacks a device change the ip adress of the device to the highest rank. they have fully control of the system.
-
if the vlan setup is being used i cant catogirize the wifi because it hasnt vlans (only the second router can have a vlan and the same interface) but for example a rough iot wifi device could listen on the network.
The next two pieces of code would be the nfttables.conf the ip isnt quite ready yet beacse the input and forward iifnames and oifnames arnt connected to the defines. i did my best but im not even a novel just a noob trying to understand so big disclamer copy stuff from it on your own risk:
IP:
flush ruleset
#Defines
##interfaces
define wan = eth0.300
define wan6 = eth0.300
##Subnets ipv4 and ipv6
###local servers that don't need internet access like ftp, rstp, logging servers etc.
define net_ipv4_servers_local = 10.0.0.0/24
define net_ipv6_servers_local = fe00:0::/64
###online servers that need internet access like minecraft, websites, mailing server etc.
define net_ipv4_servers_online = 10.0.1.0/24
define net_ipv6_servers_online = fe00:1::/64
###The untrusted wifi and lan network where guests just can login
define net_ipv4_guests = 10.0.2.0/24
define net_ipv6_guests = fe00:2::/64
###The untrusted but fine serivices like chromecast printers nests thermostat that need acces the internet.
define net_ipv4_iot_online = 10.0.3.0/24
define net_ipv6_iot_online = fe00:3::/64
###The really untrusted services like ip camera's that only need a ntp and ftp server rstp server to send there data and control them.
define net_ipv4_iot_local = 10.0.4.0/24
define net_ipv6_iot_local = fe00:4::/64
###The hosts ip addresses like luci proxmox logging website (from the logging server).
define net_ipv4_local_hosts = 10.0.5.0/24
define net_ipv6_local_hosts = fe00:5::/64
###Trusted devices that can control everything like PC's/ mobile devices
define net_ipv4_home = 10.0.6.0/24
define net_ipv6_home = fe00:6::/64
#start ipv4/ipv6 filter
table inet filter{
#prerouting for nat's
chain prerouting {
type nat hook prerouting priority 0; policy accept;
#This is the rule, it says router when a packet arrives for tcp port 12345, that it is forward only the ssh port on a machine on the LAN. This is forwarded using #dnat - destination NAT, as its a ssh connection, and anything back from the machine on LAN is send back to machine sending the original packet. This is done in #prerouting it is done as soon as the packet enters the machine. A similar command would used if you wanted a WWW server on a local machine exported to the WAN so #people could connect over the internet. ipv6 needs brackeds for the ports like [ipv6]:port number
#dnat to tcp dport map {12345 : 192.168.2.111}
}
#input every packet that received by the router drop the connection if there isnt a exeption
chain input {
type filter hook input priority 0; policy drop;
#accept own created connections drop everything else
ct state vmap { established : accept, related : accept, invalid : drop }
#drop connections that arn't comming from the loopback
iif != lo ip daddr 127.0.0.1/8 counter drop comment "drop connections to loopback not coming from loopback"
iif != lo ip6 daddr ::1/128 counter drop comment "drop connections to loopback not coming from loopback"
# allow loopback traffic, anything else jump to chain for further evaluation
iifname vmap { lo : accept, $wan : jump inbound_wan, $home : jump inbound_home, $server_locale : jump inbound_server_locale , $server_online : jump inbound_server_online, $iot_locale : jump inbound_iot_locale , $iot_online : jump inbound_iot_online, $hosts : jump inbound_hosts , $gasten : jump inbound_gasten}
}
#Everything that being transmited trough the router to a differnt host. drop the connection if there isnt a exeption
chain forward {
type filter hook forward priority 0; policy drop;
#accept own created connections drop everything else
ct state vmap { established : accept, related : accept, invalid : drop }
#Home is the highest rank so they can reach everything, but nothing can reach home
iifname $home accept
#Every interface that needs special rules before going to the internet
oifname $wan iifname {$gasten : jump outbound_gasten, $iot_online : jump outbound_iot_online, $server_online : jump outbound_server_online}
#Interfaces that can reach eachother only one way.
meta iifname . meta oifname {$gasten . $server_online, $home . $hosts} accept
}
#the nat masquerade to hide every ip address ipv4 and ipv6
chain postrouting {
type nat hook postrouting priority 100; policy accept;
#masquerade private IP addresses
oifname "eth0" masquerade
}
#chains from the input chain so packets received by the firewall itself
##wan -> firewall
chain inbound_wan {
# The incomming packets from the wan port (nothing because if there is a connection from the home -> wan established thet connection will be accepted) only the server # ports that need to be accepted like 443 for a website and 25565 for minecraft
}
##home -> firewall
chain inbound_home {
}
##server_locale -> firewall
chain inbound_server_locale {
#only the ntp
udp dport {123} accept
}
##server_online -> firewall
chain inbound_server_online {
#only http https ntp dns and i think the minecraft server talks over the 25565 port accept
tcp dport {53, 80, 123, 443 , 25565} accept
udp dport {53, 123, 25565} accept
}
##IOT_locale -> firewall
chain inbound_iot_locale {
#only the ntp this is likeyly just the printers and two ip camera's
udp dport {123} accept
}
##IOT_online -> firewalll
chain inbound_iot_online {
#this is the scary one like nest thermostat chromecast smart tv's smart lights. they need a verarity of ports not knowing what they doing or talking to so TODO:more protection over here!
accept
}
##guests -> firewall
chain inbound_gasten {
#not knowing who is connected to your wifi dns http https ntp ports opened, TODO:check because gasten_inbound is more trustwothy than iot devices this is forwarded to the server online zone what everyone can reach else it is inpossible to reach minecraft etc. but mayby the ports of the servers need to be addet to reach or a dnat for the dns bc it isnt the same ip address to lookup the ddns to reach isnt going automatic to the right incomming port and forwarded ip addres. if the destination address matches the ddns ip then forward to the online server.
tcp dport {53, 80, 123, 443} accept
udp dport {53, 123} accept
}
##hosts -> firewall
chain inbound_hosts {
#nothing needed like proxmox luci logging output running on this (logging output site is running on the local server line but forwarded to this subnet TODO:)
}
#Chains from the forwarded chain so packets send from the firewall to a different host
##guest network untrusted cant reach Sh*t but safe modus so only dns http https ntp
chain outbound_gasten {
tcp dport {53, 80, 123, 443} accept
udp dport {53, 123} accept
}
##IOT_online really dont know how to get this one safe
chain outbound_iot_online {
accept
}
##Server online all the neccasery ports that own online services use.
chain outbound_server_online {
#only http https ntp dns and i think the minecraft server talks over the 25565 port accept
tcp dport {53, 80, 123, 443 , 25565} accept
udp dport {53, 123, 25565} accept
}
}
and the vlan one:
#remove every ruleset and build new ruleset
flush ruleset
#Defines
##nics with vlans there are 4096 vlan possabilities
## wan (eth0 with vlan 300 for internet acces) the vlans for ipv4 and ipv6 can be changed in the future, from isp.
define wan4 = eth0.300
define wan6 = eth0.300
##eth1 (lan port 1) and eth2 (lan port 2) for excample purpouse eth2 not connected
###local servers that don't need internet access like ftp, rstp, logging servers etc.
define server_locale = eth1.1
###online servers that need internet access like minecraft, websites, mailing server etc.
define server_online = eth1.50
###The untrusted wifi and lan network where guests just can login
define gasten = eth1.100
###The untrusted but fine serivices like chromecast printers nests thermostat that need acces the internet.
define iot_online = eth1.150
###The really untrusted services like ip camera's that only need a ntp and ftp server rstp server to send there data and control them.
define iot_locale = eth1.200
###The hosts ip addresses like luci proxmox logging website (from the logging server).
define hosts = eth1.250
###Trusted devices that can control everything like PC's/ mobile devices
define home = eth1.299
#start ipv4/ipv6 filter
table inet filter{
#prerouting for nat's
chain prerouting {
type nat hook prerouting priority 0; policy accept;
#This is the rule, it says router when a packet arrives for tcp port 12345, that it is forward only the ssh port on a machine on the LAN. This is forwarded using #dnat - destination NAT, as its a ssh connection, and anything back from the machine on LAN is send back to machine sending the original packet. This is done in #prerouting it is done as soon as the packet enters the machine. A similar command would used if you wanted a WWW server on a local machine exported to the WAN so #people could connect over the internet. ipv6 needs brackeds for the ports like [ipv6]:port number
#dnat to tcp dport map {12345 : 192.168.2.111}
}
#input every packet that received by the router drop the connection if there isnt a exeption
chain input {
type filter hook input priority 0; policy drop;
#accept own created connections drop everything else
ct state vmap { established : accept, related : accept, invalid : drop }
#drop connections that arn't comming from the loopback
iif != lo ip daddr 127.0.0.1/8 counter drop comment "drop connections to loopback not coming from loopback"
iif != lo ip6 daddr ::1/128 counter drop comment "drop connections to loopback not coming from loopback"
# allow loopback traffic, anything else jump to chain for further evaluation
iifname vmap { lo : accept, $wan4 : jump inbound_wan, $wan6 : jump inbound_wan, $home : jump inbound_home, $server_locale : jump inbound_server_locale , $server_online : jump inbound_server_online, $iot_locale : jump inbound_iot_locale , $iot_online : jump inbound_iot_online, $hosts : jump inbound_hosts , $gasten : jump inbound_gasten}
}
#Everything that being transmited trough the router to a differnt host. drop the connection if there isnt a exeption
chain forward {
type filter hook forward priority 0; policy drop;
#accept own created connections drop everything else
ct state vmap { established : accept, related : accept, invalid : drop }
#Home is the highest rank so they can reach everything, but nothing can reach home
iifname $home accept
#Every interface that needs special rules before going to the internet
oifname $wan4 iifname {$gasten : jump outbound_gasten, $iot_online : jump outbound_iot_online, $server_online : jump outbound_server_online}
oifname $wan6 iifname {$gasten : jump outbound_gasten, $iot_online : jump outbound_iot_online, $server_online : jump outbound_server_online}
#Interfaces that can reach eachother only one way.
meta iifname . meta oifname {$gasten . $server_online, $home . $hosts} accept
}
#the nat masquerade to hide every ip address ipv4 and ipv6
chain postrouting {
type nat hook postrouting priority 100; policy accept;
#masquerade private IP addresses ipv4
oifname $wan4 masquerade
#masquerade private IP addresses ipv6
oifname $wan6 masquerade
}
#chains from the input chain so packets received by the firewall itself
##wan -> firewall
chain inbound_wan {
# The incomming packets from the wan port (nothing because if there is a connection from the home -> wan established thet connection will be accepted) only the server # ports that need to be accepted like 443 for a website and 25565 for minecraft
}
##home -> firewall
chain inbound_home {
}
##server_locale -> firewall
chain inbound_server_locale {
#only the ntp
udp dport {123} accept
}
##server_online -> firewall
chain inbound_server_online {
#only http https ntp dns and i think the minecraft server talks over the 25565 port accept
tcp dport {53, 80, 123, 443 , 25565} accept
udp dport {53, 123, 25565} accept
}
##IOT_locale -> firewall
chain inbound_iot_locale {
#only the ntp this is likeyly just the printers and two ip camera's
udp dport {123} accept
}
##IOT_online -> firewalll
chain inbound_iot_online {
#this is the scary one like nest thermostat chromecast smart tv's smart lights. they need a verarity of ports not knowing what they doing or talking to so TODO:more protection over here!
accept
}
##guests -> firewall
chain inbound_gasten {
#not knowing who is connected to your wifi dns http https ntp ports opened, TODO:check because gasten_inbound is more trustwothy than iot devices this is forwarded to the server online zone what everyone can reach else it is inpossible to reach minecraft etc. but mayby the ports of the servers need to be addet to reach or a dnat for the dns bc it isnt the same ip address to lookup the ddns to reach isnt going automatic to the right incomming port and forwarded ip addres. if the destination address matches the ddns ip then forward to the online server.
tcp dport {53, 80, 123, 443} accept
udp dport {53, 123} accept
}
##hosts -> firewall
chain inbound_hosts {
#nothing needed like proxmox luci logging output running on this (logging output site is running on the local server line but forwarded to this subnet TODO:)
}
#Chains from the forwarded chain so packets send from the firewall to a different host
##guest network untrusted cant reach Sh*t but safe modus so only dns http https ntp
chain outbound_gasten {
tcp dport {53, 80, 123, 443} accept
udp dport {53, 123} accept
}
##IOT_online really dont know how to get this one safe
chain outbound_iot_online {
accept
}
##Server online all the neccasery ports that own online services use.
chain outbound_server_online {
#only http https ntp dns and i think the minecraft server talks over the 25565 port accept
tcp dport {53, 80, 123, 443 , 25565} accept
udp dport {53, 123, 25565} accept
}
}
am i on the right track? of overthinking it? how would you keep everything save?
the idea is to make a lot of differnt DMZ to keep everything apart to keep things apart that need to be seperated so:
- servers that need to be online inside proxmox can be online
- servers that are local and have special cases:
- ftp rstp only reached by the wifi camera's for the ftp and rstp
- everything that logs like proxmox openwrt websites and minecraft can log inside the logging server for easy acces
- The ftp rstp and logging server only can be reached trough hi ranked devices like a pc.
- the online servers that run services can be reached by the guest network (but by the ddns address and port number)
- everything untrusted blocked.
thanks for reading this, and trying to help me
kind regards,
Elfje4life