From 8e11c19dc0c4a24a1f3071da2953e6043559f030 Mon Sep 17 00:00:00 2001 From: suyuan <175338101@qq.com> Date: Wed, 18 Jan 2023 20:37:29 +0800 Subject: [PATCH] addfix --- luci-app-cpufreq/Makefile | 16 + .../luasrc/controller/cpufreq.lua | 11 + luci-app-cpufreq/luasrc/model/cbi/cpufreq.lua | 68 +++ luci-app-cpufreq/po/zh-cn/cpufreq.po | 32 ++ luci-app-cpufreq/root/etc/config/cpufreq | 3 + luci-app-cpufreq/root/etc/init.d/cpufreq | 27 ++ .../root/etc/uci-defaults/10-cpufreq | 104 +++++ .../share/rpcd/acl.d/luci-app-cpufreq.json | 11 + luci-app-ipsec-server/Makefile | 24 + .../luasrc/controller/ipsec-server.lua | 24 + .../model/cbi/ipsec-server/l2tp_user.lua | 35 ++ .../luasrc/model/cbi/ipsec-server/online.lua | 83 ++++ .../model/cbi/ipsec-server/settings.lua | 64 +++ .../luasrc/model/cbi/ipsec-server/users.lua | 54 +++ .../view/ipsec-server/ipsec-server_status.htm | 21 + .../po/zh-cn/ipsec-server.po | 77 ++++ luci-app-ipsec-server/po/zh_Hans | 1 + .../root/etc/config/luci-app-ipsec-server | 7 + .../root/etc/init.d/luci-app-ipsec-server | 274 +++++++++++ .../etc/uci-defaults/luci-app-ipsec-server | 23 + .../rpcd/acl.d/luci-app-ipsec-server.json | 11 + .../root/usr/share/xl2tpd/ip-down | 27 ++ .../root/usr/share/xl2tpd/ip-up | 58 +++ luci-app-ipsec-vpnd/Makefile | 18 + .../luasrc/controller/ipsec-server.lua | 18 + .../luasrc/model/cbi/ipsec-server.lua | 35 ++ .../luasrc/view/ipsec/ipsec_status.htm | 22 + luci-app-ipsec-vpnd/po/zh-cn/ipsec.po | 32 ++ luci-app-ipsec-vpnd/root/etc/config/ipsec | 9 + luci-app-ipsec-vpnd/root/etc/init.d/ipsec | 427 ++++++++++++++++++ luci-app-ipsec-vpnd/root/etc/ipsec.include | 11 + .../root/etc/uci-defaults/luci-ipsec | 81 ++++ luci-app-zerotier/Makefile | 19 + .../luasrc/controller/zerotier.lua | 22 + .../luasrc/model/cbi/zerotier/info.lua | 15 + .../luasrc/model/cbi/zerotier/settings.lua | 27 ++ .../luasrc/view/zerotier/zerotier_status.htm | 22 + luci-app-zerotier/po/zh-cn/zerotier.po | 17 + luci-app-zerotier/root/etc/init.d/zerotier | 113 +++++ .../root/etc/uci-defaults/40_luci-zerotier | 18 + luci-app-zerotier/root/etc/zerotier.start | 28 ++ luci-app-zerotier/root/etc/zerotier.stop | 15 + .../root/etc/zerotier/zerotier.log | 0 43 files changed, 2004 insertions(+) create mode 100644 luci-app-cpufreq/Makefile create mode 100644 luci-app-cpufreq/luasrc/controller/cpufreq.lua create mode 100644 luci-app-cpufreq/luasrc/model/cbi/cpufreq.lua create mode 100644 luci-app-cpufreq/po/zh-cn/cpufreq.po create mode 100644 luci-app-cpufreq/root/etc/config/cpufreq create mode 100644 luci-app-cpufreq/root/etc/init.d/cpufreq create mode 100644 luci-app-cpufreq/root/etc/uci-defaults/10-cpufreq create mode 100644 luci-app-cpufreq/root/usr/share/rpcd/acl.d/luci-app-cpufreq.json create mode 100644 luci-app-ipsec-server/Makefile create mode 100644 luci-app-ipsec-server/luasrc/controller/ipsec-server.lua create mode 100644 luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/l2tp_user.lua create mode 100644 luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/online.lua create mode 100644 luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/settings.lua create mode 100644 luci-app-ipsec-server/luasrc/model/cbi/ipsec-server/users.lua create mode 100644 luci-app-ipsec-server/luasrc/view/ipsec-server/ipsec-server_status.htm create mode 100644 luci-app-ipsec-server/po/zh-cn/ipsec-server.po create mode 100644 luci-app-ipsec-server/po/zh_Hans create mode 100644 luci-app-ipsec-server/root/etc/config/luci-app-ipsec-server create mode 100644 luci-app-ipsec-server/root/etc/init.d/luci-app-ipsec-server create mode 100644 luci-app-ipsec-server/root/etc/uci-defaults/luci-app-ipsec-server create mode 100644 luci-app-ipsec-server/root/usr/share/rpcd/acl.d/luci-app-ipsec-server.json create mode 100644 luci-app-ipsec-server/root/usr/share/xl2tpd/ip-down create mode 100644 luci-app-ipsec-server/root/usr/share/xl2tpd/ip-up create mode 100644 luci-app-ipsec-vpnd/Makefile create mode 100644 luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua create mode 100644 luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server.lua create mode 100644 luci-app-ipsec-vpnd/luasrc/view/ipsec/ipsec_status.htm create mode 100644 luci-app-ipsec-vpnd/po/zh-cn/ipsec.po create mode 100644 luci-app-ipsec-vpnd/root/etc/config/ipsec create mode 100644 luci-app-ipsec-vpnd/root/etc/init.d/ipsec create mode 100644 luci-app-ipsec-vpnd/root/etc/ipsec.include create mode 100644 luci-app-ipsec-vpnd/root/etc/uci-defaults/luci-ipsec create mode 100644 luci-app-zerotier/Makefile create mode 100644 luci-app-zerotier/luasrc/controller/zerotier.lua create mode 100644 luci-app-zerotier/luasrc/model/cbi/zerotier/info.lua create mode 100644 luci-app-zerotier/luasrc/model/cbi/zerotier/settings.lua create mode 100644 luci-app-zerotier/luasrc/view/zerotier/zerotier_status.htm create mode 100644 luci-app-zerotier/po/zh-cn/zerotier.po create mode 100644 luci-app-zerotier/root/etc/init.d/zerotier create mode 100644 luci-app-zerotier/root/etc/uci-defaults/40_luci-zerotier create mode 100644 luci-app-zerotier/root/etc/zerotier.start create mode 100644 luci-app-zerotier/root/etc/zerotier.stop create mode 100644 luci-app-zerotier/root/etc/zerotier/zerotier.log diff --git a/luci-app-cpufreq/Makefile b/luci-app-cpufreq/Makefile new file mode 100644 index 000000000..5a95b059b --- /dev/null +++ b/luci-app-cpufreq/Makefile @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-3.0-only +# +# Copyright (C) 2021 ImmortalWrt.org + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI for CPU Freq Setting +LUCI_DEPENDS:=@(arm||aarch64) + +PKG_NAME:=luci-app-cpufreq +PKG_VERSION:=1 +PKG_RELEASE:=$(COMMITCOUNT) + +include ../../luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-cpufreq/luasrc/controller/cpufreq.lua b/luci-app-cpufreq/luasrc/controller/cpufreq.lua new file mode 100644 index 000000000..2bf7a5686 --- /dev/null +++ b/luci-app-cpufreq/luasrc/controller/cpufreq.lua @@ -0,0 +1,11 @@ +module("luci.controller.cpufreq", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/cpufreq") then + return + end + + local page = entry({"admin", "system", "cpufreq"}, cbi("cpufreq"), _("CPU Freq"), 90) + page.dependent = false + page.acl_depends = { "luci-app-cpufreq" } +end diff --git a/luci-app-cpufreq/luasrc/model/cbi/cpufreq.lua b/luci-app-cpufreq/luasrc/model/cbi/cpufreq.lua new file mode 100644 index 000000000..febb7ad90 --- /dev/null +++ b/luci-app-cpufreq/luasrc/model/cbi/cpufreq.lua @@ -0,0 +1,68 @@ +local fs = require "nixio.fs" + +function string.split(input, delimiter) + input = tostring(input) + delimiter = tostring(delimiter) + if (delimiter=='') then return false end + local pos,arr = 0, {} + for st,sp in function() return string.find(input, delimiter, pos, true) end do + table.insert(arr, string.sub(input, pos, st - 1)) + pos = sp + 1 + end + table.insert(arr, string.sub(input, pos)) + return arr +end + +mp = Map("cpufreq", translate("CPU Freq Settings")) +mp.description = translate("Set CPU Scaling Governor to Max Performance or Balance Mode") + +s = mp:section(NamedSection, "cpufreq", "settings") +s.anonymouse = true + +local policy_nums = luci.sys.exec("echo -n $(find /sys/devices/system/cpu/cpufreq/policy* -maxdepth 0 | grep -Eo '[0-9]+')") +for _, policy_num in ipairs(string.split(policy_nums, " ")) do + if not fs.access("/sys/devices/system/cpu/cpufreq/policy" .. policy_num .. "/scaling_available_frequencies") then return end + + cpu_freqs = fs.readfile("/sys/devices/system/cpu/cpufreq/policy" .. policy_num .. "/scaling_available_frequencies") + cpu_freqs = string.sub(cpu_freqs, 1, -3) + + cpu_governors = fs.readfile("/sys/devices/system/cpu/cpufreq/policy" .. policy_num .. "/scaling_available_governors") + cpu_governors = string.sub(cpu_governors, 1, -3) + + + freq_array = string.split(cpu_freqs, " ") + governor_array = string.split(cpu_governors, " ") + + s:tab(policy_num, translate("Policy " .. policy_num)) + + governor = s:taboption(policy_num, ListValue, "governor" .. policy_num, translate("CPU Scaling Governor")) + for _, e in ipairs(governor_array) do + if e ~= "" then governor:value(e, translate(e, string.upper(e))) end + end + + minfreq = s:taboption(policy_num, ListValue, "minfreq" .. policy_num, translate("Min Idle CPU Freq")) + for _, e in ipairs(freq_array) do + if e ~= "" then minfreq:value(e) end + end + + maxfreq = s:taboption(policy_num, ListValue, "maxfreq" .. policy_num, translate("Max Turbo Boost CPU Freq")) + for _, e in ipairs(freq_array) do + if e ~= "" then maxfreq:value(e) end + end + + sdfactor = s:taboption(policy_num, Value, "sdfactor" .. policy_num, translate("CPU Switching Sampling rate")) + sdfactor.datatype="range(1,100000)" + sdfactor.description = translate("The sampling rate determines how frequently the governor checks to tune the CPU (ms)") + sdfactor.placeholder = 10 + sdfactor.default = 10 + sdfactor:depends("governor" .. policy_num, "ondemand") + + upthreshold = s:taboption(policy_num, Value, "upthreshold" .. policy_num, translate("CPU Switching Threshold")) + upthreshold.datatype="range(1,99)" + upthreshold.description = translate("Kernel make a decision on whether it should increase the frequency (%)") + upthreshold.placeholder = 50 + upthreshold.default = 50 + upthreshold:depends("governor" .. policy_num, "ondemand") +end + +return mp diff --git a/luci-app-cpufreq/po/zh-cn/cpufreq.po b/luci-app-cpufreq/po/zh-cn/cpufreq.po new file mode 100644 index 000000000..bd818d774 --- /dev/null +++ b/luci-app-cpufreq/po/zh-cn/cpufreq.po @@ -0,0 +1,32 @@ +msgid "CPU Freq" +msgstr "CPU 性能优化调节" + +msgid "CPU Freq Settings" +msgstr "CPU 性能优化调节设置" + +msgid "Set CPU Scaling Governor to Max Performance or Balance Mode" +msgstr "设置路由器的 CPU 性能模式(高性能/均衡省电)" + +msgid "CPU Scaling Governor" +msgstr "CPU 工作模式" + +msgid "CPU Freq from 48000 to 716000 (Khz)" +msgstr "CPU 频率范围为 48000 到 716000 (Khz)" + +msgid "Min Idle CPU Freq" +msgstr "待机 CPU 最小频率" + +msgid "Max Turbo Boost CPU Freq" +msgstr "最大 Turbo Boost CPU 频率" + +msgid "CPU Switching Sampling rate" +msgstr "CPU 切换周期" + +msgid "The sampling rate determines how frequently the governor checks to tune the CPU (ms)" +msgstr "CPU 检查切换的周期 (ms)。注意:过于频繁的切换频率会引起网络延迟抖动" + +msgid "CPU Switching Threshold" +msgstr "CPU 切换频率触发阈值" + +msgid "Kernel make a decision on whether it should increase the frequency (%)" +msgstr "当 CPU 占用率超过 (%) 的情况下触发内核切换频率" diff --git a/luci-app-cpufreq/root/etc/config/cpufreq b/luci-app-cpufreq/root/etc/config/cpufreq new file mode 100644 index 000000000..5c2c070e9 --- /dev/null +++ b/luci-app-cpufreq/root/etc/config/cpufreq @@ -0,0 +1,3 @@ + +config settings 'cpufreq' + diff --git a/luci-app-cpufreq/root/etc/init.d/cpufreq b/luci-app-cpufreq/root/etc/init.d/cpufreq new file mode 100644 index 000000000..4dda93bc7 --- /dev/null +++ b/luci-app-cpufreq/root/etc/init.d/cpufreq @@ -0,0 +1,27 @@ +#!/bin/sh /etc/rc.common +START=15 + +NAME="cpufreq" + +config_get_cpufreq() +{ + config_get "$NAME" "$1" +} + +start() +{ + config_load "$NAME" + + for i in $(find /sys/devices/system/cpu/cpufreq/policy* -maxdepth 0 | grep -Eo '[0-9]+') + do + [ -z "$(config_get_cpufreq "governor$i")" ] && return + + config_get_cpufreq "governor$i" > "/sys/devices/system/cpu/cpufreq/policy$i/scaling_governor" + config_get_cpufreq "minfreq$i" > "/sys/devices/system/cpu/cpufreq/policy$i/scaling_min_freq" + config_get_cpufreq "maxfreq$i" > "/sys/devices/system/cpu/cpufreq/policy$i/scaling_max_freq" + if [ "$(config_get_cpufreq "governor$i")" = "ondemand" ]; then + config_get_cpufreq "sdfactor$i" > "/sys/devices/system/cpu/cpufreq/ondemand/sampling_down_factor" + config_get_cpufreq "upthreshold$i" > "/sys/devices/system/cpu/cpufreq/ondemand/up_threshold" + fi + done +} diff --git a/luci-app-cpufreq/root/etc/uci-defaults/10-cpufreq b/luci-app-cpufreq/root/etc/uci-defaults/10-cpufreq new file mode 100644 index 000000000..4ad31dd5f --- /dev/null +++ b/luci-app-cpufreq/root/etc/uci-defaults/10-cpufreq @@ -0,0 +1,104 @@ +#!/bin/sh + +uci_write_config() { + uci -q set cpufreq.cpufreq.governor$1="$2" + uci -q set cpufreq.cpufreq.minfreq$1="$3" + uci -q set cpufreq.cpufreq.maxfreq$1="$4" + [ -n "$5" ] && uci -q set cpufreq.cpufreq.sdfactor$1="$5" + [ -n "$6" ] && uci -q set cpufreq.cpufreq.upthreshold$1="$6" + uci -q commit cpufreq +} + +CPU_FREQS="$(cat '/sys/devices/system/cpu/cpufreq/policy0/scaling_available_frequencies')" +CPU_POLICYS="$(find '/sys/devices/system/cpu/cpufreq/policy'* -maxdepth 0 | grep -Eo '[0-9]+')" +source "/etc/openwrt_release" +case "$DISTRIB_TARGET" in + "bcm27xx/bcm2710") + uci_write_config 0 ondemand 600000 1200000 10 50 + ;; + "bcm27xx/bcm2711") + uci_write_config 0 ondemand 600000 1500000 10 50 + ;; + "ipq40xx/generic") + uci_write_config 0 ondemand 200000 716000 10 50 + ;; + "ipq60xx/generic") + if echo "$CPU_FREQS" | grep -q "1800000"; then + # IPQ6010/18/28 + CPU_MAX_FREQ="1800000" + else + # IPQ6000 + CPU_MAX_FREQ="1200000" + fi + uci_write_config 0 ondemand 864000 $CPU_MAX_FREQ 10 50 + ;; + "ipq806x/generic") + if echo "$CPU_FREQS" | grep -q "1725000"; then + # IPQ8065 + CPU_MAX_FREQ="1725000" + elif echo "$CPU_FREQS" | grep -q "1400000"; then + # IPQ8064 + CPU_MAX_FREQ="1400000" + else + # IPQ8062 + CPU_MAX_FREQ="1000000" + fi + uci_write_config 0 ondemand 600000 $CPU_MAX_FREQ 10 50 + # IPQ8064/5 + echo "$CPU_POLICYS" | grep -q "1" && uci_write_config 1 ondemand 600000 1200000 10 50 + ;; + "ipq807x/generic") + if echo "$CPU_FREQS" | grep -q "2208000"; then + # IPQ8072/4/6/8A + CPU_MAX_FREQ="2208000" + else + # IPQ8071A + CPU_MAX_FREQ="1382400" + fi + uci_write_config 0 ondemand 1017600 $CPU_MAX_FREQ 10 50 + ;; + "mediatek/mt7622") + uci_write_config 0 ondemand 600000 1350000 10 50 + ;; + "meson/meson8b") + uci_write_config 0 schedutil 816000 1536000 + ;; + "rockchip/armv8") + if echo "$CPU_POLICYS" | grep -q "4"; then + # RK3399 + uci_write_config 0 schedutil 600000 1608000 + uci_write_config 4 schedutil 600000 2016000 + else + if echo "$CPU_FREQS" | grep -q "1992000"; then + # RK3568 + CPU_MAX_FREQ="1992000" + elif echo "$CPU_FREQS" | grep -q "1800000"; then + # RK3566 + CPU_MAX_FREQ="1800000" + else + # RK3328 + CPU_MAX_FREQ="1512000" + fi + uci_write_config 0 schedutil 816000 $CPU_MAX_FREQ + fi + ;; + "sunxi/cortexa53") + if echo "$CPU_FREQS" | grep -q "1800000"; then + # H6 + uci_write_config 0 schedutil 816000 1800000 + else + # H5 + uci_write_config 0 ondemand 648000 1200000 10 50 + fi + ;; +esac + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@cpufreq[-1] + add ucitrack cpufreq + set ucitrack.@cpufreq[-1].init=cpufreq + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/luci-app-cpufreq/root/usr/share/rpcd/acl.d/luci-app-cpufreq.json b/luci-app-cpufreq/root/usr/share/rpcd/acl.d/luci-app-cpufreq.json new file mode 100644 index 000000000..fae58ae40 --- /dev/null +++ b/luci-app-cpufreq/root/usr/share/rpcd/acl.d/luci-app-cpufreq.json @@ -0,0 +1,11 @@ +{ + "luci-app-cpufreq": { + "description": "Grant UCI access for luci-app-cpufreq", + "read": { + "uci": [ "cpufreq" ] + }, + "write": { + "uci": [ "cpufreq" ] + } + } +} diff --git a/luci-app-ipsec-server/Makefile b/luci-app-ipsec-server/Makefile new file mode 100644 index 000000000..786a9e607 --- /dev/null +++ b/luci-app-ipsec-server/Makefile @@ -0,0 +1,24 @@ +# 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_VERSION:=20211223 +PKG_RELEASE:=2 + +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 ../../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..41451e4a1 --- /dev/null +++ b/luci-app-ipsec-server/po/zh_Hans @@ -0,0 +1 @@ +zh-cn \ No newline at end of file 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..9371763e2 --- /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.ifname="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..9948a496d --- /dev/null +++ b/luci-app-ipsec-vpnd/Makefile @@ -0,0 +1,18 @@ +# 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 +PKG_VERSION:=1.0 +PKG_RELEASE:=11 + +include ../../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..c02a16070 --- /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.description = translate("LAN DHCP reserved started IP addresses with the same subnet mask") +clientip.datatype = "ip4addr" +clientip.optional = false +clientip.rmempty = false + +clientdns = s:option(Value, "clientdns", translate("VPN Client DNS")) +clientdns.description = translate("DNS using in VPN tunnel.Set to the router's LAN IP is recommended") +clientdns.datatype = "ip4addr" +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..727633502 --- /dev/null +++ b/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po @@ -0,0 +1,32 @@ +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/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..83b4c231e --- /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.ifname="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-zerotier/Makefile b/luci-app-zerotier/Makefile new file mode 100644 index 000000000..4946b5f37 --- /dev/null +++ b/luci-app-zerotier/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI for Zerotier +LUCI_DEPENDS:=+zerotier +LUCI_PKGARCH:=all + +PKG_NAME:=luci-app-zerotier +PKG_VERSION:=1.0 +PKG_RELEASE:=20 + +include ../../luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-zerotier/luasrc/controller/zerotier.lua b/luci-app-zerotier/luasrc/controller/zerotier.lua new file mode 100644 index 000000000..0b9d55178 --- /dev/null +++ b/luci-app-zerotier/luasrc/controller/zerotier.lua @@ -0,0 +1,22 @@ +module("luci.controller.zerotier", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/zerotier") then + return + end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + + entry({"admin", "vpn", "zerotier"}, alias("admin", "vpn", "zerotier", "general"), _("ZeroTier"), 99) + entry({"admin", "vpn", "zerotier", "general"}, cbi("zerotier/settings"), _("Base Setting"), 1) + entry({"admin", "vpn", "zerotier", "log"}, form("zerotier/info"), _("Interface Info"), 2) + + entry({"admin", "vpn", "zerotier", "status"}, call("act_status")) +end + +function act_status() + local e = {} + e.running = luci.sys.call("pgrep /usr/bin/zerotier-one >/dev/null") == 0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/luci-app-zerotier/luasrc/model/cbi/zerotier/info.lua b/luci-app-zerotier/luasrc/model/cbi/zerotier/info.lua new file mode 100644 index 000000000..e392cb0f4 --- /dev/null +++ b/luci-app-zerotier/luasrc/model/cbi/zerotier/info.lua @@ -0,0 +1,15 @@ +local fs = require "nixio.fs" +local conffile = "/tmp/zero.info" + +f = SimpleForm("logview") + +t = f:field(TextValue, "conf") +t.rmempty = true +t.rows = 19 +function t.cfgvalue() + luci.sys.exec("for i in $(ifconfig | grep 'zt' | awk '{print $1}'); do ifconfig $i; done > /tmp/zero.info") + return fs.readfile(conffile) or "" +end +t.readonly = "readonly" + +return f diff --git a/luci-app-zerotier/luasrc/model/cbi/zerotier/settings.lua b/luci-app-zerotier/luasrc/model/cbi/zerotier/settings.lua new file mode 100644 index 000000000..8e6102cc5 --- /dev/null +++ b/luci-app-zerotier/luasrc/model/cbi/zerotier/settings.lua @@ -0,0 +1,27 @@ +a = Map("zerotier") +a.title = translate("ZeroTier") +a.description = translate("Zerotier is an open source, cross-platform and easy to use virtual LAN") + +a:section(SimpleSection).template = "zerotier/zerotier_status" + +t = a:section(NamedSection, "sample_config", "zerotier") +t.anonymous = true +t.addremove = false + +e = t:option(Flag, "enabled", translate("Enable")) +e.default = 0 +e.rmempty = false + +e = t:option(DynamicList, "join", translate('ZeroTier Network ID')) +e.password = true +e.rmempty = false + +e = t:option(Flag, "nat", translate("Auto NAT Clients")) +e.description = translate("Allow zerotier clients access your LAN network") +e.default = 0 +e.rmempty = false + +e = t:option(DummyValue, "opennewwindow", translate("")) +e.description = translate("Create or manage your zerotier network, and auth clients who could access") + +return a diff --git a/luci-app-zerotier/luasrc/view/zerotier/zerotier_status.htm b/luci-app-zerotier/luasrc/view/zerotier/zerotier_status.htm new file mode 100644 index 000000000..9d216c5d9 --- /dev/null +++ b/luci-app-zerotier/luasrc/view/zerotier/zerotier_status.htm @@ -0,0 +1,22 @@ + + +
+

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

+
diff --git a/luci-app-zerotier/po/zh-cn/zerotier.po b/luci-app-zerotier/po/zh-cn/zerotier.po new file mode 100644 index 000000000..dd3cd714a --- /dev/null +++ b/luci-app-zerotier/po/zh-cn/zerotier.po @@ -0,0 +1,17 @@ +msgid "Zerotier is an open source, cross-platform and easy to use virtual LAN" +msgstr "Zerotier 是一个开源,跨平台,而且适合内网穿透互联的傻瓜配置虚拟 VPN LAN" + +msgid "Auto NAT Clients" +msgstr "自动允许客户端 NAT" + +msgid "Allow zerotier clients access your LAN network" +msgstr "允许 Zerotier 的拨入客户端访问路由器 LAN 资源(需要在 Zerotier 管理页面设定到 LAN 网段的路由表)" + +msgid "Create or manage your zerotier network, and auth clients who could access" +msgstr "点击跳转到 Zerotier 官网管理平台,新建或者管理网络,并允许客户端接入访问你私人网路(新接入的节点默认不允许访问)" + +msgid "Base Setting" +msgstr "基本设置" + +msgid "Interface Info" +msgstr "接口信息" diff --git a/luci-app-zerotier/root/etc/init.d/zerotier b/luci-app-zerotier/root/etc/init.d/zerotier new file mode 100644 index 000000000..666d67533 --- /dev/null +++ b/luci-app-zerotier/root/etc/init.d/zerotier @@ -0,0 +1,113 @@ +#!/bin/sh /etc/rc.common + +START=99 + +USE_PROCD=1 + +PROG=/usr/bin/zerotier-one +CONFIG_PATH=/var/lib/zerotier-one + +service_triggers() { + procd_add_reload_trigger "zerotier" + procd_add_interface_trigger "interface.*.up" wan /etc/init.d/zerotier restart +} + +section_enabled() { + config_get_bool enabled "$1" 'enabled' 0 + [ $enabled -gt 0 ] +} + +start_instance() { + local cfg="$1" + local port secret config_path + local ARGS="" + + if ! section_enabled "$cfg"; then + echo "disabled in config" + return 1 + fi + + [ -d /etc/config/zero ] || mkdir -p /etc/config/zero + config_path=/etc/config/zero + + config_get_bool port $cfg 'port' + config_get secret $cfg 'secret' + + # Remove existing link or folder + rm -rf $CONFIG_PATH + + # Create link from CONFIG_PATH to config_path + if [ -n "$config_path" -a "$config_path" != $CONFIG_PATH ]; then + if [ ! -d "$config_path" ]; then + echo "ZeroTier config_path does not exist: $config_path" + return + fi + + ln -s $config_path $CONFIG_PATH + fi + + mkdir -p $CONFIG_PATH/networks.d + + if [ -n "$port" ]; then + ARGS="$ARGS -p$port" + fi + + if [ "$secret" = "generate" ]; then + echo "Generate secret - please wait..." + local sf="/tmp/zt.$cfg.secret" + + zerotier-idtool generate "$sf" > /dev/null + [ $? -ne 0 ] && return 1 + + secret="$(cat $sf)" + rm "$sf" + + uci set zerotier.$cfg.secret="$secret" + uci commit zerotier + fi + + if [ -n "$secret" ]; then + echo "$secret" > $CONFIG_PATH/identity.secret + # make sure there is not previous identity.public + rm -f $CONFIG_PATH/identity.public + fi + + add_join() { + # an (empty) config file will cause ZT to join a network + touch $CONFIG_PATH/networks.d/$1.conf + } + + config_list_foreach $cfg 'join' add_join + + procd_open_instance + procd_set_param command $PROG $ARGS $CONFIG_PATH + procd_set_param stderr 1 + procd_close_instance +} + +start_service() { + config_load 'zerotier' + config_foreach start_instance 'zerotier' + touch /tmp/zero.log && /etc/zerotier.start > /tmp/zero.log 2>&1 & +} + +stop_instance() { + rm -f /tmp/zero.log + local cfg="$1" + + /etc/zerotier.stop > /tmp/zero.log 2>&1 & + + # Remove existing link or folder + rm -f $CONFIG_PATH/networks.d/*.conf + rm -rf $CONFIG_PATH +} + +stop_service() { + config_load 'zerotier' + config_foreach stop_instance 'zerotier' +} + +reload_service() { + stop + start +} diff --git a/luci-app-zerotier/root/etc/uci-defaults/40_luci-zerotier b/luci-app-zerotier/root/etc/uci-defaults/40_luci-zerotier new file mode 100644 index 000000000..616824562 --- /dev/null +++ b/luci-app-zerotier/root/etc/uci-defaults/40_luci-zerotier @@ -0,0 +1,18 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@zerotier[-1] + add ucitrack zerotier + set ucitrack.@zerotier[-1].init=zerotier + commit ucitrack + + delete firewall.zerotier + set firewall.zerotier=include + set firewall.zerotier.type=script + set firewall.zerotier.path=/etc/zerotier.start + set firewall.zerotier.reload=1 + commit firewall +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/luci-app-zerotier/root/etc/zerotier.start b/luci-app-zerotier/root/etc/zerotier.start new file mode 100644 index 000000000..b43e5f974 --- /dev/null +++ b/luci-app-zerotier/root/etc/zerotier.start @@ -0,0 +1,28 @@ +#!/bin/sh + +zero_enable="$(uci get zerotier.sample_config.enabled)" + +[ "${zero_enable}" -ne "1" ] && exit 0 + +[ -f "/tmp/zero.log" ] && { + while [ "$(ifconfig | grep 'zt' | awk '{print $1}')" = "" ] + do + sleep 1 + done +} + +nat_enable="$(uci get zerotier.sample_config.nat)" +zt0="$(ifconfig | grep 'zt' | awk '{print $1}')" +echo "${zt0}" > "/tmp/zt.nif" + +[ "${nat_enable}" -eq "1" ] && { + for i in ${zt0} + do + ip_segment="" + iptables -I FORWARD -i "$i" -j ACCEPT + iptables -I FORWARD -o "$i" -j ACCEPT + iptables -t nat -I POSTROUTING -o "$i" -j MASQUERADE + ip_segment="$(ip route | grep "dev $i proto kernel" | awk '{print $1}')" + iptables -t nat -I POSTROUTING -s "${ip_segment}" -j MASQUERADE + done +} diff --git a/luci-app-zerotier/root/etc/zerotier.stop b/luci-app-zerotier/root/etc/zerotier.stop new file mode 100644 index 000000000..cbe7ec4b6 --- /dev/null +++ b/luci-app-zerotier/root/etc/zerotier.stop @@ -0,0 +1,15 @@ +#!/bin/sh + +zt0="$(ifconfig | grep 'zt' | awk '{print $1}')" +[ -z "${zt0}" ] && zt0="$(cat "/tmp/zt.nif")" + +for i in ${zt0} +do + ip_segment="" + iptables -D FORWARD -i "$i" -j ACCEPT 2>/dev/null + iptables -D FORWARD -o "$i" -j ACCEPT 2>/dev/null + iptables -t nat -D POSTROUTING -o "$i" -j MASQUERADE 2>/dev/null + ip_segment="$(ip route | grep "dev $i proto" | awk '{print $1}')" + iptables -t nat -D POSTROUTING -s "${ip_segment}" -j MASQUERADE 2>/dev/null + echo "zt interface $i is stopped!" +done diff --git a/luci-app-zerotier/root/etc/zerotier/zerotier.log b/luci-app-zerotier/root/etc/zerotier/zerotier.log new file mode 100644 index 000000000..e69de29bb