Skip to content
Snippets Groups Projects
Commit c19b4efd authored by Nils Schneider's avatar Nils Schneider
Browse files

new basic configmode

parent 4783a52a
No related branches found
No related tags found
No related merge requests found
Showing
with 304 additions and 330 deletions
......@@ -15,7 +15,7 @@ define Package/gluon-config-mode
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci based config mode for user friendly setup of new meshnodes
DEPENDS:=+gluon-core +uhttpd +dnsmasq +luci-mod-admin-core
DEPENDS:=+gluon-core +uhttpd +dnsmasq +luci-mod-admin-core +luci-mod-failsafe +ip +luci-theme-openwrt +haveged
endef
define Package/gluon-config-mode/description
......
config wizard
option enabled '1'
option configured '0'
config wizard
option enabled '1'
option configured '0'
option keyaddress '<a href="mailto:keys@luebeck.freifunk.net">keys@luebeck.freifunk.net</a>'
......@@ -4,10 +4,10 @@
wait=3
wait_config_mode() {
wait_configmode() {
sleep $wait
uci set 'config_mode.@wizard[0].enabled=1'
uci commit config_mode
uci set 'configmode.@wizard[0].enabled=1'
uci commit configmode
reboot
}
......@@ -15,14 +15,14 @@ wait_config_mode() {
if [ "$BUTTON" = wps -o "$BUTTON" = reset ]; then
case "$ACTION" in
pressed)
wait_config_mode &
wait_configmode &
PID=$!
echo $PID > /tmp/.wait_config_mode
echo $PID > /tmp/.wait_configmode
;;
released)
if [ -r /tmp/.wait_config_mode ]; then
kill $(cat /tmp/.wait_config_mode)
rm /tmp/.wait_config_mode
if [ -r /tmp/.wait_configmode ]; then
kill $(cat /tmp/.wait_configmode)
rm /tmp/.wait_configmode
fi
;;
esac
......
......@@ -3,12 +3,12 @@
START=12
config_mode_iface=eth0
config_mode_addr=192.168.1.1
config_mode_plen=24
configmode_iface=eth0
configmode_addr=192.168.1.1
configmode_plen=24
config_mode_dnsname=freifunk
config_mode_dhcp_range=192.168.1.2,192.168.1.254
configmode_dnsname=freifunk
configmode_dhcp_range=192.168.1.2,192.168.1.254
check_enable() {
config_get enabled "$1" enabled
......@@ -21,17 +21,18 @@ check_enable() {
start() {
enable=0
config_load config_mode
config_load configmode
config_foreach check_enable wizard
if [ "$enable" = '1' ]; then
lua -luci -e 'require "luci.model.uci"; uci_state=luci.model.uci.cursor_state(); uci_state:section("config_mode", "wizard", nil, { running = "1" }); uci_state:save("config_mode")'
uci set 'config_mode.@wizard[0].enabled=0'
uci commit config_mode
lua -luci -e 'require "luci.model.uci"; uci_state=luci.model.uci.cursor_state(); uci_state:section("configmode", "wizard", nil, { running = "1" }); uci_state:save("configmode")'
uci set 'configmode.@wizard[0].enabled=0'
uci commit configmode
ip addr add $config_mode_addr/$config_mode_plen dev $config_mode_iface
ip link set up dev $config_mode_iface
ip addr add $configmode_addr/$configmode_plen dev $configmode_iface
ip link set up dev $configmode_iface
/etc/init.d/haveged start
/etc/init.d/telnet start
/etc/init.d/dropbear start
/etc/init.d/uhttpd start
......@@ -40,8 +41,8 @@ start() {
# correctly finish firstboot
/etc/init.d/done boot
echo "$config_mode_addr $config_mode_dnsname" > /tmp/hosts.config_mode
dnsmasq -h -H /tmp/hosts.config_mode -R -F interface:$config_mode_iface,$config_mode_dhcp_range -l /tmp/dhcp.leases -O option:router
echo "$configmode_addr $configmode_dnsname" > /tmp/hosts.configmode
dnsmasq -h -H /tmp/hosts.configmode -R -F interface:$configmode_iface,$configmode_dhcp_range -l /tmp/dhcp.leases -O option:router
. /etc/diag.sh
get_status_led
......
--[[
Copyright 2013 Nils Schneider <nils@nilsschneider.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.configmode.configmode", package.seeall)
local meshvpn_name = "mesh_vpn"
function index()
local uci_state = luci.model.uci.cursor_state()
if uci_state:get_first("configmode", "wizard", "running", "0") == "1" then
local root = node()
if not root.target then
root.target = alias("configmode")
root.index = true
end
page = node()
page.lock = true
page.target = alias("configmode")
page.subindex = true
page.index = false
page = node("configmode")
page.title = _("Configmode")
page.target = alias("configmode", "wizard")
page.order = 5
page.setuser = "root"
page.setgroup = "root"
page.index = true
entry({"configmode", "wizard"}, form("configmode/wizard"), _("Wizard"), 10).index = true
entry({"configmode", "reboot"}, call("action_reboot"))
end
end
function action_reboot()
local configmode = require "luci.tools.configmode"
local pubkey
local uci = luci.model.uci.cursor()
local address = uci:get_first("configmode", "wizard", "keyaddress")
local meshvpn_enabled = uci:get("fastd", meshvpn_name, "enabled", "0")
if meshvpn_enabled == "1" then
pubkey = configmode.get_fastd_pubkey(meshvpn_name)
end
luci.template.render("configmode/reboot", {pubkey=pubkey, address=address})
uci:foreach("configmode", "wizard", function(s)
uci:set("configmode", s[".name"], "configured", "1")
uci:set("configmode", s[".name"], "enabled", "0")
end)
uci:save("configmode")
uci:commit("configmode")
luci.sys.reboot()
end
module("luci.controller.freifunk.index", package.seeall)
function index()
local uci_state = luci.model.uci.cursor_state()
if uci_state:get_first("config_mode", "wizard", "running", "0") == "1" then
local root = node()
root.target = alias("wizard", "welcome")
root.index = true
end
end
module("luci.controller.freifunk.wizard", package.seeall)
function index()
local uci_state = luci.model.uci.cursor_state()
if uci_state:get_first("config_mode", "wizard", "running", "0") == "1" then
entry({"wizard", "welcome"}, template("freifunk-wizard/welcome"), "Willkommen", 10).dependent=false
entry({"wizard", "password"}, form("freifunk-wizard/password"), "Passwort", 20).dependent=false
entry({"wizard", "hostname"}, form("freifunk-wizard/hostname"), "Hostname", 30).dependent=false
entry({"wizard", "meshvpn"}, form("freifunk-wizard/meshvpn"), "Mesh-VPN", 40).dependent=false
entry({"wizard", "meshvpn", "pubkey"}, template("freifunk-wizard/meshvpn-key"), "Mesh-VPN Key", 1).dependent=false
entry({"wizard", "completed"}, template("freifunk-wizard/completed"), "Fertig", 50).dependent=false
entry({"wizard", "completed", "reboot"}, call("reboot"), "reboot", 1).dependent=false
end
end
function reboot()
local uci = luci.model.uci.cursor()
uci:foreach("config_mode", "wizard",
function(s)
uci:set("config_mode", s[".name"], "configured", "1")
end
)
uci:save("config_mode")
uci:commit("config_mode")
luci.sys.reboot()
end
local configmode = require "luci.tools.configmode"
local meshvpn_name = "mesh_vpn"
local uci = luci.model.uci.cursor()
local f, s, o
-- prepare fastd key as early as possible
configmode.setup_fastd_secret(meshvpn_name)
f = SimpleForm("wizard", "Wizard", "Lorem ipsum...")
s = f:section(SimpleSection, "Grundeinstellungen", nil)
o = s:option(Value, "_hostname", "Knotenname")
o.value = uci:get_first("system", "system", "hostname")
o.rmempty = false
o.datatype = "hostname"
o = s:option(Flag, "_meshvpn", "Mesh-VPN aktivieren?")
o.default = string.format("%d", uci:get("fastd", meshvpn_name, "enabled", "0"))
o.rmempty = false
o = s:option(Flag, "_bwlimit", "Bandbreitenbegrenzung aktivieren?")
o.default = string.format("%d", uci:get_first("freifunk", "bandwidth", "enabled", "0"))
o.rmempty = false
o = s:option(Flag, "_autoupdate", "Automatische Updates aktivieren?")
o.default = string.format("%d", uci:get_first("autoupdater", "autoupdater", "enabled", "0"))
o.rmempty = false
s = f:section(SimpleSection, "GPS Koordinaten", "Hier kannst du die GPS Koordinaten deines Knotens festlegen damit er in der Karte angezeigt werden kann.")
o = s:option(Value, "_latitude", "Breitengrad")
o.default = string.format("%f", uci:get_first("system", "location", "latitude", "0"))
o.rmempty = false
o.datatype = "float"
o = s:option(Value, "_longitude", "Längengrad")
o.default = string.format("%f", uci:get_first("system", "location", "longitude", "0"))
o.rmempty = false
o.datatype = "float"
function f.handle(self, state, data)
if state == FORM_VALID then
local stat = false
uci:foreach("autoupdater", "autoupdater", function(s)
uci:set("autoupdater", s[".name"], "enabled", data._autoupdate)
end)
uci:save("autoupdater")
uci:commit("autoupdater")
uci:foreach("freifunk", "bandwidth", function(s)
uci:set("freifunk", s[".name"], "enabled", data._bwlimit)
end)
uci:save("freifunk")
uci:commit("freifunk")
uci:set("fastd", meshvpn_name, "enabled", data._meshvpn)
uci:save("fastd")
uci:commit("fastd")
uci:foreach("system", "system", function(s)
uci:set("system", s[".name"], "hostname", data._hostname)
end)
uci:foreach("system", "location", function(s)
uci:set("system", s[".name"], "latitude", data._latitude)
uci:set("system", s[".name"], "longitude", data._longitude)
end)
uci:save("system")
uci:commit("system")
luci.http.redirect(luci.dispatcher.build_url("configmode", "reboot"))
end
return true
end
return f
local uci = luci.model.uci.cursor()
local nav = require "luci.tools.freifunk-wizard.nav"
local f = SimpleForm("hostname", "Name deines Freifunkknotens", "Als nächstes solltest du einem Freifunkknoten einen individuellen Namen geben. Dieser hilft dir und auch uns den Überblick zu behalten.")
f.template = "freifunk-wizard/wizardform"
hostname = f:field(Value, "hostname", "Hostname")
hostname.value = uci:get_first("system", "system", "hostname")
hostname.rmempty = false
function hostname.validate(self, value, section)
return value
end
function f.handle(self, state, data)
if state == FORM_VALID then
local stat = true
uci:foreach("system", "system", function(s)
stat = stat and uci:set("system", s[".name"], "hostname", data.hostname)
end
)
stat = stat and uci:save("system")
stat = stat and uci:commit("system")
if stat then
nav.maybe_redirect_to_successor()
f.message = "Hostname geändert!"
else
f.errmessage = "Fehler!"
end
end
return true
end
return f
local meshvpn_name = "mesh_vpn"
local uci = luci.model.uci.cursor()
local nav = require "luci.tools.freifunk-wizard.nav"
local f = SimpleForm("meshvpn", "Mesh-VPN", "<p>Um deinen Freifunkknoten auch über das Internet mit dem Freifunk-Netzwerk zu verbinden, kann das Mesh-VPN aktiviert werden.\
Dies erlaubt es, den Freifunk-Knoten zu betreiben, auch wenn es keine anderen Knoten in deiner Umgebung gibt, mit denen eine WLAN-Verbindung möglich ist.</p>\
<p>Dabei wird zur Kommunikation ein verschlüsselter Tunnel verwendet, sodass für den Anschluss-Inhaber keinerlei Risiken entstehen.</p>\
<p>Damit das Mesh-VPN deine Internet-Verbindung nicht unverhältnismäßig auslastet, kann die Bandbreite begrenzt werden. Wenn du zum Beispiel eine DSL-16000-Leitung hast\
und maximal ein Viertel der Leitung zur Verfügung stellen willst, muss als Downstream-Bandbreite 4000 kbit/s eingetragen werden.</p>\
<p>Um das Freifunk-Netz nicht zu sehr auszubremsen, bitten wir darum, mindestens 1000 kbit/s im Downstream und 100 kbit/s im Upstream bereitzustellen.</p>")
f.template = "freifunk-wizard/wizardform"
meshvpn = f:field(Flag, "meshvpn", "Mesh-VPN aktivieren?")
meshvpn.default = string.format("%d", uci:get("fastd", meshvpn_name, "enabled", "0"))
meshvpn.rmempty = false
tc = f:field(Flag, "tc", "Bandbreitenbegrenzung aktivieren?")
tc.default = string.format("%d", uci:get_first("freifunk", "bandwidth", "enabled", "0"))
tc.rmempty = false
downstream = f:field(Value, "downstream", "Downstream-Bandbreite (kbit/s)")
downstream.value = uci:get_first("freifunk", "bandwidth", "downstream", "0")
upstream = f:field(Value, "upstream", "Upstream-Bandbreite (kbit/s)")
upstream.value = uci:get_first("freifunk", "bandwidth", "upstream", "0")
function f.handle(self, state, data)
if state == FORM_VALID then
local stat = false
uci:set("fastd", meshvpn_name, "enabled", data.meshvpn)
uci:save("fastd")
uci:commit("fastd")
uci:foreach("freifunk", "bandwidth", function(s)
uci:set("freifunk", s[".name"], "upstream", data.upstream)
uci:set("freifunk", s[".name"], "downstream", data.downstream)
uci:set("freifunk", s[".name"], "enabled", data.tc)
end
)
uci:save("freifunk")
uci:commit("freifunk")
if data.meshvpn == "1" then
local secret = uci:get("fastd", meshvpn_name, "secret")
if not secret or not secret:match("%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x") then
luci.sys.call("/etc/init.d/haveged start")
local f = io.popen("fastd --generate-key --machine-readable", "r")
local secret = f:read("*a")
f:close()
luci.sys.call("/etc/init.d/haveged stop")
uci:set("fastd", meshvpn_name, "secret", secret)
uci:save("fastd")
uci:commit("fastd")
end
luci.http.redirect(luci.dispatcher.build_url("wizard", "meshvpn", "pubkey"))
else
nav.maybe_redirect_to_successor()
end
end
return true
end
return f
local nav = require "luci.tools.freifunk-wizard.nav"
f = SimpleForm("password", "Administrator-Passwort setzen", "<p>Damit nur du Zugriff auf deinen Freifunkknoten hast, solltest du jetzt ein Passwort vergeben. \
Da man mit Hilfe von diesem beliebige Einstellungen geändert werden können, sollte es möglichst sicher sein.</p>\
<p>Bitte beachte dazu folgende Hinweise:</p>\
<ul>\
<li>Es sollte in keinem Wörterbuch vorkommen.</li>\
<li>Es sollte mehr als acht Zeichen beinhalten.</li>\
<li>Es sollte auch Zahlen &amp; Sonderzeichen enthalten.</li>\
</ul>")
f.template = "freifunk-wizard/wizardform"
pw1 = f:field(Value, "pw1", "Passwort")
pw1.password = true
pw1.rmempty = false
pw2 = f:field(Value, "pw2", "Wiederholung")
pw2.password = true
pw2.rmempty = false
function pw2.validate(self, value, section)
return pw1:formvalue(section) == value and value
end
function f.handle(self, state, data)
if state == FORM_VALID then
local stat = luci.sys.user.setpasswd("root", data.pw1) == 0
if stat then
nav.maybe_redirect_to_successor()
f.message = "Passwort geändert!"
else
f.errmessage = "Fehler!"
end
data.pw1 = nil
data.pw2 = nil
end
return true
end
return f
local luci = require "luci"
local io = require "io"
module "luci.tools.configmode"
function setup_fastd_secret(name)
local uci = luci.model.uci.cursor()
local secret = uci:get("fastd", name, "secret")
if not secret or not secret:match("%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x%x") then
local f = io.popen("fastd --generate-key --machine-readable", "r")
local secret = f:read("*a")
f:close()
uci:set("fastd", name, "secret", secret)
uci:save("fastd")
uci:commit("fastd")
end
end
function get_fastd_pubkey(name)
local f = io.popen("/etc/init.d/fastd show_key " .. name, "r")
local key = f:read("*a")
f:close()
return key
end
module("luci.tools.freifunk-wizard.nav", package.seeall)
function maybe_redirect_to_successor()
local pre, suc = get()
if suc then
luci.http.redirect(luci.dispatcher.build_url("wizard", suc.href))
end
end
function get()
local disp = require "luci.dispatcher"
local request = disp.context.path
local category = request[1]
local cattree = category and disp.node(category)
local childs = disp.node_childs(cattree)
local predecessor = nil
local successor = nil
if #childs > 0 then
local found_pre = false
for i, r in ipairs(childs) do
local nnode = cattree.nodes[r]
nnode.href = r
if r == request[2] then
found_pre = true
elseif found_pre and successor == nil then
successor = nnode
end
if not found_pre then
predecessor = nnode
end
end
end
return predecessor, successor
end
<%#
LuCI - Lua Configuration Interface
Copyright 2008 Steven Barth <steven@midlink.org>
Copyright 2008 Jo-Philipp Wich <xm@leipzig.freifunk.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
-%>
<html>
<head>
<title><%=luci.sys.hostname()%> - <% if title then %><%=title%><% else %><%:Rebooting...%><% end %></title>
<link rel="stylesheet" type="text/css" media="screen" href="<%=media%>/cascade.css" />
</head>
<body>
<div id="maincontainer">
<div id="maincontent">
<h2>Geschafft! Dein Freifunkknoten ist nun fertig eingerichtet.</h2>
<% if pubkey then %>
<fieldset class="cbi-section">
<p>
Dies ist der öffentliche Schlüssel deines Freifunkknotens. Bitte schicke ihn an <%=address%>, um ihn auf den Freifunkservern eintragen zu lassen. Sobald der Schlüssel eingetragen wurde, kann dein Knoten das Mesh-VPN nutzen.
</p>
<div style="text-align: center;font-size: 2em;line-height: 1em; background: #f5f5f5; border: 1px solid #ececec; margin-bottom: 0.5em; padding: 0.5em">
<%=pubkey%>
</div>
</fieldset>
<% end %>
<fieldset class="cbi-section">
<p>
Dein Knoten startet jetzt neu. Anschließend wird er versuchen sich mit anderen Knoten in der Nähe zu verbinden. Wir wünschen dir viel Spaß dabei Freifunk zu erkunden!
</p>
</fieldset>
</div>
</div>
</body>
</html>
<%
local disp = require "luci.dispatcher"
%>
<%+header%>
<h2>Konfiguration abgeschlossen</h2>
<p>Die Konfiguration deines Freifunkknotens ist nun abgeschlossen. Damit sie aktiv wird, muss der Knoten neugestartet werden.<p>
<p>Um später wieder in den Konfiguration-Modus zurückzukehren, zum Beispiel um die Konfiguration zu verändern oder ein Firmware-Upgrade durchzuführen,
muss der QSS-Button am Gehäuse für einige Sekunden gedrückt gehalten werden, während der Knoten läuft. Der Knoten wird dann neu starten und in
den Konfigurationsmodus zurückkehren.</p>
<p>
<a class="btn primary" href="<%=disp.build_url("wizard", "completed", "reboot")%>">Jetzt neustarten!</a>
</p>
<%+footer%>
<% local xtime
if exectime then
xtime = (string.format("%.2fs", os.clock() - exectime))
end %>
<footer class="footer">
<p><a href="http://luci.subsignal.org">Powered by <%= luci.__appname__ .. " (" .. luci.__version__ .. ")" %></a>
<% if xtime then %>
<br/>
Script execution time: <%=xtime%>
<% end %>
</p>
</footer>
</div>
</body>
</html>
<%
local fs = require "luci.fs"
local sys = require "luci.sys"
local http = require "luci.http"
local disp = require "luci.dispatcher"
local hostname = sys.hostname()
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<link rel="stylesheet" type="text/css" media="screen" href="/wizard/bootstrap.css" />
<title><%=striptags( hostname )%> - Wizard</title>
</head>
<body class="lang_<%=luci.i18n.context.lang%>">
<div class="container">
<div class="page-header">
<h1>Freifunk Wizard</h1>
</div>
<%
local meshvpn_name = "mesh_vpn"
local address = "freifunk.luebeck@asta.uni-luebeck.de"
local disp = require "luci.dispatcher"
local f = io.popen("/etc/init.d/fastd show_key " .. meshvpn_name, "r")
local key = f:read("*a")
f:close()
%>
<%+header%>
<h2>Schlüsselaustausch</h2>
<p>Dies ist der öffentliche Schlüssel deines Freifunkknotens. Bitte schicke ihn an <%=address%>, um ihn auf den Freifunkservern eintragen zu lassen. Sobald der Schlüssel eingetragen wurde, kann dein Knoten das Mesh-VPN nutzen.</p>
<div style="text-align: center;font-size: 2em;line-height: 1em; background: #f5f5f5; border: 1px solid #ececec; margin-bottom: 0.5em; padding: 0.5em">
<%=key%>
</div>
<%+freifunk-wizard/nav%>
<%+footer%>
<%
local nav = require "luci.tools.freifunk-wizard.nav"
local predecessor, successor = nav.get()
%>
<div class="actions">
<% if successor then %>
<a class="btn primary" href="<%=luci.dispatcher.build_url("wizard", successor.href)%>">Weiter</a>
<% end %>
<% if predecessor then %>
<a class="btn" href="<%=luci.dispatcher.build_url("wizard", predecessor.href)%>">Zurück</a>
<% end %>
</div>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment