Browse Source

gluon-core: firewall rework, make base policy more restrictive

 * gluon-core, gluon-client-bridge: introduce new firewall zone: local_client
 * gluon-core: put clients in local_client zone, introduce drop-zone,
   set dns-rules and zones
 * gluon-respondd: allow respondd on mesh
 * gluon-status-page-api: allow http input on mesh and client
Christof Schulze 7 years ago
parent
commit
1c1c9f8fc7

+ 17 - 5
package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network

@@ -40,17 +40,25 @@ uci:section('network', 'interface', 'client', {
 
 uci:save('network')
 
-
+-- TODO: remove this line and the next in 2019. Firewall zones have been renamed in 2017.
 uci:delete('firewall', 'client')
-uci:section('firewall', 'zone', 'client', {
-	name = 'client',
+
+uci:section('firewall', 'zone', 'drop', {
+	name = 'drop',
 	network = {'client'},
 	input = 'DROP',
 	output = 'DROP',
 	forward = 'DROP',
 })
 
-uci:save('firewall')
+uci:section('firewall', 'zone', 'local_client', {
+	name = 'local_client',
+	network = {'local_node'},
+	input = 'REJECT',
+	output = 'ACCEPT',
+	forward = 'REJECT',
+})
+
 
 
 local dnsmasq = uci:get_first('dhcp', 'dnsmasq')
@@ -58,13 +66,17 @@ uci:set('dhcp', dnsmasq, 'boguspriv', false)
 uci:set('dhcp', dnsmasq, 'localise_queries', false)
 uci:set('dhcp', dnsmasq, 'rebind_protection', false)
 
+-- TODO: remove this line and the next two in 2019 the zones were removed in 2017
 uci:delete('dhcp', 'client')
-uci:section('dhcp', 'dhcp', 'client', {
+uci:delete('firewall', 'local_node')
+
+uci:section('dhcp', 'dhcp', 'local_client', {
 	interface = 'client',
 	ignore = true,
 })
 
 uci:save('dhcp')
+uci:save('firewall')
 
 
 sysctl.set('net.ipv6.conf.br-client.forwarding', 0)

+ 42 - 6
package/gluon-core/luasrc/lib/gluon/upgrade/140-firewall-rules

@@ -11,14 +11,50 @@ local function reject_input_on_wan(zone)
 
 	return true
 end
+
 uci:foreach('firewall', 'zone', reject_input_on_wan)
 
-uci:section('firewall', 'rule', 'wan_ssh', {
-	name = 'wan_ssh',
-	src = 'wan',
-	dest_port = '22',
-	proto = 'tcp',
-	target = 'ACCEPT',
+-- the client zone is set up by gluon-client-bridge
+--
+uci:section('firewall', 'zone', 'mesh', {
+	name = 'mesh',
+	network = {},
+	input = 'REJECT',
+	output = 'ACCEPT',
+	forward = 'REJECT',
 })
 
+-- allow inbound ssh from anywhere
+for _, zone in ipairs({ 'wan', 'local_client', 'mesh' }) do
+	uci:section('firewall', 'rule', zone .. '_ssh', {
+		name =  zone .. '_ssh',
+		src = zone,
+		dest_port = '22',
+		proto = 'tcp',
+		target = 'ACCEPT',
+	})
+end
+
+
+-- allow icmp in/out/forward on all relevant zones
+for _, zone in ipairs ({ 'mesh', 'local_client' } ) do
+	uci:section('firewall', 'rule',  zone .. '_ICMPv6_in', {
+		src = zone,
+		proto = 'icmp',
+		icmp_type = {'echo-request', 'echo-reply', 'destination-unreachable', 'packet-too-big', 'time-exceeded', 'bad-header', 'unknown-header-type', 'router-solicitation', 'neighbour-solicitation', 'router-advertisement', 'neighbour-advertisement', },
+		limit = '1000/sec',
+		family = 'ipv6',
+		target = 'ACCEPT',
+	})
+
+	uci:section('firewall', 'rule', zone .. '_ICMPv6_out', {
+		dest = zone,
+		proto = 'icmp',
+		icmp_type = {'echo-request', 'echo-reply', 'destination-unreachable', 'packet-too-big', 'time-exceeded', 'bad-header', 'unknown-header-type', 'router-solicitation', 'neighbour-solicitation', 'router-advertisement', 'neighbour-advertisement' },
+		limit = '1000/sec',
+		family = 'ipv6',
+		target = 'ACCEPT',
+	})
+end
+
 uci:save('firewall')

+ 12 - 0
package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config

@@ -14,6 +14,17 @@ uci:set('dhcp', dnsmasq, 'localservice', false)
 uci:set('dhcp', dnsmasq, 'server', dns.servers)
 uci:set('dhcp', dnsmasq, 'cachesize', dns.cacheentries)
 
+uci:delete('firewall', 'client_dns')
+if dns.servers then
+	-- allow inbound traffic for dns from client zone
+	uci:section('firewall', 'rule', 'client_dns', {
+		src = 'local_client',
+		dest_port = '53',
+		proto = 'tcpudp',
+		target = 'ACCEPT',
+	})
+end
+
 if next_node.name and next_node.ip4 then
 	uci:section('dhcp', 'domain', 'nextnode4', {
 		name = next_node.name,
@@ -33,3 +44,4 @@ else
 end
 
 uci:save('dhcp')
+uci:save('firewall')

+ 12 - 0
package/gluon-l3roamd/luasrc/lib/gluon/upgrade/150-firewall-l3roamd

@@ -0,0 +1,12 @@
+#!/usr/bin/lua
+local uci = require('simple-uci').cursor()
+
+uci:section('firewall', 'rule',  'mesh_l3roamd', {
+	name = 'mesh_l3roamd',
+	src = 'mesh',
+	dest_port = '5523',
+	proto = 'udp',
+	target = 'ACCEPT',
+})
+
+uci:save('firewall')

+ 7 - 22
package/gluon-mesh-batman-adv/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-client-bridge

@@ -7,7 +7,7 @@
 local site = require 'gluon.site'
 local sysconfig = require 'gluon.sysconfig'
 local sysctl = require 'gluon.sysctl'
-
+local util = require 'gluon.util'
 local uci = require('simple-uci').cursor()
 
 
@@ -34,28 +34,13 @@ uci:section('network', 'route6', 'local_node_route6', {
 
 uci:save('network')
 
+local networks = uci:get_list('firewall', 'mesh', 'network')
+util.add_to_set(networks, 'client')
+uci:set_list('firewall', 'mesh', 'network', networks)
 
-uci:section('firewall', 'zone', 'client', {
-	input = 'ACCEPT',
-	output = 'ACCEPT',
-	forward = 'REJECT',
-})
-
-uci:section('firewall', 'rule', 'client_dns', {
-	name = 'client_dns',
-	src = 'client',
-	dest_port = '53',
-	target = 'REJECT',
-})
-
-uci:delete('firewall', 'local_node')
-uci:section('firewall', 'zone', 'local_node', {
-	name = 'local_node',
-	network = {'local_node'},
-	input = 'ACCEPT',
-	output = 'ACCEPT',
-	forward = 'REJECT',
-})
+local networks = uci:get_list('firewall', 'drop', 'network')
+util.remove_from_set(networks, 'client')
+uci:set_list('firewall', 'drop', 'network', networks)
 
 uci:delete('firewall', 'local_node_dns')
 

+ 25 - 20
package/gluon-respondd/luasrc/lib/gluon/upgrade/400-respondd-firewall

@@ -5,27 +5,32 @@ local uci = require('simple-uci').cursor()
 uci:delete('firewall', 'wan_announced')
 
 -- Allow respondd port on WAN to allow resolving neighbours over mesh-on-wan
-uci:section('firewall', 'rule', 'wan_respondd',
-  {
-    name = 'wan_respondd',
-    src = 'wan',
-    src_ip = 'fe80::/64',
-    dest_port = '1001',
-    proto = 'udp',
-    target = 'ACCEPT',
-  }
-)
+uci:section('firewall', 'rule', 'wan_respondd', {
+	name = 'wan_respondd',
+	src = 'wan',
+	src_ip = 'fe80::/64',
+	dest_port = '1001',
+	proto = 'udp',
+	target = 'ACCEPT',
+})
 
 -- Restrict respondd queries to link-local addresses to prevent amplification attacks from outside
-uci:section('firewall', 'rule', 'client_respondd',
-  {
-    name = 'client_respondd',
-    src = 'client',
-    src_ip = '!fe80::/64',
-    dest_port = '1001',
-    proto = 'udp',
-    target = 'REJECT',
-  }
-)
+uci:section('firewall', 'rule', 'client_respondd', {
+	name = 'client_respondd',
+	src = 'client_local',
+	src_ip = 'fe80::/64',
+	dest_port = '1001',
+	proto = 'udp',
+	target = 'ACCEPT',
+})
+
+uci:section('firewall', 'rule',  'mesh_respondd_ll', {
+	name = 'mesh_respondd_ll',
+	src = 'mesh',
+	src_ip = 'fe80::/64',
+	dest_port = '1001',
+	proto = 'udp',
+	target = 'ACCEPT',
+})
 
 uci:save('firewall')

+ 12 - 0
package/gluon-status-page-api/luasrc/lib/gluon/upgrade/981-firewall-status-page

@@ -0,0 +1,12 @@
+#!/usr/bin/lua
+local uci = require('simple-uci').cursor()
+
+for _, zone in ipairs({'mesh', 'local_client'}) do
+	uci:section('firewall', 'rule', zone .. '_http', {
+		src = zone,
+		dest_port = '80',
+		proto = 'tcp',
+		target = 'ACCEPT',
+	})
+end
+uci:save('firewall')