diff --git a/internal/web/actions/default/servers/create.go b/internal/web/actions/default/servers/create.go index 4ff12af9..3092348d 100644 --- a/internal/web/actions/default/servers/create.go +++ b/internal/web/actions/default/servers/create.go @@ -564,9 +564,11 @@ func (this *CreateAction) RunPost(params struct { var remoteAddrConfig = &serverconfigs.HTTPRemoteAddrConfig{ IsOn: true, Value: "${rawRemoteAddr}", + Type: serverconfigs.HTTPRemoteAddrTypeDefault, } if params.RemoteAddrIsOn { remoteAddrConfig.Value = "${remoteAddr}" + remoteAddrConfig.Type = serverconfigs.HTTPRemoteAddrTypeProxy } remoteAddrConfigJSON, err := json.Marshal(remoteAddrConfig) if err != nil { diff --git a/internal/web/actions/default/servers/groups/group/settings/remoteAddr/index.go b/internal/web/actions/default/servers/groups/group/settings/remoteAddr/index.go index 36f6225e..a9bcc468 100644 --- a/internal/web/actions/default/servers/groups/group/settings/remoteAddr/index.go +++ b/internal/web/actions/default/servers/groups/group/settings/remoteAddr/index.go @@ -10,6 +10,7 @@ import ( "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/iwind/TeaGo/actions" + "regexp" "strings" ) @@ -54,9 +55,29 @@ func (this *IndexAction) RunPost(params struct { err := json.Unmarshal(params.RemoteAddrJSON, remoteAddrConfig) if err != nil { this.Fail("参数校验失败:" + err.Error()) + return } remoteAddrConfig.Value = strings.TrimSpace(remoteAddrConfig.Value) + + switch remoteAddrConfig.Type { + case serverconfigs.HTTPRemoteAddrTypeRequestHeader: + if len(remoteAddrConfig.RequestHeaderName) == 0 { + this.FailField("requestHeaderName", "请输入请求报头") + return + } + if !regexp.MustCompile(`^[\w-_]+$`).MatchString(remoteAddrConfig.RequestHeaderName) { + this.FailField("requestHeaderName", "请求报头中只能含有数字、英文字母、下划线、中划线") + return + } + remoteAddrConfig.Value = "${header." + remoteAddrConfig.RequestHeaderName + "}" + case serverconfigs.HTTPRemoteAddrTypeVariable: + if len(remoteAddrConfig.Value) == 0 { + this.FailField("value", "请输入自定义变量") + return + } + } + err = remoteAddrConfig.Init() if err != nil { this.Fail("配置校验失败:" + err.Error()) diff --git a/internal/web/actions/default/servers/server/settings/locations/remoteAddr/index.go b/internal/web/actions/default/servers/server/settings/locations/remoteAddr/index.go index 9de70758..e867d8d4 100644 --- a/internal/web/actions/default/servers/server/settings/locations/remoteAddr/index.go +++ b/internal/web/actions/default/servers/server/settings/locations/remoteAddr/index.go @@ -9,6 +9,7 @@ import ( "github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb" "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/iwind/TeaGo/actions" + "regexp" "strings" ) @@ -46,9 +47,29 @@ func (this *IndexAction) RunPost(params struct { err := json.Unmarshal(params.RemoteAddrJSON, remoteAddrConfig) if err != nil { this.Fail("参数校验失败:" + err.Error()) + return } remoteAddrConfig.Value = strings.TrimSpace(remoteAddrConfig.Value) + + switch remoteAddrConfig.Type { + case serverconfigs.HTTPRemoteAddrTypeRequestHeader: + if len(remoteAddrConfig.RequestHeaderName) == 0 { + this.FailField("requestHeaderName", "请输入请求报头") + return + } + if !regexp.MustCompile(`^[\w-_]+$`).MatchString(remoteAddrConfig.RequestHeaderName) { + this.FailField("requestHeaderName", "请求报头中只能含有数字、英文字母、下划线、中划线") + return + } + remoteAddrConfig.Value = "${header." + remoteAddrConfig.RequestHeaderName + "}" + case serverconfigs.HTTPRemoteAddrTypeVariable: + if len(remoteAddrConfig.Value) == 0 { + this.FailField("value", "请输入自定义变量") + return + } + } + err = remoteAddrConfig.Init() if err != nil { this.Fail("配置校验失败:" + err.Error()) diff --git a/internal/web/actions/default/servers/server/settings/remoteAddr/index.go b/internal/web/actions/default/servers/server/settings/remoteAddr/index.go index b6ef573a..6bdd27e9 100644 --- a/internal/web/actions/default/servers/server/settings/remoteAddr/index.go +++ b/internal/web/actions/default/servers/server/settings/remoteAddr/index.go @@ -10,6 +10,7 @@ import ( "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs" "github.com/iwind/TeaGo/actions" "github.com/iwind/TeaGo/types" + "regexp" "strings" ) @@ -63,6 +64,25 @@ func (this *IndexAction) RunPost(params struct { } remoteAddrConfig.Value = strings.TrimSpace(remoteAddrConfig.Value) + + switch remoteAddrConfig.Type { + case serverconfigs.HTTPRemoteAddrTypeRequestHeader: + if len(remoteAddrConfig.RequestHeaderName) == 0 { + this.FailField("requestHeaderName", "请输入请求报头") + return + } + if !regexp.MustCompile(`^[\w-_]+$`).MatchString(remoteAddrConfig.RequestHeaderName) { + this.FailField("requestHeaderName", "请求报头中只能含有数字、英文字母、下划线、中划线") + return + } + remoteAddrConfig.Value = "${header." + remoteAddrConfig.RequestHeaderName + "}" + case serverconfigs.HTTPRemoteAddrTypeVariable: + if len(remoteAddrConfig.Value) == 0 { + this.FailField("value", "请输入自定义变量") + return + } + } + err = remoteAddrConfig.Init() if err != nil { this.Fail("配置校验失败:" + err.Error()) diff --git a/web/public/js/components/server/http-remote-addr-config-box.js b/web/public/js/components/server/http-remote-addr-config-box.js index 76a17c23..80c2e200 100644 --- a/web/public/js/components/server/http-remote-addr-config-box.js +++ b/web/public/js/components/server/http-remote-addr-config-box.js @@ -7,13 +7,35 @@ Vue.component("http-remote-addr-config-box", { isPrior: false, isOn: false, value: "${rawRemoteAddr}", - isCustomized: false + type: "default", + + requestHeaderName: "" } } - let optionValue = "" - if (!config.isCustomized && (config.value == "${remoteAddr}" || config.value == "${rawRemoteAddr}")) { - optionValue = config.value + // type + if (config.type == null || config.type.length == 0) { + config.type = "default" + switch (config.value) { + case "${rawRemoteAddr}": + config.type = "default" + break + case "${remoteAddrValue}": + config.type = "default" + break + case "${remoteAddr}": + config.type = "proxy" + break + default: + if (config.value != null && config.value.length > 0) { + config.type = "variable" + } + } + } + + // value + if (config.value == null || config.value.length == 0) { + config.value = "${rawRemoteAddr}" } return { @@ -21,33 +43,70 @@ Vue.component("http-remote-addr-config-box", { options: [ { name: "直接获取", - description: "用户直接访问边缘节点,即 \"用户 --> 边缘节点\" 模式,这时候可以直接从连接中读取到真实的IP地址。", - value: "${rawRemoteAddr}" + description: "用户直接访问边缘节点,即 \"用户 --> 边缘节点\" 模式,这时候系统会试图从直接的连接中读取到客户端IP地址。", + value: "${rawRemoteAddr}", + type: "default" }, { name: "从上级代理中获取", - description: "用户和边缘节点之间有别的代理服务转发,即 \"用户 --> [第三方代理服务] --> 边缘节点\",这时候只能从上级代理中获取传递的IP地址。", - value: "${remoteAddr}" + description: "用户和边缘节点之间有别的代理服务转发,即 \"用户 --> [第三方代理服务] --> 边缘节点\",这时候只能从上级代理中获取传递的IP地址;上级代理传递的请求报头中必须包含 X-Forwarded-For 或 X-Real-IP 信息。", + value: "${remoteAddr}", + type: "proxy" }, { - name: "[自定义]", + name: "从请求报头中读取", + description: "从自定义请求报头读取客户端IP。", + value: "", + type: "requestHeader" + }, + { + name: "[自定义变量]", description: "通过自定义变量来获取客户端真实的IP地址。", - value: "" + value: "", + type: "variable" } - ], - optionValue: optionValue + ] + } + }, + watch: { + "config.requestHeaderName": function (value) { + if (this.config.type == "requestHeader"){ + this.config.value = "${header." + value.trim() + "}" + } } }, methods: { isOn: function () { return ((!this.vIsLocation && !this.vIsGroup) || this.config.isPrior) && this.config.isOn }, - changeOptionValue: function () { - if (this.optionValue.length > 0) { - this.config.value = this.optionValue - this.config.isCustomized = false - } else { - this.config.isCustomized = true + changeOptionType: function () { + let that = this + + switch(this.config.type) { + case "default": + this.config.value = "${rawRemoteAddr}" + break + case "proxy": + this.config.value = "${remoteAddr}" + break + case "requestHeader": + this.config.value = "" + if (this.requestHeaderName != null && this.requestHeaderName.length > 0) { + this.config.value = "${header." + this.requestHeaderName + "}" + } + + setTimeout(function () { + that.$refs.requestHeaderInput.focus() + }) + break + case "variable": + this.config.value = "${rawRemoteAddr}" + + setTimeout(function () { + that.$refs.variableInput.focus() + }) + + break } } }, @@ -63,7 +122,7 @@ Vue.component("http-remote-addr-config-box", { -

选中后表示使用自定义的请求变量获取客户端IP。

+

选中后,表示使用自定义的请求变量获取客户端IP。

@@ -71,20 +130,28 @@ Vue.component("http-remote-addr-config-box", { 获取IP方式 * - + -

{{option.description}}

+

{{option.description}}

- + + + + 请求报头 * + + +

请输入包含有客户端IP的请求报头,需要注意大小写,常见的有X-Forwarded-ForX-Real-IPX-Client-IP等。

+ + + + + 读取IP变量值 * - -
- -

通过此变量获取用户的IP地址。具体可用的请求变量列表可参考官方网站文档。

-
+ +

通过此变量获取用户的IP地址。具体可用的请求变量列表可参考官方网站文档;比如通过报头传递IP的情形,可以使用\${header.你的自定义报头}(类似于\${header.X-Forwarded-For},需要注意大小写规范)。