diff --git a/luci-app-ipsec-server/Makefile b/luci-app-ipsec-server/Makefile new file mode 100644 index 000000000..d590d8921 --- /dev/null +++ b/luci-app-ipsec-server/Makefile @@ -0,0 +1,22 @@ +# Copyright (C) 2018-2021 Lienol +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-ipsec-server + +PKG_MAINTAINER:=Lienol + +LUCI_TITLE:=LuCI support for IPSec VPN Server +LUCI_DEPENDS:=+kmod-tun +luci-lib-jsonc +strongswan +strongswan-minimal +strongswan-mod-kernel-libipsec +strongswan-mod-openssl +strongswan-mod-xauth-generic +xl2tpd +LUCI_PKGARCH:=all + +define Package/$(PKG_NAME)/conffiles +/etc/config/luci-app-ipsec-server +endef + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-ipsec-server/luasrc/controller/ipsec-server.lua b/luci-app-ipsec-server/luasrc/controller/ipsec-server.lua new file mode 100644 index 000000000..e9a271af4 --- /dev/null +++ b/luci-app-ipsec-server/luasrc/controller/ipsec-server.lua @@ -0,0 +1,24 @@ +-- Copyright 2018-2020 Lienol +module("luci.controller.ipsec-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/luci-app-ipsec-server") then + return + end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + entry({"admin", "vpn", "ipsec-server"}, alias("admin", "vpn", "ipsec-server", "settings"), _("IPSec VPN Server"), 49).dependent = false + entry({"admin", "vpn", "ipsec-server", "settings"}, cbi("ipsec-server/settings"), _("General Settings"), 10).leaf = true + entry({"admin", "vpn", "ipsec-server", "users"}, cbi("ipsec-server/users"), _("Users Manager"), 20).leaf = true + entry({"admin", "vpn", "ipsec-server", "l2tp_user"}, cbi("ipsec-server/l2tp_user")).leaf = true + entry({"admin", "vpn", "ipsec-server", "online"}, cbi("ipsec-server/online"), _("L2TP Online Users"), 30).leaf = true + entry({"admin", "vpn", "ipsec-server", "status"}, call("act_status")).leaf = true +end + +function act_status() + local e = {} + e["ipsec_status"] = luci.sys.call("/usr/bin/pgrep ipsec >/dev/null") == 0 + e["l2tp_status"] = luci.sys.call("top -bn1 | grep -v grep | grep '/var/etc/xl2tpd' >/dev/null") == 0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/l2tp_user.lua b/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/l2tp_user.lua new file mode 100644 index 000000000..3b8460c65 --- /dev/null +++ b/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/l2tp_user.lua @@ -0,0 +1,35 @@ +local d = require "luci.dispatcher" +local sys = require "luci.sys" + +m = Map("luci-app-ipsec-server", "L2TP/IPSec PSK " .. translate("Users Manager")) +m.redirect = d.build_url("admin", "vpn", "ipsec-server", "users") + +if sys.call("command -v xl2tpd > /dev/null") == 0 then + s = m:section(NamedSection, arg[1], "l2tp_users", "") + s.addremove = false + s.anonymous = true + + o = s:option(Flag, "enabled", translate("Enabled")) + o.default = 1 + o.rmempty = false + + o = s:option(Value, "username", translate("Username")) + o.placeholder = translate("Username") + o.rmempty = false + + o = s:option(Value, "password", translate("Password")) + o.placeholder = translate("Password") + o.rmempty = false + + o = s:option(Value, "ipaddress", translate("IP address")) + o.placeholder = translate("Automatically") + o.datatype = "ip4addr" + o.rmempty = true + + o = s:option(DynamicList, "routes", translate("Static Routes")) + o.placeholder = "192.168.10.0/24" + o.datatype = "ipmask4" + o.rmempty = true +end + +return m diff --git a/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/online.lua b/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/online.lua new file mode 100644 index 000000000..d47b30053 --- /dev/null +++ b/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/online.lua @@ -0,0 +1,83 @@ +local o = require "luci.dispatcher" +local fs = require "nixio.fs" +local jsonc = require "luci.jsonc" + +local sessions = {} +local session_path = "/var/etc/xl2tpd/session" +if fs.access(session_path) then + for filename in fs.dir(session_path) do + local session_file = session_path .. "/" .. filename + local file = io.open(session_file, "r") + local t = jsonc.parse(file:read("*a")) + if t then + t.session_file = session_file + sessions[#sessions + 1] = t + end + file:close() + end +end + +local blacklist = {} +local firewall_user_path = "/etc/firewall.user" +if fs.access(firewall_user_path) then + for line in io.lines(firewall_user_path) do + local m = line:match('xl2tpd%-blacklist%-([^\n]+)') + if m then + local t = {} + t.ip = m + blacklist[#blacklist + 1] = t + end + end +end + +f = SimpleForm("processes") +f.reset = false +f.submit = false + +t = f:section(Table, sessions, translate("L2TP Online Users")) +t:option(DummyValue, "username", translate("Username")) +t:option(DummyValue, "interface", translate("Interface")) +t:option(DummyValue, "ip", translate("Client IP")) +t:option(DummyValue, "remote_ip", translate("IP address")) +t:option(DummyValue, "login_time", translate("Login Time")) + +_blacklist = t:option(Button, "_blacklist", translate("Blacklist")) +function _blacklist.render(e, t, a) + e.title = translate("Add to Blacklist") + e.inputstyle = "remove" + Button.render(e, t, a) +end +function _blacklist.write(t, s) + local e = t.map:get(s, "remote_ip") + luci.util.execi("echo 'iptables -I INPUT -s %s -p udp -m multiport --dports 500,4500,1701 -j DROP ## xl2tpd-blacklist-%s' >> /etc/firewall.user" % {e, e}) + luci.util.execi("iptables -I INPUT -s %s -p udp -m multiport --dports 500,4500,1701 -j DROP" % {e}) + luci.util.execi("rm -f " .. t.map:get(s, "session_file")) + null, t.tag_error[s] = luci.sys.process.signal(t.map:get(s, "pid"), 9) + luci.http.redirect(o.build_url("admin/vpn/ipsec-server/online")) +end + +_kill = t:option(Button, "_kill", translate("Forced offline")) +_kill.inputstyle = "remove" +function _kill.write(t, s) + luci.util.execi("rm -f " .. t.map:get(s, "session_file")) + null, t.tag_error[t] = luci.sys.process.signal(t.map:get(s, "pid"), 9) + luci.http.redirect(o.build_url("admin/vpn/ipsec-server/online")) +end + +t = f:section(Table, blacklist, translate("Blacklist")) +t:option(DummyValue, "ip", translate("IP address")) + +_blacklist2 = t:option(Button, "_blacklist2", translate("Blacklist")) +function _blacklist2.render(e, t, a) + e.title = translate("Remove from Blacklist") + e.inputstyle = "apply" + Button.render(e, t, a) +end +function _blacklist2.write(t, s) + local e = t.map:get(s, "ip") + luci.util.execi("sed -i -e '/## xl2tpd-blacklist-%s/d' /etc/firewall.user" % {e}) + luci.util.execi("iptables -D INPUT -s %s -p udp -m multiport --dports 500,4500,1701 -j DROP" % {e}) + luci.http.redirect(o.build_url("admin/vpn/ipsec-server/online")) +end + +return f diff --git a/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/settings.lua b/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/settings.lua new file mode 100644 index 000000000..b88dd230d --- /dev/null +++ b/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/settings.lua @@ -0,0 +1,64 @@ +local sys = require "luci.sys" + +m = Map("luci-app-ipsec-server", translate("IPSec VPN Server")) +m.template = "ipsec-server/ipsec-server_status" + +s = m:section(TypedSection, "service") +s.anonymous = true + +o = s:option(DummyValue, "ipsec-server_status", translate("Current Condition")) +o.rawhtml = true +o.cfgvalue = function(t, n) + return '' +end + +enabled = s:option(Flag, "enabled", translate("Enable")) +enabled.description = translate("Use a client that supports IPSec Xauth PSK (iOS or Android) to connect to this server.") +enabled.default = 0 +enabled.rmempty = false + +clientip = s:option(Value, "clientip", translate("VPN Client IP")) +clientip.description = translate("VPN Client reserved started IP addresses with the same subnet mask, such as: 192.168.100.10/24") +clientip.datatype = "ip4addr" +clientip.optional = false +clientip.rmempty = false + +secret = s:option(Value, "secret", translate("Secret Pre-Shared Key")) +secret.password = true + +if sys.call("command -v xl2tpd > /dev/null") == 0 then + o = s:option(DummyValue, "l2tp_status", "L2TP " .. translate("Current Condition")) + o.rawhtml = true + o.cfgvalue = function(t, n) + return '' + end + + o = s:option(Flag, "l2tp_enable", "L2TP " .. translate("Enable")) + o.description = translate("Use a client that supports L2TP over IPSec PSK to connect to this server.") + o.default = 0 + o.rmempty = false + + o = s:option(Value, "l2tp_localip", "L2TP " .. translate("Server IP")) + o.description = translate("VPN Server IP address, such as: 192.168.101.1") + o.datatype = "ip4addr" + o.rmempty = true + o.default = "192.168.101.1" + o.placeholder = o.default + + o = s:option(Value, "l2tp_remoteip", "L2TP " .. translate("Client IP")) + o.description = translate("VPN Client IP address range, such as: 192.168.101.10-20") + o.rmempty = true + o.default = "192.168.101.10-20" + o.placeholder = o.default + + if sys.call("ls -L /usr/lib/ipsec/libipsec* 2>/dev/null >/dev/null") == 0 then + o = s:option(DummyValue, "_o", " ") + o.rawhtml = true + o.cfgvalue = function(t, n) + return string.format('%s', translate("L2TP/IPSec is not compatible with kernel-libipsec, which will disable this module.")) + end + o:depends("l2tp_enable", true) + end +end + +return m diff --git a/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/users.lua b/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/users.lua new file mode 100644 index 000000000..87a21be74 --- /dev/null +++ b/luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/users.lua @@ -0,0 +1,54 @@ +local d = require "luci.dispatcher" +local sys = require "luci.sys" + +m = Map("luci-app-ipsec-server") + +s = m:section(TypedSection, "ipsec_users", "IPSec Xauth PSK " .. translate("Users Manager")) +s.description = translate("Use a client that supports IPSec Xauth PSK (iOS or Android) to connect to this server.") +s.addremove = true +s.anonymous = true +s.template = "cbi/tblsection" + +o = s:option(Flag, "enabled", translate("Enabled")) +o.default = 1 +o.rmempty = false + +o = s:option(Value, "username", translate("Username")) +o.placeholder = translate("Username") +o.rmempty = false + +o = s:option(Value, "password", translate("Password")) +o.placeholder = translate("Password") +o.rmempty = false + +if sys.call("command -v xl2tpd > /dev/null") == 0 then + s = m:section(TypedSection, "l2tp_users", "L2TP/IPSec PSK " .. translate("Users Manager")) + s.description = translate("Use a client that supports L2TP over IPSec PSK to connect to this server.") + s.addremove = true + s.anonymous = true + s.template = "cbi/tblsection" + s.extedit = d.build_url("admin", "vpn", "ipsec-server", "l2tp_user", "%s") + function s.create(e, t) + t = TypedSection.create(e, t) + luci.http.redirect(e.extedit:format(t)) + end + + o = s:option(Flag, "enabled", translate("Enabled")) + o.default = 1 + o.rmempty = false + + o = s:option(Value, "username", translate("Username")) + o.placeholder = translate("Username") + o.rmempty = false + + o = s:option(Value, "password", translate("Password")) + o.placeholder = translate("Password") + o.rmempty = false + + o = s:option(Value, "ipaddress", translate("IP address")) + o.placeholder = translate("Automatically") + o.datatype = "ip4addr" + o.rmempty = true +end + +return m diff --git a/luci-app-ipsec-server/luasrc/view/ipsec-server/ipsec-server_status.htm b/luci-app-ipsec-server/luasrc/view/ipsec-server/ipsec-server_status.htm new file mode 100644 index 000000000..93e36a405 --- /dev/null +++ b/luci-app-ipsec-server/luasrc/view/ipsec-server/ipsec-server_status.htm @@ -0,0 +1,21 @@ +<% include("cbi/map") %> + diff --git a/luci-app-ipsec-server/po/zh-cn/ipsec-server.po b/luci-app-ipsec-server/po/zh-cn/ipsec-server.po new file mode 100644 index 000000000..5c9049e02 --- /dev/null +++ b/luci-app-ipsec-server/po/zh-cn/ipsec-server.po @@ -0,0 +1,77 @@ +msgid "IPSec VPN Server" +msgstr "IPSec VPN 服务器" + +msgid "Use a client that supports IPSec Xauth PSK (iOS or Android) to connect to this server." +msgstr "使用支持 IPSec Xauth PSK(iOS 或 Android)的客户端连接到此服务端。" + +msgid "Use a client that supports L2TP over IPSec PSK to connect to this server." +msgstr "使用支持 L2TP over IPSec PSK 的客户端连接到此服务端。" + +msgid "Current Condition" +msgstr "当前状态" + +msgid "General settings" +msgstr "基本设置" + +msgid "Enabled" +msgstr "启用" + +msgid "VPN Client IP" +msgstr "VPN客户端地址段" + +msgid "VPN Client reserved started IP addresses with the same subnet mask, such as: 192.168.100.10/24" +msgstr "VPN客户端获取IP的起始地址,例如:192.168.100.10/24" + +msgid "Secret Pre-Shared Key" +msgstr "PSK密钥" + +msgid "VPN Server IP address, such as: 192.168.101.1" +msgstr "VPN服务端IP地址,例如:192.168.101.1" + +msgid "VPN Client IP address range, such as: 192.168.101.10-20" +msgstr "VPN客户端获取IP范围,例如:192.168.101.10-20" + +msgid "L2TP/IPSec is not compatible with kernel-libipsec, which will disable this module." +msgstr "L2TP/IPSec不兼容kernel-libipsec,开启将会禁用此模块。" + +msgid "Users Manager" +msgstr "用户管理" + +msgid "Username" +msgstr "用户名" + +msgid "Password" +msgstr "密码" + +msgid "IP address" +msgstr "IP 地址" + +msgid "Automatically" +msgstr "自动分配" + +msgid "Online Users" +msgstr "在线用户" + +msgid "L2TP Online Users" +msgstr "L2TP 在线用户" + +msgid "Login Time" +msgstr "登录时间" + +msgid "Blacklist" +msgstr "黑名单" + +msgid "Add to Blacklist" +msgstr "加入黑名单" + +msgid "Remove from Blacklist" +msgstr "移出黑名单" + +msgid "Forced offline" +msgstr "强制下线" + +msgid "NOT RUNNING" +msgstr "未运行" + +msgid "RUNNING" +msgstr "运行中" diff --git a/luci-app-ipsec-server/po/zh_Hans b/luci-app-ipsec-server/po/zh_Hans new file mode 100644 index 000000000..e69de29bb diff --git a/luci-app-ipsec-server/root/etc/config/luci-app-ipsec-server b/luci-app-ipsec-server/root/etc/config/luci-app-ipsec-server new file mode 100644 index 000000000..6d90a5d69 --- /dev/null +++ b/luci-app-ipsec-server/root/etc/config/luci-app-ipsec-server @@ -0,0 +1,7 @@ + +config service 'ipsec' + option enabled '0' + option secret 'ipsec' + option clientip '192.168.100.10/24' + + diff --git a/luci-app-ipsec-server/root/etc/init.d/luci-app-ipsec-server b/luci-app-ipsec-server/root/etc/init.d/luci-app-ipsec-server new file mode 100644 index 000000000..7b7e0a235 --- /dev/null +++ b/luci-app-ipsec-server/root/etc/init.d/luci-app-ipsec-server @@ -0,0 +1,274 @@ +#!/bin/sh /etc/rc.common + +START=99 + +CONFIG="luci-app-ipsec-server" +IPSEC_SECRETS_FILE=/etc/ipsec.secrets +IPSEC_CONN_FILE=/etc/ipsec.conf +CHAP_SECRETS=/etc/ppp/chap-secrets +L2TP_PATH=/var/etc/xl2tpd +L2TP_CONTROL_FILE=${L2TP_PATH}/control +L2TP_CONFIG_FILE=${L2TP_PATH}/xl2tpd.conf +L2TP_OPTIONS_FILE=${L2TP_PATH}/options.xl2tpd +L2TP_LOG_FILE=${L2TP_PATH}/xl2tpd.log + +vt_clientip=$(uci -q get ${CONFIG}.@service[0].clientip) +l2tp_enabled=$(uci -q get ${CONFIG}.@service[0].l2tp_enable) +l2tp_localip=$(uci -q get ${CONFIG}.@service[0].l2tp_localip) + +ipt_flag="IPSec VPN Server" + +get_enabled_anonymous_secs() { + uci -q show "${CONFIG}" | grep "${1}\[.*\.enabled='1'" | cut -d '.' -sf2 +} + +ipt_rule() { + if [ "$1" = "add" ]; then + iptables -t nat -I POSTROUTING -s ${vt_clientip} -m comment --comment "${ipt_flag}" -j MASQUERADE 2>/dev/null + iptables -I forwarding_rule -s ${vt_clientip} -m comment --comment "${ipt_flag}" -j ACCEPT 2>/dev/null + iptables -I forwarding_rule -m policy --dir in --pol ipsec --proto esp -m comment --comment "${ipt_flag}" -j ACCEPT 2>/dev/null + iptables -I forwarding_rule -m policy --dir out --pol ipsec --proto esp -m comment --comment "${ipt_flag}" -j ACCEPT 2>/dev/null + iptables -I INPUT -p udp -m multiport --dports 500,4500 -m comment --comment "${ipt_flag}" -j ACCEPT 2>/dev/null + iptables -t mangle -I OUTPUT -p udp -m multiport --sports 500,4500 -m comment --comment "${ipt_flag}" -j RETURN 2>/dev/null + [ "${l2tp_enabled}" = 1 ] && { + iptables -t nat -I POSTROUTING -s ${l2tp_localip%.*}.0/24 -m comment --comment "${ipt_flag}" -j MASQUERADE 2>/dev/null + iptables -I forwarding_rule -s ${l2tp_localip%.*}.0/24 -m comment --comment "${ipt_flag}" -j ACCEPT 2>/dev/null + iptables -I INPUT -p udp --dport 1701 -m comment --comment "${ipt_flag}" -j ACCEPT 2>/dev/null + iptables -t mangle -I OUTPUT -p udp --sport 1701 -m comment --comment "${ipt_flag}" -j RETURN 2>/dev/null + } + else + ipt_del() { + for i in $(seq 1 $($1 -nL $2 | grep -c "${ipt_flag}")); do + local index=$($1 --line-number -nL $2 | grep "${ipt_flag}" | head -1 | awk '{print $1}') + $1 -w -D $2 $index 2>/dev/null + done + } + ipt_del "iptables" "forwarding_rule" + ipt_del "iptables" "INPUT" + ipt_del "iptables -t nat" "POSTROUTING" + ipt_del "iptables -t mangle" "OUTPUT" + fi +} + +gen_include() { + echo '#!/bin/sh' > /var/etc/ipsecvpn.include + extract_rules() { + echo "*$1" + iptables-save -t $1 | grep "${ipt_flag}" | \ + sed -e "s/^-A \(INPUT\)/-I \1 1/" + echo 'COMMIT' + } + cat <<-EOF >> /var/etc/ipsecvpn.include + iptables-save -c | grep -v "${ipt_flag}" | iptables-restore -c + iptables-restore -n <<-EOT + $(extract_rules filter) + $(extract_rules nat) + EOT + EOF + return 0 +} + +start() { + local vt_enabled=$(uci -q get ${CONFIG}.@service[0].enabled) + [ "$vt_enabled" = 0 ] && return 1 + + local vt_gateway="${vt_clientip%.*}.1" + local vt_secret=$(uci -q get ${CONFIG}.@service[0].secret) + + local l2tp_enabled=$(uci -q get ${CONFIG}.@service[0].l2tp_enable) + [ "${l2tp_enabled}" = 1 ] && { + touch ${CHAP_SECRETS} + local vt_remoteip=$(uci -q get ${CONFIG}.@service[0].l2tp_remoteip) + local ipsec_l2tp_config=$(cat <<-EOF + ####################################### + # L2TP Connections + ####################################### + + conn L2TP-IKEv1-PSK + type=transport + keyexchange=ikev1 + authby=secret + leftprotoport=udp/l2tp + left=%any + right=%any + rekey=no + forceencaps=yes + ike=aes128-sha1-modp2048,aes128-sha1-modp1024,3des-sha1-modp1024,3des-sha1-modp1536 + esp=aes128-sha1,3des-sha1 + EOF + ) + + mkdir -p ${L2TP_PATH} + cat > ${L2TP_OPTIONS_FILE} <<-EOF + name "l2tp-server" + ipcp-accept-local + ipcp-accept-remote + ms-dns ${l2tp_localip} + noccp + auth + idle 1800 + mtu 1400 + mru 1400 + lcp-echo-failure 10 + lcp-echo-interval 60 + connect-delay 5000 + EOF + cat > ${L2TP_CONFIG_FILE} <<-EOF + [global] + port = 1701 + ;debug avp = yes + ;debug network = yes + ;debug state = yes + ;debug tunnel = yes + [lns default] + ip range = ${vt_remoteip} + local ip = ${l2tp_localip} + require chap = yes + refuse pap = yes + require authentication = no + name = l2tp-server + ;ppp debug = yes + pppoptfile = ${L2TP_OPTIONS_FILE} + length bit = yes + EOF + + local l2tp_users=$(get_enabled_anonymous_secs "@l2tp_users") + [ -n "${l2tp_users}" ] && { + for _user in ${l2tp_users}; do + local u_enabled=$(uci -q get ${CONFIG}.${_user}.enabled) + [ "${u_enabled}" -eq 1 ] || continue + + local u_username=$(uci -q get ${CONFIG}.${_user}.username) + [ -n "${u_username}" ] || continue + + local u_password=$(uci -q get ${CONFIG}.${_user}.password) + [ -n "${u_password}" ] || continue + + local u_ipaddress=$(uci -q get ${CONFIG}.${_user}.ipaddress) + [ -n "${u_ipaddress}" ] || u_ipaddress="*" + + echo "${u_username} l2tp-server ${u_password} ${u_ipaddress}" >> ${CHAP_SECRETS} + done + } + unset user + + echo "ip-up-script /usr/share/xl2tpd/ip-up" >> ${L2TP_OPTIONS_FILE} + echo "ip-down-script /usr/share/xl2tpd/ip-down" >> ${L2TP_OPTIONS_FILE} + + xl2tpd -c ${L2TP_CONFIG_FILE} -C ${L2TP_CONTROL_FILE} -D >${L2TP_LOG_FILE} 2>&1 & + rm -f "/usr/lib/ipsec/libipsec.so.0" + } + + cat > ${IPSEC_CONN_FILE} <<-EOF + # ipsec.conf - strongSwan IPsec configuration file + + config setup + uniqueids=no + charondebug="cfg 2, dmn 2, ike 2, net 0" + + conn %default + dpdaction=clear + dpddelay=300s + rekey=no + left=%defaultroute + leftfirewall=yes + right=%any + ikelifetime=60m + keylife=20m + rekeymargin=3m + keyingtries=1 + auto=add + + ####################################### + # Default non L2TP Connections + ####################################### + + conn Non-L2TP + leftsubnet=0.0.0.0/0 + rightsubnet=${vt_clientip} + rightsourceip=${vt_clientip} + rightdns=${vt_gateway} + ike=aes128-sha1-modp2048,aes128-sha1-modp1024,3des-sha1-modp1024,3des-sha1-modp1536 + esp=aes128-sha1,3des-sha1 + + # Cisco IPSec + conn IKEv1-PSK-XAuth + also=Non-L2TP + keyexchange=ikev1 + leftauth=psk + rightauth=psk + rightauth2=xauth + + $ipsec_l2tp_config + EOF + + cat > /etc/ipsec.secrets <<-EOF + # /etc/ipsec.secrets - strongSwan IPsec secrets file + : PSK "$vt_secret" + EOF + + local ipsec_users=$(get_enabled_anonymous_secs "@ipsec_users") + [ -n "${ipsec_users}" ] && { + for _user in ${ipsec_users}; do + local u_enabled=$(uci -q get ${CONFIG}.${_user}.enabled) + [ "${u_enabled}" -eq 1 ] || continue + + local u_username=$(uci -q get ${CONFIG}.${_user}.username) + [ -n "${u_username}" ] || continue + + local u_password=$(uci -q get ${CONFIG}.${_user}.password) + [ -n "${u_password}" ] || continue + + echo "${u_username} : XAUTH '${u_password}'" >> ${IPSEC_SECRETS_FILE} + done + } + unset user + + ipt_rule add + + /usr/lib/ipsec/starter --daemon charon --nofork > /dev/null 2>&1 & + gen_include + + uci -q batch <<-EOF >/dev/null + set network.ipsec_server.ipaddr="${vt_clientip%.*}.1" + commit network + EOF + ifup ipsec_server > /dev/null 2>&1 +} + +stop() { + ifdown ipsec_server > /dev/null 2>&1 + sed -i '/l2tp-server/d' ${CHAP_SECRETS} 2>/dev/null + top -bn1 | grep "${L2TP_PATH}" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 + rm -rf ${L2TP_PATH} + ps -w | grep "/usr/lib/ipsec" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 + ipt_rule del + rm -rf /var/etc/ipsecvpn.include + ln -s "libipsec.so.0.0.0" "/usr/lib/ipsec/libipsec.so.0" >/dev/null 2>&1 +} + +gen_iface_and_firewall() { + uci -q batch <<-EOF >/dev/null + delete network.ipsec_server + set network.ipsec_server=interface + set network.ipsec_server.device="ipsec0" + set network.ipsec_server.device="ipsec0" + set network.ipsec_server.proto="static" + set network.ipsec_server.ipaddr="${vt_clientip%.*}.1" + set network.ipsec_server.netmask="255.255.255.0" + commit network + + delete firewall.ipsecserver + set firewall.ipsecserver=zone + set firewall.ipsecserver.name="ipsecserver" + set firewall.ipsecserver.input="ACCEPT" + set firewall.ipsecserver.forward="ACCEPT" + set firewall.ipsecserver.output="ACCEPT" + set firewall.ipsecserver.network="ipsec_server" + commit firewall + EOF +} + +if [ -z "$(uci -q get network.ipsec_server)" ] || [ -z "$(uci -q get firewall.ipsecserver)" ]; then + gen_iface_and_firewall +fi diff --git a/luci-app-ipsec-server/root/etc/uci-defaults/luci-app-ipsec-server b/luci-app-ipsec-server/root/etc/uci-defaults/luci-app-ipsec-server new file mode 100644 index 000000000..3a791a03a --- /dev/null +++ b/luci-app-ipsec-server/root/etc/uci-defaults/luci-app-ipsec-server @@ -0,0 +1,23 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete firewall.luci_app_ipsec_server + set firewall.luci_app_ipsec_server=include + set firewall.luci_app_ipsec_server.type=script + set firewall.luci_app_ipsec_server.path=/var/etc/ipsecvpn.include + set firewall.luci_app_ipsec_server.reload=1 +EOF + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@luci-app-ipsec-server[-1] + add ucitrack luci-app-ipsec-server + set ucitrack.@luci-app-ipsec-server[-1].init=luci-app-ipsec-server + commit ucitrack +EOF + +/etc/init.d/ipsec disable 2>/dev/null +/etc/init.d/ipsec stop 2>/dev/null +/etc/init.d/xl2tpd disable 2>/dev/null +/etc/init.d/xl2tpd stop 2>/dev/null +rm -rf /tmp/luci-*cache +exit 0 diff --git a/luci-app-ipsec-server/root/usr/share/rpcd/acl.d/luci-app-ipsec-server.json b/luci-app-ipsec-server/root/usr/share/rpcd/acl.d/luci-app-ipsec-server.json new file mode 100644 index 000000000..d12ed9841 --- /dev/null +++ b/luci-app-ipsec-server/root/usr/share/rpcd/acl.d/luci-app-ipsec-server.json @@ -0,0 +1,11 @@ +{ + "luci-app-ipsec-server": { + "description": "Grant UCI access for luci-app-ipsec-server", + "read": { + "uci": [ "luci-app-ipsec-server" ] + }, + "write": { + "uci": [ "luci-app-ipsec-server" ] + } + } +} diff --git a/luci-app-ipsec-server/root/usr/share/xl2tpd/ip-down b/luci-app-ipsec-server/root/usr/share/xl2tpd/ip-down new file mode 100644 index 000000000..9434e7615 --- /dev/null +++ b/luci-app-ipsec-server/root/usr/share/xl2tpd/ip-down @@ -0,0 +1,27 @@ +#!/bin/sh + +_LOGOUT_TIME="$(date "+%Y-%m-%d %H:%M:%S")" +CONFIG="luci-app-ipsec-server" +L2TP_PATH=/var/etc/xl2tpd +L2TP_SESSION_PATH=${L2TP_PATH}/session + +_USERNAME=${PEERNAME} +_IFACE=${1} +_TTY=${2} +_SPEED=${3} +_LOCALIP=${4} +_PEERIP=${5} +_REMOTEIP=${6} +_BYTES_SENT=${BYTES_SENT} +_BYTES_RCVD=${BYTES_RCVD} +_CONNECT_TIME=${CONNECT_TIME} + +rm -f ${L2TP_SESSION_PATH}/${_USERNAME}.${_IFACE} +rm -f /var/run/${_IFACE}.pid + +#可根据退出的账号自定义脚本,如静态路由表,组网等。 +SCRIPT="/usr/share/xl2tpd/ip-down.d/${_USERNAME}" +[ -s "$SCRIPT" ] && { + [ ! -x "$SCRIPT" ] && chmod 0755 "$SCRIPT" + "$SCRIPT" "$@" +} diff --git a/luci-app-ipsec-server/root/usr/share/xl2tpd/ip-up b/luci-app-ipsec-server/root/usr/share/xl2tpd/ip-up new file mode 100644 index 000000000..6109d037e --- /dev/null +++ b/luci-app-ipsec-server/root/usr/share/xl2tpd/ip-up @@ -0,0 +1,58 @@ +#!/bin/sh + +_LOGIN_TIME="$(date "+%Y-%m-%d %H:%M:%S")" +CONFIG="luci-app-ipsec-server" +L2TP_PATH=/var/etc/xl2tpd +L2TP_SESSION_PATH=${L2TP_PATH}/session + +_USERNAME=${PEERNAME} +_IFACE=${1} +_TTY=${2} +_SPEED=${3} +_LOCALIP=${4} +_PEERIP=${5} + +_PID=$(cat /var/run/${_IFACE}.pid 2>/dev/null) +_REMOTEIP=$(cat /var/etc/xl2tpd/xl2tpd.log 2>/dev/null | grep "PID: ${_PID}" | grep -o -E '([0-9]{1,3}[\.]){3}[0-9]{1,3}') + +mkdir -p ${L2TP_SESSION_PATH} + +cat <<-EOF > ${L2TP_SESSION_PATH}/${_USERNAME}.${_IFACE} + { + "username": "${_USERNAME}", + "interface": "${_IFACE}", + "tty": "${_TTY}", + "speed": "${_SPEED}", + "ip": "${_PEERIP}", + "remote_ip": "${_REMOTEIP}", + "pid": "${_PID}", + "login_time": "${_LOGIN_TIME}" + } +EOF + +#只能单用户使用 +cfgid=$(uci show ${CONFIG} | grep "@l2tp_users" | grep "\.username='${_USERNAME}'" | cut -d '.' -sf 2) +[ -n "$cfgid" ] && { + HAS_LOGIN=$(ls ${L2TP_SESSION_PATH} | grep "^${_USERNAME}\.ppp" | grep -v "${_IFACE}") + [ -n "$HAS_LOGIN" ] && { + #踢出之前的用户 + KO_IFACE=$(echo $HAS_LOGIN | awk -F '.' '{print $2}') + KO_PID=$(cat /var/run/${KO_IFACE}.pid 2>/dev/null) + [ -n "$KO_PID" ] && kill -9 ${KO_PID} >/dev/null 2>&1 + rm -f ${L2TP_SESSION_PATH}/${HAS_LOGIN} + rm -f /var/run/${KO_IFACE}.pid + } + routes=$(uci -q get ${CONFIG}.${cfgid}.routes) + [ -n "$routes" ] && { + for router in ${routes}; do + route add -net ${router} dev ${_IFACE} >/dev/null 2>&1 + done + } +} + +#可根据登录的账号自定义脚本,如组网、日志、限速、权限等特殊待遇。 +SCRIPT="/usr/share/xl2tpd/ip-up.d/${_USERNAME}" +[ -s "$SCRIPT" ] && { + [ ! -x "$SCRIPT" ] && chmod 0755 "$SCRIPT" + "$SCRIPT" "$@" +} diff --git a/luci-app-ipsec-vpnd/Makefile b/luci-app-ipsec-vpnd/Makefile new file mode 100644 index 000000000..22e4d0358 --- /dev/null +++ b/luci-app-ipsec-vpnd/Makefile @@ -0,0 +1,16 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for IPSec VPN Server (IKEv1 with PSK and Xauth) +LUCI_DEPENDS:=+strongswan +strongswan-minimal +strongswan-mod-xauth-generic +strongswan-mod-kernel-libipsec +kmod-tun +LUCI_PKGARCH:=all + +PKG_NAME:=luci-app-ipsec-vpnd + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua b/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua new file mode 100644 index 000000000..4594275e6 --- /dev/null +++ b/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua @@ -0,0 +1,18 @@ +module("luci.controller.ipsec-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/ipsec") then + return + end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + entry({"admin", "vpn", "ipsec-server"}, cbi("ipsec-server"), _("IPSec VPN Server"), 80).dependent = false + entry({"admin", "vpn", "ipsec-server", "status"}, call("act_status")).leaf = true +end + +function act_status() + local e = {} + e.running = luci.sys.call("pgrep ipsec >/dev/null") == 0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server.lua b/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server.lua new file mode 100644 index 000000000..aa11ae1d8 --- /dev/null +++ b/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server.lua @@ -0,0 +1,35 @@ +mp = Map("ipsec") +mp.title = translate("IPSec VPN Server") +mp.description = translate("IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)") + +mp:section(SimpleSection).template = "ipsec/ipsec_status" + +s = mp:section(NamedSection, "ipsec", "service") +s.anonymouse = true + +enabled = s:option(Flag, "enabled", translate("Enable")) +enabled.default = 0 +enabled.rmempty = false + +clientip = s:option(Value, "clientip", translate("VPN Client IP")) +clientip.datatype = "ip4addr" +clientip.description = translate("LAN DHCP reserved started IP addresses with the same subnet mask") +clientip.optional = false +clientip.rmempty = false + +clientdns = s:option(Value, "clientdns", translate("VPN Client DNS")) +clientdns.datatype = "ip4addr" +clientdns.description = translate("DNS using in VPN tunnel.Set to the router's LAN IP is recommended") +clientdns.optional = false +clientdns.rmempty = false + +account = s:option(Value, "account", translate("Account")) +account.datatype = "string" + +password = s:option(Value, "password", translate("Password")) +password.password = true + +secret = s:option(Value, "secret", translate("Secret Pre-Shared Key")) +secret.password = true + +return mp diff --git a/luci-app-ipsec-vpnd/luasrc/view/ipsec/ipsec_status.htm b/luci-app-ipsec-vpnd/luasrc/view/ipsec/ipsec_status.htm new file mode 100644 index 000000000..1e256c73b --- /dev/null +++ b/luci-app-ipsec-vpnd/luasrc/view/ipsec/ipsec_status.htm @@ -0,0 +1,22 @@ + + +
+

+ <%:Collecting data...%> +

+
diff --git a/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po b/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po new file mode 100644 index 000000000..e051d341c --- /dev/null +++ b/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po @@ -0,0 +1,34 @@ +msgid "IPSec VPN Server" +msgstr "IPSec VPN 服务器" + +msgid "IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)" +msgstr "使用iOS 或者 Andriod (IKEv1 with PSK and Xauth) 原生内置 IPSec VPN 客户端进行连接" + +msgid "VPN Client IP" +msgstr "VPN客户端地址段" + +msgid "LAN DHCP reserved started IP addresses with the same subnet mask" +msgstr "VPN客户端使用独立子网段,默认为 10.10.10.2/24" + +msgid "VPN Client DNS" +msgstr "VPN客户端DNS服务器" + +msgid "DNS using in VPN tunnel.Set to the router's LAN IP is recommended" +msgstr "指定VPN客户端的DNS地址。推荐设置为 ipsec0 虚拟接口地址,默认为 10.10.10.1" + +msgid "Account" +msgstr "账户" + +msgid "Secret Pre-Shared Key" +msgstr "PSK密钥" + +msgid "IPSec VPN Server status" +msgstr "IPSec VPN 服务器运行状态" + +msgid "Disable from startup" +msgstr "禁止开机启动" + +msgid "Enable on startup" +msgstr "允许开机启动" + + diff --git a/luci-app-ipsec-vpnd/po/zh_Hans b/luci-app-ipsec-vpnd/po/zh_Hans new file mode 100644 index 000000000..e69de29bb diff --git a/luci-app-ipsec-vpnd/root/etc/config/ipsec b/luci-app-ipsec-vpnd/root/etc/config/ipsec new file mode 100644 index 000000000..4cd3f6422 --- /dev/null +++ b/luci-app-ipsec-vpnd/root/etc/config/ipsec @@ -0,0 +1,9 @@ + +config service 'ipsec' + option clientdns '10.10.10.1' + option account 'lean' + option secret 'myopenwrt' + option enabled '0' + option password '12345678' + option clientip '10.10.10.2/24' + diff --git a/luci-app-ipsec-vpnd/root/etc/init.d/ipsec b/luci-app-ipsec-vpnd/root/etc/init.d/ipsec new file mode 100644 index 000000000..5a4c6a217 --- /dev/null +++ b/luci-app-ipsec-vpnd/root/etc/init.d/ipsec @@ -0,0 +1,427 @@ +#!/bin/sh /etc/rc.common + +START=90 +STOP=10 + +USE_PROCD=1 +PROG=/usr/lib/ipsec/starter + +. $IPKG_INSTROOT/lib/functions.sh +. $IPKG_INSTROOT/lib/functions/network.sh + +IPSEC_SECRETS_FILE=/etc/ipsec.secrets +IPSEC_CONN_FILE=/etc/ipsec.conf +STRONGSWAN_CONF_FILE=/etc/strongswan.conf + +IPSEC_VAR_SECRETS_FILE=/var/ipsec/ipsec.secrets +IPSEC_VAR_CONN_FILE=/var/ipsec/ipsec.conf +STRONGSWAN_VAR_CONF_FILE=/var/ipsec/strongswan.conf + +WAIT_FOR_INTF=0 + +file_reset() { + : > "$1" +} + +xappend() { + local file="$1" + shift + + echo "${@}" >> "${file}" +} + +remove_include() { + local file="$1" + local include="$2" + + sed -i "\_${include}_d" "${file}" +} + +remove_includes() { + remove_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}" + remove_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}" + remove_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}" +} + +do_include() { + local conf="$1" + local uciconf="$2" + local backup=`mktemp -t -p /tmp/ ipsec-init-XXXXXX` + + [ ! -f "${conf}" ] && rm -rf "${conf}" + touch "${conf}" + + cat "${conf}" | grep -v "${uciconf}" > "${backup}" + mv "${backup}" "${conf}" + xappend "${conf}" "include ${uciconf}" + file_reset "${uciconf}" +} + +ipsec_reset() { + do_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}" +} + +ipsec_xappend() { + xappend "${IPSEC_VAR_CONN_FILE}" "$@" +} + +swan_reset() { + do_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}" +} + +swan_xappend() { + xappend "${STRONGSWAN_VAR_CONF_FILE}" "$@" +} + +secret_reset() { + do_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}" +} + +secret_xappend() { + xappend "${IPSEC_VAR_SECRETS_FILE}" "$@" +} + +warning() { + echo "WARNING: $@" >&2 +} + +add_crypto_proposal() { + local encryption_algorithm + local hash_algorithm + local dh_group + + config_get encryption_algorithm "$1" encryption_algorithm + config_get hash_algorithm "$1" hash_algorithm + config_get dh_group "$1" dh_group + + [ -n "${encryption_algorithm}" ] && \ + crypto="${crypto:+${crypto},}${encryption_algorithm}${hash_algorithm:+-${hash_algorithm}}${dh_group:+-${dh_group}}" +} + +set_crypto_proposal() { + local conf="$1" + local proposal + + crypto="" + + config_get crypto_proposal "$conf" crypto_proposal "" + for proposal in $crypto_proposal; do + add_crypto_proposal "$proposal" + done + + [ -n "${crypto}" ] && { + local force_crypto_proposal + + config_get_bool force_crypto_proposal "$conf" force_crypto_proposal + + [ "${force_crypto_proposal}" = "1" ] && crypto="${crypto}!" + } + + crypto_proposal="${crypto}" +} + +config_conn() { + # Generic ipsec conn section shared by tunnel and transport + local mode + local local_subnet + local local_nat + local local_sourceip + local local_updown + local local_firewall + local remote_subnet + local remote_sourceip + local remote_updown + local remote_firewall + local ikelifetime + local lifetime + local margintime + local keyingtries + local dpdaction + local dpddelay + local inactivity + local keyexchange + + config_get mode "$1" mode "route" + config_get local_subnet "$1" local_subnet "" + config_get local_nat "$1" local_nat "" + config_get local_sourceip "$1" local_sourceip "" + config_get local_updown "$1" local_updown "" + config_get local_firewall "$1" local_firewall "" + config_get remote_subnet "$1" remote_subnet "" + config_get remote_sourceip "$1" remote_sourceip "" + config_get remote_updown "$1" remote_updown "" + config_get remote_firewall "$1" remote_firewall "" + config_get ikelifetime "$1" ikelifetime "3h" + config_get lifetime "$1" lifetime "1h" + config_get margintime "$1" margintime "9m" + config_get keyingtries "$1" keyingtries "3" + config_get dpdaction "$1" dpdaction "none" + config_get dpddelay "$1" dpddelay "30s" + config_get inactivity "$1" inactivity + config_get keyexchange "$1" keyexchange "ikev2" + + [ -n "$local_nat" ] && local_subnet=$local_nat + + ipsec_xappend "conn $config_name-$1" + ipsec_xappend " left=%any" + ipsec_xappend " right=$remote_gateway" + + [ -n "$local_sourceip" ] && ipsec_xappend " leftsourceip=$local_sourceip" + [ -n "$local_subnet" ] && ipsec_xappend " leftsubnet=$local_subnet" + + [ -n "$local_firewall" ] && ipsec_xappend " leftfirewall=$local_firewall" + [ -n "$remote_firewall" ] && ipsec_xappend " rightfirewall=$remote_firewall" + + ipsec_xappend " ikelifetime=$ikelifetime" + ipsec_xappend " lifetime=$lifetime" + ipsec_xappend " margintime=$margintime" + ipsec_xappend " keyingtries=$keyingtries" + ipsec_xappend " dpdaction=$dpdaction" + ipsec_xappend " dpddelay=$dpddelay" + + [ -n "$inactivity" ] && ipsec_xappend " inactivity=$inactivity" + + if [ "$auth_method" = "psk" ]; then + ipsec_xappend " leftauth=psk" + ipsec_xappend " rightauth=psk" + + [ "$remote_sourceip" != "" ] && ipsec_xappend " rightsourceip=$remote_sourceip" + [ "$remote_subnet" != "" ] && ipsec_xappend " rightsubnet=$remote_subnet" + + ipsec_xappend " auto=$mode" + else + warning "AuthenticationMethod $auth_method not supported" + fi + + [ -n "$local_identifier" ] && ipsec_xappend " leftid=$local_identifier" + [ -n "$remote_identifier" ] && ipsec_xappend " rightid=$remote_identifier" + [ -n "$local_updown" ] && ipsec_xappend " leftupdown=$local_updown" + [ -n "$remote_updown" ] && ipsec_xappend " rightupdown=$remote_updown" + ipsec_xappend " keyexchange=$keyexchange" + + set_crypto_proposal "$1" + [ -n "${crypto_proposal}" ] && ipsec_xappend " esp=$crypto_proposal" + [ -n "${ike_proposal}" ] && ipsec_xappend " ike=$ike_proposal" +} + +config_tunnel() { + config_conn "$1" + + # Specific for the tunnel part + ipsec_xappend " type=tunnel" +} + +config_transport() { + config_conn "$1" + + # Specific for the transport part + ipsec_xappend " type=transport" +} + +config_remote() { + local enabled + local gateway + local pre_shared_key + local auth_method + + config_name=$1 + + config_get_bool enabled "$1" enabled 0 + [ $enabled -eq 0 ] && return + + config_get gateway "$1" gateway + config_get pre_shared_key "$1" pre_shared_key + config_get auth_method "$1" authentication_method + config_get local_identifier "$1" local_identifier "" + config_get remote_identifier "$1" remote_identifier "" + + [ "$gateway" = "any" ] && remote_gateway="%any" || remote_gateway="$gateway" + + [ -z "$local_identifier" ] && { + local ipdest + + [ "$remote_gateway" = "%any" ] && ipdest="1.1.1.1" || ipdest="$remote_gateway" + local_gateway=`ip route get $ipdest | awk -F"src" '/src/{gsub(/ /,"");print $2}'` + } + + [ -n "$local_identifier" ] && secret_xappend -n "$local_identifier " || secret_xappend -n "$local_gateway " + [ -n "$remote_identifier" ] && secret_xappend -n "$remote_identifier " || secret_xappend -n "$remote_gateway " + + secret_xappend ": PSK \"$pre_shared_key\"" + + set_crypto_proposal "$1" + ike_proposal="$crypto_proposal" + + config_list_foreach "$1" tunnel config_tunnel + + config_list_foreach "$1" transport config_transport + + ipsec_xappend "" +} + +config_ipsec() { + local debug + local rtinstall_enabled + local routing_tables_ignored + local routing_table + local routing_table_id + local interface + local device_list + + ipsec_reset + secret_reset + swan_reset + + ipsec_xappend "# generated by /etc/init.d/ipsec" + ipsec_xappend "version 2" + ipsec_xappend "" + + secret_xappend "# generated by /etc/init.d/ipsec" + + config_get debug "$1" debug 0 + config_get_bool rtinstall_enabled "$1" rtinstall_enabled 1 + [ $rtinstall_enabled -eq 1 ] && install_routes=yes || install_routes=no + + # prepare extra charon config option ignore_routing_tables + for routing_table in $(config_get "$1" "ignore_routing_tables"); do + if [ "$routing_table" -ge 0 ] 2>/dev/null; then + routing_table_id=$routing_table + else + routing_table_id=$(sed -n '/[ \t]*[0-9]\+[ \t]\+'$routing_table'[ \t]*$/s/[ \t]*\([0-9]\+\).*/\1/p' /etc/iproute2/rt_tables) + fi + + [ -n "$routing_table_id" ] && append routing_tables_ignored "$routing_table_id" + done + + local interface_list=$(config_get "$1" "interface") + if [ -z "$interface_list" ]; then + WAIT_FOR_INTF=0 + else + for interface in $interface_list; do + network_get_device device $interface + [ -n "$device" ] && append device_list "$device" "," + done + [ -n "$device_list" ] && WAIT_FOR_INTF=0 || WAIT_FOR_INTF=1 + fi + + swan_xappend "# generated by /etc/init.d/ipsec" + swan_xappend "charon {" + swan_xappend " load_modular = yes" + swan_xappend " install_routes = $install_routes" + [ -n "$routing_tables_ignored" ] && swan_xappend " ignore_routing_tables = $routing_tables_ignored" + [ -n "$device_list" ] && swan_xappend " interfaces_use = $device_list" + swan_xappend " plugins {" + swan_xappend " include /etc/strongswan.d/charon/*.conf" + swan_xappend " }" + swan_xappend " syslog {" + swan_xappend " identifier = ipsec" + swan_xappend " daemon {" + swan_xappend " default = $debug" + swan_xappend " }" + swan_xappend " auth {" + swan_xappend " default = $debug" + swan_xappend " }" + swan_xappend " }" + swan_xappend "}" +} + +prepare_env() { + mkdir -p /var/ipsec + remove_includes + config_load ipsec + config_foreach config_ipsec ipsec + config_foreach config_remote remote +} + +service_running() { + ipsec status > /dev/null 2>&1 +} + +reload_service() { + local bool vt_enabled=`uci get ipsec.@service[0].enabled 2>/dev/null` + [ "$vt_enabled" = 0 ] && /etc/init.d/ipsec stop && return + running && { + prepare_env + [ $WAIT_FOR_INTF -eq 0 ] && { + ipsec rereadall + ipsec reload + return + } + } + [ "$vt_enabled" = 1 ] && start +} + +check_ipsec_interface() { + local intf + + for intf in $(config_get "$1" interface); do + procd_add_interface_trigger "interface.*" "$intf" /etc/init.d/ipsec reload + done +} + +service_triggers() { + procd_add_reload_trigger "ipsec" + config load "ipsec" + config_foreach check_ipsec_interface ipsec +} + +start_service() { + local vt_enabled=`uci get ipsec.@service[0].enabled 2>/dev/null` + local vt_clientip=`uci get ipsec.@service[0].clientip` + local vt_clientdns=`uci get ipsec.@service[0].clientdns` + local vt_account=`uci get ipsec.@service[0].account` + local vt_password=`uci get ipsec.@service[0].password 2>/dev/null` + local vt_secret=`uci get ipsec.@service[0].secret 2>/dev/null` + + [ "$vt_enabled" = 0 ] && /etc/init.d/ipsec stop && return + + cat > /etc/ipsec.conf < /etc/ipsec.secrets </dev/null +iptables -D FORWARD -m policy --dir out --pol ipsec --proto esp -j ACCEPT 2>/dev/null +iptables -D INPUT -m policy --dir in --pol ipsec --proto esp -j ACCEPT 2>/dev/null +iptables -D OUTPUT -m policy --dir out --pol ipsec --proto esp -j ACCEPT 2>/dev/null + +iptables -I FORWARD -m policy --dir in --pol ipsec --proto esp -j ACCEPT +iptables -I FORWARD -m policy --dir out --pol ipsec --proto esp -j ACCEPT +iptables -I INPUT -m policy --dir in --pol ipsec --proto esp -j ACCEPT +iptables -I OUTPUT -m policy --dir out --pol ipsec --proto esp -j ACCEPT + +echo 1 > /proc/sys/net/ipv4/conf/br-lan/proxy_arp diff --git a/luci-app-ipsec-vpnd/root/etc/uci-defaults/luci-ipsec b/luci-app-ipsec-vpnd/root/etc/uci-defaults/luci-ipsec new file mode 100644 index 000000000..5bebceee1 --- /dev/null +++ b/luci-app-ipsec-vpnd/root/etc/uci-defaults/luci-ipsec @@ -0,0 +1,81 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete firewall.ipsecd + set firewall.ipsecd=include + set firewall.ipsecd.type=script + set firewall.ipsecd.path=/etc/ipsec.include + set firewall.ipsecd.reload=1 + commit firewall +EOF + +uci -q batch <<-EOF >/dev/null + delete network.VPN + set network.VPN=interface + set network.VPN.device="ipsec0" + set network.VPN.proto="static" + set network.VPN.ipaddr="10.10.10.1" + set network.VPN.netmask="255.255.255.0" + + commit network + + delete firewall.ike + add firewall rule + rename firewall.@rule[-1]="ike" + set firewall.@rule[-1].name="ike" + set firewall.@rule[-1].target="ACCEPT" + set firewall.@rule[-1].src="wan" + set firewall.@rule[-1].proto="udp" + set firewall.@rule[-1].dest_port="500" + + delete firewall.ipsec + add firewall rule + rename firewall.@rule[-1]="ipsec" + set firewall.@rule[-1].name="ipsec" + set firewall.@rule[-1].target="ACCEPT" + set firewall.@rule[-1].src="wan" + set firewall.@rule[-1].proto="udp" + set firewall.@rule[-1].dest_port="4500" + + delete firewall.ah + add firewall rule + rename firewall.@rule[-1]="ah" + set firewall.@rule[-1].name="ah" + set firewall.@rule[-1].target="ACCEPT" + set firewall.@rule[-1].src="wan" + set firewall.@rule[-1].proto="ah" + + delete firewall.esp + add firewall rule + rename firewall.@rule[-1]="esp" + set firewall.@rule[-1].name="esp" + set firewall.@rule[-1].target="ACCEPT" + set firewall.@rule[-1].src="wan" + set firewall.@rule[-1].proto="esp" + + delete firewall.VPN + set firewall.VPN=zone + set firewall.VPN.name="VPN" + set firewall.VPN.input="ACCEPT" + set firewall.VPN.forward="ACCEPT" + set firewall.VPN.output="ACCEPT" + set firewall.VPN.network="VPN" + + delete firewall.vpn + set firewall.vpn=forwarding + set firewall.vpn.name="vpn" + set firewall.vpn.dest="wan" + set firewall.vpn.src="VPN" + + commit firewall +EOF + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@ipsec[-1] + add ucitrack ipsec + set ucitrack.@ipsec[-1].init=ipsec + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/luci-app-ipsec-vpnd/root/usr/share/rpcd/acl.d/luci-app-ipsec-vpnd.json b/luci-app-ipsec-vpnd/root/usr/share/rpcd/acl.d/luci-app-ipsec-vpnd.json new file mode 100644 index 000000000..ca300c090 --- /dev/null +++ b/luci-app-ipsec-vpnd/root/usr/share/rpcd/acl.d/luci-app-ipsec-vpnd.json @@ -0,0 +1,11 @@ +{ + "luci-app-ipsec-vpnd": { + "description": "Grant UCI access for luci-app-ipsec-vpnd", + "read": { + "uci": [ "ipsec" ] + }, + "write": { + "uci": [ "ipsec" ] + } + } +} diff --git a/luci-app-ipsec-vpnserver-manyusers/Makefile b/luci-app-ipsec-vpnserver-manyusers/Makefile new file mode 100644 index 000000000..d838d9d16 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/Makefile @@ -0,0 +1,14 @@ +# Copyright (C) 2018-2020 Lienol +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for IPSec VPN Server +LUCI_DEPENDS:=+strongswan +strongswan-minimal +strongswan-mod-xauth-generic +LUCI_PKGARCH:=all + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-ipsec-vpnserver-manyusers/luasrc/controller/ipsec-server.lua b/luci-app-ipsec-vpnserver-manyusers/luasrc/controller/ipsec-server.lua new file mode 100644 index 000000000..7b79f812c --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/luasrc/controller/ipsec-server.lua @@ -0,0 +1,27 @@ +-- Copyright 2018-2019 Lienol +module("luci.controller.ipsec-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/ipsec") then return end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + local page = entry({"admin", "vpn", "ipsec-server"}, + alias("admin", "vpn", "ipsec-server", "settings"), + _("IPSec VPN Server")) + page.order = 49 + page.dependent = false + page.acl_depends = { "luci-app-ipsec-vpnserver-manyusers" } + entry({"admin", "vpn", "ipsec-server", "settings"}, + cbi("ipsec-server/settings"), _("General Settings"), 10).leaf = true + entry({"admin", "vpn", "ipsec-server", "users"}, cbi("ipsec-server/users"), + _("Users Manager"), 20).leaf = true + entry({"admin", "vpn", "ipsec-server", "status"}, call("status")).leaf = + true +end + +function status() + local e = {} + e.status = luci.sys.call("/usr/bin/pgrep ipsec > /dev/null") == 0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/luci-app-ipsec-vpnserver-manyusers/luasrc/model/cbi/ipsec-server/settings.lua b/luci-app-ipsec-vpnserver-manyusers/luasrc/model/cbi/ipsec-server/settings.lua new file mode 100644 index 000000000..d2415d527 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/luasrc/model/cbi/ipsec-server/settings.lua @@ -0,0 +1,105 @@ +local s = require "luci.sys" +local net = require"luci.model.network".init() +local ifaces = s.net:devices() +local m, s, o +mp = Map("ipsec", translate("IPSec VPN Server")) +mp.description = translate( + "IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)") +mp.template = "ipsec-server/index" + +s = mp:section(TypedSection, "service") +s.anonymous = true +o = s:option(DummyValue, "ipsec-server_status", translate("Current Condition")) +o.template = "ipsec-server/status" +enabled = s:option(Flag, "enabled", translate("Enable")) +enabled.default = 0 +enabled.rmempty = false + +clientip = s:option(Value, "clientip", translate("VPN Client IP")) +clientip.datatype = "ip4addr" +clientip.description = translate( + "VPN Client reserved started IP addresses with the same subnet mask") +clientip.optional = false +clientip.rmempty = false + +--[[ +clientdns = s:option(Value, "clientdns", translate("VPN Client DNS")) +clientdns.datatype = "ip4addr" +clientdns.description = translate("DNS using in VPN tunnel.") +clientdns.optional = false +clientdns.rmempty = false +]]-- + +secret = s:option(Value, "secret", translate("Secret Pre-Shared Key")) +secret.password = true + +function mp.on_save(self) + require "luci.model.uci" + require "luci.sys" + + local have_ike_rule = false + local have_ipsec_rule = false + local have_ah_rule = false + local have_esp_rule = false + + luci.model.uci.cursor():foreach('firewall', 'rule', function(section) + if section.name == 'ike' then have_ike_rule = true end + if section.name == 'ipsec' then have_ipsec_rule = true end + if section.name == 'ah' then have_ah_rule = true end + if section.name == 'esp' then have_esp_rule = true end + end) + + if not have_ike_rule then + local cursor = luci.model.uci.cursor() + local ike_rulename = cursor:add('firewall', 'rule') + cursor:tset('firewall', ike_rulename, { + ['name'] = 'ike', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 'udp', + ['dest_port'] = 500 + }) + cursor:save('firewall') + cursor:commit('firewall') + end + if not have_ipsec_rule then + local cursor = luci.model.uci.cursor() + local ipsec_rulename = cursor:add('firewall', 'rule') + cursor:tset('firewall', ipsec_rulename, { + ['name'] = 'ipsec', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 'udp', + ['dest_port'] = 4500 + }) + cursor:save('firewall') + cursor:commit('firewall') + end + if not have_ah_rule then + local cursor = luci.model.uci.cursor() + local ah_rulename = cursor:add('firewall', 'rule') + cursor:tset('firewall', ah_rulename, { + ['name'] = 'ah', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 'ah' + }) + cursor:save('firewall') + cursor:commit('firewall') + end + if not have_esp_rule then + local cursor = luci.model.uci.cursor() + local esp_rulename = cursor:add('firewall', 'rule') + cursor:tset('firewall', esp_rulename, { + ['name'] = 'esp', + ['target'] = 'ACCEPT', + ['src'] = 'wan', + ['proto'] = 'esp' + }) + cursor:save('firewall') + cursor:commit('firewall') + end + +end + +return mp diff --git a/luci-app-ipsec-vpnserver-manyusers/luasrc/model/cbi/ipsec-server/users.lua b/luci-app-ipsec-vpnserver-manyusers/luasrc/model/cbi/ipsec-server/users.lua new file mode 100644 index 000000000..3477448f1 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/luasrc/model/cbi/ipsec-server/users.lua @@ -0,0 +1,18 @@ +mp = Map("ipsec", translate("IPSec VPN Server")) +mp.description = translate( + "IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)") + +s = mp:section(TypedSection, "users", translate("Users Manager")) +s.addremove = true +s.anonymous = true +s.template = "cbi/tblsection" + +enabled = s:option(Flag, "enabled", translate("Enabled")) +enabled.rmempty = false +username = s:option(Value, "username", translate("User name")) +username.placeholder = translate("User name") +username.rmempty = true +password = s:option(Value, "password", translate("Password")) +password.rmempty = true + +return mp diff --git a/luci-app-ipsec-vpnserver-manyusers/luasrc/view/ipsec-server/index.htm b/luci-app-ipsec-vpnserver-manyusers/luasrc/view/ipsec-server/index.htm new file mode 100644 index 000000000..017f042c4 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/luasrc/view/ipsec-server/index.htm @@ -0,0 +1,13 @@ +<% include("cbi/map") %> + diff --git a/luci-app-ipsec-vpnserver-manyusers/luasrc/view/ipsec-server/status.htm b/luci-app-ipsec-vpnserver-manyusers/luasrc/view/ipsec-server/status.htm new file mode 100644 index 000000000..2c50928a9 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/luasrc/view/ipsec-server/status.htm @@ -0,0 +1,3 @@ +<%+cbi/valueheader%> +<%=pcdata(self:cfgvalue(section) or self.default or "")%> +<%+cbi/valuefooter%> diff --git a/luci-app-ipsec-vpnserver-manyusers/po/zh-cn b/luci-app-ipsec-vpnserver-manyusers/po/zh-cn new file mode 100644 index 000000000..e69de29bb diff --git a/luci-app-ipsec-vpnserver-manyusers/po/zh_Hans/ipsec.po b/luci-app-ipsec-vpnserver-manyusers/po/zh_Hans/ipsec.po new file mode 100644 index 000000000..349daca80 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/po/zh_Hans/ipsec.po @@ -0,0 +1,50 @@ +msgid "IPSec VPN Server" +msgstr "IPSec VPN 服务器" + +msgid "IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)" +msgstr "使用iOS 或者 Andriod (IKEv1 with PSK and Xauth) 原生内置 IPSec VPN 客户端进行连接" + +msgid "IPSec VPN Server status" +msgstr "IPSec VPN 服务器运行状态" + +msgid "Current Condition" +msgstr "当前状态" + +msgid "General settings" +msgstr "基本设置" + +msgid "VPN Client IP" +msgstr "VPN客户端地址段" + +msgid "VPN Client reserved started IP addresses with the same subnet mask" +msgstr "VPN客户端获取IP的起始地址,例如 192.168.100.10/24" + +msgid "VPN Client DNS" +msgstr "VPN客户端DNS服务器" + +msgid "DNS using in VPN tunnel." +msgstr "指定VPN客户端的DNS地址。" + +msgid "Secret Pre-Shared Key" +msgstr "PSK密钥" + +msgid "is_nat" +msgstr "NAT转发" + +msgid "Interface" +msgstr "接口" + +msgid "Specify interface forwarding traffic." +msgstr "指定接口转发流量。" + +msgid "Disable from startup" +msgstr "禁止开机启动" + +msgid "Enable on startup" +msgstr "允许开机启动" + +msgid "NOT RUNNING" +msgstr "未运行" + +msgid "RUNNING" +msgstr "运行中" \ No newline at end of file diff --git a/luci-app-ipsec-vpnserver-manyusers/root/etc/config/ipsec b/luci-app-ipsec-vpnserver-manyusers/root/etc/config/ipsec new file mode 100644 index 000000000..d837e0916 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/root/etc/config/ipsec @@ -0,0 +1,12 @@ + +config service 'ipsec' + option enabled '0' + option secret 'ipsec' + option clientip '192.168.100.10/24' + option clientdns '223.5.5.5' + +config users + option enabled '1' + option username 'guest' + option password '123456' + diff --git a/luci-app-ipsec-vpnserver-manyusers/root/etc/init.d/ipsecvpn b/luci-app-ipsec-vpnserver-manyusers/root/etc/init.d/ipsecvpn new file mode 100644 index 000000000..99aafa6cf --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/root/etc/init.d/ipsecvpn @@ -0,0 +1,68 @@ +#!/bin/sh /etc/rc.common + +START=99 + +IPSEC_SECRETS_FILE=/etc/ipsec.secrets +IPSEC_CONN_FILE=/etc/ipsec.conf + +setup_login() { + config_get enabled $1 enabled + [ "$enabled" -eq 0 ] && return 0 + config_get username $1 username + config_get password $1 password + [ -n "$username" ] || return 0 + [ -n "$password" ] || return 0 + echo "$username : XAUTH '$password'" >> $IPSEC_SECRETS_FILE +} + +start() { + local vt_enabled=$(uci -q get ipsec.@service[0].enabled) + [ "$vt_enabled" = 0 ] && return 1 + + local vt_clientip=$(uci -q get ipsec.@service[0].clientip) + local vt_clientdns=$(uci -q get ipsec.@service[0].clientdns) + [ -z "$vt_clientdns" ] && local vt_clientdns="8.8.4.4" + local vt_secret=$(uci -q get ipsec.@service[0].secret) + + cat > $IPSEC_CONN_FILE < /etc/ipsec.secrets < /dev/null 2>&1 & + fw3 -q reload 2>&1 & +} + +stop() { + ps -w | grep "/usr/lib/ipsec" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 + fw3 -q reload 2>&1 +} \ No newline at end of file diff --git a/luci-app-ipsec-vpnserver-manyusers/root/etc/uci-defaults/luci-app-ipsec-vpnserver-manyusers b/luci-app-ipsec-vpnserver-manyusers/root/etc/uci-defaults/luci-app-ipsec-vpnserver-manyusers new file mode 100644 index 000000000..48cd77da8 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/root/etc/uci-defaults/luci-app-ipsec-vpnserver-manyusers @@ -0,0 +1,23 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete firewall.ipsecvpn + set firewall.ipsecvpn=include + set firewall.ipsecvpn.type=script + set firewall.ipsecvpn.path=/usr/share/ipsecvpn/firewall.include + set firewall.ipsecvpn.reload=1 +EOF + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@ipsec[-1] + add ucitrack ipsec + set ucitrack.@ipsec[-1].init=ipsecvpn + commit ucitrack +EOF + +/etc/init.d/ipsec disable && /etc/init.d/ipsec stop +rm -f /etc/init.d/ipsec +chmod a+x /usr/share/ipsecvpn/* >/dev/null 2>&1 + +rm -rf /tmp/luci-*cache +exit 0 diff --git a/luci-app-ipsec-vpnserver-manyusers/root/usr/share/ipsecvpn/firewall.include b/luci-app-ipsec-vpnserver-manyusers/root/usr/share/ipsecvpn/firewall.include new file mode 100644 index 000000000..16f017ea2 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/root/usr/share/ipsecvpn/firewall.include @@ -0,0 +1,39 @@ +#!/bin/sh + +iptables -D INPUT -p udp -m multiport --dports 500,4500 -m comment --comment "IPSec VPN Server" -j ACCEPT 2> /dev/null +ipsec_nums=$(iptables -t nat -n -L POSTROUTING 2>/dev/null | grep -c "IPSec VPN Server") +if [ -n "$ipsec_nums" ]; then + until [ "$ipsec_nums" = 0 ] + do + rules=$(iptables -t nat -n -L POSTROUTING --line-num 2>/dev/null | grep "IPSec VPN Server" | awk '{print $1}') + for rule in $rules + do + iptables -t nat -D POSTROUTING $rule 2> /dev/null + break + done + ipsec_nums=$(expr $ipsec_nums - 1) + done +fi +nums=$(iptables -n -L forwarding_rule 2>/dev/null | grep -c "IPSec VPN Server") +if [ -n "$nums" ]; then + until [ "$nums" = 0 ] + do + rules=$(iptables -n -L forwarding_rule --line-num 2>/dev/null | grep "IPSec VPN Server" | awk '{print $1}') + for rule in $rules + do + iptables -D forwarding_rule $rule 2> /dev/null + break + done + nums=$(expr $nums - 1) + done +fi + +enable=$(uci -q get ipsec.ipsec.enabled) +if [ -n "$enable" -a "$enable" == 1 ]; then + clientip=$(uci -q get ipsec.ipsec.clientip) + iptables -t nat -I POSTROUTING -s ${clientip%.*}.0/24 -m comment --comment "IPSec VPN Server" -j MASQUERADE + iptables -I forwarding_rule -s ${clientip%.*}.0/24 -m comment --comment "IPSec VPN Server" -j ACCEPT + iptables -I forwarding_rule -m policy --dir in --pol ipsec --proto esp -m comment --comment "IPSec VPN Server" -j ACCEPT + iptables -I forwarding_rule -m policy --dir out --pol ipsec --proto esp -m comment --comment "IPSec VPN Server" -j ACCEPT + iptables -I INPUT -p udp -m multiport --dports 500,4500 -m comment --comment "IPSec VPN Server" -j ACCEPT +fi diff --git a/luci-app-ipsec-vpnserver-manyusers/root/usr/share/rpcd/acl.d/luci-app-ipsec-vpnserver-manyusers.json b/luci-app-ipsec-vpnserver-manyusers/root/usr/share/rpcd/acl.d/luci-app-ipsec-vpnserver-manyusers.json new file mode 100644 index 000000000..0daa049a2 --- /dev/null +++ b/luci-app-ipsec-vpnserver-manyusers/root/usr/share/rpcd/acl.d/luci-app-ipsec-vpnserver-manyusers.json @@ -0,0 +1,11 @@ +{ + "luci-app-ipsec-vpnserver-manyusers": { + "description": "Grant UCI access for luci-app-ipsec-vpnserver-manyusers", + "read": { + "uci": [ "ipsec" ] + }, + "write": { + "uci": [ "ipsec" ] + } + } +} diff --git a/netmaker-openwrt/netmaker/Makefile b/netmaker-openwrt/netmaker/Makefile index 903dd2beb..1c45a9979 100644 --- a/netmaker-openwrt/netmaker/Makefile +++ b/netmaker-openwrt/netmaker/Makefile @@ -8,13 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=netmaker -PKG_VERSION:=0.9.4 -PKG_RELEASE:=1 +PKG_VERSION:=0.16.1 +PKG_RELEASE:=2 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/gravitl/netmaker.git -PKG_SOURCE_VERSION:=e9bce264719f88c30e252ecc754d08f422f4c080 -PKG_SOURCE_DATE:=20220117 +PKG_SOURCE_VERSION:=e0964fccfe9d02dd3e4c52ea98dc8faac99241c9 +PKG_SOURCE_DATE:=20221014 PKG_MIRROR_HASH:=skip PKG_LICENSE:=MIT