From e820fe36230d2ea39d0d2f2d42e6479a156c7979 Mon Sep 17 00:00:00 2001 From: Cameron Thompson <50184035+iamromulan@users.noreply.github.com> Date: Thu, 30 Jan 2025 20:43:29 -0500 Subject: [PATCH] Add wireguard luci app - Pulled from GoldenOrb --- .../luci-app-GO-wireguard/CONTROL/control | 11 + .../luci-app-GO-wireguard/CONTROL/postinst | 3 + .../luci-app-GO-wireguard/CONTROL/prerm | 4 + ipk-source/luci-app-GO-wireguard/build-ipk | 74 ++++ .../root/etc/config/wireguard | 5 + .../root/etc/config/wireguard_recipes | 36 ++ .../root/etc/init.d/wireguard | 92 +++++ .../usr/lib/lua/luci/controller/wireguard.lua | 111 ++++++ .../lua/luci/model/cbi/wireguard-client.lua | 104 ++++++ .../lua/luci/model/cbi/wireguard-server.lua | 130 +++++++ .../usr/lib/lua/luci/model/cbi/wireguard.lua | 182 ++++++++++ .../view/wireguard/cbi-select-input-add.htm | 111 ++++++ .../usr/lib/lua/luci/view/wireguard/conf.htm | 27 ++ .../lib/lua/luci/view/wireguard/ovpn_css.htm | 38 ++ .../lua/luci/view/wireguard/pageswitch.htm | 30 ++ .../lib/lua/luci/view/wireguard/text_conf.htm | 61 ++++ .../lib/lua/luci/view/wireguard/wireguard.htm | 228 ++++++++++++ .../root/usr/lib/wireguard/conf.sh | 134 +++++++ .../root/usr/lib/wireguard/create.sh | 81 +++++ .../root/usr/lib/wireguard/keygen.sh | 68 ++++ .../root/usr/lib/wireguard/startvpn.sh | 327 ++++++++++++++++++ .../root/usr/lib/wireguard/stopvpn.sh | 75 ++++ .../root/usr/lib/wireguard/text.sh | 19 + .../luci-static/resources/icons/wireguard.png | Bin 0 -> 22762 bytes .../resources/icons/wireguard_disabled.png | Bin 0 -> 23205 bytes 25 files changed, 1951 insertions(+) create mode 100755 ipk-source/luci-app-GO-wireguard/CONTROL/control create mode 100755 ipk-source/luci-app-GO-wireguard/CONTROL/postinst create mode 100755 ipk-source/luci-app-GO-wireguard/CONTROL/prerm create mode 100755 ipk-source/luci-app-GO-wireguard/build-ipk create mode 100755 ipk-source/luci-app-GO-wireguard/root/etc/config/wireguard create mode 100755 ipk-source/luci-app-GO-wireguard/root/etc/config/wireguard_recipes create mode 100755 ipk-source/luci-app-GO-wireguard/root/etc/init.d/wireguard create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/controller/wireguard.lua create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard-client.lua create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard-server.lua create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard.lua create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/cbi-select-input-add.htm create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/conf.htm create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/ovpn_css.htm create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/pageswitch.htm create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/text_conf.htm create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/wireguard.htm create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/conf.sh create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/create.sh create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/keygen.sh create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/startvpn.sh create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/stopvpn.sh create mode 100755 ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/text.sh create mode 100755 ipk-source/luci-app-GO-wireguard/root/www/luci-static/resources/icons/wireguard.png create mode 100755 ipk-source/luci-app-GO-wireguard/root/www/luci-static/resources/icons/wireguard_disabled.png diff --git a/ipk-source/luci-app-GO-wireguard/CONTROL/control b/ipk-source/luci-app-GO-wireguard/CONTROL/control new file mode 100755 index 0000000..4484a20 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/CONTROL/control @@ -0,0 +1,11 @@ +Package: ext-wireguard +Version: 4.500-1 +Depends: libc, wireguard-tools, kmod-wireguard, luci-proto-wireguard, udptunnel, eoip +Source: package/rooter/0optionalapps/ext-wireguard +SourceName: ext-wireguard +Section: utils +SourceDateEpoch: 1716401566 +Maintainer: Created by DM/makefile by Cobia@whirlpool +Architecture: all +Installed-Size: 23912 +Description: Install scripts for Wireguard diff --git a/ipk-source/luci-app-GO-wireguard/CONTROL/postinst b/ipk-source/luci-app-GO-wireguard/CONTROL/postinst new file mode 100755 index 0000000..77d54d2 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/CONTROL/postinst @@ -0,0 +1,3 @@ +#!/bin/sh +ln -sf /usr/bin/udptunnel /sbin/udptunnel +exit 0 diff --git a/ipk-source/luci-app-GO-wireguard/CONTROL/prerm b/ipk-source/luci-app-GO-wireguard/CONTROL/prerm new file mode 100755 index 0000000..12d06ec --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/CONTROL/prerm @@ -0,0 +1,4 @@ +#!/bin/sh +[ -s ${IPKG_INSTROOT}/lib/functions.sh ] || exit 0 +. ${IPKG_INSTROOT}/lib/functions.sh +default_prerm $0 $@ diff --git a/ipk-source/luci-app-GO-wireguard/build-ipk b/ipk-source/luci-app-GO-wireguard/build-ipk new file mode 100755 index 0000000..eb83cf6 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/build-ipk @@ -0,0 +1,74 @@ +#!/bin/sh + +# Script for building OpenWRT .ipk packages using tar by iamromulan +# Works with SDXPPINN OpenWRT - iamromulan +# This script accepts an optional path to the directory containing the `CONTROL` and `root` directories. +# Usage: ./build-ipk.sh [path] +# If no path is provided, the script will look in the current directory for `CONTROL` and `root` directories. +# This will spit out an ipk in the current directory + +# Check if the script is run as root. If not, rerun with sudo. +if [ "$(id -u)" -ne 0 ]; then + echo "Script is not running as root. Re-executing with sudo..." + exec sudo "$0" "$@" +fi + +# Set the default build path to the current directory +build_path="." + +# Check if a path is provided as the first argument +if [ "$1" ]; then + build_path="$1" +fi + +# Check if the required directories are present in the specified path +if [ ! -d "${build_path}/CONTROL" ] || [ ! -d "${build_path}/root" ]; then + echo "Error: CONTROL and root directories must be present in the specified path (${build_path})." + exit 1 +fi + +# Extract values from the CONTROL/control file in the specified path +pkgname=$(grep -i '^Package:' "${build_path}/CONTROL/control" | awk '{print $2}') +version=$(grep -i '^Version:' "${build_path}/CONTROL/control" | awk '{print $2}') +architecture=$(grep -i '^Architecture:' "${build_path}/CONTROL/control" | awk '{print $2}') + +# Check if values are extracted correctly +if [ -z "$pkgname" ] || [ -z "$version" ] || [ -z "$architecture" ]; then + echo "Error: Failed to extract Package, Version, or Architecture from ${build_path}/CONTROL/control." + exit 1 +fi + +# Set the final IPK name based on the extracted values +ipkname="${pkgname}_${version}_${architecture}.ipk" + +# Ensure all CONTROL scripts are executable +echo "Setting permissions for CONTROL scripts..." +chmod +x "${build_path}/CONTROL"/* + +# Set ownership for CONTROL and root files +echo "Setting ownership for all package files..." +chown -R root:root "${build_path}/CONTROL"/* +chown -R root:root "${build_path}/root"/* + +# Create control.tar.gz from the CONTROL directory +echo "Creating control.tar.gz..." +tar -czvf control.tar.gz -C "${build_path}/CONTROL" . + +# Create data.tar.gz from the root directory +echo "Creating data.tar.gz..." +tar -czvf data.tar.gz -C "${build_path}/root" . + +# Create debian-binary file (must contain exactly "2.0" without a newline) +echo -n "2.0" > debian-binary +chown -R root:root debian-binary + +# Combine the components into the final .ipk file using tar +echo "Packaging ${ipkname}..." +tar -czvf "$ipkname" debian-binary control.tar.gz data.tar.gz + +# Clean up intermediate files +echo "Cleaning up temporary files..." +rm -f control.tar.gz data.tar.gz debian-binary + +echo "IPK package ${ipkname} created successfully using tar." + diff --git a/ipk-source/luci-app-GO-wireguard/root/etc/config/wireguard b/ipk-source/luci-app-GO-wireguard/root/etc/config/wireguard new file mode 100755 index 0000000..77908d4 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/etc/config/wireguard @@ -0,0 +1,5 @@ + +config settings 'settings' + option enabled '0' + option client '0' + option server '0' diff --git a/ipk-source/luci-app-GO-wireguard/root/etc/config/wireguard_recipes b/ipk-source/luci-app-GO-wireguard/root/etc/config/wireguard_recipes new file mode 100755 index 0000000..52a6b2b --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/etc/config/wireguard_recipes @@ -0,0 +1,36 @@ +config wireguard_recipe b_client + option _description "Wireguard Client" + option _role "client" + option client "1" + option port "51280" + option auto '0' + option addresses '' + option dns '' + option privatekey '' + option name '' + option keepalive '25' + option publickey '' + option presharedkey '' + option ips '' + option ra_ips '1' + option endpoint_host '' + option sport '51280' + option active '0' + option udptunnel '0' + option mtu '1280' + +config wireguard_recipe b_server + option _description "Wireguard Server" + option _role "server" + option client "0" + option port "51280" + option auto '0' + option addresses '' + option publickey '' + option privatekey '' + option usepre '0' + option presharedkey '' + option active '0' + option udptunnel '0' + option udpport '54321' + option mtu '1280' \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/etc/init.d/wireguard b/ipk-source/luci-app-GO-wireguard/root/etc/init.d/wireguard new file mode 100755 index 0000000..16a34ce --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/etc/init.d/wireguard @@ -0,0 +1,92 @@ +#!/bin/sh /etc/rc.common +. /lib/functions.sh +# Copyright (C) 2006 OpenWrt.org + +START=99 + +log() { + logger -t "WireGuard Init.d : " "$@" +} + +chk_zone() { + local config=$1 + + config_get src $config src + config_get dest $config dest + if [ $src = "lan" -a $dest = "wg" ]; then + uci set firewall."$config".dest="wan" + uci commit firewall + fi +} + +check_config () { + log "Check Client Interfaces" + uci delete network.wg0 + uci delete network.wg1 + uci commit network + uci set network.wg0=interface + uci set network.wg0.proto="wireguard" + uci set network.wg0.auto="0" + uci set network.wg0.private_key="" + uci set network.wg0.listen_port="" + uci add_list network.wg0.addresses="" + uci set network.wg1=interface + uci set network.wg1.proto="wireguard" + uci set network.wg1.auto="0" + uci set network.wg1.private_key="" + uci set network.wg1.listen_port="" + uci add_list network.wg1.addresses="" + uci commit network + + uci delete firewall.wgzone + uci delete firewall.wgwforward + uci delete firewall.wwgforward + uci delete firewall.lwgforward + uci delete firewall.wglforward + uci commit firewall + uci set firewall.wgzone=zone + uci set firewall.wgzone.name="wg" + uci set firewall.wgzone.forward="ACCEPT" + uci set firewall.wgzone.output="ACCEPT" + uci set firewall.wgzone.network="wg0 wg1" + uci set firewall.wgzone.input="ACCEPT" + uci set firewall.wgzone.masq="1" + uci set firewall.wgzone.mtu_fix="1" + uci commit firewall + + config_load firewall + config_foreach chk_zone forwarding + + /etc/init.d/firewall restart +} + +chk_start() { + local config=$1 + + config_get auto $config auto + uci set wireguard."$config".active="0" + uci commit wireguard + if [ $auto = '1' ]; then + /usr/lib/wireguard/startvpn.sh $config + else + /usr/lib/wireguard/stopvpn.sh $config + fi +} + +start() { + uci set wireguard.settings.client="0" + uci set wireguard.settings.server="0" + uci commit wireguard + if [ ! -e /etc/openvpn ]; then + mkdir /etc/openvpn + fi + check_config + + config_load wireguard + config_foreach chk_start wireguard + if [ -e /etc/crontabs/root ]; then + sed -i '/wireguard_watchdog/d' /etc/crontabs/root + fi + echo '* * * * * /usr/bin/wireguard_watchdog' >> /etc/crontabs/root + /etc/init.d/cron restart +} \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/controller/wireguard.lua b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/controller/wireguard.lua new file mode 100755 index 0000000..48ea3c3 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/controller/wireguard.lua @@ -0,0 +1,111 @@ +-- Copyright 2016-2017 Dan Luedtke +-- Licensed to the public under the Apache License 2.0. + +module("luci.controller.wireguard", package.seeall) + +I18N = require "luci.i18n" +translate = I18N.translate + +function index() + local multilock = luci.model.uci.cursor():get("custom", "multiuser", "multi") or "0" + local rootlock = luci.model.uci.cursor():get("custom", "multiuser", "root") or "0" + if (multilock == "0") or (multilock == "1" and rootlock == "1") then + entry({"admin", "vpn", "wireguard"}, cbi("wireguard"), _("Wireguard"), 63) + entry( {"admin", "vpn", "wireguard", "client"}, cbi("wireguard-client"), nil ).leaf = true + entry( {"admin", "vpn", "wireguard", "server"}, cbi("wireguard-server"), nil ).leaf = true + end + + entry( {"admin", "vpn", "wireguard", "wupload"}, call("conf_upload")) + entry( {"admin", "vpn", "generateconf"}, call("conf_gen")) + entry( {"admin", "vpn", "textconf"}, call("text_gen")) + entry( {"admin", "vpn", "wirestatus"}, call("wirestatus")) +end + +function conf_upload() + local fs = require("nixio.fs") + local http = require("luci.http") + local util = require("luci.util") + local uci = require("luci.model.uci").cursor() + local upload = http.formvalue("ovpn_file") + local name = http.formvalue("instance_name2") + local file = "/etc/openvpn/" ..name.. ".conf" + + if name and upload then + local fp + + http.setfilehandler( + function(meta, chunk, eof) + local data = util.trim(chunk:gsub("\r\n", "\n")) .. "\n" + data = util.trim(data:gsub("[\128-\255]", "")) + + if not fp and meta and meta.name == "ovpn_file" then + fp = io.open(file, "w") + end + if fp and data then + fp:write(data) + end + if fp and eof then + fp:close() + end + end + ) + + if fs.access(file) then + os.execute("/usr/lib/wireguard/conf.sh " .. name .. " " .. file) + end + end + http.redirect(luci.dispatcher.build_url('admin/vpn/wireguard')) +end + +function conf_gen() + os.execute("/usr/lib/wireguard/create.sh") +end + +function text_gen() + local set = luci.http.formvalue("set") + os.execute("/usr/lib/wireguard/text.sh " .. "\"" .. set .. "\"") +end + +function wirestatus() + local data = { } + local last_device = "" + + local wg_dump = io.popen("wg show all dump") + if wg_dump then + local line + for line in wg_dump:lines() do + local line = string.split(line, "\t") + if not (last_device == line[1]) then + last_device = line[1] + data[line[1]] = { + name = line[1], + public_key = line[3], + listen_port = line[4], + fwmark = line[5], + peers = { } + } + else + local peer = { + public_key = line[2], + endpoint = line[4], + allowed_ips = { }, + latest_handshake = line[6], + transfer_rx = line[7], + transfer_tx = line[8], + persistent_keepalive = line[9] + } + if not (line[4] == '(none)') then + for ipkey, ipvalue in pairs(string.split(line[5], ",")) do + if #ipvalue > 0 then + table.insert(peer['allowed_ips'], ipvalue) + end + end + end + table.insert(data[line[1]].peers, peer) + end + end + end + + luci.http.prepare_content("application/json") + luci.http.write_json(data) +end \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard-client.lua b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard-client.lua new file mode 100755 index 0000000..45e2216 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard-client.lua @@ -0,0 +1,104 @@ +require("luci.ip") +require("luci.model.uci") + +--luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1]) + +local m = Map("wireguard", translate("Wireguard Client"), translate("Set up a Wireguard Client")) + +e = m:section(NamedSection, "settings", "") + +m.on_init = function(self) + --luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1]) +end + +btn = e:option(Button, "_btn", translate(" ")) +btn.inputtitle = translate("Back to Main Page") +btn.inputstyle = "apply" +btn.redirect = luci.dispatcher.build_url( + "admin", "vpn", "wireguard" +) +function btn.write(self, section, value) + luci.http.redirect( self.redirect ) +end + + +local s = m:section( NamedSection, arg[1], "wireguard", translate("Client") ) + +ip = s:option(Value, "addresses", translate("IP Addresses :"), translate("Comma separated list of IP Addresses that server will accept from this client")); +ip.rmempty = true; +ip.optional=false; +ip.default="10.14.0.2/24"; + +port = s:option(Value, "port", translate("Listen Port :"), translate("Client Listen Port")); +port.rmempty = true; +port.optional=false; +port.default="51820"; + +ul = s:option(ListValue, "udptunnel", translate("Enable UDP over TCP :")); +ul:value("0", translate("No")) +ul:value("1", translate("Yes")) +ul.default=0 + +dns = s:option(Value, "dns", translate("DNS Servers :"), translate("Comma separated list of DNS Servers.")); +dns.rmempty = true; +dns.optional=false; + +mtu = s:option(Value, "mtu", translate("MTU :"), translate("Maximum MTU")); +mtu.rmempty = true; +mtu.optional=false; +mtu.datatype = 'range(1280,1420)'; +mtu.default="1280"; + +pka = s:option(Value, "persistent_keepalive", translate("Persistent Keep Alive :"), translate("Seconds between keep alive messages")); +pka.rmempty = true; +pka.optional=false; +pka.datatype = 'range(1,100)'; +pka.default="25"; + +pkey = s:option(Value, "privatekey", translate("Private Key :"), translate("Private Key supplied by the Server")); +pkey.rmempty = true; +pkey.optional=false; + +il = s:option(ListValue, "wginter", translate("Interface to Use :")); +il:value("0", translate("WG0")) +il:value("1", translate("WG1")) +il.default="0" + +bl = s:option(ListValue, "auto", translate("Start on Boot :")); +bl:value("0", translate("No")) +bl:value("1", translate("Yes")) +bl.default="0" + +xbl = s:option(ListValue, "forward", translate("All Traffic Through Tunnel :")); +xbl:value("0", translate("No")) +xbl:value("1", translate("Yes")) +xbl.default="1" + +s = m:section( NamedSection, arg[1], "wireguard", translate("Server") ) + +name = s:option( Value, "name", translate("Server Name :"), translate("Optional Server name")) + +pukey = s:option(Value, "publickey", translate("Public Key :"), translate("Public Key of the Server")); +pukey.rmempty = true; +pukey.optional=false; + +prkey = s:option(Value, "presharedkey", translate("Presharedkey :"), translate("PreShared Key from the Server")); +prkey.rmempty = true; +prkey.optional=false; + +host = s:option(Value, "endpoint_host", translate("Server Address :"), translate("URL or IP Address of Server")); +host.rmempty = true; +host.optional=false; +host.default=""; + +sport = s:option(Value, "sport", translate("Listen Port :"), translate("Server Listen Port")); +sport.rmempty = true; +sport.optional=false; +sport.default="51820"; + +sip = s:option(Value, "ips", translate("Allowed IP Addresses :"), translate("Comma separated list of IP Addresses that server will accept")); +sip.rmempty = true; +sip.optional=false; +sip.default="10.14.0.0/24"; + +return m \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard-server.lua b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard-server.lua new file mode 100755 index 0000000..5fb15ee --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard-server.lua @@ -0,0 +1,130 @@ +require("luci.ip") +require("luci.model.uci") + +--luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1]) + +local m = Map("wireguard", translate("Wireguard Server"), translate("Set up a Wireguard Server")) + +e = m:section(NamedSection, "settings", "") + +m.on_init = function(self) + luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1]) +end + +m.on_after_save = function(self) + luci.sys.call("/usr/lib/wireguard/keygen.sh " .. arg[1] .. "&") +end + +btn = e:option(Button, "_btn", translate(" ")) +btn.inputtitle = translate("Back to Main Page") +btn.inputstyle = "apply" +btn.redirect = luci.dispatcher.build_url( + "admin", "vpn", "wireguard" +) +function btn.write(self, section, value) + luci.http.redirect( self.redirect ) +end + + +local s = m:section( NamedSection, arg[1], "wireguard", translate("Server") ) + +ip = s:option(Value, "addresses", translate("Internal IP Address :")); +ip.rmempty = true; +ip.optional=false; +ip.default="10.14.0.1/32"; +ip.datatype = "ipaddr" + +host = s:option(Value, "endpoint_host", translate("Server Address :"), translate("URL or IP Address of Server")); +host.rmempty = true; +host.optional=false; +host.default="example.wireguard.org"; + +port = s:option(Value, "port", translate("Port :"), translate("Server Listen Port. Default is 51280")); +port.rmempty = true; +port.optional=false; +port.default="51280"; + +ul = s:option(ListValue, "udptunnel", "Enable UDP over TCP :"); +ul:value("0", translate("No")) +ul:value("1", translate("Yes")) +ul.default=0 + +uport = s:option(Value, "udpport", translate("UDP over TCP Port :"), translate("Server Local TCP Port. Default is 54321")); +uport.rmempty = true; +uport.optional=false; +uport.default="54321"; +uport:depends("udptunnel", "1") + +pkey = s:option(DummyValue, "privatekey", translate("Private Key :")); +pkey.optional=false; + +pukey = s:option(DummyValue, "publickey", translate("Public Key :"), translate("Server Public key sent to Clients")); +pukey.optional=false; + +pl = s:option(ListValue, "usepre", "Use PreSharedKey :"); +pl:value("0", translate("No")) +pl:value("1", translate("Yes")) +pl.default=0 + +prkey = s:option(DummyValue, "presharedkey", translate("PreShared Key :"), translate("PreShared Key sent to Client")); +prkey.optional=false; +prkey:depends("usepre", "1") + +bl = s:option(ListValue, "auto", translate("Start on Boot :")); +bl:value("0", translate("No")) +bl:value("1", translate("Yes")) +bl.default="0" + +xbl = s:option(ListValue, "forward", translate("All Traffic Through Tunnel :")); +xbl:value("0", translate("No")) +xbl:value("1", translate("Yes")) +xbl.default="1" + + +b3 = s:option(DummyValue, "blank", " "); + +sx = s:option(Value, "_dmy1", translate(" ")) +sx.template = "wireguard/conf" + +ss = m:section(TypedSection, "custom" .. arg[1], translate("Clients"), translate("Clients of this server")) +ss.anonymous = true +ss.addremove = true + +name = ss:option(Value, "name", translate("Client Name")) +name.optional=false; + +cport = ss:option(Value, "endpoint_port", translate("Listen Port :"), translate("Port sent to Client. Default is 51280")); +cport.rmempty = true; +cport.optional=false; +cport.default=""; + +aip = ss:option(Value, "address", translate("Assigned IP Address :"), translate("IP Address assigned to Client")); +aip.rmempty = true; +aip.optional=false; +aip.default="10.14.0.2/32"; + +dns = ss:option(Value, "dns", translate("DNS Servers :"), translate("Comma separated list of DNS Servers sent to Client")); +dns.rmempty = true; +dns.optional=false; +dns.default=""; + +mtu = ss:option(Value, "mtu", translate("MTU :"), translate("Maximum MTU")); +mtu.rmempty = true; +mtu.optional=false; +mtu.datatype = 'range(1280,1420)'; +mtu.default="1280"; + +aip = ss:option(Value, "allowed_ips", translate("Allowed IP Address :"), translate("Comma separated list of IP Addresses allowed from Client")); +aip.rmempty = true; +aip.optional=false; +aip.default="0.0.0.0/0,::/0"; + +pukey = ss:option(DummyValue, "publickey", translate("Public Key :"), translate("Client Public Key")); +pukey.optional=false; + +pikey = ss:option(DummyValue, "privatekey", translate("Private Key :"), translate("Private Key sent to Client")); +pikey.optional=false; + +b3 = ss:option(DummyValue, "blank", " "); + +return m \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard.lua b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard.lua new file mode 100755 index 0000000..0aab305 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/model/cbi/wireguard.lua @@ -0,0 +1,182 @@ +local fs = require "nixio.fs" +local sys = require "luci.sys" +local uci = require "luci.model.uci".cursor() +local testfullps = sys.exec("ps --help 2>&1 | grep BusyBox") --check which ps do we have +local psstring = (string.len(testfullps)>0) and "ps w" or "ps axfw" --set command we use to get pid + +local m = Map("wireguard", translate("Wireguard"), translate("Set up a Wireguard VPN Tunnel on your Router")) + +local s = m:section( TypedSection, "wireguard", translate("Instances"), translate("Below is a list of configured Wireguard Instances and their current state") ) +s.template = "cbi/tblsection" +s.template_addremove = "wireguard/cbi-select-input-add" +s.addremove = true +s.add_select_options = { } + +local cfg = s:option(DummyValue, "config") +function cfg.cfgvalue(self, section) + local file_cfg = self.map:get(section, "client") + if file_cfg == "1" then + s.extedit = luci.dispatcher.build_url("admin", "vpn", "wireguard", "client", "%s") + else + s.extedit = luci.dispatcher.build_url("admin", "vpn", "wireguard", "server", "%s") + end +end + +uci:load("wireguard_recipes") +uci:foreach( "wireguard_recipes", "wireguard_recipe", + function(section) + s.add_select_options[section['.name']] = + section['_description'] or section['.name'] + end +) + +function s.parse(self, section) + local recipe = luci.http.formvalue( + luci.cbi.CREATE_PREFIX .. self.config .. "." .. + self.sectiontype .. ".select" + ) + + if recipe and not s.add_select_options[recipe] then + self.invalid_cts = true + else + TypedSection.parse( self, section ) + end +end + +function s.create(self, name) + local recipe = luci.http.formvalue( + luci.cbi.CREATE_PREFIX .. self.config .. "." .. + self.sectiontype .. ".select" + ) + local name = luci.http.formvalue( + luci.cbi.CREATE_PREFIX .. self.config .. "." .. + self.sectiontype .. ".text" + ) + if #name > 3 and not name:match("[^a-zA-Z0-9_]") then + local s = uci:section("wireguard", "wireguard", name) + if s then + local options = uci:get_all("wireguard_recipes", recipe) + for k, v in pairs(options) do + if k ~= "_role" and k ~= "_description" then + if type(v) == "boolean" then + v = v and "1" or "0" + end + uci:set("wireguard", name, k, v) + end + end + uci:save("wireguard") + uci:commit("wireguard") + if extedit then + luci.http.redirect( self.extedit:format(name) ) + end + end + elseif #name > 0 then + self.invalid_cts = true + end + return 0 +end + +function s.remove(self, name) + local cfg_file = "/etc/openvpn/" ..name.. ".conf" + local auth_file = "/etc/openvpn/" ..name.. ".auth" + if fs.access(cfg_file) then + fs.unlink(cfg_file) + end + if fs.access(auth_file) then + fs.unlink(auth_file) + end + uci:delete("wireguard", name) + uci:save("wireguard") + uci:commit("wireguard") +end + +local port = s:option( DummyValue, "client", translate("Type") ) +function port.cfgvalue(self, section) + local val = AbstractValue.cfgvalue(self, section) + if val == nil then + val = 0 + end + if val == "1" then + return "Client" + else + return "Server" + end +end + +local addr = s:option( DummyValue, "addresses", translate("IP Addresses") ) +function addr.cfgvalue(self, section) + local val = AbstractValue.cfgvalue(self, section) + return val or "----" +end + +local auto = s:option( DummyValue, "udptunnel", translate("UDP over TCP") ) +function auto.cfgvalue(self, section) + local val = AbstractValue.cfgvalue(self, section) + if val == nil then + val = 0 + end + if val == "1" then + return "Yes" + else + return "No" + end +end + +local auto = s:option( DummyValue, "auto", translate("Start on Boot") ) +function auto.cfgvalue(self, section) + local val = AbstractValue.cfgvalue(self, section) + if val == nil then + val = 0 + end + if val == "1" then + return "Yes" + else + return "No" + end +end + +local active = s:option( DummyValue, "active", translate("Started") ) +function active.cfgvalue(self, section) + local val = AbstractValue.cfgvalue(self, section) + if val == nil then + val = 0 + end + if val == "1" then + return "Yes" + else + return "No" + end +end + +local updown = s:option( Button, "_updown", translate("Start/Stop") ) +updown._state = false +updown.redirect = luci.dispatcher.build_url( + "admin", "vpn", "wireguard" +) +function updown.cbid(self, section) + local file_cfg = self.map:get(section, "active") + if file_cfg == "1" then + pid = 1 + else + pid = nil + end + self._state = pid ~= nil + self.option = self._state and "stop" or "start" + return AbstractValue.cbid(self, section) +end +function updown.cfgvalue(self, section) + self.title = self._state and "stop" or "start" + self.inputstyle = self._state and "reset" or "reload" +end +function updown.write(self, section, value) + if self.option == "stop" then + sys.call("/usr/lib/wireguard/stopvpn.sh %s" % section) + else + sys.call("/usr/lib/wireguard/startvpn.sh %s" % section) + end + luci.http.redirect( self.redirect ) +end + +m:section(SimpleSection).template = "wireguard/wireguard" + +return m \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/cbi-select-input-add.htm b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/cbi-select-input-add.htm new file mode 100755 index 0000000..8f37846 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/cbi-select-input-add.htm @@ -0,0 +1,111 @@ + + + +<%+wireguard/ovpn_css%> + +
+
+

<%:Template based configuration%>

+
+
+ +
+
+ +
+
+
+
+
+

<%:Conf configuration file upload%>

+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/conf.htm b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/conf.htm new file mode 100755 index 0000000..e75e88f --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/conf.htm @@ -0,0 +1,27 @@ + + + +
+ + + + + + + +
   
+
diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/ovpn_css.htm b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/ovpn_css.htm new file mode 100755 index 0000000..55c0a54 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/ovpn_css.htm @@ -0,0 +1,38 @@ + diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/pageswitch.htm b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/pageswitch.htm new file mode 100755 index 0000000..47056fa --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/pageswitch.htm @@ -0,0 +1,30 @@ +<%# + Copyright 2008 Steven Barth + Copyright 2008 Jo-Philipp Wich + Licensed to the public under the Apache License 2.0. +-%> + +<%+openvpn/ovpn_css%> + +
+

+ <%:Overview%> » + <%=luci.i18n.translatef("Instance \"%s\"", self.instance)%> +

+ <% if self.mode == "basic" then %> + "><%:Switch to advanced configuration%> »

+


+ <% elseif self.mode == "advanced" then %> + <%:Switch to basic configuration%> »

+


+ <%:Configuration category%>: + <% for i, c in ipairs(self.categories) do %> + <% if c == self.category then %> + <%=translate(c)%> + <% else %> + "><%=translate(c)%> + <% end %> + <% if next(self.categories, i) then %>|<% end %> + <% end %> + <% end %> +
diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/text_conf.htm b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/text_conf.htm new file mode 100755 index 0000000..2a1a4b5 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/text_conf.htm @@ -0,0 +1,61 @@ +<% + +%> + + + +
+ <%:Paste Configuration File Here%> + + + + +
+ +
+ + + + + + + + + + +
<%:Instance Name : %>
<%:Start on Boot : %>
+ +  
+
diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/wireguard.htm b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/wireguard.htm new file mode 100755 index 0000000..cf7544e --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/lua/luci/view/wireguard/wireguard.htm @@ -0,0 +1,228 @@ +<%# + Copyright 2016-2017 Dan Luedtke + Licensed to the public under the Apache License 2.0. +-%> + +<% + +-%> + + + +

<%:WireGuard Status%>

+ +
+ +
+ + + + + + +
+
<%:Interface %>
+
  
+ + + + + + + + + + + + + + + +
  +
<%:Configuration%>
+
   +
+ <%:Collecting data...%> +
+
  +
<%:Peer%>
+
   +
+ <%:Collecting data...%> +
+
+ + + + + + + +
+
<%:Interface %>
+
  
+ + + + + + + + + + + + + + + +
  +
<%:Configuration%>
+
   +
+ <%:Collecting data...%> +
+
  +
<%:Peer%>
+
   +
+ <%:Collecting data...%> +
+
+ +
+ +
+ diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/conf.sh b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/conf.sh new file mode 100755 index 0000000..5c36ca2 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/conf.sh @@ -0,0 +1,134 @@ +#!/bin/sh + +log() { + modlog "Wireguard Conf" "$@" +} + +name=$1 +file=$2 +auto=$3 +if [ -z $auto ]; then + auto="0" +fi + +extract() { + line=$1 + PD=$(echo "$line" | grep "#") + if [ ! -z "$PD" ]; then + return + fi + PRK=$(echo "$line" | grep "PrivateKey" | tr " " ",") + if [ ! -z "$PRK" ]; then + PrivateKey=$(echo $PRK | cut -d, -f3) + fi + PRK=$(echo "$line" | grep "PublicKey" | tr " " ",") + if [ ! -z "$PRK" ]; then + PublicKey=$(echo $PRK | cut -d, -f3) + fi + PRK=$(echo "$line" | grep "PresharedKey" | tr " " ",") + if [ ! -z "$PRK" ]; then + PreSharedKey=$(echo $PRK | cut -d, -f3) + fi + INTER=$(echo "$line" | grep "WGinterface" | tr " " ",") + if [ ! -z "$INTER" ]; then + wginter=$(echo $INTER | cut -d, -f3) + if [ "$wginter" -gt 1 ]; then + wginter="1" + fi + fi + PRK=$(echo "$line" | grep "Address" | tr " " "#") + if [ ! -z "$PRK" ]; then + if [ -z $Address ]; then + Address=$(echo $PRK | cut -d# -f3) + else + Address=$Address","$(echo $PRK | cut -d# -f3) + fi + fi + PRK=$(echo "$line" | grep "dns" | tr " " "#") + if [ ! -z "$PRK" ]; then + dns=$(echo $PRK | cut -d# -f3) + fi + PRK=$(echo "$line" | grep "DNS" | tr " " "#") + if [ ! -z "$PRK" ]; then + dns=$(echo $PRK | cut -d# -f3) + fi + PRK=$(echo "$line" | grep "ListenPort" | tr " " ",") + if [ ! -z "$PRK" ]; then + listenport=$(echo $PRK | cut -d, -f3) + fi + PRK=$(echo "$line" | grep "AllowedIPs" | tr " " "#") + if [ ! -z "$PRK" ]; then + if [ -z $allowedips ]; then + allowedips=$(echo $PRK | cut -d# -f3) + else + allowedips=$allowedips","$(echo $PRK | cut -d# -f3) + fi + fi + PRK=$(echo "$line" | grep "Endpoint" | tr " " ",") + if [ ! -z "$PRK" ]; then + endpoint=$(echo $PRK | cut -d, -f3) + fi + MTU=$(echo "$line" | grep "MTU" | tr " " ",") + if [ ! -z "$MTU" ]; then + mtu=$(echo $MTU | cut -d, -f3) + fi +} + +listenport="51280" +dns="" +sed -i -e "s!PrivateKey= !PrivateKey=!g" $file +sed -i -e "s!PrivateKey=!PrivateKey = !g" $file +sed -i -e "s!PublicKey= !PublicKey=!g" $file +sed -i -e "s!PublicKey=!PublicKey = !g" $file +sed -i -e "s!PresharedKey= !PresharedKey=!g" $file +sed -i -e "s!PresharedKey=!PresharedKey = !g" $file +sed -i -e "s!Address= !Address=!g" $file +sed -i -e "s!Address=!Address = !g" $file +sed -i -e "s!WGinterface=!WGinterface = !g" $file +sed -i -e "s!WGinterface= !WGinterface = !g" $file +sed -i -e "s!dns= !dns=!g" $file +sed -i -e "s!dns=!dns = !g" $file +sed -i -e "s!DNS= !DNS=!g" $file +sed -i -e "s!DNS=!DNS = !g" $file +sed -i -e "s!ListenPort= !ListenPort=!g" $file +sed -i -e "s!ListenPort=!ListenPort = !g" $file +sed -i -e "s!AllowedIPs= !AllowedIPs=!g" $file +sed -i -e "s!AllowedIPs=!AllowedIPs = !g" $file +sed -i -e "s!Endpoint= !Endpoint=!g" $file +sed -i -e "s!Endpoint=!Endpoint = !g" $file +sed -i -e "s!MTU= !MTU=!g" $file +sed -i -e "s!MTU=!MTU = !g" $file + +while IFS= read -r linex +do + extract "$linex" +done < $file +extract "$linex" +PRK=$(echo "$endpoint" | tr ":" ",") +endpoint=$(echo $PRK | cut -d, -f1) +sport=$(echo $PRK | cut -d, -f2) +if [ -z "$wginter" ]; then + wginter="0" +fi +uci delete wireguard.$name +uci set wireguard.$name=wireguard +uci set wireguard.$name.auto=$auto +uci set wireguard.$name.client="1" +uci set wireguard.$name.active="0" +uci set wireguard.$name.privatekey="$PrivateKey" +uci set wireguard.$name.presharedkey="$PreSharedKey" +uci set wireguard.$name.port="$listenport" +uci set wireguard.$name.addresses="$Address" +uci set wireguard.$name.dns="$dns" +uci set wireguard.$name.wginter="$wginter" +uci set wireguard.$name.publickey="$PublicKey" +uci set wireguard.$name.endpoint_host="$endpoint" +uci set wireguard.$name.ips="$allowedips" +uci set wireguard.$name.name="$name" +uci set wireguard.$name.sport="$sport" +uci set wireguard.$name.mtu="$mtu" +uci set wireguard.$name.persistent_keepalive='25' +uci commit wireguard + +rm -f $file + \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/create.sh b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/create.sh new file mode 100755 index 0000000..bbde0c8 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/create.sh @@ -0,0 +1,81 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Wireguard Conf" "$@" +} + +WG=$(cat /tmp/wginst) + +do_create() { + local config=$1 + + config_get name $config name + if [ -z $name ]; then + name=$config + fi + + echo "----Start Conf File for "$name" ----" >> ${PKI_DIR}/package/wg.conf + echo "[Interface]" >> ${PKI_DIR}/package/wg.conf + config_get privatekey $config privatekey + echo "PrivateKey = "$privatekey >> ${PKI_DIR}/package/wg.conf + config_get address $config address + echo "Address = "$address >> ${PKI_DIR}/package/wg.conf + config_get endpoint_port $config endpoint_port + if [ ! -z $endpoint_port ]; then + echo "ListenPort = "$endpoint_port >> ${PKI_DIR}/package/wg.conf + fi + config_get dns $config dns + if [ ! -z $dns ]; then + echo "DNS = "$dns >> ${PKI_DIR}/package/wg.conf + fi + config_get mtu $config mtu + if [ ! -z $mtu ]; then + echo "MTU = "$mtu >> ${PKI_DIR}/package/wg.conf + fi + config_get wginter $config wginter + if [ -z"$wginter"]; then + wginter=0 + fi + #echo "PrivateKey = "$wginter >> ${PKI_DIR}/package/wg.conf + echo " " >> ${PKI_DIR}/package/wg.conf + echo "[Peer]" >> ${PKI_DIR}/package/wg.conf + PUB=$(uci get wireguard."$WG".publickey) + echo "PublicKey = "$PUB >> ${PKI_DIR}/package/wg.conf + USE=$(uci get wireguard."$WG".usepre) + if [ $USE = "1" ]; then + PRE=$(uci get wireguard."$WG".presharedkey) + echo "PresharedKey = "$PRE >> ${PKI_DIR}/package/wg.conf + fi + HOST=$(uci get wireguard."$WG".endpoint_host) + PORT=$(uci get wireguard."$WG".port) + if [ ! -z $PORT ]; then + HOST=$HOST":"$PORT + fi + echo "Endpoint = "$HOST >> ${PKI_DIR}/package/wg.conf + config_get allowed_ips $config allowed_ips + echo "AllowedIPs = "$allowed_ips >> ${PKI_DIR}/package/wg.conf + echo "----EndConf File for "$name" ----" >> ${PKI_DIR}/package/wg.conf + echo " " >> ${PKI_DIR}/package/wg.conf +} + +#PKI_DIR="/tmp/wireguard" +PKI_DIR="/www" +#rm -rfv "$PKI_DIR" +#mkdir -p ${PKI_DIR} +#chmod -R 0777 ${PKI_DIR} +cd ${PKI_DIR} +mkdir -p package +cd .. +chmod -R 0777 ${PKI_DIR}/package +#rm -rfv "/www/package" +#ln -s ${PKI_DIR}/package /www/package + + +rm -f ${PKI_DIR}/package/wg.conf +config_load wireguard +config_foreach do_create custom$WG + +cd ${PKI_DIR}/package + +tar -czf wgconf.tar.gz wg.conf diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/keygen.sh b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/keygen.sh new file mode 100755 index 0000000..4733ae1 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/keygen.sh @@ -0,0 +1,68 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + modlog "Wireguard KeyGen" "$@" +} + +WG=$1 + +ww=$(echo "$WG" | grep "https") +if [ ! -z "$ww" ]; then + exit 0 +fi +echo "$WG" > /tmp/wginst + +sleep 5 + +EXST=$(uci get wireguard."$WG") +if [ -z $EXST ]; then + uci set wireguard."$WG"="wireguard" + uci commit wireguard +fi + +PRIV=$(uci get wireguard."$WG".privatekey) +if [ -z $PRIV ]; then + umask u=rw,g=,o= + wg genkey | tee /tmp/wgserver.key | wg pubkey > /tmp/wgclient.pub + wg genpsk > /tmp/wg.psk + + WG_KEY="$(cat /tmp/wgserver.key)" # private key + WG_PSK="$(cat /tmp/wg.psk)" # shared key + WG_PUB="$(cat /tmp/wgclient.pub)" # public key to be used on other end + rm -f /tmp/wgserver.key + rm -f /tmp/wg.psk + rm -f /tmp/wgclient.pub + uci set wireguard."$WG".privatekey=$WG_KEY + uci set wireguard."$WG".publickey=$WG_PUB + uci set wireguard."$WG".presharedkey=$WG_PSK + uci commit wireguard +fi + +do_custom() { + local config=$1 + + config_get privatekey $config privatekey + if [ -z "$privatekey" ]; then + umask u=rw,g=,o= + wg genkey | tee /tmp/wgserver.key | wg pubkey > /tmp/wgclient.pub + wg genpsk > /tmp/wg.psk + + WG_KEY="$(cat /tmp/wgserver.key)" # private key + WG_PSK="$(cat /tmp/wg.psk)" # shared key + WG_PUB="$(cat /tmp/wgclient.pub)" # public key to be used on other end + rm -f /tmp/wgserver.key + rm -f /tmp/wg.psk + rm -f /tmp/wgclient.pub + log "$WG_KEY" + uci set wireguard."$config".privatekey=$WG_KEY + uci set wireguard."$config".publickey=$WG_PUB + uci set wireguard."$config".presharedkey=$WG_PSK + uci set wireguard."$config".persistent_keepalive='25' + uci set wireguard."$config".route_allowed_ips='1' + fi +} + +config_load wireguard +config_foreach do_custom custom$WG +uci commit wireguard \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/startvpn.sh b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/startvpn.sh new file mode 100755 index 0000000..5beade6 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/startvpn.sh @@ -0,0 +1,327 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Wireguard Start" "$@" +} + +WG=$1 + +chk_zone() { + local config=$1 + + config_get src $config src + config_get dest $config dest + if [ $src = "lan" -a $dest = "wan" ]; then + uci set firewall."$config".dest="wg" + uci commit firewall + fi +} + +do_dns() { + cdns=$1 + local ifce=$2 + ldns=$(uci -q get network.wg$ifce.dns) + ex=$(echo "$ldns" | grep "$cdns") + if [ -z $ex ]; then + log "Add DNS $cdns to WG$ifce" + uci add_list network.wg$ifce.dns="$cdns" + uci commit network + /etc/init.d/network reload + fi +} + +do_port() { + PORT=$1 + udp=$2 + # look for rule for this port + INB="inbound"$PORT$udp + RULE=$(uci -q get firewall.$INB) + if [ -z $RULE ]; then + uci set firewall.$INB=rule + uci set firewall.$INB.name=$INB + uci set firewall.$INB.target=ACCEPT + uci set firewall.$INB.src=* + uci set firewall.$INB.proto=$udp + uci set firewall.$INB.dest_port=$PORT + uci commit firewall + /etc/init.d/firewall reload + fi +} + +do_delete() { + local config=$1 + + uci delete network.$1 +} + +create_speer() { + local config=$1 + + uci set network.$config="wireguard_wg1" + + config_get persistent_keepalive $config persistent_keepalive + uci set network.$config.persistent_keepalive="$persistent_keepalive" + config_get route_allowed_ips $config route_allowed_ips + uci set network.$config.route_allowed_ips="$route_allowed_ips" + config_get publickey $config publickey + uci set network.$config.public_key="$publickey" + usepre=$(uci -q get wireguard.$WG.usepre) + log "$usepre" + if [ $usepre = "1" ]; then + presharedkey=$(uci -q get wireguard.$WG.presharedkey) + log "$presharedkey" + uci set network.$config.preshared_key="$presharedkey" + fi + config_get allowed_ips $config allowed_ips + allowed_ips=$allowed_ips"," + ips=$(echo $allowed_ips | cut -d, -f1) + i=1 + while [ ! -z $ips ] + do + uci add_list network.$config.allowed_ips="$ips" + i=$((i+1)) + ips=$(echo $allowed_ips | cut -d, -f$i) + done + +} + +create_cpeer() { + local config=$1 + local ifce=$2 + + uci set network.$config="wireguard_wg$ifce" + + publickey=$(uci -q get wireguard."$config".publickey) + uci set network.$config.public_key="$publickey" + presharedkey=$(uci -q get wireguard."$WG".presharedkey) + if [ ! -z $presharedkey ]; then + uci set network.$config.preshared_key="$presharedkey" + fi + persistent_keepalive=$(uci -q get wireguard."$config".persistent_keepalive) + if [ -z $persistent_keepalive ]; then + persistent_keepalive=25 + fi + uci set network.$config.persistent_keepalive="$persistent_keepalive" + route_allowed_ips=1 + uci set network.$config.route_allowed_ips="$route_allowed_ips" + + if [ $UDP = 1 ]; then + endpoint_host="127.0.0.1" + uci set network.$config.endpoint_host="$endpoint_host" + sport=$(uci -q get wireguard."$config".port) + if [ -z $sport ]; then + sport="54321" + fi + uci set network.$config.endpoint_port="$sport" + else + endpoint_host=$(uci -q get wireguard."$config".endpoint_host) + uci set network.$config.endpoint_host="$endpoint_host" + sport=$(uci -q get wireguard."$config".sport) + if [ -z $sport ]; then + sport="51280" + fi + uci set network.$config.endpoint_port="$sport" + fi + + ips=$(uci -q get wireguard."$config".ips)"," + cips=$(echo $ips | cut -d, -f1) + i=1 + while [ ! -z $cips ] + do + uci add_list network.$config.allowed_ips="$cips" + i=$((i+1)) + cips=$(echo $ips | cut -d, -f$i) + done +} + +handle_server() { + config_foreach do_delete wireguard_wg1 + + uci delete network.wg1 + uci set network.wg1="interface" + uci set network.wg1.proto="wireguard" + + auto=$(uci -q get wireguard."$WG".auto) + if [ -z $auto ]; then + auto="0" + fi + uci set network.wg1.auto="$auto" + + port=$(uci -q get wireguard."$WG".port) + if [ -z $port ]; then + port="51280" + fi + uci set network.wg1.listen_port="$port" + do_port $port udp + + privatekey=$(uci -q get wireguard."$WG".privatekey) + uci set network.wg1.private_key="$privatekey" + + ips=$(uci -q get wireguard."$WG".addresses)"," + cips=$(echo $ips | cut -d, -f1) + i=1 + while [ ! -z $cips ] + do + uci add_list network.wg1.addresses="$cips" + i=$((i+1)) + cips=$(echo $ips | cut -d, -f"$i") + if [ -z $cips ]; then + break + fi + done + + config_load wireguard + config_foreach create_speer custom$WG + + uci commit network +} + +handle_client() { + ifce=$1 + config_foreach do_delete wireguard_wg$ifce + + uci delete network.wg$ifce + uci set network.wg$ifce="interface" + uci set network.wg$ifce.proto="wireguard" + uci set network.wg$ifce.metric="1" + + auto=$(uci -q get wireguard."$WG".auto) + if [ -z $auto ]; then + auto="0" + fi + uci set network.wg$ifce.auto="$auto" + mtu=$(uci -q get wireguard."$WG".mtu) + if [ ! -z $mtu ]; then + uci set network.wg$ifce.mtu="$mtu" + fi + dns=$(uci -q get wireguard."$WG".dns) + if [ ! -z $dns ]; then + do_dns $dns $ifce + fi + port=$(uci -q get wireguard."$WG".port) + if [ -z $port ]; then + port="51280" + fi + uci set network.wg$ifce.listen_port="$port" + do_port $port udp + + privatekey=$(uci -q get wireguard."$WG".privatekey) + uci set network.wg$ifce.private_key="$privatekey" + + ips=$(uci -q get wireguard."$WG".addresses)"," + cips=$(echo $ips | cut -d, -f1) + i=1 + while [ ! -z "$cips" ] + do + uci add_list network.wg$ifce.addresses="$cips" + i=$((i+1)) + cips=$(echo "$ips" | cut -d, -f"$i") + if [ -z "$cips" ]; then + break + fi + done + uci add_list network.wg$ifce.addresses="::/0" + + create_cpeer $WG $ifce + + uci commit network +} + +udp_server() { + local config=$1 + udpport=$(uci -q get wireguard."$WG".udpport) + if [ -z $udpport ]; then + udpport="54321" + fi + port=$(uci -q get wireguard."$WG".port) + if [ -z $port ]; then + port="54321" + fi + do_port $udpport tcp + udptunnel -s -v "0.0.0.0:"$udpport "127.0.0.1:"$port & + #log "udptunnel -s -v 0.0.0.0:$udpport 127.0.0.1:$port" +} + +udp_client() { + local config=$1 + port=$(uci -q get wireguard."$WG".port) + if [ -z $port ]; then + port="54321" + fi + endpoint_host=$(uci -q get wireguard.$WG.endpoint_host) + sport=$(uci -q get wireguard.$WG.sport) + if [ -z $sport ]; then + sport="51280" + fi + + udptunnel "127.0.0.1:"$port $endpoint_host":"$sport & + #log "udptunnel 127.0.0.1:$port $endpoint_host:$sport" +} + +forward=$(uci -q get wireguard."$WG".forward) +if [ "$forward" != "0" ]; then + config_load firewall + config_foreach chk_zone forwarding +else + uci set firewall.wgwforward=forwarding + uci set firewall.wgwforward.dest="wan" + uci set firewall.wgwforward.src="wg" + + uci set firewall.wwgforward=forwarding + uci set firewall.wwgforward.dest="wg" + uci set firewall.wwgforward.src="wan" + + uci set firewall.lwgforward=forwarding + uci set firewall.lwgforward.dest="wg" + uci set firewall.lwgforward.src="lan" + + uci set firewall.wglforward=forwarding + uci set firewall.wglforward.dest="lan" + uci set firewall.wglforward.src="wg" + uci commit firewall +fi +/etc/init.d/firewall restart + +config_load network +SERVE=$(uci -q get wireguard."$WG".client) +if [ $SERVE = "0" ]; then + running=$(uci -q get wireguard.settings.server) + if [ $running = 1 ]; then + exit 0 + fi + UDP=$(uci -q get wireguard."$WG".udptunnel) + if [ $UDP = 1 ]; then + udp_server $WG + fi + handle_server + uci commit network + ifup wg1 + sleep 2 + uci set wireguard.settings.server="1" +else + running=$(uci -q get wireguard.settings.client) + log "Client running $running" + + INTER=$(uci -q get wireguard."$WG".wginter) + if [ -z "$INTER" ]; then + INTER=0 + fi + UDP=$(uci -q get wireguard."$WG".udptunnel) + if [ $UDP = 1 ]; then + udp_client $WG + fi + handle_client $INTER + uci commit network + log "Start Interface" + ifup wg$INTER + sleep 2 + uci set wireguard.settings.client="1" + if [ -e /usr/lib/wireguard/wiremwan3.sh ]; then + /usr/lib/wireguard/wiremwan3.sh start + fi +fi + +uci set wireguard."$WG".active="1" +uci commit wireguard + diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/stopvpn.sh b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/stopvpn.sh new file mode 100755 index 0000000..6258784 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/stopvpn.sh @@ -0,0 +1,75 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Wireguard Stop" "$@" +} + +chk_zone() { + local config=$1 + + config_get src $config src + config_get dest $config dest + if [ $src = "lan" -a $dest = "wg" ]; then + uci set firewall."$config".dest="wan" + uci commit firewall + fi +} + +WG=$1 + +forward=$(uci -q get wireguard."$WG".forward) +if [ "$forward" != "0" ]; then + config_load firewall + config_foreach chk_zone forwarding +else + uci delete firewall.wgwforward + uci delete firewall.wwgforward + uci delete firewall.lwgforward + uci delete firewall.wglforward + uci commit firewall +fi +/etc/init.d/firewall restart + +SERVE=$(uci get wireguard."$WG".client) +if [ $SERVE = "0" ]; then + ifdown wg1 + uci set wireguard.settings.server="0" + uci delete network.wg1 + uci set network.wg1=interface + uci set network.wg1.proto="wireguard" + uci set network.wg1.auto="0" + uci set network.wg1.private_key="" + uci set network.wg1.listen_port="" + uci add_list network.wg1.addresses="" + uci commit network +else + INTER=$(uci -q get wireguard."$WG".wginter) + if [ -z "$INTER" ]; then + INTER=0 + fi + ifdown wg$INTER + uci set wireguard.settings.client="0" + uci delete network.wg$INTER + uci set network.wg$INTER=interface + uci set network.wg$INTER.proto="wireguard" + uci set network.wg$INTER.auto="0" + uci set network.wg$INTER.private_key="" + uci set network.wg$INTER.listen_port="" + uci add_list network.wg$INTER.addresses="" + uci commit network + if [ -e /usr/lib/wireguard/wiremwan3.sh ]; then + /usr/lib/wireguard/wiremwan3.sh stop + fi + ifup wan +fi +UDP=$(uci get wireguard."$WG".udptunnel) +if [ $UDP = 1 ]; then + PID=$(ps |grep "udptunnel" | grep -v grep |head -n 1 | awk '{print $1}') + kill -9 $PID +fi + +uci set wireguard."$WG".active="0" +uci commit wireguard + +/etc/init.d/wireguard stop \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/text.sh b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/text.sh new file mode 100755 index 0000000..2f5a622 --- /dev/null +++ b/ipk-source/luci-app-GO-wireguard/root/usr/lib/wireguard/text.sh @@ -0,0 +1,19 @@ +#!/bin/sh +. /lib/functions.sh + +log() { + logger -t "Wireguard TextConf" "$@" +} + +conf1=$1 +conf=$(echo $conf1) +conf=$(echo "$conf" | tr "?" "~") + +boot=$(echo "$conf" | cut -d~ -f1) +iname=$(echo "$conf" | cut -d~ -f2) +conf=$(echo "$conf1" | tr "?" "~") +confile=$(echo "$conf" | cut -d~ -f3) + +echo "$confile" > /tmp/confile + +/usr/lib/wireguard/conf.sh $iname /tmp/confile $boot \ No newline at end of file diff --git a/ipk-source/luci-app-GO-wireguard/root/www/luci-static/resources/icons/wireguard.png b/ipk-source/luci-app-GO-wireguard/root/www/luci-static/resources/icons/wireguard.png new file mode 100755 index 0000000000000000000000000000000000000000..34f85d8486f4499a7ed215d5a20057f4048a9024 GIT binary patch literal 22762 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 YsyNG(0Rzr1YRU?j7+M$<>$@KPADp!95dZ)H literal 0 HcmV?d00001 diff --git a/ipk-source/luci-app-GO-wireguard/root/www/luci-static/resources/icons/wireguard_disabled.png b/ipk-source/luci-app-GO-wireguard/root/www/luci-static/resources/icons/wireguard_disabled.png new file mode 100755 index 0000000000000000000000000000000000000000..ccfb7aece3b8a4219681262fe78d78f2c477c6bc GIT binary patch literal 23205 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 literal 0 HcmV?d00001