gluon-nftables: init
This commit is contained in:
parent
4318048aed
commit
40b1f1b1e2
16
package/gluon-nftables/Makefile
Normal file
16
package/gluon-nftables/Makefile
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
|
PKG_NAME:=gluon-nftables
|
||||||
|
|
||||||
|
include ../gluon.mk
|
||||||
|
|
||||||
|
define Package/gluon-nftables
|
||||||
|
TITLE:=Nftables support
|
||||||
|
DEPENDS:=+nftables-json
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/gluon-nftables/description
|
||||||
|
Gluon community wifi mesh firmware framework: Nftables support
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(eval $(call BuildPackageGluon,gluon-nftables))
|
188
package/gluon-nftables/luasrc/lib/gluon/upgrade/300-nftables
Executable file
188
package/gluon-nftables/luasrc/lib/gluon/upgrade/300-nftables
Executable file
@ -0,0 +1,188 @@
|
|||||||
|
#!/usr/bin/lua
|
||||||
|
|
||||||
|
local uci = require('simple-uci').cursor()
|
||||||
|
local glob = require 'posix.glob'
|
||||||
|
|
||||||
|
-- Library
|
||||||
|
|
||||||
|
function string.starts(string, start)
|
||||||
|
return string.sub(string, 1, string.len(start)) == start
|
||||||
|
end
|
||||||
|
|
||||||
|
function basepath(str)
|
||||||
|
return str:match("([^./\\]+).lua")
|
||||||
|
end
|
||||||
|
|
||||||
|
function write_all_lines(table, file, close)
|
||||||
|
for _, line in ipairs(table) do
|
||||||
|
file:write(line .. '\n')
|
||||||
|
end
|
||||||
|
|
||||||
|
if close then
|
||||||
|
file:write('}\n')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function read_include(file)
|
||||||
|
local f = assert(io.open(path(file), "rb"))
|
||||||
|
local content = f:read("*all")
|
||||||
|
f:close()
|
||||||
|
return content
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Functions
|
||||||
|
|
||||||
|
function path(name)
|
||||||
|
return '/lib/gluon/nftables/' .. name .. '.nft'
|
||||||
|
end
|
||||||
|
|
||||||
|
function include(name, parameters)
|
||||||
|
local boilerplate = {
|
||||||
|
type = 'nftables',
|
||||||
|
path = path(name),
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v in pairs(parameters) do
|
||||||
|
boilerplate[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
|
uci:section('firewall', 'include', 'gluon_nftables_' .. name, boilerplate)
|
||||||
|
end
|
||||||
|
|
||||||
|
function rule(name, chain, content)
|
||||||
|
local file = io.open(path(name), 'w')
|
||||||
|
file:write(content + '\n')
|
||||||
|
file:close()
|
||||||
|
|
||||||
|
include(name, {
|
||||||
|
position = 'chain-post',
|
||||||
|
chain = chain,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local bridge = {
|
||||||
|
chain = {
|
||||||
|
INPUT = {
|
||||||
|
'chain input {',
|
||||||
|
'type filter hook input priority filter; policy accept;',
|
||||||
|
},
|
||||||
|
FORWARD = {
|
||||||
|
'chain forward {',
|
||||||
|
'type filter hook forward priority filter; policy accept;',
|
||||||
|
},
|
||||||
|
OUTPUT = {
|
||||||
|
'chain output {',
|
||||||
|
'type filter hook output priority filter; policy accept;',
|
||||||
|
},
|
||||||
|
PREROUTING = {
|
||||||
|
'chain prerouting {',
|
||||||
|
'type filter hook prerouting priority dstnat; policy accept;',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
table = {
|
||||||
|
pre = {
|
||||||
|
'table bridge gluon',
|
||||||
|
'flush table bridge gluon',
|
||||||
|
'table bridge gluon {',
|
||||||
|
},
|
||||||
|
post = {
|
||||||
|
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function bridge_rule(chain, content)
|
||||||
|
if bridge.chain[chain] == nil then
|
||||||
|
error('No bridge chain ' .. chain)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(bridge.chain[chain], content)
|
||||||
|
end
|
||||||
|
|
||||||
|
function bridge_table(position, content)
|
||||||
|
if bridge.table[position] == nil then
|
||||||
|
error('No bridge position ' .. position)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(bridge.table[position], content)
|
||||||
|
end
|
||||||
|
|
||||||
|
function bridge_chain(name)
|
||||||
|
if bridge.chain[name] ~= nil then
|
||||||
|
error('Chain already exists ' .. name)
|
||||||
|
end
|
||||||
|
|
||||||
|
bridge.chain[name] = {
|
||||||
|
'chain ' .. name:lower() .. ' {'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
function bridge_include_rule(chain, file)
|
||||||
|
if bridge.chain[chain] == nil then
|
||||||
|
error('No bridge chain ' .. chain)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(bridge.chain[chain], read_include(file))
|
||||||
|
end
|
||||||
|
|
||||||
|
function bridge_include_table(position, file)
|
||||||
|
if bridge.table[position] == nil then
|
||||||
|
error('No bridge position ' .. position)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(bridge.table[position], read_include(file))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Loader
|
||||||
|
|
||||||
|
function load_file(path)
|
||||||
|
local nft = assert(loadfile(path))
|
||||||
|
|
||||||
|
local fncs = setmetatable({
|
||||||
|
path = path,
|
||||||
|
include = include,
|
||||||
|
rule = rule,
|
||||||
|
|
||||||
|
bridge_rule = bridge_rule,
|
||||||
|
bridge_chain = bridge_chain,
|
||||||
|
bridge_table = bridge_table,
|
||||||
|
bridge_include_rule = bridge_include_rule,
|
||||||
|
bridge_include_table = bridge_include_table,
|
||||||
|
}, { __index = _G })
|
||||||
|
|
||||||
|
local env = setmetatable({}, { __index = fncs })
|
||||||
|
setfenv(nft, env)
|
||||||
|
|
||||||
|
nft()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Clean old rules
|
||||||
|
|
||||||
|
uci:foreach('firewall', 'include', function(i)
|
||||||
|
if string.starts(i['.name'], 'gluon_nftables_') then
|
||||||
|
uci:delete('firewall', i['.name'])
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Load new rules
|
||||||
|
|
||||||
|
for _, path in ipairs(glob.glob("/lib/gluon/nftables/*.lua", 0) or {}) do
|
||||||
|
print(' - NFTables: ' .. basepath(path))
|
||||||
|
load_file(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
local b = io.open(path('bridge'), 'w')
|
||||||
|
|
||||||
|
include('bridge', {
|
||||||
|
position = 'ruleset-pre',
|
||||||
|
})
|
||||||
|
|
||||||
|
write_all_lines(bridge.table.pre, b)
|
||||||
|
|
||||||
|
for _, lines in pairs(bridge.chain) do
|
||||||
|
write_all_lines(lines, b, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
write_all_lines(bridge.table.post, b, true)
|
||||||
|
|
||||||
|
uci:save('firewall')
|
Loading…
Reference in New Issue
Block a user