Kaynağa Gözat

增加 web_base_url 配置, 用于配置 web 后台可置于代理子路径下

涵曦 5 yıl önce
ebeveyn
işleme
383dbd1b7b

+ 25 - 0
README.md

@@ -46,6 +46,7 @@ nps是一款轻量级、高性能、功能强大的**内网穿透**代理服务
     * [配置文件说明](#服务端配置文件)
     * [使用https](#使用https)
     * [与nginx配合](#与nginx配合)
+    * [web使用Caddy代理](#web使用Caddy代理)
     * [关闭http|https代理](#关闭代理)
     * [将nps安装到系统](#将nps安装到系统)
     * [流量数据持久化](#流量数据持久化)
@@ -307,6 +308,7 @@ nps是一款轻量级、高性能、功能强大的**内网穿透**代理服务
 web_port | web管理端口
 web_password | web界面管理密码
 web_username | web界面管理账号
+web_base_url | web管理主路径,用于将web管理置于代理子路径后面
 bridge_port  | 服务端客户端通信端口
 https_proxy_port | 域名代理https代理监听端口
 http_proxy_port | 域名代理http代理监听端口
@@ -365,6 +367,29 @@ server {
     }
 }
 ```
+
+### web使用Caddy代理
+
+如果将web配置到Caddy代理,实现子路径访问nps,可以这样配置.
+
+假设我们想通过 `http://caddy_ip:caddy_port/nps` 来访问后台, Caddyfile 这样配置:
+
+```Caddyfile
+caddy_ip:caddy_port/nps {
+  #server_ip 为 nps 服务器IP
+  #web_port 为 nps 后台端口
+  proxy / http://server_ip:web_port/nps {
+	transparent
+  }
+}
+```
+
+nps.conf 修改 `web_base_url` 为 `/nps` 即可
+```
+web_base_url=/nps
+```
+
+
 ### 关闭代理
 
 如需关闭http代理可在配置文件中将http_proxy_port设置为空,如需关闭https代理可在配置文件中将https_proxy_port设置为空。

+ 2 - 1
cmd/nps/nps.go

@@ -14,7 +14,7 @@ import (
 	"github.com/cnlh/nps/server/tool"
 	"github.com/cnlh/nps/vender/github.com/astaxie/beego"
 	"github.com/cnlh/nps/vender/github.com/astaxie/beego/logs"
-	_ "github.com/cnlh/nps/web/routers"
+	"github.com/cnlh/nps/web/routers"
 	"log"
 	"os"
 	"path/filepath"
@@ -28,6 +28,7 @@ var (
 func main() {
 	flag.Parse()
 	beego.LoadAppConfig("ini", filepath.Join(common.GetRunPath(), "conf", "nps.conf"))
+	routers.Init()
 	if len(os.Args) > 1 {
 		switch os.Args[1] {
 		case "test":

+ 3 - 0
conf/nps.conf

@@ -41,6 +41,9 @@ web_username=admin
 web_password=123
 web_port = 8080
 web_ip=0.0.0.0
+web_base_url=
+# if web under proxy use sub path. like http://host/nps need this.
+#web_base_url=/nps
 
 #Web API unauthenticated IP address(the len of auth_crypt_key must be 16)
 auth_key=test

+ 1 - 1
server/proxy/tcp.go

@@ -62,7 +62,7 @@ func (s *WebServer) Start() error {
 		<-stop
 	}
 	beego.BConfig.WebConfig.Session.SessionOn = true
-	beego.SetStaticPath("/static", filepath.Join(common.GetRunPath(), "web", "static"))
+	beego.SetStaticPath(beego.AppConfig.String("web_base_url")+"/static", filepath.Join(common.GetRunPath(), "web", "static"))
 	beego.SetViewsPath(filepath.Join(common.GetRunPath(), "web", "views"))
 	if l, err := connection.GetWebManagerListener(); err == nil {
 		beego.InitBeforeHTTPRun()

+ 4 - 1
web/controllers/base.go

@@ -21,6 +21,7 @@ type BaseController struct {
 
 //初始化参数
 func (s *BaseController) Prepare() {
+	s.Data["web_base_url"] = beego.AppConfig.String("web_base_url")
 	controllerName, actionName := s.GetControllerAndAction()
 	s.controllerName = strings.ToLower(controllerName[0 : len(controllerName)-10])
 	s.actionName = strings.ToLower(actionName)
@@ -33,7 +34,7 @@ func (s *BaseController) Prepare() {
 	timeNowUnix := time.Now().Unix()
 	if !((math.Abs(float64(timeNowUnix-int64(timestamp))) <= 20) && (crypt.Md5(configKey+strconv.Itoa(timestamp)) == md5Key)) {
 		if s.GetSession("auth") != true {
-			s.Redirect("/login/index", 302)
+			s.Redirect(beego.AppConfig.String("web_base_url")+"/login/index", 302)
 		}
 	}
 	if s.GetSession("isAdmin") != nil && !s.GetSession("isAdmin").(bool) {
@@ -59,6 +60,7 @@ func (s *BaseController) Prepare() {
 
 //加载模板
 func (s *BaseController) display(tpl ...string) {
+	s.Data["web_base_url"] = beego.AppConfig.String("web_base_url")
 	var tplname string
 	if s.Data["menu"] == nil {
 		s.Data["menu"] = s.actionName
@@ -82,6 +84,7 @@ func (s *BaseController) display(tpl ...string) {
 
 //错误
 func (s *BaseController) error() {
+	s.Data["web_base_url"] = beego.AppConfig.String("web_base_url")
 	s.Layout = "public/layout.html"
 	s.TplName = "public/error.html"
 }

+ 2 - 0
web/controllers/index.go

@@ -4,6 +4,7 @@ import (
 	"github.com/cnlh/nps/lib/file"
 	"github.com/cnlh/nps/server"
 	"github.com/cnlh/nps/server/tool"
+	"github.com/cnlh/nps/vender/github.com/astaxie/beego"
 )
 
 type IndexController struct {
@@ -11,6 +12,7 @@ type IndexController struct {
 }
 
 func (s *IndexController) Index() {
+	s.Data["web_base_url"] = beego.AppConfig.String("web_base_url")
 	s.Data["data"] = server.GetDashboardData()
 	s.SetInfo("dashboard")
 	s.display("index/index")

+ 3 - 1
web/controllers/login.go

@@ -13,6 +13,7 @@ type LoginController struct {
 }
 
 func (self *LoginController) Index() {
+	self.Data["web_base_url"] = beego.AppConfig.String("web_base_url")
 	self.Data["register_allow"], _ = beego.AppConfig.Bool("allow_user_register")
 	self.TplName = "login/index.html"
 }
@@ -59,6 +60,7 @@ func (self *LoginController) Verify() {
 }
 func (self *LoginController) Register() {
 	if self.Ctx.Request.Method == "GET" {
+		self.Data["web_base_url"] = beego.AppConfig.String("web_base_url")
 		self.TplName = "login/register.html"
 	} else {
 		if b, err := beego.AppConfig.Bool("allow_user_register"); err != nil || !b {
@@ -90,5 +92,5 @@ func (self *LoginController) Register() {
 
 func (self *LoginController) Out() {
 	self.SetSession("auth", false)
-	self.Redirect("/login/index", 302)
+	self.Redirect(beego.AppConfig.String("web_base_url")+"/login/index", 302)
 }

+ 18 - 6
web/routers/router.go

@@ -5,10 +5,22 @@ import (
 	"github.com/cnlh/nps/web/controllers"
 )
 
-func init() {
-	beego.Router("/", &controllers.IndexController{}, "*:Index")
-	beego.AutoRouter(&controllers.IndexController{})
-	beego.AutoRouter(&controllers.LoginController{})
-	beego.AutoRouter(&controllers.ClientController{})
-	beego.AutoRouter(&controllers.AuthController{})
+func Init() {
+	web_base_url := beego.AppConfig.String("web_base_url")
+	if len(web_base_url) > 0 {
+		ns := beego.NewNamespace(web_base_url,
+			beego.NSRouter("/", &controllers.IndexController{}, "*:Index"),
+			beego.NSAutoRouter(&controllers.IndexController{}),
+			beego.NSAutoRouter(&controllers.LoginController{}),
+			beego.NSAutoRouter(&controllers.ClientController{}),
+			beego.NSAutoRouter(&controllers.AuthController{}),
+		)
+		beego.AddNamespace(ns)
+	} else {
+		beego.Router("/", &controllers.IndexController{}, "*:Index")
+		beego.AutoRouter(&controllers.IndexController{})
+		beego.AutoRouter(&controllers.LoginController{})
+		beego.AutoRouter(&controllers.ClientController{})
+		beego.AutoRouter(&controllers.AuthController{})
+	}
 }

+ 2 - 2
web/static/js/langchange.js

@@ -12,7 +12,7 @@
 
         $.ajax({
             type: "GET",
-            url: defaults.file,
+            url: window.nps.web_base_url + defaults.file,
             dataType: "xml",
             success: function (xml) {
                 $(xml).find('text').each(function () {
@@ -65,4 +65,4 @@ $(document).ready(function () {
         setCookie("lang", "zh")
         $("body").cloudLang({lang: "zh", file: "/static/page/lang-example.xml"});
     });
-});
+});

+ 1 - 1
web/views/client/add.html

@@ -134,7 +134,7 @@
         $("#add").on("click", function () {
             $.ajax({
                 type: "POST",
-                url: "/client/add",
+                url: "{{.web_base_url}}/client/add",
                 data: $("form").serializeArray(),
                 success: function (res) {
                     alert(res.msg)

+ 1 - 1
web/views/client/edit.html

@@ -145,7 +145,7 @@
         $("#add").on("click", function () {
             $.ajax({
                 type: "POST",
-                url: "/client/edit",
+                url: "{{.web_base_url}}/client/edit",
                 data: $("form").serializeArray(),
                 success: function (res) {
                     alert(res.msg)

+ 9 - 9
web/views/client/list.html

@@ -20,7 +20,7 @@
 
                 <div class="table-responsive">
                     <div id="toolbar">
-                        <a href="/client/add" class="btn btn-primary dim" type="button" langtag="info-new">新增</a>
+                        <a href="{{.web_base_url}}/client/add" class="btn btn-primary dim" type="button" langtag="info-new">新增</a>
                     </div>
                     <table id="taskList_table" class="table-striped table-hover"
                            data-mobile-responsive="true"></table>
@@ -42,7 +42,7 @@
         if (confirm("Are you sure you want to delete it??")) {
             $.ajax({
                 type: "POST",
-                url: "/client/del",
+                url: "{{.web_base_url}}/client/del",
                 data: {"id": id},
                 success: function (res) {
                     alert(res.msg)
@@ -58,7 +58,7 @@
         if (confirm("Are you sure you want to start it??")) {
             $.ajax({
                 type: "POST",
-                url: "/client/changestatus",
+                url: "{{.web_base_url}}/client/changestatus",
                 data: {"id": id, "status": 1},
                 success: function (res) {
                     alert(res.msg)
@@ -74,7 +74,7 @@
         if (confirm("Are you sure you want to stop it?")) {
             $.ajax({
                 type: "POST",
-                url: "/client/changestatus",
+                url: "{{.web_base_url}}/client/changestatus",
                 data: {
                     "id": id, "status": 0
                 },
@@ -90,26 +90,26 @@
     }
 
     function edit(id) {
-        window.location.href = "/client/edit?id=" + id
+        window.location.href = "{{.web_base_url}}/client/edit?id=" + id
     }
 
     function add() {
-        window.location.href = "/client/add"
+        window.location.href = "{{.web_base_url}}/client/add"
     }
 
     function tunnel(id) {
-        window.location.href = "/index/all?client_id=" + id
+        window.location.href = "{{.web_base_url}}/index/all?client_id=" + id
     }
 
     function host(id) {
-        window.location.href = "/index/hostlist?client_id=" + id
+        window.location.href = "{{.web_base_url}}/index/hostlist?client_id=" + id
     }
 
     /*bootstrap table*/
     $('#table').bootstrapTable({
         toolbar: "#toolbar",
         method: 'post', // 服务器数据的请求方式 get or post
-        url: "/client/list", // 服务器数据的加载地址
+        url: "{{.web_base_url}}/client/list", // 服务器数据的加载地址
         contentType: "application/x-www-form-urlencoded",
         striped: true, // 设置为true会有隔行变色效果
         search: true,

+ 1 - 1
web/views/index/add.html

@@ -162,7 +162,7 @@
         $("#add").on("click", function () {
             $.ajax({
                 type: "POST",
-                url: "/index/add",
+                url: "{{.web_base_url}}/index/add",
                 data: $("form").serializeArray(),
                 success: function (res) {
                     alert(res.msg)

+ 1 - 1
web/views/index/edit.html

@@ -160,7 +160,7 @@
         $("#add").on("click", function () {
             $.ajax({
                 type: "POST",
-                url: "/index/edit",
+                url: "{{.web_base_url}}/index/edit",
                 data: $("form").serializeArray(),
                 success: function (res) {
                     alert(res.msg)

+ 1 - 1
web/views/index/hadd.html

@@ -112,7 +112,7 @@
         $("#add").on("click", function () {
             $.ajax({
                 type: "POST",
-                url: "/index/addhost",
+                url: "{{.web_base_url}}/index/addhost",
                 data: $("form").serializeArray(),
                 success: function (res) {
                     alert(res.msg)

+ 1 - 1
web/views/index/hedit.html

@@ -116,7 +116,7 @@
         $("#add").on("click", function () {
             $.ajax({
                 type: "POST",
-                url: "/index/edithost",
+                url: "{{.web_base_url}}/index/edithost",
                 data: $("form").serializeArray(),
                 success: function (res) {
                     alert(res.msg)

+ 3 - 3
web/views/index/hlist.html

@@ -18,7 +18,7 @@
                 <div class="content">
                     <div class="table-responsive">
                         <div id="toolbar">
-                            <a href="/index/addhost?vkey={{.task_id}}&client_id={{.client_id}}"
+                            <a href="{{.web_base_url}}/index/addhost?vkey={{.task_id}}&client_id={{.client_id}}"
                                class="btn btn-primary dim"
                                type="button" langtag="info-new">新增</a>
                         </div>
@@ -158,7 +158,7 @@
         if (confirm("Are you sure you want to delete it??")) {
             $.ajax({
                 type: "POST",
-                url: "/index/delhost",
+                url: "{{.web_base_url}}/index/delhost",
                 data: {"id": id},
                 success: function (res) {
                     alert(res.msg)
@@ -171,7 +171,7 @@
     }
 
     function edit(id) {
-        window.location.href = "/index/edithost?id=" + id
+        window.location.href = "{{.web_base_url}}/index/edithost?id=" + id
     }
 
 

+ 6 - 6
web/views/index/list.html

@@ -18,7 +18,7 @@
                 <div class="content">
                     <div class="table-responsive">
                         <div id="toolbar">
-                            <a href="/index/add?type={{.type}}&client_id={{.client_id}}" class="btn btn-primary dim"
+                            <a href="{{.web_base_url}}/index/add?type={{.type}}&client_id={{.client_id}}" class="btn btn-primary dim"
                                type="button" langtag="info-new">新增</a>
                         </div>
                         <table id="taskList_table" class="table-striped table-hover"
@@ -40,7 +40,7 @@
     $('#table').bootstrapTable({
         toolbar: "#toolbar",
         method: 'post', // 服务器数据的请求方式 get or post
-        url: "/index/gettunnel", // 服务器数据的加载地址
+        url: "{{.web_base_url}}/index/gettunnel", // 服务器数据的加载地址
         queryParams: function (params) {
             return {
                 "offset": params.offset,
@@ -191,7 +191,7 @@
         if (confirm("Are you sure you want to delete it??")) {
             $.ajax({
                 type: "POST",
-                url: "/index/del",
+                url: "{{.web_base_url}}/index/del",
                 data: {"id": id},
                 success: function (res) {
                     alert(res.msg)
@@ -207,7 +207,7 @@
         if (confirm("Are you sure you want to start it??")) {
             $.ajax({
                 type: "POST",
-                url: "/index/start",
+                url: "{{.web_base_url}}/index/start",
                 data: {"id": id},
                 success: function (res) {
                     alert(res.msg)
@@ -223,7 +223,7 @@
         if (confirm("Are you sure you want to stop it??")) {
             $.ajax({
                 type: "POST",
-                url: "/index/stop",
+                url: "{{.web_base_url}}/index/stop",
                 data: {"id": id},
                 success: function (res) {
                     alert(res.msg)
@@ -236,7 +236,7 @@
     }
 
     function edit(id) {
-        window.location.href = "/index/edit?id=" + id
+        window.location.href = "{{.web_base_url}}/index/edit?id=" + id
     }
 
 </script>

+ 7 - 7
web/views/login/index.html

@@ -8,10 +8,10 @@
 
     <title>nps admin login</title>
 
-    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
-    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
+    <link href="{{.web_base_url}}/static/css/bootstrap.min.css" rel="stylesheet">
+    <link href="{{.web_base_url}}/static/font-awesome/css/font-awesome.css" rel="stylesheet">
 
-    <link href="/static/css/style.css" rel="stylesheet">
+    <link href="{{.web_base_url}}/static/css/style.css" rel="stylesheet">
 
 </head>
 
@@ -49,7 +49,7 @@
                     </div>
                     <button onclick="login()" class="btn btn-primary block full-width m-b">login</button>
                 {{if eq true .register_allow}}
-                    <a class="btn btn-sm btn-white btn-block" href="/login/register">register</a>
+                    <a class="btn btn-sm btn-white btn-block" href="{{.web_base_url}}/login/register">register</a>
                 {{end}}
                 </form>
             </div>
@@ -59,7 +59,7 @@
 </div>
 
 </body>
-<script src="/static/js/jquery-2.1.1.js"></script>
+<script src="{{.web_base_url}}/static/js/jquery-2.1.1.js"></script>
 </html>
 
 
@@ -68,11 +68,11 @@
     function login() {
         $.ajax({
             type: "POST",
-            url: "/login/verify",
+            url: "{{.web_base_url}}/login/verify",
             data: $("form").serializeArray(),
             success: function (res) {
                 if (res.status) {
-                    window.location.href = "/index/index"
+                    window.location.href = "{{.web_base_url}}/index/index"
                 } else {
                     alert(res.msg)
                 }

+ 7 - 7
web/views/login/register.html

@@ -8,10 +8,10 @@
 
     <title>nps register</title>
 
-    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
-    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
+    <link href="{{.web_base_url}}/static/css/bootstrap.min.css" rel="stylesheet">
+    <link href="{{.web_base_url}}/static/font-awesome/css/font-awesome.css" rel="stylesheet">
 
-    <link href="/static/css/style.css" rel="stylesheet">
+    <link href="{{.web_base_url}}/static/css/style.css" rel="stylesheet">
 
 </head>
 
@@ -34,22 +34,22 @@
             </div>
             <button onclick="register()" type="submit" class="btn btn-primary block full-width m-b">register</button>
 
-            <a class="btn btn-sm btn-white btn-block" href="/login/index">login</a>
+            <a class="btn btn-sm btn-white btn-block" href="{{.web_base_url}}/login/index">login</a>
         </form>
     </div>
 </div>
 
-<script src="/static/js/jquery-2.1.1.js"></script>
+<script src="{{.web_base_url}}/static/js/jquery-2.1.1.js"></script>
 <script>
     function register() {
         $.ajax({
             type: "POST",
-            url: "/login/register",
+            url: "{{.web_base_url}}/login/register",
             data: $("form").serializeArray(),
             success: function (res) {
                 alert(res.msg)
                 if (res.status) {
-                    window.location.href = "/login/index"
+                    window.location.href = "{{.web_base_url}}/login/index"
                 }
             }
         })

+ 26 - 23
web/views/public/layout.html

@@ -9,22 +9,22 @@
 
     <title>nps admin</title>
 
-    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
-    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
-    <link href="/static/css/style.css" rel="stylesheet">
-    <script src="/static/js/main.js"></script>
+    <link href="{{.web_base_url}}/static/css/bootstrap.min.css" rel="stylesheet">
+    <link href="{{.web_base_url}}/static/font-awesome/css/font-awesome.css" rel="stylesheet">
+    <link href="{{.web_base_url}}/static/css/style.css" rel="stylesheet">
+    <script src="{{.web_base_url}}/static/js/main.js"></script>
     <!-- Mainly scripts -->
-    <script src="/static/js/jquery-2.1.1.js"></script>
-    <script src="/static/js/bootstrap.min.js"></script>
-    <script src="/static/js/echarts.min.js"></script>
+    <script src="{{.web_base_url}}/static/js/jquery-2.1.1.js"></script>
+    <script src="{{.web_base_url}}/static/js/bootstrap.min.js"></script>
+    <script src="{{.web_base_url}}/static/js/echarts.min.js"></script>
     <!-- Latest compiled and minified CSS -->
-    <link rel="stylesheet" href="/static/css/bootstrap-table.min.css">
+    <link rel="stylesheet" href="{{.web_base_url}}/static/css/bootstrap-table.min.css">
 
     <!-- Latest compiled and minified JavaScript -->
-    <script src="/static/js/bootstrap-table.min.js"></script>
-    <script src="/static/js/inspinia.js"></script>
+    <script src="{{.web_base_url}}/static/js/bootstrap-table.min.js"></script>
+    <script src="{{.web_base_url}}/static/js/inspinia.js"></script>
     <!-- Latest compiled and minified Locales -->
-    <script src="/static/js/langchange.js" type="text/javascript"></script>
+    <script src="{{.web_base_url}}/static/js/langchange.js" type="text/javascript"></script>
 
 </head>
 
@@ -35,7 +35,7 @@
             <ul class="nav metismenu" id="side-menu">
                 <li class="nav-header">
                     <div class="dropdown profile-element"> <span>
-                    {{/*<img alt="image" class="img-circle" src="/static/img/profile_small.jpg"/>*/}}
+                    {{/*<img alt="image" class="img-circle" src="{{.web_base_url}}/static/img/profile_small.jpg"/>*/}}
                     </span>
                         <a href="#">
                             <span class="clear"> <span class="block m-t-xs"> <strong class="font-bold">
@@ -53,42 +53,42 @@
                     </div>
                 </li>
                 <li class="{{if eq "index" .menu}}active{{end}}">
-                    <a href="/"><i class="fa fa-dashboard"></i> <span langtag="menu-dashboard"
+                    <a href="{{.web_base_url}}/"><i class="fa fa-dashboard"></i> <span langtag="menu-dashboard"
                                                                       class="nav-label">仪表盘</span></a>
                 </li>
                 <li class="{{if eq "client" .menu}}active{{end}}">
-                    <a href="/client/list"><i class="fa fa-clipboard"></i> <span langtag="menu-client"
+                    <a href="{{.web_base_url}}/client/list"><i class="fa fa-clipboard"></i> <span langtag="menu-client"
                                                                                  class="nav-label">客户端</span></a>
                 </li>
                 <li class="{{if eq "host" .menu}}active{{end}}">
-                    <a href="/index/hostlist"><i class="fa fa-paperclip"></i> <span langtag="menu-host"
+                    <a href="{{.web_base_url}}/index/hostlist"><i class="fa fa-paperclip"></i> <span langtag="menu-host"
                                                                                     class="nav-label">域名解析</span></a>
                 </li>
                 <li class="{{if eq "tcp" .menu}}active{{end}}">
-                    <a href="/index/tcp"><i class="fa fa-line-chart"></i> <span langtag="menu-tcp"
+                    <a href="{{.web_base_url}}/index/tcp"><i class="fa fa-line-chart"></i> <span langtag="menu-tcp"
                                                                                 class="nav-label">tcp隧道</span></a>
                 </li>
                 <li class="{{if eq "udp" .menu}}active{{end}}">
-                    <a href="/index/udp"><i class="fa fa-server"></i> <span langtag="menu-udp"
+                    <a href="{{.web_base_url}}/index/udp"><i class="fa fa-server"></i> <span langtag="menu-udp"
                                                                             class="nav-label">udp隧道</span></a>
                 </li>
                 <li class="{{if eq "http" .menu}}active{{end}}">
-                    <a href="/index/http"><i class="fa fa-html5"></i> <span langtag="menu-http"
+                    <a href="{{.web_base_url}}/index/http"><i class="fa fa-html5"></i> <span langtag="menu-http"
                                                                             class="nav-label">http代理</span></a>
                 </li>
                 <li class="{{if eq "socks5" .menu}}active{{end}}">
-                    <a href="/index/socks5"><i class="fa fa-table"></i> <span langtag="menu-socks5" class="nav-label">socks5代理</span></a>
+                    <a href="{{.web_base_url}}/index/socks5"><i class="fa fa-table"></i> <span langtag="menu-socks5" class="nav-label">socks5代理</span></a>
                 </li>
                 <li class="{{if eq "secret" .menu}}active{{end}}">
-                    <a href="/index/secret"><i class="fa fa-backward"></i> <span langtag="menu-secret"
+                    <a href="{{.web_base_url}}/index/secret"><i class="fa fa-backward"></i> <span langtag="menu-secret"
                                                                                  class="nav-label">私密代理</span></a>
                 </li>
                 <li class="{{if eq "p2p" .menu}}active{{end}}">
-                    <a href="/index/p2p"><i class="fa fa-dashcube"></i> <span langtag="menu-p2p"
+                    <a href="{{.web_base_url}}/index/p2p"><i class="fa fa-dashcube"></i> <span langtag="menu-p2p"
                                                                               class="nav-label">p2p代理</span></a>
                 </li>
                 <li class="{{if eq "file" .menu}}active{{end}}">
-                    <a href="/index/file"><i class="fa fa-laptop"></i> <span langtag="menu-file"
+                    <a href="{{.web_base_url}}/index/file"><i class="fa fa-laptop"></i> <span langtag="menu-file"
                                                                              class="nav-label">文件代理</span></a>
                 </li>
             </ul>
@@ -115,7 +115,7 @@
                     </li>
 
                     <li>
-                        <a href="/login/out">
+                        <a href="{{.web_base_url}}/login/out">
                             <i class="fa fa-sign-out"></i> logout
                         </a>
                     </li>
@@ -142,6 +142,9 @@
 </html>
 
 <script>
+   window.nps = {
+       "web_base_url": {{.web_base_url}},
+   }
     // googleTranslateElementInit()
     //
     // function googleTranslateElementInit() {