From e824a6cb0d7a29e8dceafaa7cf76397cdada398a Mon Sep 17 00:00:00 2001 From: Tim Wilkinson Date: Tue, 3 Dec 2024 23:46:32 -0800 Subject: [PATCH] Complete migration of random /etc/config.mesh files into UCI (#1743) --- files/app/main/status/e/dhcp.ut | 2 +- files/app/main/status/e/local-services.ut | 58 ++++----- files/app/main/status/e/network.ut | 17 +-- files/app/partial/dhcp.ut | 2 +- files/app/partial/local-services.ut | 2 +- files/etc/uci-defaults/20_setup_migrate | 82 ++++++++++-- files/usr/lib/lua/aredn/services.lua | 6 +- files/usr/local/bin/node-setup | 127 +++++++------------ files/usr/share/ucode/aredn/configuration.uc | 15 +-- 9 files changed, 159 insertions(+), 152 deletions(-) diff --git a/files/app/main/status/e/dhcp.ut b/files/app/main/status/e/dhcp.ut index 5b34a1c0..a8f29257 100755 --- a/files/app/main/status/e/dhcp.ut +++ b/files/app/main/status/e/dhcp.ut @@ -132,7 +132,7 @@ for (let i = 0; i < length(res); i++) { } } } -const f = fs.open(dhcp.leases); +const f = fs.open("/tmp/dhcp.leases"); if (f) { for (let l = f.read("line"); length(l); l = f.read("line")) { // ?, mac, ip, name, ? diff --git a/files/app/main/status/e/local-services.ut b/files/app/main/status/e/local-services.ut index 95da37fc..71203579 100755 --- a/files/app/main/status/e/local-services.ut +++ b/files/app/main/status/e/local-services.ut @@ -50,25 +50,29 @@ if (request.env.REQUEST_METHOD === "PUT") { } if ("aliases" in request.args) { const aliases = json(request.args.aliases); - const dhcp = configuration.getDHCP(); - let f = fs.open(dhcp.aliases, "w"); - if (f) { - for (let i = 0; i < length(aliases); i++) { - f.write(`${aliases[i]}\n`); - } - f.close(); + if (!uciMesh.get("setup", "aliases")) { + uciMesh.set("setup", "aliases", "aliases"); } + if (length(aliases)) { + uciMesh.set("setup", "aliases", "alias", aliases); + } + else { + uciMesh.delete("setup", "aliases", "alias"); + } + uciMesh.commit("setup"); } if ("ports" in request.args) { const ports = json(request.args.ports); - const dhcp = configuration.getDHCP(); - let f = fs.open(dhcp.ports, "w"); - if (f) { - for (let i = 0; i < length(ports); i++) { - f.write(`${ports[i]}\n`); - } - f.close(); + if (!uciMesh.get("setup", "ports")) { + uciMesh.set("setup", "ports", "ports"); } + if (length(ports)) { + uciMesh.set("setup", "ports", "port", ports); + } + else { + uciMesh.delete("setup", "ports", "port"); + } + uciMesh.commit("setup"); } print(_R("changes")); return; @@ -158,26 +162,20 @@ for (let i = 0; i < length(res); i++) { } } } -let f = fs.open(dhcp.aliases); -if (f) { - for (let l = f.read("line"); length(l); l = f.read("line")) { - const v = match(trim(l), /^(.+) (.+)$/); - if (v) { - push(aliases.map, { hostname: v[2], address: v[1] }); - } +const als = uciMesh.get("setup", "aliases", "alias") || []; +for (let i = 0; i < length(als); i++) { + const v = match(trim(als[i]), /^(.+) (.+)$/); + if (v) { + push(aliases.map, { hostname: v[2], address: v[1] }); } - f.close(); } const ports = []; -f = fs.open(dhcp.ports); -if (f) { - for (let l = f.read("line"); length(l); l = f.read("line")) { - const m = match(trim(l), /^(wan|wifi|both):(tcp|udp|both):([0-9\-]+):([.0-9]+):([0-9]+):([01])$/); - if (m) { - push(ports, { src: m[1], type: m[2], sports: m[3], dst: m[4], dport: m[5], enabled: m[6] === "1" }); - } +const pts = uciMesh.get("setup", "ports", "port") || []; +for (let l = 0; l < length(pts); l++) { + const m = match(trim(pts[l]), /^(wan|wifi|both):(tcp|udp|both):([0-9\-]+):([.0-9]+):([0-9]+):([01])$/); + if (m) { + push(ports, { src: m[1], type: m[2], sports: m[3], dst: m[4], dport: m[5], enabled: m[6] === "1" }); } - f.close(); } %}
diff --git a/files/app/main/status/e/network.ut b/files/app/main/status/e/network.ut index afce3bcf..a95b7db2 100755 --- a/files/app/main/status/e/network.ut +++ b/files/app/main/status/e/network.ut @@ -62,27 +62,20 @@ if (request.env.REQUEST_METHOD === "PUT") { configuration.setSetting("dmz_dhcp_start", 2); configuration.setSetting("dmz_dhcp_end", (2 << (mode - 1)) - 2); const dhcp = configuration.getDHCP(); - let f = fs.open(dhcp.aliases); - if (f) { + const als = uciMesh.get("setup", "aliases", "alias"); + if (als) { const aliases = []; const dmz_dhcp_start = (wifi_shift + 2) & 0xff; const dmz_dhcp_end = dmz_dhcp_start + (2 << (mode - 1)) - 4; const n_lan_ip = iptoarr(dmz_lan_ip); - for (let l = f.read("line"); length(l); l = f.read("line")) { - const v = match(trim(l), /^(.+) (.+)$/); + for (let l = 0; l < length(als); l++) { + const v = match(trim(als[l]), /^(.+) (.+)$/); if (v) { const octet = max(dmz_dhcp_start, min(dmz_dhcp_end, n_lan_ip[3] + iptoarr(v[1])[3] - o_lan_ip[3])); push(aliases, `${arrtoip([ n_lan_ip[0], n_lan_ip[1], n_lan_ip[2], octet ])} ${v[2]}\n`); } } - f.close(); - f = fs.open(dhcp.aliases, "w"); - if (f) { - for (let i = 0; i < length(aliases); i++) { - f.write(aliases[i]); - } - f.close(); - } + uciMesh.set("setup", "aliases", "alias", aliases); } } } diff --git a/files/app/partial/dhcp.ut b/files/app/partial/dhcp.ut index c45a028e..4fcc901e 100755 --- a/files/app/partial/dhcp.ut +++ b/files/app/partial/dhcp.ut @@ -39,7 +39,7 @@ let at = 0; let ao = 0; if (dhcp.enabled) { - const f = fs.open(dhcp.leases); + const f = fs.open("/tmp/dhcp.leases"); if (f) { while (length(f.read("line"))) { da++; diff --git a/files/app/partial/local-services.ut b/files/app/partial/local-services.ut index a3b80f4d..4dd02868 100755 --- a/files/app/partial/local-services.ut +++ b/files/app/partial/local-services.ut @@ -106,7 +106,7 @@ if (dhcp.enabled) { const leased = {}; - f = fs.open(dhcp.leases); + f = fs.open("/tmp/dhcp.leases"); if (f) { for (let l = f.read("line"); length(l); l = f.read("line")) { const m = split(trim(l), " "); diff --git a/files/etc/uci-defaults/20_setup_migrate b/files/etc/uci-defaults/20_setup_migrate index f3f95cd5..50e1b2a0 100755 --- a/files/etc/uci-defaults/20_setup_migrate +++ b/files/etc/uci-defaults/20_setup_migrate @@ -53,7 +53,6 @@ if not c:get("setup", "globals") and nixio.fs.stat("/etc/config.mesh/_setup") th end end end - c:commit("setup") end -- Migrate the old school _setup.services.{nat,dmz} files @@ -66,15 +65,16 @@ if not c:get("setup", "services") then else file = nil end + c:set("setup", "services", "services") if file then local services = {} for line in io.lines(file) do services[#services + 1] = line end - c:set("setup", "services", "services") - c:set("setup", "services", "service", services) - c:commit("setup") + if #services > 0 then + c:set("setup", "services", "service", services) + end end end @@ -88,15 +88,16 @@ if not c:get("setup", "dhcpreservations") then else file = nil end + c:set("setup", "dhcpreservations", "dhcpreservations") if file then local dhcp = {} for line in io.lines(file) do dhcp[#dhcp + 1] = line end - c:set("setup", "dhcpreservations", "dhcpreservations") - c:set("setup", "dhcpreservations", "reservation", dhcp) - c:commit("setup") + if #dhcp > 0 then + c:set("setup", "dhcpreservations", "reservation", dhcp) + end end end @@ -110,15 +111,16 @@ if not c:get("setup", "dhcptags") then else file = nil end + c:set("setup", "dhcptags", "dhcptags") if file then local dhcp = {} for line in io.lines(file) do dhcp[#dhcp + 1] = line end - c:set("setup", "dhcptags", "dhcptags") - c:set("setup", "dhcptags", "tag", dhcp) - c:commit("setup") + if #dhcp > 0 then + c:set("setup", "dhcptags", "tag", dhcp) + end end end @@ -132,18 +134,67 @@ if not c:get("setup", "dhcpoptions") then else file = nil end + c:set("setup", "dhcpoptions", "dhcpoptions") if file then local dhcp = {} for line in io.lines(file) do dhcp[#dhcp + 1] = line end - c:set("setup", "dhcpoptions", "dhcpoptions") - c:set("setup", "dhcpoptions", "option", dhcp) - c:commit("setup") + if #dhcp > 0 then + c:set("setup", "dhcpoptions", "option", dhcp) + end end end +-- Migrate the old school _setup.ports.{nat,dmz} files +if not c:get("setup", "ports") then + local file = "/etc/config.mesh/ports." + if (nixio.fs.stat(file .. "nat", "size") or -1) >= 0 then + file = file .. "nat" + elseif (nixio.fs.stat(file .. "dmz", "size") or -1) >= 0 then + file = file .. "dmz" + else + file = nil + end + c:set("setup", "ports", "ports") + if file then + local ports = {} + for line in io.lines(file) + do + ports[#ports + 1] = line + end + if #ports > 0 then + c:set("setup", "ports", "port", ports) + end + end +end + +-- Migrate the old school _setup.aliases.{nat,dmz} files +if not c:get("setup", "aliases") then + local file = "/etc/config.mesh/aliases." + if (nixio.fs.stat(file .. "nat", "size") or -1) >= 0 then + file = file .. "nat" + elseif (nixio.fs.stat(file .. "dmz", "size") or -1) >= 0 then + file = file .. "dmz" + else + file = nil + end + c:set("setup", "aliases", "aliases") + if file then + local aliases = {} + for line in io.lines(file) + do + aliases[#aliases + 1] = line + end + if #aliases > 0 then + c:set("setup", "aliases", "alias", aliases) + end + end +end + +c:commit("setup") + -- Dont remove this yet otherwise we cannot revert this node -- os.remove("/etc/config.mesh/_setup") -- os.remove("/etc/config.mesh/_setup.service.dmz") @@ -154,6 +205,11 @@ end -- os.remove("/etc/config.mesh/_setup.dhcptags.nat") -- os.remove("/etc/config.mesh/_setup.dhcpoptions.dmz") -- os.remove("/etc/config.mesh/_setup.dhcpoptions.nat") +-- os.remove("/etc/config.mesh/_setup.ports.dmz") +-- os.remove("/etc/config.mesh/_setup.ports.nat") +-- os.remove("/etc/config.mesh/aliases.dmz") +-- os.remove("/etc/config.mesh/aliases.nat") +-- os.remove("/etc/config.mesh/aliases") __EOF__ /usr/bin/lua /tmp/setup_migrate diff --git a/files/usr/lib/lua/aredn/services.lua b/files/usr/lib/lua/aredn/services.lua index 6c4825bf..98ac6f96 100755 --- a/files/usr/lib/lua/aredn/services.lua +++ b/files/usr/lib/lua/aredn/services.lua @@ -183,11 +183,11 @@ local function get(validate) -- Load NAT local nat = nil if dmz_mode == "0" then - local portfile = "/etc/config.mesh/_setup.ports.nat" - if nixio.fs.access(portfile) then + local ports = uci.cursor("/etc/config.mesh"):get_all("setup", "ports", "port") + if ports then nat = {} local lname = name:lower() .. ".local.mesh" - for line in io.lines(portfile) + for _, line in ipairs(ports) do local _, type, sport, addr, dport, enable = line:match("^(.+):(.+):(.+):(.+):(%d+):(%d)$") if enable == "1" then diff --git a/files/usr/local/bin/node-setup b/files/usr/local/bin/node-setup index 720f0d9b..d8c5734d 100755 --- a/files/usr/local/bin/node-setup +++ b/files/usr/local/bin/node-setup @@ -307,29 +307,6 @@ do end end --- select ports and dhcp files based on mode -local portfile = "/etc/config.mesh/_setup.ports" -local aliasfile = "/etc/config.mesh/aliases" -if is_nat_mode() then - portfile = portfile .. ".nat" - aliasfile = aliasfile .. ".nat" -else - portfile = portfile .. ".dmz" - aliasfile = aliasfile .. ".dmz" -end - --- check for old aliases file, copy it to .dmz and create symlink --- just in case anyone is already using the file for some script or something -if not nixio.fs.readlink("/etc/config.mesh/aliases") then - if nixio.fs.stat("/etc/config.mesh/aliases") then - filecopy("/etc/config.mesh/aliases", "/etc/config.mesh/aliases.dmz") - os.remove("/etc/config.mesh/aliases") - else - io.open("/etc/config.mesh/aliases.dmz", "a"):close() - end - nixio.fs.symlink("aliases.dmz", "/etc/config.mesh/aliases") -end - -- generate the new school bridge configuration if nixio.fs.stat("/etc/aredn_include/bridge.network.user") then cfg.bridge_network_config = expand_vars(read_all("/etc/aredn_include/bridge.network.user")) @@ -703,50 +680,47 @@ if fw then end end - if nixio.fs.access(portfile) then - for line in io.lines(portfile) - do - if not (line:match("^%s*#") or line:match("^%s*$")) then - local dip = line:match("dmz_ip = (%w+)") - if dip and is_dmz_mode() then - fw:write("\nconfig redirect\n option src wifi\n option proto tcp\n option src_dip " .. cfg.wifi_ip .. "\n option dest_ip " .. dip .. "\n") - fw:write("\nconfig redirect\n option src wifi\n option proto udp\n option src_dip " .. cfg.wifi_ip .. "\n option dest_ip " .. dip .. "\n") - else - local intf, type, oport, host, iport, enable = line:match("(.*):(.*):(.*):(.*):(.*):(.*)") - if enable == "1" then - local match = "option src_dport " .. oport .. "\n" - if type == "tcp" then - match = match .. " option proto tcp\n" - elseif type == "udp" then - match = match .. " option proto udp\n" - end - -- uci the host and then - -- set the inside port unless the rule uses an outside port range - host = "option dest_ip " .. host .. "\n" - if not oport:match("-") then - host = host .. " option dest_port " .. iport .. "\n" - end - if is_dmz_mode() and intf == "both" then - intf = "wan" - end - if intf == "both" then - fw:write("\nconfig redirect\n option src wifi\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") - fw:write("\nconfig redirect\n option src dtdlink\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") - if vpnzone then - fw:write("\nconfig redirect\n option src vpn\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") - end - fw:write("config redirect\n option src wan\n option dest lan\n " .. match .. " " .. host .. "\n") - elseif intf == "wifi" and is_nat_mode() then - fw:write("\nconfig redirect\n option src dtdlink\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") - fw:write("\nconfig redirect\n option src wifi\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") - if vpnzone then - fw:write("\nconfig redirect\n option src vpn\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") - end - elseif intf == "wan" then - fw:write("\nconfig redirect\n option src dtdlink\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") - fw:write("config redirect\n option src wan\n option dest lan\n " .. match .. " " .. host .. "\n") - end + local ports = cm:get_all("setup", "ports", "port") or {} + for _, line in ipairs(ports) + do + local dip = line:match("dmz_ip = (%w+)") + if dip and is_dmz_mode() then + fw:write("\nconfig redirect\n option src wifi\n option proto tcp\n option src_dip " .. cfg.wifi_ip .. "\n option dest_ip " .. dip .. "\n") + fw:write("\nconfig redirect\n option src wifi\n option proto udp\n option src_dip " .. cfg.wifi_ip .. "\n option dest_ip " .. dip .. "\n") + else + local intf, type, oport, host, iport, enable = line:match("(.*):(.*):(.*):(.*):(.*):(.*)") + if enable == "1" then + local match = "option src_dport " .. oport .. "\n" + if type == "tcp" then + match = match .. " option proto tcp\n" + elseif type == "udp" then + match = match .. " option proto udp\n" + end + -- uci the host and then + -- set the inside port unless the rule uses an outside port range + host = "option dest_ip " .. host .. "\n" + if not oport:match("-") then + host = host .. " option dest_port " .. iport .. "\n" + end + if is_dmz_mode() and intf == "both" then + intf = "wan" + end + if intf == "both" then + fw:write("\nconfig redirect\n option src wifi\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") + fw:write("\nconfig redirect\n option src dtdlink\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") + if vpnzone then + fw:write("\nconfig redirect\n option src vpn\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") end + fw:write("config redirect\n option src wan\n option dest lan\n " .. match .. " " .. host .. "\n") + elseif intf == "wifi" and is_nat_mode() then + fw:write("\nconfig redirect\n option src dtdlink\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") + fw:write("\nconfig redirect\n option src wifi\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") + if vpnzone then + fw:write("\nconfig redirect\n option src vpn\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") + end + elseif intf == "wan" then + fw:write("\nconfig redirect\n option src dtdlink\n option dest lan\n " .. match .. " option src_dip " .. cfg.wifi_ip .. "\n " .. host .. "\n") + fw:write("config redirect\n option src wan\n option dest lan\n " .. match .. " " .. host .. "\n") end end end @@ -1081,21 +1055,16 @@ if h and e then -- aliases need to ba added to /etc/hosts or they will now show up on the localnode -- nor will the services thehy offer -- also add a comment to the hosts file so we can display the aliases differently if needed - local f = io.open(aliasfile, "r") - if f then - for line in f:lines() - do - if not (line:match("^%s*#") or line:match("^%s*$")) then - local ip, host = line:match("(%S+)%s+(%S+)") - if ip then - if host:match("%.") and not host:match("%.local%.mesh$") then - host = host .. ".local.mesh" - end - h:write(ip .. "\t" .. host .. " #ALIAS\n") - end + local aliases = cm:get_all("setup", "aliases", "alias") or {} + for _, line in ipairs(aliases) + do + local ip, host = line:match("(%S+)%s+(%S+)") + if ip then + if host:match("%.") and not host:match("%.local%.mesh$") then + host = host .. ".local.mesh" end + h:write(ip .. "\t" .. host .. " #ALIAS\n") end - f:close() end h:write("\n") diff --git a/files/usr/share/ucode/aredn/configuration.uc b/files/usr/share/ucode/aredn/configuration.uc index a2014543..bdbc9c8d 100755 --- a/files/usr/share/ucode/aredn/configuration.uc +++ b/files/usr/share/ucode/aredn/configuration.uc @@ -219,10 +219,7 @@ export function getDHCP(mode) end: `${i[0]}.${i[1]}.${(e >> 8) & 255}.${e & 255}`, gateway: setup.lan_ip, mask: setup.lan_mask, - cidr: network.netmaskToCIDR(setup.lan_mask), - leases: "/tmp/dhcp.leases", - ports: "/etc/config.mesh/_setup.ports.nat", - aliases: "/etc/config.mesh/aliases.nat" + cidr: network.netmaskToCIDR(setup.lan_mask) }; } else if (setup.dmz_mode === "1") { @@ -239,10 +236,7 @@ export function getDHCP(mode) end: `${i[0]}.${i[1]}.${(e >> 8) & 255}.${e & 255}`, gateway: setup.lan_ip, mask: setup.lan_mask, - cidr: network.netmaskToCIDR(setup.lan_mask), - leases: "/tmp/dhcp.leases", - ports: "/etc/config.mesh/_setup.ports.dmz", - aliases: "/etc/config.mesh/aliases.dmz" + cidr: network.netmaskToCIDR(setup.lan_mask) }; } else { @@ -259,10 +253,7 @@ export function getDHCP(mode) end: `${i[0]}.${i[1]}.${(e >> 8) & 255}.${e & 255}`, gateway: setup.dmz_lan_ip, mask: setup.dmz_lan_mask, - cidr: network.netmaskToCIDR(setup.dmz_lan_mask), - leases: "/tmp/dhcp.leases", - ports: "/etc/config.mesh/_setup.ports.dmz", - aliases: "/etc/config.mesh/aliases.dmz" + cidr: network.netmaskToCIDR(setup.dmz_lan_mask) }; } };