Luci-app-wireguard QR code - adding Endpoint to config file

I am trying to add the Endpoint parameter to the Peer section in WireGuard QR code. The problem I am encountering is as follows: the WireGuard App on my phone fails to import the configuration; it returns the error

could not parse endpoint yourdomain.ddns.net

Note that the port is missing, although I included it in the code.

I know that the Lua code below is getting valid values for the listenPort and the endPoint, I have independently confirmed those; so I am not sure why I am seeing this error, as it is just a simple string concatenation, right? I do not believe I need to use any escape sequences for a colon in Lua, although I have tried \ and % anyway. I tried wrapping it all in a tostring() function as well. Am I doing something obviously wrong?

local qr_enc
	local qr_code
	local qr_privkey
    local endPoint = luci.sys.exec("uci get ddns.myddns.domain")
    local listenPort = luci.sys.exec("uci get network.wg0.listen_port)
    local endPointString = tostring(endPoint .. ":" .. listenPort)
	if fs.access("/usr/bin/qrencode") then
		qr_privkey = qr_clean("privkey", luci.sys.exec("wg genkey 2>/dev/null"))
		if qr_pubkey[ikey] and qr_privkey then
			qr_enc = "[Interface]\n" ..qr_privkey.. "\n[Peer]\n" ..qr_pubkey[ikey].. "\nAllowedIPs = 0.0.0.0/0, ::/0\nEndpoint = ".. endPointString .."\n"
			qr_code = luci.sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- '" ..qr_enc.. "' 2>/dev/null")
		else
			qr_code = "<em>The QR-Code could not be generated, the wg interface setup is incomplete!</em>"
		end
	else
		qr_code = "<em>For QR-Code support please install the package 'qrencode'!</em>"
	end

the colon needs more escaping (1 for lua, 2 for qrencode), see a working example here (for wifi qrcode generation):

1 Like

Thanks for the pointer, but I am still not sure what the escape character is supposed to be for the colon based on that example.

It looks like it's actually not getting the host name now. This is different than what I saw yesterday. Running that code yields the following error:

Tue Jun 30 08:49:45 2020 daemon.err uhttpd[6324]: sh: :51820: not found

notice it is only logging the port and the colon, not the host name. Is the colon some kind of delimiter?
this is the code

       local qr_enc                                                                                                                                                              
        local qr_code                                                                                                                                                             
        local qr_privkey                                                                                                                                                          
                                                                                                                                                                                  
        local host = luci.sys.exec("uci get ddns.ddns.lookup_host")                                                                                                               
        local listenPort = tostring(luci.sys.exec("uci get network.wg0.listen_port"))                                                                                             
        local endPoint = tostring(host..":"..listenPort)                                                                                                                          
                                                                                                                                                                                  
        luci.sys.exec("echo "..endPoint)                                                                                                                                          
                                                                                                                                                                                  
        if fs.access("/usr/bin/qrencode") then                                                                                                                                    
                qr_privkey = qr_clean("privkey", luci.sys.exec("wg genkey 2>/dev/null"))                                                                                          
                if qr_pubkey[ikey] and qr_privkey then                                                                                                                            
                                                                                                                                                                                  
                        qr_enc = "[Interface]\n" ..qr_privkey.. "\n[Peer]\n" ..qr_pubkey[ikey].. "\nAllowedIPs = 0.0.0.0/0, ::/0\nEndpoint = ".. endPoint .."\nPersistentKeepalive
                        qr_code = luci.sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- '" ..qr_enc.. "' 2>/dev/null")                                           
                else                                                                                                                                                              
                        qr_code = "<em>The QR-Code could not be generated, the wg interface setup is incomplete!</em>"                                                            
                end                                                                                                                                                               
        else                                                                                                                                                                      
                qr_code = "<em>For QR-Code support please install the package 'qrencode'!</em>"                                                                                   
        end

Sorry for the wrong "escape" pointer. I've mocked up your requirement in the existing wireguard code - and this one works for me:

	local qr_enc
	local qr_code
	local qr_privkey
	local host = "wg.example.com"
	local listenPort = "45000"
	local endPoint = tostring(host.. ":" ..listenPort)
	if fs.access("/usr/bin/qrencode") then
		qr_privkey = qr_clean("privkey", luci.sys.exec("wg genkey 2>/dev/null"))
		if qr_pubkey[ikey] and qr_privkey then
			qr_enc = "[Interface]\n" ..qr_privkey.. "\n[Peer]\n" ..qr_pubkey[ikey].. "\nAllowedIPs = 0.0.0.0/0, ::/0\nEndpoint = " ..endPoint.. "\nPersistentKeepalive = 25\n"
			qr_code = luci.sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- '" ..qr_enc.. "' 2>/dev/null")
		else
			qr_code = "<em>The QR-Code could not be generated, the wg interface setup is incomplete!</em>"
		end
	else
		qr_code = "<em>For QR-Code support please install the package 'qrencode'!</em>"
	end

Successfully tested with an Android 10 mobile phone ...

Yes, that's one way I tested it as well, and that worked, but it is just static string. At least it confirmed that the strings are being concatenated. Nevertheless, when running the uci get commands it always gives me that error. I don't understand why. Can you test it out?

These might set the variables for you on your system

uci set system.lookup_host="testvpn.ddns.net"
uci set system.listen_port="51820"
uci commit system

Works for me as well ...

/etc/config/system

config system
        [...]
	option host 'wg.example.com'
	option port '45000'

wg excerpt

[...]
<%-
	local qr_enc
	local qr_code
	local qr_privkey
	local uci  = require "luci.model.uci".cursor()
	local host = uci:get("system", "@system[0]", "host") or ""
	local listenPort = uci:get("system", "@system[0]", "port") or ""
	local endPoint = tostring(host.. ":" ..listenPort)
	if fs.access("/usr/bin/qrencode") then
		qr_privkey = qr_clean("privkey", luci.sys.exec("wg genkey 2>/dev/null"))
		if qr_pubkey[ikey] and qr_privkey then
			qr_enc = "[Interface]\n" ..qr_privkey.. "\n[Peer]\n" ..qr_pubkey[ikey].. "\nAllowedIPs = 0.0.0.0/0, ::/0\nEndpoint = " ..endPoint.. "\nPersistentKeepalive = 25\n"
			qr_code = luci.sys.exec("/usr/bin/qrencode --inline --8bit --type=SVG --output=- '" ..qr_enc.. "' 2>/dev/null")
		else
			qr_code = "<em>The QR-Code could not be generated, the wg interface setup is incomplete!</em>"
		end
	else
		qr_code = "<em>For QR-Code support please install the package 'qrencode'!</em>"
	end
-%>
[...]