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
This commit is contained in:
Christof Schulze 2017-06-14 19:40:08 +02:00 committed by Matthias Schiffer
parent 7351fb5d4a
commit 1c1c9f8fc7
No known key found for this signature in database
GPG Key ID: 16EF3F64CB201D9C
7 changed files with 127 additions and 53 deletions

View File

@ -40,17 +40,25 @@ uci:section('network', 'interface', 'client', {
uci:save('network') uci:save('network')
-- TODO: remove this line and the next in 2019. Firewall zones have been renamed in 2017.
uci:delete('firewall', 'client') uci:delete('firewall', 'client')
uci:section('firewall', 'zone', 'client', {
name = 'client', uci:section('firewall', 'zone', 'drop', {
name = 'drop',
network = {'client'}, network = {'client'},
input = 'DROP', input = 'DROP',
output = 'DROP', output = 'DROP',
forward = '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') 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, 'localise_queries', false)
uci:set('dhcp', dnsmasq, 'rebind_protection', 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:delete('dhcp', 'client')
uci:section('dhcp', 'dhcp', 'client', { uci:delete('firewall', 'local_node')
uci:section('dhcp', 'dhcp', 'local_client', {
interface = 'client', interface = 'client',
ignore = true, ignore = true,
}) })
uci:save('dhcp') uci:save('dhcp')
uci:save('firewall')
sysctl.set('net.ipv6.conf.br-client.forwarding', 0) sysctl.set('net.ipv6.conf.br-client.forwarding', 0)

View File

@ -11,14 +11,50 @@ local function reject_input_on_wan(zone)
return true return true
end end
uci:foreach('firewall', 'zone', reject_input_on_wan) uci:foreach('firewall', 'zone', reject_input_on_wan)
uci:section('firewall', 'rule', 'wan_ssh', { -- the client zone is set up by gluon-client-bridge
name = 'wan_ssh', --
src = 'wan', 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', dest_port = '22',
proto = 'tcp', proto = 'tcp',
target = 'ACCEPT', 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') uci:save('firewall')

View File

@ -14,6 +14,17 @@ uci:set('dhcp', dnsmasq, 'localservice', false)
uci:set('dhcp', dnsmasq, 'server', dns.servers) uci:set('dhcp', dnsmasq, 'server', dns.servers)
uci:set('dhcp', dnsmasq, 'cachesize', dns.cacheentries) 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 if next_node.name and next_node.ip4 then
uci:section('dhcp', 'domain', 'nextnode4', { uci:section('dhcp', 'domain', 'nextnode4', {
name = next_node.name, name = next_node.name,
@ -33,3 +44,4 @@ else
end end
uci:save('dhcp') uci:save('dhcp')
uci:save('firewall')

View File

@ -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')

View File

@ -7,7 +7,7 @@
local site = require 'gluon.site' local site = require 'gluon.site'
local sysconfig = require 'gluon.sysconfig' local sysconfig = require 'gluon.sysconfig'
local sysctl = require 'gluon.sysctl' local sysctl = require 'gluon.sysctl'
local util = require 'gluon.util'
local uci = require('simple-uci').cursor() local uci = require('simple-uci').cursor()
@ -34,28 +34,13 @@ uci:section('network', 'route6', 'local_node_route6', {
uci:save('network') 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', { local networks = uci:get_list('firewall', 'drop', 'network')
input = 'ACCEPT', util.remove_from_set(networks, 'client')
output = 'ACCEPT', uci:set_list('firewall', 'drop', 'network', networks)
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',
})
uci:delete('firewall', 'local_node_dns') uci:delete('firewall', 'local_node_dns')

View File

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

View File

@ -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')