update 2026-05-27 23:25:57

This commit is contained in:
action
2026-05-27 23:25:57 +08:00
parent 84f707b52b
commit d0159b49a5
759 changed files with 362365 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
# 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 OpenVPN Server
LUCI_DEPENDS:=+openvpn-openssl +openvpn-easy-rsa
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-openvpn-server-client
PKG_VERSION:=6.0
PKG_RELEASE:=3
MAINTAINER:=lunatickochiya <125438787@qq.com>
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature
@@ -0,0 +1,35 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2025 LunaticKochiya<125438787@qq.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
module("luci.controller.openvpn-server", package.seeall)
function index()
if not nixio.fs.access("/etc/config/openvpn") then
return
end
entry({"admin", "services", "openvpn-server"},firstchild(), _("OpenVPN Server"), 1).dependent = true
entry({"admin", "services", "openvpn-server", "general"}, cbi("openvpn-server/openvpn-server"), _("OpenVPN Server"), 1).leaf = true
entry({"admin", "services", "openvpn-server", "client"},cbi("openvpn-server/openvpn-server_ovpn"), _("Client"), 2).leaf = true
entry({"admin", "services", "openvpn-server", "log"},form("openvpn-server/openvpn-server_run_log"), _("Running log"), 3).leaf = true
entry({"admin", "services", "openvpn-server","status"},call("act_status")).leaf=true
end
function act_status()
local e={}
e.running=luci.sys.call("pgrep openvpn >/dev/null")==0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end
@@ -0,0 +1,274 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2025 LunaticKochiya<125438787@qq.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
--require("luci.tools.webadmin")
local uci = require "luci.model.uci".cursor()
local sys = require "luci.sys"
local function get_openvpn_info()
local version_str = sys.exec("openvpn --version 2>/dev/null | head -n1")
local full_output = sys.exec("openvpn --version 2>/dev/null")
local major, minor, patch = version_str:match("OpenVPN%s+(%d+)%.(%d+)%.(%d+)")
if not (major and minor and patch) then
return nil, nil, nil, false
end
local lzo_supported = full_output:match("%[LZO%]") ~= nil
return tonumber(major), tonumber(minor), tonumber(patch), lzo_supported
end
local major, minor, patch, lzo = get_openvpn_info()
mp = Map("openvpn", "OpenVPN Server",translate("An easy config OpenVPN Server Web-UI"))
mp:section(SimpleSection).template = "openvpn/openvpn_status"
s = mp:section(TypedSection, "openvpn")
s.anonymous = true
s.addremove = false
s.filter = function(self, section)
return section:match("^myvpn") ~= nil
end
s:tab("basic", translate("Base Setting"))
o = s:taboption("basic", Flag, "enabled", translate("Enable"))
port = s:taboption("basic", Value, "port", translate("Port"))
port.datatype = "range(1,65535)"
ddns = s:taboption("basic", Value, "ddns", translate("WAN DDNS or IP"))
ddns.datatype = "string"
ddns.default = "exmple.com"
ddns.rmempty = false
localnet = s:taboption("basic", Value, "server", translate("Client Network"))
localnet.datatype = "string"
localnet.description = translate("VPN Client Network IP with subnet")
proto = s:taboption("basic",Value,"proto", translate("proto"))
proto.datatype = "string"
proto:value("tcp4")
proto:value("udp4")
proto:value("tcp6")
proto:value("udp6")
proto.default ="tcp4"
if (major > 2) or (major == 2 and minor >= 6) then
disable_dco = s:taboption("basic",Flag,"disable_dco", translate("disable dco"))
disable_dco.description = translate("Disabling DCO provides better compatibility but disables acceleration.")
end
if (major > 2) or (major == 2 and minor >= 5) then
allow_compression = s:taboption("basic",Value,"allow_compression", translate("Allow Compression"))
allow_compression.datatype = "string"
allow_compression:value("asym")
allow_compression:value("yes")
allow_compression:value("no")
allow_compression.default="asym"
allow_compression.description = translate("Allow compression, DCO can only be used when set to NO. asym is compatible mode.")
push_peer_info = s:taboption("basic",Flag,"push_peer_info", translate("push peer info"))
push_peer_info.description = translate("This will allow the server to know more info about the client like HWADDR, very useful for managing IoT devices.")
end
if lzo then
comp_lzo = s:taboption("basic",Value,"comp_lzo", translate("comp_lzo"))
comp_lzo.datatype = "string"
comp_lzo:value("adaptive")
comp_lzo:value("yes")
comp_lzo:value("no")
if (major > 2) or (major == 2 and minor >= 5) then
comp_lzo:depends("allow_compression", "yes")
comp_lzo:depends("allow_compression", "asym")
comp_lzo:depends("comp_lzo", "yes")
comp_lzo:depends("comp_lzo", "adaptive")
comp_lzo.default="adaptive"
else
comp_lzo:depends("comp_lzo", "yes")
comp_lzo:depends("comp_lzo", "adaptive")
comp_lzo.default="adaptive"
end
comp_lzo.description = translate("Using LZO compression, it does not support versions above 2.5.X, does not support DCO; if your version number is greater than this version, select NO to disable it.")
end
auth_user_pass_verify = s:taboption("basic",Value,"auth_user_pass_verify", translate("user password verify"))
auth_user_pass_verify.datatype = "string"
auth_user_pass_verify.description = translate("Default: /etc/openvpn/server/checkpsw.sh via-env, leave it empty to disable")
script_security = s:taboption("basic",Value,"script_security", translate("script_security: to use with user and password"))
script_security.datatype = "range(1,3)"
script_security:value("1")
script_security:value("2")
script_security:value("3")
script_security.description = translate("Default 3, leave it empty to disable")
duplicate_cn = s:taboption("basic",Flag,"duplicate_cn", translate("duplicate_cn"))
duplicate_cn.description = translate("This option allows multiple clients to connect using the same certificate and key and assign different IP addresses")
client_to_client = s:taboption("basic",Flag,"client_to_client", translate("client-to-client"))
client_to_client.description = translate("Allow clients to see each other, otherwise multiple clients can only access the server and cannot connect to each other")
username_as_common_name = s:taboption("basic",Flag,"username_as_common_name", translate("username_as_common_name"))
username_as_common_name.description = translate("Use the UserName provided by the client as the Common Name")
client_cert_not_required = s:taboption("basic",Flag,"client_cert_not_required", translate("client_cert_not_required"))
client_cert_not_required.description = translate("After this option is enabled, the client does not need cert and key. If this option is not enabled, cert and key and user password double verification are required.")
list = s:taboption("basic", DynamicList, "push")
list.title = translate("Client Settings")
list.datatype = "string"
list.description = translate("Set route 192.168.0.0 255.255.255.0 and dhcp-option DNS 192.168.0.1 base on your router")
local o
o = s:taboption("basic", Button,"certificate",translate("OpenVPN Client config file"))
o.inputtitle = translate("Download .ovpn file")
o.description = translate("If you use user password verification only, remember to delete the key and cert.")
o.inputstyle = "reload"
o.write = function()
luci.sys.call("sh /etc/genovpn.sh 2>&1 >/dev/null")
Download()
end
s:tab("code", translate("Client code"))
local conf = "/etc/ovpnadd.conf"
local NXFS = require "nixio.fs"
o = s:taboption("code", TextValue, "conf")
o.description = translate("Here is the code that you want to add to the .ovpn file. If you use user password verification, you need to add auth-user-pass")
o.rows = 13
o.wrap = "off"
o.cfgvalue = function(self, section)
return NXFS.readfile(conf) or ""
end
o.write = function(self, section, value)
NXFS.writefile(conf, value:gsub("\r\n", "\n"))
end
s:tab("passwordfile", translate("User and password"))
local pass = "/etc/openvpn/server/psw-file"
local NXFS = require "nixio.fs"
o = s:taboption("passwordfile", TextValue, "pass")
o.description = translate("Each line contains a pair of user and password, separated by a space")
o.rows = 13
o.wrap = "off"
o.cfgvalue = function(self, section)
return NXFS.readfile(pass) or ""
end
o.write = function(self, section, value)
NXFS.writefile(pass, value:gsub("\r\n", "\n"))
end
s:tab("checkpsw", translate("Authentication script"))
local checkpswconf = "/etc/openvpn/server/checkpsw.sh"
local NXFS = require "nixio.fs"
o = s:taboption("checkpsw", TextValue, "checkpswconf")
o.description = translate("Authentication script")
o.rows = 13
o.wrap = "off"
o.cfgvalue = function(self, section)
return NXFS.readfile(checkpswconf) or ""
end
o.write = function(self, section, value)
NXFS.writefile(checkpswconf, value:gsub("\r\n", "\n"))
end
local pid = luci.util.exec("/usr/bin/pgrep openvpn")
function openvpn_process_status()
local status = "OpenVPN is not running now "
if pid ~= "" then
status = "OpenVPN is running with the PID " .. pid .. ""
end
local status = { status=status }
local table = { pid=status }
return table
end
function Download()
local t,e
t=nixio.open("/tmp/my.ovpn","r")
luci.http.header('Content-Disposition','attachment; filename="my.ovpn"')
luci.http.prepare_content("application/octet-stream")
while true do
e=t:read(nixio.const.buffersize)
if(not e)or(#e==0)then
break
else
luci.http.write(e)
end
end
t:close()
luci.http.close()
end
t = mp:section(Table, openvpn_process_status())
t.anonymous = true
t:option(DummyValue, "status", translate("OpenVPN status"))
if pid == "" then
start = t:option(Button, "_start", translate("Start"))
start.inputstyle = "apply"
function start.write(self, section)
luci.util.exec("uci set openvpn.myvpn.enabled=='1' && uci commit openvpn")
message = luci.util.exec("/etc/init.d/openvpn start 2>&1")
luci.util.exec("sleep 2")
luci.http.redirect(
luci.dispatcher.build_url("admin", "services", "openvpn-server") .. "?message=" .. message
)
end
else
stop = t:option(Button, "_stop", translate("Stop"))
stop.inputstyle = "reset"
function stop.write(self, section)
luci.util.exec("uci set openvpn.myvpn.enabled=='0' && uci commit openvpn")
luci.util.exec("/etc/init.d/openvpn stop")
luci.util.exec("sleep 2")
luci.http.redirect(
luci.dispatcher.build_url("admin", "services", "openvpn-server")
)
end
end
local comp_lzo_val = uci:get("openvpn", "myvpn", "comp_lzo")
function mp.on_after_commit(self)
os.execute("uci set firewall.openvpn.dest_port=$(uci get openvpn.myvpn.port) && uci commit firewall && /etc/init.d/firewall restart")
os.execute("/etc/init.d/openvpn restart")
if comp_lzo_val == "no" then
uci:delete("openvpn", "myvpn", "comp_lzo")
uci:commit("openvpn")
end
end
gen = t:option(Button,"cert",translate("OpenVPN Cert"))
gen.inputstyle = "apply"
function gen.write(self, section)
luci.util.exec("/etc/openvpncert.sh")
end
--local apply = luci.http.formvalue("cbi.apply")
--if apply then
-- os.execute("/etc/init.d/openvpn restart")
--end
return mp
@@ -0,0 +1,180 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2025 LunaticKochiya<125438787@qq.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local NXFS = require "nixio.fs"
local sys = require "luci.sys"
local util = require "luci.util"
local base_dir = "/etc/openvpn"
local function get_config_path(identifier)
if identifier and identifier:match("^[a-zA-Z0-9_%-]+$") then
return base_dir .. "/" .. identifier .. ".conf"
end
return nil
end
m2 = Map("openvpn", "OpenVPN Client", translate("Configuration for OpenVPN client instances. The instance name you provide becomes the UCI section name (e.g., 'client1' leads to `config openvpn 'client1'`)."))
m2:section(SimpleSection).template = "openvpn/openvpn_status"
sl = m2:section(TypedSection, "openvpn", translate("OpenVPN Client Instances"))
sl.title = translate("OpenVPN Client Instances")
sl.anonymous = false
sl.addremove = true
sl.description = translate("Enter a unique identifier (e.g., client1, client2) when adding an instance. This identifier is used for the UCI section name and the corresponding .conf file.")
sl.sortable = true
sl.filter = function(self, section)
return section:match("^client") ~= nil
end
sl:tab("base", translate("Base Settings"))
sl:tab("config_file", translate("Client Config File Content"))
local o
o = sl:taboption("base", Flag, "enabled", translate("Enable Instance"))
o.default = o.disabled
o.rmempty = false
o = sl:taboption("base", Value, "config", translate("Config File Path"))
o.readonly = true
o.placeholder = translate("Auto-generated based on instance identifier")
o.datatype = "file"
o.rmempty = false
o.cfgvalue = function(self, section)
return get_config_path(section) or translate("Invalid instance identifier.")
end
o = sl:taboption("config_file", TextValue, "_config_content")
o.title = translate("OpenVPN Configuration (.ovpn/.conf)")
o.description = translate("Paste the content of the .ovpn or .conf file here. This will be saved to the path shown in 'Base Settings'.")
o.rows = 15
o.wrap = "off"
o.rmempty = true
o.cfgvalue = function(self, section)
local conf_file = get_config_path(section)
if conf_file then
return NXFS.readfile(conf_file) or ""
else
return "-- " .. translate("Cannot read file: Invalid instance identifier used for this section.") .. " --"
end
end
o.write = function(self, section, value)
local conf_file = get_config_path(section)
if not conf_file then
luci.util.perror("OpenVPN: Invalid identifier '" .. tostring(section) .. "', cannot write config file.")
return
end
if value and value ~= "" then
NXFS.writefile(conf_file, value:gsub("\r\n", "\n"))
self.map:set(section, "config", conf_file)
else
NXFS.remove(conf_file)
end
end
o.remove = function(self, section)
local conf_file = get_config_path(section)
if conf_file then
NXFS.remove(conf_file)
end
end
sl.on_remove = function(self, section)
local conf_file = get_config_path(section)
if conf_file then
local ok, err = NXFS.remove(conf_file)
if ok then
luci.util.perror("OpenVPN: Removed config file: " .. conf_file)
else
luci.util.perror("OpenVPN: Error removing config file " .. conf_file .. ": " .. tostring(err))
end
end
TypedSection.on_remove(self, section)
end
sp = m2:section(TypedSection, "openvpnpassword", translate("OpenVPN Client Authentication"))
sp.title = translate("OpenVPN Client Authentication")
sp.anonymous = false
sp.addremove = true
sp.description = translate("Configure authentication files for OpenVPN client instances.")
sp.sortable = true
o = sp:option(Value, "pwdfile", translate("Authentication File Path"))
o.placeholder = translate("Enter the path for the authentication file (e.g., /etc/openvpn/password.txt)")
o.datatype = "string"
o.rmempty = false
o = sp:option(TextValue, "_auth_content", translate("Authentication File Content"))
o.description = translate("Enter the content of the authentication file (e.g., username on the first line, password on the second line). This will be saved to the path shown above.")
o.rows = 5
o.wrap = "off"
o.rmempty = true
o.cfgvalue = function(self, section)
local pwdfile = self.map:get(section, "pwdfile")
if pwdfile then
return NXFS.readfile(pwdfile) or ""
else
return "-- " .. translate("Cannot read file: Invalid instance identifier used for this section.") .. " --"
end
end
o.write = function(self, section, value)
local pwdfile = self.map:get(section, "pwdfile")
if not pwdfile then
luci.util.perror("OpenVPN: Invalid identifier '" .. tostring(section) .. "', cannot write authentication file.")
return
end
if value and value ~= "" then
NXFS.writefile(pwdfile, value:gsub("\r\n", "\n"))
else
NXFS.remove(pwdfile)
end
end
o.remove = function(self, section)
local pwdfile = self.map:get(section, "pwdfile")
if pwdfile then
NXFS.remove(pwdfile)
end
end
sp.on_remove = function(self, section)
local pwdfile = self.map:get(section, "pwdfile")
if pwdfile then
local ok, err = NXFS.remove(pwdfile)
if ok then
luci.util.perror("OpenVPN: Removed authentication file: " .. pwdfile)
else
luci.util.perror("OpenVPN: Error removing authentication file " .. pwdfile .. ": " .. tostring(err))
end
end
TypedSection.on_remove(self, section)
end
m2.on_commit = function(self)
local result = sys.call("/etc/init.d/openvpn reload")
if result ~= 0 then
self.message = translate("Failed to reload OpenVPN service.")
end
end
return m2
@@ -0,0 +1,83 @@
--[[
LuCI - Lua Configuration Interface
Copyright 2025 LunaticKochiya<125438787@qq.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local fs = require "nixio.fs"
local conffile = "/var/openvpn.log"
local conffile_pass = "/etc/openvpn/openvpn-password.log"
f = SimpleForm("logview")
t1 = f:field(TextValue, "conf_file_log")
t1.rmempty = true
t1.rows = 20
t1.css_style = "width: 95vw !important;"
function t1.cfgvalue()
return fs.readfile(conffile) or ""
end
t1.readonly = "readonly"
t1.description = "OpenVPN Log File"
t2 = f:field(TextValue, "conf_logread")
t2.rmempty = true
t2.rows = 20
t2.css_style = "width: 95vw !important;"
function t2.cfgvalue()
local log_output = ""
local handle = io.popen("logread | grep openvpn")
if handle then
log_output = handle:read("*a")
handle:close()
end
return log_output or ""
end
t2.readonly = "readonly"
t2.description = "OpenVPN Logread Output"
t3 = f:field(TextValue, "conf_file_pass_log")
t3.rmempty = true
t3.rows = 20
t3.css_style = "width: 95vw !important;"
function t3.cfgvalue()
return fs.readfile(conffile_pass) or ""
end
t3.readonly = "readonly"
t3.description = "OpenVPN Password Log File"
local clear_btn = f:field(Button, "clear_pass_log")
clear_btn.title = "清空登陆日志"
clear_btn.inputstyle = "remove"
clear_btn.description = "点击清空上面内容"
function clear_btn.write(self, section)
fs.writefile(conffile_pass, "")
end
t4 = f:field(TextValue, "ifconfig_tun")
t4.rmempty = true
t4.rows = 10
t4.css_style = "width: 95vw !important;"
function t4.cfgvalue()
local ifconfig_output = ""
local handle = io.popen("ifconfig | grep -A 6 '^tun' 2>/dev/null")
if handle then
ifconfig_output = handle:read("*a")
handle:close()
end
return ifconfig_output or "No tun interfaces found"
end
t4.readonly = "readonly"
t4.description = "All tun Interfaces Configuration"
return f
@@ -0,0 +1,22 @@
<script type="text/javascript">//<![CDATA[
XHR.poll(3, '<%=url([[admin]], [[services]], [[openvpn-server]], [[status]])%>', null,
function(x, data) {
var tb = document.getElementById('openvpn_status');
if (data && tb) {
if (data.running) {
var links = '<em><b><font color=green>OpenVPN <%:RUNNING%></font></b></em>';
tb.innerHTML = links;
} else {
tb.innerHTML = '<em><b><font color=red>OpenVPN <%:NOT RUNNING%></font></b></em>';
}
}
}
);
//]]>
</script>
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
<fieldset class="cbi-section">
<p id="openvpn_status">
<em><%:Collecting data...%></em>
</p>
</fieldset>
@@ -0,0 +1,218 @@
msgid "OpenVPN Server"
msgstr "OpenVPN 服务器"
msgid "An easy config OpenVPN Server Web-UI"
msgstr "易于使用的 OpenVPN 服务器 Web-UI"
msgid "Base Setting"
msgstr "基本设置"
msgid "Enable"
msgstr "启用"
msgid "Port"
msgstr "端口"
msgid "WAN DDNS or IP"
msgstr "WAN口的 DDNS域名 或者 IP"
msgid "Client Network"
msgstr "客户端网段"
msgid "VPN Client Network IP with subnet"
msgstr "客户端分配的网段地址(默认为 10.8.0.0 255.255.255.0"
msgid "Client Settings"
msgstr "客户端推送配置"
msgid "OpenVPN Client config file"
msgstr "OpenVPN 客户端配置文件"
msgid "Download .ovpn file"
msgstr "一键下载 .ovpn 文件"
msgid "If you are using IOS client, please download this .ovpn file and send it via QQ or Email to your IOS device"
msgstr "如果你使用的是 iOS 设备,你可以使用 QQ 或者邮件发送到自己的设备上用 OpenVPN 客户端打开导入"
msgid "Special Code"
msgstr "特殊代码"
msgid "(!)Special Code you know that add in to client .ovpn file"
msgstr "(!)特殊代码将自动合并到客户端的 .ovpn 配置文件中"
msgid "Set route 192.168.0.0 255.255.255.0 and dhcp-option DNS 192.168.0.1 base on your router"
msgstr "根据路由的实际LAN IP 修改 route 192.168.0.0 255.255.255.0 和 dhcp-option DNS 192.168.0.1 这两行"
msgid "OpenVPN status"
msgstr "OpenVPN 运行状态"
msgid "Running log"
msgstr "运行日志"
msgid "Login log"
msgstr "登陆日志"
msgid "user password verify"
msgstr "帐号密码验证"
msgid "Default: /etc/openvpn/server/checkpsw.sh via-env, leave it empty to disable"
msgstr "默认设置:/etc/openvpn/server/checkpsw.sh via-env,留空禁用"
msgid "script_security: to use with user and password"
msgstr "script_security配合帐号密码验证使用"
msgid "Default 3, leave it empty to disable"
msgstr "默认设置:3,留空禁用"
msgid "This option allows multiple clients to connect using the same certificate and key and assign different IP addresses"
msgstr "这个选项允许多个客户端使用相同的证书和密钥进行连接,并分配不同的 IP"
msgid "Allow clients to see each other, otherwise multiple clients can only access the server and cannot connect to each other"
msgstr "允许客户端之间相互可见,否则多个客户端只能看到服务器,而看不到彼此"
msgid "After this option is enabled, the client does not need cert and key. If this option is not enabled, cert and key and user password double verification are required."
msgstr "打开后客户端则不需要cert和key,不打开则需要cert和key以及帐号密码双重验证"
msgid "If you use user password verification only, remember to delete the key and cert."
msgstr "如果使用单独帐号密码验证,一定要记得删除key和cert内容"
msgid "Client code"
msgstr "客户端代码"
msgid "Here is the code that you want to add to the .ovpn file. If you use user password verification, you need to add auth-user-pass"
msgstr "想要加入到.ovpn文件里的代码,如果使用帐号密码验证则需要加入auth-user-pass"
msgid "User and password"
msgstr "帐号密码"
msgid "Each line contains a pair of user and password, separated by a space"
msgstr "每行一组帐号密码,帐号密码中间空格隔开"
msgid "compess use lzo"
msgstr "使用lzo"
msgid "Use the UserName provided by the client as the Common Name"
msgstr "使用客户端提供的UserName作为Common Name"
msgid "Authentication script"
msgstr "认证脚本"
msgid "user pass code"
msgstr "帐号密码"
msgid "OpenVPN Client Config"
msgstr "OpenVPN 客户端配置"
msgid "Delete config file"
msgstr "删除配置文件"
msgid "Delete conf"
msgstr "删除配置并停止服务"
msgid "Start Client Only Button"
msgstr "仅启动客户端"
msgid "each one code one line username first"
msgstr "第一行写用户名,第二行写密码,仅仅在客户端代码里加入auth-user-pass pass.txt才有效"
msgid "An easy config OpenVPN Client Web-UI"
msgstr "简单的OpenVPN客户端WEB界面"
msgid "Here is the code that you want to add to the .ovpn file. If you use user password verification, you need to add auth-user-pass pass.txt"
msgstr "目前仅仅支持openvpn的.ovpn格式作为客户端,在windows用文本方式打开.ovpn文件,粘贴到上面空白处,如果需要帐号密码验证你需要加入 auth-user-pass pass.txt到.ovpn文件。"
msgid "Clear the client configuration file, note: if you do not use the client mode, be sure to clear the configuration file! The start button in server mode will cause the server and client to start at the same time. If you only want to start the server, click this button."
msgstr "清除客户端配置文件,注意:如果不使用客户端模式的话务必清除配置文件!服务端模式的启动按钮会导致同时启动服务端和客户端,如果只想启动服务端,点击此按钮。"
msgid "Only start client mode. This button is different from the start button in server mode!"
msgstr "仅仅启动客户端模式。此按钮与服务端模式的启动按钮不同!"
msgid "Only stop client mode. This button is different from the stop button in server mode!"
msgstr "仅仅停用客户端模式。此按钮与服务端模式的停用按钮不同!同时禁止openvpn服务,禁止自启动。"
msgid "click save and apply below this page to write config to file"
msgstr "点击页面下方的保存应用后会写入到配置文件里"
msgid "Click Enable WAN port input data mode below, so that other machines can access this machine. You can also go to the firewall page to set it yourself."
msgstr "点击下方的启用WAN口输入数据模式,让别的机器可以访问本机。你也可以去防火墙页面自行设置。(非必要设置,不要重复点击一个按钮)"
msgid "Configuration for OpenVPN client instances. The instance name you provide becomes the UCI section name (e.g., 'client1' leads to `config openvpn 'client1'`)."
msgstr "OpenVPN 客户端实例的配置。您提供的实例名称将成为 UCI 部分名称(例如,'client1' 对应于 `config openvpn 'client1'`)。"
msgid "OpenVPN Client"
msgstr "OpenVPN 客户端"
msgid "OpenVPN Client Instances"
msgstr "OpenVPN 客户端实例"
msgid "Enter a unique identifier (e.g., client1, client2) when adding an instance. This identifier is used for the UCI section name and the corresponding .conf file."
msgstr "添加实例时输入唯一标识符(例如,client1、client2)。该标识符用于 UCI 部分名称和相应的 .conf 文件。"
msgid "Enable Instance"
msgstr "启用实例"
msgid "Auto-generated based on instance identifier"
msgstr "根据实例标识符自动生成"
msgid "Invalid instance identifier."
msgstr "无效的实例标识符。"
msgid "OpenVPN Configuration (.ovpn/.conf)"
msgstr "OpenVPN 配置 (.ovpn/.conf)"
msgid "Paste the content of the .ovpn or .conf file here. This will be saved to the path shown in 'Base Settings'."
msgstr "在此粘贴 .ovpn 或 .conf 文件的内容。将保存到“基本设置”中显示的路径。"
msgid "Cannot read file: Invalid instance identifier used for this section."
msgstr "无法读取文件:此部分使用的实例标识符无效。"
msgid "Authentication File Path"
msgstr "认证文件路径"
msgid "Enter the path for the authentication file (e.g., /etc/openvpn/password.txt)"
msgstr "输入认证文件的路径(例如,/etc/openvpn/password.txt"
msgid "Authentication File Content"
msgstr "认证文件内容"
msgid "Enter the content of the authentication file (e.g., username on the first line, password on the second line). This will be saved to the path shown above."
msgstr "输入认证文件的内容(例如,第一行是用户名,第二行是密码)。将保存到上面显示的路径。"
msgid "Failed to restart OpenVPN service."
msgstr "重启 OpenVPN 服务失败。"
msgid "Removed config file: "
msgstr "已移除配置文件:"
msgid "Error removing config file "
msgstr "移除配置文件时出错 "
msgid "Removed authentication file: "
msgstr "已移除认证文件:"
msgid "Error removing authentication file "
msgstr "移除认证文件时出错 "
msgid "Base Settings "
msgstr "基本设置 "
msgid "OpenVPN Client Authentication "
msgstr "OpenVPN客户端认证账号密码 "
msgid "Configure authentication files for OpenVPN client instances. "
msgstr "给OpenVPN客户端配置账号密码文件 "
msgid "Config File Path "
msgstr "配置文件路径 "
msgid "Using LZO compression, it does not support versions above 2.5.X, does not support DCO; if your version number is greater than this version, select NO to disable it."
msgstr "使用LZO压缩,不支持2.5.X以上的版本,不支持DCO,如果你的版本号大于这个版本选择NO来禁用它"
msgid "This will allow the server to know more info about the client like HWADDR, very useful for managing IoT devices."
msgstr "这将允许服务器获取更多关于客户端的信息,比如硬件地址(HWADDR),这对于管理物联网设备非常有用。"
msgid "Disabling DCO provides better compatibility but disables acceleration."
msgstr "禁用DCO可以提供更好的兼容性,但会关闭加速功能。"
+1
View File
@@ -0,0 +1 @@
zh-cn
@@ -0,0 +1,41 @@
config openvpn 'myvpn'
option enabled '0'
option proto 'tcp4'
option dev 'tun'
option topology 'subnet'
option server '10.8.0.0 255.255.255.0'
option comp_lzo 'adaptive'
option ca '/etc/openvpn/pki/ca.crt'
option dh '/etc/openvpn/pki/dh.pem'
option cert '/etc/openvpn/pki/server.crt'
option key '/etc/openvpn/pki/server.key'
option persist_key '1'
option persist_tun '1'
option max_clients '88'
option keepalive '10 120'
option verb '3'
option status '/var/log/openvpn_status.log'
option log '/tmp/openvpn.log'
option port '1194'
option ddns 'myserver.f3322.net'
option auth_user_pass_verify '/etc/openvpn/server/checkpsw.sh via-env'
option script_security '3'
list push 'route 192.168.9.0 255.255.255.0'
list push 'comp-lzo adaptive'
list push 'redirect-gateway def1 bypass-dhcp'
list push 'dhcp-option DNS 192.168.9.1'
config openvpn 'client1'
option enabled '0'
option config '/etc/openvpn/client1.conf'
config openvpn 'client2'
option enabled '0'
option config '/etc/openvpn/client2.conf'
config openvpnpassword 'pwd1'
option pwdfile '/etc/openvpn/pass.txt'
config openvpnpassword 'pwd2'
option pwdfile '/etc/openvpn/pass2.txt'
@@ -0,0 +1,2 @@
V 270821142642Z 01 unknown /C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=server/name=EasyRSA/emailAddress=ZJ@ZJ.com
V 270821142658Z 02 unknown /C=CN/ST=ZJ/L=ZJ/O=ZJ/OU=ZJ/CN=client1/name=EasyRSA/emailAddress=ZJ@ZJ.com
@@ -0,0 +1 @@
03
@@ -0,0 +1,10 @@
set_var EASYRSA_OPENSSL "openssl"
set_var EASYRSA_KEY_SIZE 2048
set_var EASYRSA_REQ_COUNTRY "lunatickochiya"
set_var EASYRSA_REQ_PROVINCE "github"
set_var EASYRSA_REQ_CITY "github"
set_var EASYRSA_REQ_ORG "github"
set_var EASYRSA_REQ_EMAIL "lunatickochiya@github.com"
set_var EASYRSA_REQ_OU "github"
set_var EASYRSA_CA_EXPIRE 3650
set_var EASYRSA_CERT_EXPIRE 3650
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
ddns=`uci get openvpn.myvpn.ddns`
port=`uci get openvpn.myvpn.port`
proto=`uci get openvpn.myvpn.proto`
cat > /tmp/my.ovpn <<EOF
client
dev tun
proto $proto
remote $ddns $port
resolv-retry infinite
nobind
persist-key
persist-tun
verb 3
EOF
echo '<ca>' >> /tmp/my.ovpn
cat /etc/openvpn/pki/ca.crt >> /tmp/my.ovpn
echo '</ca>' >> /tmp/my.ovpn
echo '<cert>' >> /tmp/my.ovpn
cat /etc/openvpn/pki/client1.crt >> /tmp/my.ovpn
echo '</cert>' >> /tmp/my.ovpn
echo '<key>' >> /tmp/my.ovpn
cat /etc/openvpn/pki/client1.key >> /tmp/my.ovpn
echo '</key>' >> /tmp/my.ovpn
[ -f /etc/ovpnadd.conf ] && cat /etc/ovpnadd.conf >> /tmp/my.ovpn
@@ -0,0 +1,5 @@
#!/bin/sh
/etc/init.d/openvpn stop
sleep 3
rm /etc/openvpn/client.conf
rm /etc/openvpn/pass.txt
@@ -0,0 +1,4 @@
#!/bin/sh
/etc/init.d/openvpn enable
sleep 3
/etc/init.d/openvpn restart
@@ -0,0 +1,6 @@
#!/bin/sh
sleep 2
/etc/init.d/openvpn stop
sleep 2
/etc/init.d/openvpn disable
@@ -0,0 +1,34 @@
#!/bin/sh
###########################################################
# checkpsw.sh (C) 2004 Mathias Sundman
#
# This script will authenticate OpenVPN users against
# a plain text file. The passfile should simply contain
# one row per user with the username first followed by
# one or more space(s) or tab(s) and then the password.
PASSFILE="/etc/openvpn/server/psw-file"
LOG_FILE="/etc/openvpn/openvpn-password.log"
TIME_STAMP=`date "+%Y-%m-%d %T"`
###########################################################
if [ ! -r "${PASSFILE}" ]; then
echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE}
exit 1
fi
CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`
if [ "${CORRECT_PASSWORD}" = "" ]; then
echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
fi
if [ "${password}" = "${CORRECT_PASSWORD}" ]; then
echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}
exit 0
fi
echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
@@ -0,0 +1 @@
lunatic urey
+62
View File
@@ -0,0 +1,62 @@
#!/bin/sh
function rand_str() {
(base64 /dev/urandom | tr -dc 'A-Za-z' | head -c $1) 2>/dev/null
}
function rand_str_upper() {
(rand_str $1 | tr 'a-z' 'A-Z') 2>/dev/null
}
function rand_str_lower() {
(rand_str $1 | tr 'A-Z' 'a-z') 2>/dev/null
}
function rand_easy_rsa_vars() {
local KEY_PROVINCE="$(rand_str_upper 6)"
local KEY_CITY="$(rand_str 8)"
local KEY_ORG="$(rand_str 8)"
local KEY_EMAIL="$(rand_str_lower 8)@$(rand_str_lower 4).$(rand_str_lower 3)"
local KEY_OU="$(rand_str 8)"
sed -i \
-e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_COUNTRY[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_COUNTRY\t\"$KEY_PROVINCE\"/" \
-e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_PROVINCE[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_PROVINCE\t\"$KEY_CITY\"/" \
-e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_CITY[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_CITY\t\"$KEY_ORG\"/" \
-e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_ORG[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_ORG\t\"$KEY_ORG\"/" \
-e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_EMAIL[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_EMAIL\t\"$KEY_EMAIL\"/" \
-e "s/^[[:space:]]*set_var[[:space:]]\+EASYRSA_REQ_OU[[:space:]]\+\".*\"$/set_var EASYRSA_REQ_OU\t\"$KEY_OU\"/" \
/etc/easy-rsa/vars
}
rand_easy_rsa_vars
rm -rf /root/pki
export EASYRSA_PKI="/etc/easy-rsa/pki"
export EASYRSA_VARS_FILE="/etc/easy-rsa/vars"
export EASYRSA_CLI="easyrsa --batch"
echo -en "yes\nyes\n" | $EASYRSA_CLI init-pki
# Generate DH
$EASYRSA_CLI gen-dh
# Generate for the CA
$EASYRSA_CLI build-ca nopass
# Generate for the server
$EASYRSA_CLI build-server-full server nopass
# Generate for the client
$EASYRSA_CLI build-client-full client1 nopass
# Copy files
mkdir -p /etc/openvpn/pki
cp /etc/easy-rsa/pki/ca.crt /etc/openvpn/pki/
cp /etc/easy-rsa/pki/dh.pem /etc/openvpn/pki/
cp /etc/easy-rsa/pki/issued/server.crt /etc/openvpn/pki/
cp /etc/easy-rsa/pki/private/server.key /etc/openvpn/pki/
cp /etc/easy-rsa/pki/issued/client1.crt /etc/openvpn/pki/
cp /etc/easy-rsa/pki/private/client1.key /etc/openvpn/pki/
echo "OpenVPN Cert renew successfully"
@@ -0,0 +1 @@
auth-user-pass
@@ -0,0 +1,46 @@
#!/bin/sh
openvpn_port="$(uci -q get openvpn.myvpn.port)"
[ -z "$openvpn_port" ] && openvpn_port=1194
uci -q batch <<-EOF >/dev/null
delete network.vpn0
set network.vpn0=interface
set network.vpn0.ifname='tun0'
set network.vpn0.proto='none'
commit network
delete firewall.openvpn
set firewall.openvpn=rule
set firewall.openvpn.name='openvpn'
set firewall.openvpn.target='ACCEPT'
set firewall.openvpn.src='wan'
set firewall.openvpn.proto='tcp udp'
set firewall.openvpn.dest_port="$openvpn_port"
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.masq='1'
set firewall.vpn.network='vpn0'
delete firewall.vpntowan
set firewall.vpntowan=forwarding
set firewall.vpntowan.src='vpn'
set firewall.vpntowan.dest='wan'
delete firewall.vpntolan
set firewall.vpntolan=forwarding
set firewall.vpntolan.src='vpn'
set firewall.vpntolan.dest='lan'
delete firewall.lantovpn
set firewall.lantovpn=forwarding
set firewall.lantovpn.src='lan'
set firewall.lantovpn.dest='vpn'
commit firewall
EOF
chmod 0777 /etc/openvpn/server/checkpsw.sh
rm -f /tmp/luci-indexcache
exit 0
@@ -0,0 +1,4 @@
{
"config": "openvpn",
"init": ""
}