Skip to content
Snippets Groups Projects
Unverified Commit be88eba0 authored by Matthias Schiffer's avatar Matthias Schiffer
Browse files

Refactor common parts of gluon-mesh-vpn-fastd into a gluon-mesh-vpn-core package

The fastd_mesh_vpn site.conf section is renamed to mesh_vpn.fastd.
parent 1c9b0ced
No related branches found
No related tags found
No related merge requests found
Showing
with 273 additions and 241 deletions
...@@ -95,48 +95,50 @@ ...@@ -95,48 +95,50 @@
-- }, -- },
-- }, -- },
-- Refer to http://fastd.readthedocs.org/en/latest/ to better understand mesh_vpn = {
-- what these options do. -- Refer to http://fastd.readthedocs.org/en/latest/ to better understand
fastd_mesh_vpn = { -- what these options do.
-- List of crypto-methods to use. fastd = {
methods = {'salsa2012+umac'}, -- List of crypto-methods to use.
-- enabled = true, methods = {'salsa2012+umac'},
-- configurable = true, -- enabled = true,
-- syslog_level = 'warn', -- configurable = true,
-- syslog_level = 'warn',
mtu = 1280,
groups = { mtu = 1280,
backbone = { groups = {
-- Limit number of connected peers to reduce bandwidth. backbone = {
limit = 1, -- Limit number of connected peers to reduce bandwidth.
limit = 1,
-- List of peers.
peers = { -- List of peers.
peer1 = { peers = {
key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', peer1 = {
key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
-- This is a list, so you might add multiple entries.
remotes = {'ipv4 "xxx.somehost.invalid" port xxxxxx'}, -- This is a list, so you might add multiple entries.
remotes = {'ipv4 "xxx.somehost.invalid" port xxxxxx'},
},
peer2 = {
key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
-- You can also omit the ipv4 to allow both connection via ipv4 and ipv6
remotes = {'"xxx.somehost2.invalid" port xxxxx'},
},
}, },
peer2 = {
key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
-- You can also omit the ipv4 to allow both connection via ipv4 and ipv6
remotes = {'"xxx.somehost2.invalid" port xxxxx'},
},
},
-- Optional: nested peer groups -- Optional: nested peer groups
-- groups = { -- groups = {
-- backbone_sub = { -- backbone_sub = {
-- ... -- ...
-- }, -- },
-- ...
-- },
},
-- Optional: additional peer groups, possibly with other limits
-- backbone2 = {
-- ... -- ...
-- }, -- },
}, },
-- Optional: additional peer groups, possibly with other limits
-- backbone2 = {
-- ...
-- },
}, },
bandwidth_limit = { bandwidth_limit = {
......
...@@ -169,14 +169,18 @@ mesh \: optional ...@@ -169,14 +169,18 @@ mesh \: optional
mesh = { mesh = {
batman_adv = { batman_adv = {
gw_sel_class = 1, gw_sel_class = 1,
}, },
} }
fastd_mesh_vpn mesh_vpn
Remote server setup for the fastd-based mesh VPN. Remote server setup for the mesh VPN.
The `enabled` option can be set to true to enable the VPN by default. `mtu`
defines the MTU of the VPN interface.
The `enabled` option can be set to true to enable the VPN by default. The `fastd` section configures settings specific to the *fastd* VPN
implementation.
If `configurable` is set to `false` or unset, the method list will be replaced on updates If `configurable` is set to `false` or unset, the method list will be replaced on updates
with the list from the site configuration. Setting `configurable` to `true` will allow the user to with the list from the site configuration. Setting `configurable` to `true` will allow the user to
...@@ -191,44 +195,47 @@ fastd_mesh_vpn ...@@ -191,44 +195,47 @@ fastd_mesh_vpn
You can set syslog_level from verbose (default) to warn to reduce syslog output. You can set syslog_level from verbose (default) to warn to reduce syslog output.
:: ::
fastd_mesh_vpn = { mesh_vpn = {
methods = {'salsa2012+umac'}, -- enabled = true,
-- enabled = true,
-- configurable = true,
-- syslog_level = 'warn',
mtu = 1280, mtu = 1280,
groups = {
backbone = { fastd = {
-- Limit number of connected peers from this group methods = {'salsa2012+umac'},
limit = 1, -- configurable = true,
peers = { -- syslog_level = 'warn',
peer1 = { groups = {
key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', backbone = {
-- Having multiple domains prevents SPOF in freifunk.net -- Limit number of connected peers from this group
remotes = { limit = 1,
'ipv4 "vpn1.alpha-centauri.freifunk.net" port 10000', peers = {
'ipv4 "vpn1.alpha-centauri-freifunk.de" port 10000', peer1 = {
key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
-- Having multiple domains prevents SPOF in freifunk.net
remotes = {
'ipv4 "vpn1.alpha-centauri.freifunk.net" port 10000',
'ipv4 "vpn1.alpha-centauri-freifunk.de" port 10000',
},
},
peer2 = {
key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
-- You can also omit the ipv4 to allow both connection via ipv4 and ipv6
remotes = {'"vpn2.alpha-centauri.freifunk.net" port 10000'},
}, },
}, },
peer2 = { -- Optional: nested peer groups
key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', -- groups = {
-- You can also omit the ipv4 to allow both connection via ipv4 and ipv6 -- lowend_backbone = {
remotes = {'"vpn2.alpha-centauri.freifunk.net" port 10000'}, -- limit = 1,
}, -- peers = ...
-- },
-- },
}, },
-- Optional: nested peer groups -- Optional: additional peer groups, possibly with other limits
-- groups = { -- peertopeer = {
-- lowend_backbone = { -- limit = 10,
-- limit = 1, -- peers = { ... },
-- peers = ...
-- },
-- }, -- },
}, },
-- Optional: additional peer groups, possibly with other limits
-- peertopeer = {
-- limit = 10,
-- peers = { ... },
-- },
}, },
bandwidth_limit = { bandwidth_limit = {
......
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-mesh-vpn-core
PKG_VERSION:=1
include ../gluon.mk
define Package/gluon-mesh-vpn-core
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Basic support for connecting meshes via VPN tunnels
DEPENDS:=+gluon-core +gluon-wan-dnsmasq +iptables +iptables-mod-extra +simple-tc
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef
define Build/Compile
$(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-mesh-vpn-core/install
$(CP) ./files/* $(1)/
$(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
define Package/gluon-mesh-vpn-core/postinst
#!/bin/sh
$(call GluonCheckSite,check_site.lua)
endef
$(eval $(call BuildPackage,gluon-mesh-vpn-core))
need_boolean('mesh_vpn.enabled', false)
need_number('mesh_vpn.mtu')
if need_table('mesh_vpn.bandwidth_limit', nil, false) then
need_boolean('mesh_vpn.bandwidth_limit.enabled', false)
need_number('mesh_vpn.bandwidth_limit.ingress', false)
need_number('mesh_vpn.bandwidth_limit.egress', false)
end
*nat
-I OUTPUT -m owner --gid-owner gluon-mesh-vpn -o lo -d 127.0.0.1 -p udp --dport 53 -j DNAT --to-destination :54
COMMIT
#!/usr/bin/lua
local site = require 'gluon.site_config'
local users = require 'gluon.users'
local util = require 'gluon.util'
local fs = require 'nixio.fs'
local uci = require('simple-uci').cursor()
uci:section('network', 'interface', 'mesh_vpn', {
ifname = 'mesh-vpn',
proto = 'gluon_mesh',
transitive = true,
fixed_mtu = true,
macaddr = util.generate_mac(7),
mtu = site.mesh_vpn.mtu,
})
uci:save('network')
if fs.access('/etc/config/gluon-simple-tc') then
os.rename('/etc/config/gluon-simple-tc', '/etc/config/simple-tc')
end
if not uci:get('simple-tc', 'mesh_vpn') then
local config = {
ifname = 'mesh-vpn',
enabled = false,
}
if site.mesh_vpn.bandwidth_limit then
if site.mesh_vpn.bandwidth_limit.enabled then
config.enabled = true
end
config.limit_ingress = site.mesh_vpn.bandwidth_limit.ingress
config.limit_egress = site.mesh_vpn.bandwidth_limit.egress
end
uci:section('simple-tc', 'interface', 'mesh_vpn', config)
uci:save('simple-tc')
end
-- The previously used user and group are removed, we now have a generic group
users.remove_user('gluon-fastd')
users.remove_group('gluon-fastd')
users.add_group('gluon-mesh-vpn', 800)
uci:section('firewall', 'include', 'mesh_vpn_dns', {
type = 'restore',
path = '/lib/gluon/mesh-vpn/iptables.rules',
family = 'ipv4',
})
uci:save('firewall')
...@@ -12,8 +12,8 @@ include ../gluon.mk ...@@ -12,8 +12,8 @@ include ../gluon.mk
define Package/gluon-mesh-vpn-fastd define Package/gluon-mesh-vpn-fastd
SECTION:=gluon SECTION:=gluon
CATEGORY:=Gluon CATEGORY:=Gluon
TITLE:=Support for connecting batman-adv meshes via fastd TITLE:=Support for connecting meshes via fastd
DEPENDS:=+gluon-core +libgluonutil +gluon-wan-dnsmasq +fastd +iptables +iptables-mod-extra +simple-tc DEPENDS:=+gluon-core +libgluonutil +gluon-mesh-vpn-core +fastd
endef endef
define Build/Prepare define Build/Prepare
......
local fastd_methods = {'salsa2012+gmac', 'salsa2012+umac', 'null+salsa2012+gmac', 'null+salsa2012+umac', 'null'} local fastd_methods = {'salsa2012+gmac', 'salsa2012+umac', 'null+salsa2012+gmac', 'null+salsa2012+umac', 'null'}
need_array_of('fastd_mesh_vpn.methods', fastd_methods) need_array_of('mesh_vpn.fastd.methods', fastd_methods)
need_number('fastd_mesh_vpn.mtu') need_boolean('mesh_vpn.fastd.configurable', false)
need_boolean('fastd_mesh_vpn.enabled', false)
need_boolean('fastd_mesh_vpn.configurable', false)
need_one_of('fastd_mesh_vpn.syslog_level', {'error', 'warn', 'info', 'verbose', 'debug', 'debug2'}, false) need_one_of('mesh_vpn.fastd.syslog_level', {'error', 'warn', 'info', 'verbose', 'debug', 'debug2'}, false)
local function check_peer(prefix) local function check_peer(prefix)
return function(k, _) return function(k, _)
assert_uci_name(k) assert_uci_name(k)
local table = string.format('%s[%q].', prefix, k) local table = string.format('%s[%q].', prefix, k)
need_string_match(table .. 'key', '^%x+$') need_string_match(table .. 'key', '^%x+$')
need_string_array(table .. 'remotes') need_string_array(table .. 'remotes')
end end
end end
local function check_group(prefix) local function check_group(prefix)
return function(k, _) return function(k, _)
assert_uci_name(k) assert_uci_name(k)
local table = string.format('%s[%q].', prefix, k) local table = string.format('%s[%q].', prefix, k)
need_number(table .. 'limit', false) need_number(table .. 'limit', false)
need_table(table .. 'peers', check_peer(table .. 'peers'), false) need_table(table .. 'peers', check_peer(table .. 'peers'), false)
need_table(table .. 'groups', check_group(table .. 'groups'), false) need_table(table .. 'groups', check_group(table .. 'groups'), false)
end end
end end
need_table('fastd_mesh_vpn.groups', check_group('fastd_mesh_vpn.groups')) need_table('mesh_vpn.fastd.groups', check_group('mesh_vpn.fastd.groups'))
if need_table('fastd_mesh_vpn.bandwidth_limit', nil, false) then
need_boolean('fastd_mesh_vpn.bandwidth_limit.enabled', false)
need_number('fastd_mesh_vpn.bandwidth_limit.ingress', false)
need_number('fastd_mesh_vpn.bandwidth_limit.egress', false)
end
*nat
-I OUTPUT -m owner --gid-owner gluon-fastd -o lo -d 127.0.0.1 -p udp --dport 53 -j DNAT --to-destination :54
COMMIT
#!/usr/bin/lua #!/usr/bin/lua
local site = require 'gluon.site_config' local site = require 'gluon.site_config'
local users = require 'gluon.users'
local util = require 'gluon.util' local util = require 'gluon.util'
local uci = require('simple-uci').cursor() local uci = require('simple-uci').cursor()
-- The previously used user is removed, we need root privileges to use the packet_mark option
users.remove_user('gluon-fastd')
-- Group for iptables rule
users.add_group('gluon-fastd', 800)
local enabled = uci:get('fastd', 'mesh_vpn', 'enabled') local enabled = uci:get('fastd', 'mesh_vpn', 'enabled')
if not enabled then if enabled == nil then
enabled = site.fastd_mesh_vpn.enabled or false enabled = site.mesh_vpn.enabled or false
end end
local syslog_level = uci:get('fastd', 'mesh_vpn', 'syslog_level') or 'verbose' local syslog_level = uci:get('fastd', 'mesh_vpn', 'syslog_level') or 'verbose'
local methods local methods
if site.fastd_mesh_vpn.configurable then if site.mesh_vpn.fastd.configurable then
local has_null = util.contains(site.fastd_mesh_vpn.methods, 'null') local has_null = util.contains(site.mesh_vpn.fastd.methods, 'null')
local old_methods = uci:get('fastd', 'mesh_vpn', 'method') local old_methods = uci:get('fastd', 'mesh_vpn', 'method')
if old_methods then if old_methods then
has_null = util.contains(old_methods, 'null') has_null = util.contains(old_methods, 'null')
end end
methods = {} methods = {}
if has_null then if has_null then
table.insert(methods, 'null') table.insert(methods, 'null')
end end
for _, method in ipairs(site.fastd_mesh_vpn.methods) do for _, method in ipairs(site.mesh_vpn.fastd.methods) do
if method ~= 'null' then if method ~= 'null' then
table.insert(methods, method) table.insert(methods, method)
end end
end end
else else
methods = site.fastd_mesh_vpn.methods methods = site.mesh_vpn.fastd.methods
end end
uci:section('fastd', 'fastd', 'mesh_vpn', uci:section('fastd', 'fastd', 'mesh_vpn', {
{ enabled = enabled,
enabled = enabled, group = 'gluon-mesh-vpn',
group = 'gluon-fastd', syslog_level = syslog_level,
syslog_level = syslog_level, interface = 'mesh-vpn',
interface = 'mesh-vpn', mode = 'tap',
mode = 'tap', mtu = site.mesh_vpn.mtu,
mtu = site.fastd_mesh_vpn.mtu, secure_handshakes = true,
secure_handshakes = true, method = methods,
method = methods, packet_mark = 1,
packet_mark = 1, status_socket = '/var/run/fastd.mesh_vpn.socket',
status_socket = '/var/run/fastd.mesh_vpn.socket', })
}
)
uci:delete('fastd', 'mesh_vpn', 'user') uci:delete('fastd', 'mesh_vpn', 'user')
local add_groups local add_groups
local function add_peer(group, name, config) local function add_peer(group, name, config)
uci:section('fastd', 'peer', group .. '_peer_' .. name, uci:section('fastd', 'peer', group .. '_peer_' .. name, {
{ enabled = true,
enabled = true, net = 'mesh_vpn',
net = 'mesh_vpn', group = group,
group = group, key = config.key,
key = config.key, remote = config.remotes,
remote = config.remotes, })
}
)
end end
local function add_group(name, config, parent) local function add_group(name, config, parent)
uci:delete('fastd', name) uci:delete('fastd', name)
uci:delete_all('fastd', 'peer', uci:delete_all('fastd', 'peer', function(peer)
function(peer) return (peer.net == 'mesh_vpn' and peer.group == name)
return (peer.net == 'mesh_vpn' and peer.group == name) end)
end
)
uci:section('fastd', 'peer_group', name, {
enabled = true,
uci:section('fastd', 'peer_group', name, net = 'mesh_vpn',
{ parent = parent,
enabled = true, peer_limit = config.limit,
net = 'mesh_vpn', })
parent = parent,
peer_limit = config.limit, if config.peers then
} for peername, peerconfig in pairs(config.peers) do
) add_peer(name, peername, peerconfig)
end
if config.peers then end
for peername, peerconfig in pairs(config.peers) do
add_peer(name, peername, peerconfig) add_groups(name, config.groups, name)
end
end
add_groups(name, config.groups, name)
end end
-- declared local above -- declared local above
function add_groups(prefix, groups, parent) function add_groups(prefix, groups, parent)
if groups then if groups then
for name, group in pairs(groups) do for name, group in pairs(groups) do
add_group(prefix .. '_' .. name, group, parent) add_group(prefix .. '_' .. name, group, parent)
end end
end end
end end
add_groups('mesh_vpn', site.fastd_mesh_vpn.groups) add_groups('mesh_vpn', site.mesh_vpn.fastd.groups)
uci:save('fastd') uci:save('fastd')
uci:section('network', 'interface', 'mesh_vpn',
{
ifname = 'mesh-vpn',
proto = 'gluon_mesh',
transitive = true,
fixed_mtu = true,
macaddr = util.generate_mac(7),
}
)
uci:save('network')
uci:section('firewall', 'include', 'mesh_vpn_dns',
{
type = 'restore',
path = '/lib/gluon/mesh-vpn-fastd/iptables.rules',
family = 'ipv4',
}
)
uci:save('firewall')
#!/usr/bin/lua
local site = require 'gluon.site_config'
local uci = require('simple-uci').cursor()
local fs = require 'nixio.fs'
if fs.access('/etc/config/gluon-simple-tc') then
os.rename('/etc/config/gluon-simple-tc', '/etc/config/simple-tc')
end
if not uci:get('simple-tc', 'mesh_vpn') then
local config = {
ifname = 'mesh-vpn',
enabled = false,
}
if site.fastd_mesh_vpn.bandwidth_limit then
if site.fastd_mesh_vpn.bandwidth_limit.enabled then
config.enabled = true
end
config.limit_ingress = site.fastd_mesh_vpn.bandwidth_limit.ingress
config.limit_egress = site.fastd_mesh_vpn.bandwidth_limit.egress
end
uci:section('simple-tc', 'interface', 'mesh_vpn', config)
uci:save('simple-tc')
end
assert(need_boolean('fastd_mesh_vpn.configurable') == true, assert(need_boolean('mesh_vpn.fastd.configurable') == true,
"site.conf error: expected `fastd_mesh_vpn.configurable' to be true") "site.conf error: expected `mesh_vpn.fastd.configurable' to be true")
...@@ -23,7 +23,7 @@ function mode:write(data) ...@@ -23,7 +23,7 @@ function mode:write(data)
table.insert(methods, 'null') table.insert(methods, 'null')
end end
for _, method in ipairs(site.fastd_mesh_vpn.methods) do for _, method in ipairs(site.mesh_vpn.fastd.methods) do
if method ~= 'null' then if method ~= 'null' then
table.insert(methods, method) table.insert(methods, method)
end end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment