Skip to content

Commit

Permalink
mesh-vpn: fully abstract VPN methods
Browse files Browse the repository at this point in the history
This fully abstracts VPN methods, making gluon-mesh-vpn-fastd and
gluon-mesh-vpn-tunneldigger completely self-contained.

Provide a LUA interface for generic interacting with VPN methods in
gluon-mesh-vpn-core and web packages.

This also adds the ability to install tunneldigger and fastd to the same
image, selecting the VPN method based on the selected domain.
  • Loading branch information
blocktrron committed May 11, 2021
1 parent 0ac3061 commit e4b5414
Show file tree
Hide file tree
Showing 12 changed files with 155 additions and 69 deletions.
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
local site_i18n = i18n 'gluon-site'

local uci = require("simple-uci").cursor()
local unistd = require 'posix.unistd'

local platform = require 'gluon.platform'
local site = require 'gluon.site'
local sysconfig = require 'gluon.sysconfig'
local util = require "gluon.util"
local vpn = require 'gluon.mesh-vpn'

local pretty_hostname = require 'pretty_hostname'


local has_fastd = unistd.access('/lib/gluon/mesh-vpn/fastd')
local has_tunneldigger = unistd.access('/lib/gluon/mesh-vpn/tunneldigger')


local hostname = pretty_hostname.get(uci)
local contact = uci:get_first("gluon-node-info", "owner", "contact")

local pubkey
local msg


if has_tunneldigger then
local tunneldigger_enabled = uci:get_bool("tunneldigger", "mesh_vpn", "enabled")
if not tunneldigger_enabled then
msg = site_i18n._translate('gluon-config-mode:novpn')
end
elseif has_fastd then
local fastd_enabled = uci:get_bool("fastd", "mesh_vpn", "enabled")
if fastd_enabled then
pubkey = util.trim(util.exec("/etc/init.d/fastd show_key mesh_vpn"))
if vpn.enabled() then
local _, active_vpn = vpn.get_active_proto()
pubkey = active_vpn.public_key()

if pubkey ~= nil then
msg = site_i18n._translate('gluon-config-mode:pubkey')
else
msg = site_i18n._translate('gluon-config-mode:novpn')
end
else
msg = site_i18n._translate('gluon-config-mode:novpn')
end

if not msg then return end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
local unistd = require 'posix.unistd'

local has_fastd = unistd.access('/lib/gluon/mesh-vpn/fastd')
local has_tunneldigger = unistd.access('/lib/gluon/mesh-vpn/tunneldigger')
local vpn = require 'gluon.mesh-vpn'
local _, active_vpn = vpn.get_active_proto()

return function(form, uci)
if not (has_fastd or has_tunneldigger) then
if active_vpn == nil then
return
end

Expand Down Expand Up @@ -64,5 +62,11 @@ return function(form, uci)
os.execute('exec /lib/gluon/mesh-vpn/update-config')
end

return {'gluon', 'fastd', 'tunneldigger', 'simple-tc'}
local uci_sections = {'gluon'}

for _, section in ipairs(active_vpn.uci_sections()) do
table.insert(uci_sections, section)
end

return uci_sections
end
41 changes: 11 additions & 30 deletions package/gluon-mesh-vpn-core/luasrc/lib/gluon/mesh-vpn/update-config
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
#!/usr/bin/lua

local uci = require('simple-uci').cursor()
local unistd = require 'posix.unistd'

local vpn
if unistd.access('/lib/gluon/mesh-vpn/fastd') then
vpn = 'fastd'
elseif unistd.access('/lib/gluon/mesh-vpn/tunneldigger') then
vpn = 'tunneldigger'
end
local vpn_name, vpn = require('gluon.mesh-vpn').get_active_proto()

local vpn_config = {
enabled = uci:get_bool('gluon', 'mesh_vpn', 'enabled'),
Expand All @@ -17,32 +10,20 @@ local vpn_config = {
limit_ingress = uci:get('gluon', 'mesh_vpn', 'limit_ingress'),
}

uci:delete('simple-tc', 'mesh_vpn')
uci:section('simple-tc', 'interface', 'mesh_vpn', {
ifname = 'mesh-vpn',
enabled = vpn_config.limit_enabled,
limit_egress = vpn_config.limit_egress,
})

if vpn == 'fastd' then
uci:set('fastd', 'mesh_vpn', 'enabled', vpn_config.enabled)
uci:set('simple-tc', 'mesh_vpn', 'limit_ingress', vpn_config.limit_ingress)
else
if vpn_name ~= 'fastd' then
uci:set('fastd', 'mesh_vpn', 'enabled', false)
uci:save('fastd')
end
uci:save('fastd')

if vpn == 'tunneldigger' then
uci:set('tunneldigger', 'mesh_vpn', 'enabled', vpn_config.enabled)
if vpn_name ~= 'tunneldigger' then
uci:set('tunneldigger', 'mesh_vpn', 'enabled', false)
uci:save('tunneldigger')
end

if vpn_config.limit_enabled then
uci:set('tunneldigger', 'mesh_vpn', 'limit_bw_down', vpn_config.limit_ingress)
else
uci:delete('tunneldigger', 'mesh_vpn', 'limit_bw_down')
end
vpn.enable(vpn_config.enabled)
if vpn_config.limit_enabled then
vpn.set_limit(vpn_config.limit_ingress, vpn_config.limit_egress)
else
uci:set('tunneldigger', 'mesh_vpn', 'enabled', false)
vpn.set_limit(nil, nil)
end
uci:save('tunneldigger')

uci:save('simple-tc')
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ local users = require 'gluon.users'
local util = require 'gluon.util'

local uci = require('simple-uci').cursor()
local unistd = require 'posix.unistd'

local vpn_core = require 'gluon.mesh-vpn'

uci:section('network', 'interface', 'mesh_vpn', {
ifname = 'mesh-vpn',
ifname = vpn_core.get_interface(),
proto = 'gluon_mesh',
transitive = true,
fixed_mtu = true,
Expand All @@ -35,12 +35,7 @@ uci:save('firewall')

-- VPN migration
if not uci:get('gluon', 'mesh_vpn') then
local vpn
if unistd.access('/lib/gluon/mesh-vpn/fastd') then
vpn = 'fastd'
elseif unistd.access('/lib/gluon/mesh-vpn/tunneldigger') then
vpn = 'tunneldigger'
end
local vpn, _ = vpn_core.get_active_proto()

local fastd_enabled = uci:get('fastd', 'mesh_vpn', 'enabled')
local tunneldigger_enabled = uci:get('tunneldigger', 'mesh_vpn', 'enabled')
Expand Down
44 changes: 42 additions & 2 deletions package/gluon-mesh-vpn-core/luasrc/usr/lib/lua/gluon/mesh-vpn.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,47 @@
local uci = require('simple-uci').cursor()

local util = require 'gluon.util'

local M = {}

function M.get_mesh_vpn_interface()
return 'mesh-vpn'
function M.enabled()
return uci:get_bool('gluon', 'mesh_vpn', 'enabled')
end

function M.enable(val)
return uci:set('gluon', 'mesh_vpn', 'enabled', val)
end

function M.get_interface()
return 'mesh-vpn'
end

function M.get_proto(name)
return require('gluon.mesh-vpn.proto.' .. name)
end

function M.get_proto_names()
local out = {}

for _, v in ipairs(util.glob('/lib/gluon/mesh-vpn/proto/*')) do
table.insert(out, v:match('([^/]+)$'))
end

return out
end

function M.get_active_proto()
-- Active proto is the proto in use by the currently
-- active site / domain

for _, name in ipairs(M.get_proto_names()) do
local proto = M.get_proto(name)
if proto.active() then
return name, proto
end
end

return nil, nil
end

return M
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

local site = require 'gluon.site'
local util = require 'gluon.util'
local vpn_core = require 'gluon.mesh-vpn'

local uci = require('simple-uci').cursor()

Expand Down Expand Up @@ -37,7 +38,7 @@ end
uci:section('fastd', 'fastd', 'mesh_vpn', {
group = 'gluon-mesh-vpn',
syslog_level = syslog_level,
interface = 'mesh-vpn',
interface = vpn_core.get_interface(),
mode = 'tap',
mtu = site.mesh_vpn.mtu(),
secure_handshakes = true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
local uci = require('simple-uci').cursor()

local site = require 'gluon.site'
local util = require 'gluon.util'
local vpn_core = require 'gluon.mesh-vpn'

local M = {}

function M.public_key()
return util.trim(util.exec('/etc/init.d/fastd show_key mesh_vpn'))
end

function M.enable(val)
uci:set('fastd', 'mesh_vpn', 'enabled', val)
uci:save('fastd')
end

function M.active()
return site.mesh_vpn.fastd() ~= nil
end

function M.set_limit(ingress_limit, egress_limit)
uci:delete('simple-tc', 'mesh_vpn')
if ingress_limit ~= nil and egress_limit ~= nil then
uci:section('simple-tc', 'interface', 'mesh_vpn', {
ifname = vpn_core.get_interface(),
enabled = 1,
limit_egress = egress_limit,
limit_ingress = ingress_limit,
})
end

uci:save('simple-tc')
end

function M.uci_sections()
return {'fastd', 'simple-tc'}
end

return M
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

local site = require 'gluon.site'
local util = require 'gluon.util'
local vpn_core = require 'gluon.mesh-vpn'

local uci = require('simple-uci').cursor()

Expand All @@ -23,7 +24,7 @@ end
uci:section('tunneldigger', 'broker', 'mesh_vpn', {
enabled = enabled,
uuid = util.node_id(),
interface = 'mesh-vpn',
interface = vpn_core.get_interface(),
bind_interface = 'br-wan',
group = 'gluon-mesh-vpn',
broker_selection = 'usage',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
local uci = require('simple-uci').cursor()

local site = require 'gluon.site'

local M = {}

function M.public_key()
return nil
end

function M.enable(val)
uci:set('tunneldigger', 'mesh_vpn', 'enabled', val)
uci:save('tunneldigger')
end

function M.active()
return site.mesh_vpn.tunneldigger() ~= nil
end

function M.set_limit(ingress_limit, _)
if ingress_limit ~= nil then
uci:set('tunneldigger', 'mesh_vpn', 'limit_bw_down', ingress_limit)
else
uci:delete('tunneldigger', 'mesh_vpn', 'limit_bw_down')
end
uci:save('tunneldigger')
end

function M.uci_sections()
return {'tunneldigger'}
end

return M
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
local sysconfig = require 'gluon.sysconfig'
local platform = require 'gluon.platform'
local util = require "gluon.util"
local has_vpn, vpn = pcall(require, 'gluon.mesh-vpn')

local _ = translate


local pubkey
local meshvpn_enabled = uci:get_bool("fastd", "mesh_vpn", "enabled")
if meshvpn_enabled then
pubkey = util.trim(util.exec('/etc/init.d/fastd show_key mesh_vpn'))
if has_vpn and vpn.enabled() then
local _, active_vpn = vpn.get_active_proto()
pubkey = active_vpn.public_key()
if pubkey == '' then
pubkey = nil
end
Expand Down

0 comments on commit e4b5414

Please # to comment.