148 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Lua
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Lua
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/lua
 | 
						|
 | 
						|
local site = require 'gluon.site'
 | 
						|
local util = require 'gluon.util'
 | 
						|
local vpn_core = require 'gluon.mesh-vpn'
 | 
						|
 | 
						|
local uci = require('simple-uci').cursor()
 | 
						|
local unistd = require 'posix.unistd'
 | 
						|
 | 
						|
 | 
						|
local syslog_level = uci:get('fastd', 'mesh_vpn', 'syslog_level') or 'verbose'
 | 
						|
 | 
						|
local secret = uci:get('fastd', 'mesh_vpn', 'secret')
 | 
						|
if not secret or not secret:match(('%x'):rep(64)) then
 | 
						|
	secret = 'generate'
 | 
						|
end
 | 
						|
 | 
						|
local methods
 | 
						|
 | 
						|
if site.mesh_vpn.fastd.configurable(false) then
 | 
						|
	local site_methods = site.mesh_vpn.fastd.methods()
 | 
						|
	local has_null = util.contains(site_methods, 'null@l2tp') or util.contains(site_methods, 'null')
 | 
						|
 | 
						|
	local old_methods = uci:get('fastd', 'mesh_vpn', 'method')
 | 
						|
	if old_methods then
 | 
						|
		has_null = util.contains(old_methods, 'null@l2tp') or util.contains(old_methods, 'null')
 | 
						|
	end
 | 
						|
 | 
						|
	methods = {}
 | 
						|
	if has_null then
 | 
						|
		table.insert(methods, 'null@l2tp')
 | 
						|
		table.insert(methods, 'null')
 | 
						|
	end
 | 
						|
 | 
						|
	for _, method in ipairs(site_methods) do
 | 
						|
		if method ~= 'null@l2tp' and method ~= 'null' then
 | 
						|
			table.insert(methods, method)
 | 
						|
		end
 | 
						|
	end
 | 
						|
 | 
						|
else
 | 
						|
	methods = site.mesh_vpn.fastd.methods()
 | 
						|
end
 | 
						|
 | 
						|
 | 
						|
uci:section('fastd', 'fastd', 'mesh_vpn', {
 | 
						|
	group = 'gluon-mesh-vpn',
 | 
						|
	syslog_level = syslog_level,
 | 
						|
	secret = secret,
 | 
						|
	interface = vpn_core.get_interface(),
 | 
						|
	mode = 'tap',
 | 
						|
	mtu = site.mesh_vpn.mtu(),
 | 
						|
	secure_handshakes = true,
 | 
						|
	method = methods,
 | 
						|
	packet_mark = 1,
 | 
						|
	persist_interface = true,
 | 
						|
	offload_l2tp = false,
 | 
						|
	status_socket = '/var/run/fastd.mesh_vpn.socket',
 | 
						|
})
 | 
						|
uci:delete('fastd', 'mesh_vpn', 'peer_limit')
 | 
						|
 | 
						|
-- L2TP offload support
 | 
						|
if unistd.access('/lib/gluon/mesh-vpn/fastd/l2tp') then
 | 
						|
	uci:set('fastd', 'mesh_vpn', 'mode', 'multitap')
 | 
						|
	uci:set('fastd', 'mesh_vpn', 'persist_interface', false)
 | 
						|
	uci:set('fastd', 'mesh_vpn', 'offload_l2tp', true)
 | 
						|
	uci:set('fastd', 'mesh_vpn', 'peer_limit', 1)
 | 
						|
end
 | 
						|
 | 
						|
-- Collect list of groups that have peers with 'preserve' flag
 | 
						|
local preserve_groups = {}
 | 
						|
 | 
						|
local function preserve_group(name)
 | 
						|
	if not name or preserve_groups[name] then
 | 
						|
		return
 | 
						|
	end
 | 
						|
	preserve_groups[name] = true
 | 
						|
 | 
						|
	local parent = uci:get('fastd', name, 'group')
 | 
						|
	preserve_group(parent)
 | 
						|
end
 | 
						|
 | 
						|
uci:foreach('fastd', 'peer', function(peer)
 | 
						|
	if peer.net == 'mesh_vpn' and peer.preserve == '1' then
 | 
						|
		preserve_group(peer.group)
 | 
						|
	end
 | 
						|
end)
 | 
						|
 | 
						|
 | 
						|
-- Clean up previous configuration
 | 
						|
uci:delete_all('fastd', 'peer', function(peer)
 | 
						|
	return (peer.net == 'mesh_vpn' and peer.preserve ~= '1')
 | 
						|
end)
 | 
						|
uci:delete_all('fastd', 'peer_group', function(group)
 | 
						|
	return (group.net == 'mesh_vpn' and not preserve_groups[group['.name']])
 | 
						|
end)
 | 
						|
 | 
						|
 | 
						|
local add_groups
 | 
						|
 | 
						|
local function add_peer(group, name, config)
 | 
						|
	local uci_name = group .. '_peer_' .. name
 | 
						|
	if uci:get_bool('fastd', uci_name, 'preserve') then
 | 
						|
		return
 | 
						|
	end
 | 
						|
	uci:section('fastd', 'peer', uci_name, {
 | 
						|
		enabled = true,
 | 
						|
		net = 'mesh_vpn',
 | 
						|
		group = group,
 | 
						|
		interface = 'mesh-vpn',
 | 
						|
		key = config.key,
 | 
						|
		remote = config.remotes,
 | 
						|
	})
 | 
						|
end
 | 
						|
 | 
						|
local function add_group(name, config, parent)
 | 
						|
	uci:section('fastd', 'peer_group', name, {
 | 
						|
		enabled = true,
 | 
						|
		net = 'mesh_vpn',
 | 
						|
		parent = parent,
 | 
						|
		peer_limit = config.limit,
 | 
						|
	})
 | 
						|
 | 
						|
	for peername, peerconfig in pairs(config.peers or {}) do
 | 
						|
		add_peer(name, peername, peerconfig)
 | 
						|
	end
 | 
						|
 | 
						|
	add_groups(name, config.groups, name)
 | 
						|
end
 | 
						|
 | 
						|
-- declared local above
 | 
						|
function add_groups(prefix, groups, parent)
 | 
						|
	for name, group in pairs(groups or {}) do
 | 
						|
		add_group(prefix .. '_' .. name, group, parent)
 | 
						|
	end
 | 
						|
end
 | 
						|
 | 
						|
add_groups('mesh_vpn', site.mesh_vpn.fastd.groups())
 | 
						|
 | 
						|
-- Update preserved peers as well
 | 
						|
uci:foreach('fastd', 'peer', function(peer)
 | 
						|
	if peer.net == 'mesh_vpn' then
 | 
						|
		uci:set('fastd', peer['.name'], 'interface', 'mesh-vpn')
 | 
						|
	end
 | 
						|
end)
 | 
						|
 | 
						|
uci:save('fastd')
 |