mirror of
https://gitee.com/IrisVega/frp.git
synced 2024-11-01 22:31:29 +08:00
9152c59570
* fix nil map error when using plugin headers in legacy format * create map on demand * better initialization
356 lines
12 KiB
Go
356 lines
12 KiB
Go
// Copyright 2023 The frp Authors
|
|
//
|
|
// 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
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package legacy
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/samber/lo"
|
|
|
|
"github.com/fatedier/frp/pkg/config/types"
|
|
v1 "github.com/fatedier/frp/pkg/config/v1"
|
|
)
|
|
|
|
func Convert_ClientCommonConf_To_v1(conf *ClientCommonConf) *v1.ClientCommonConfig {
|
|
out := &v1.ClientCommonConfig{}
|
|
out.User = conf.User
|
|
out.Auth.Method = v1.AuthMethod(conf.ClientConfig.AuthenticationMethod)
|
|
out.Auth.Token = conf.ClientConfig.Token
|
|
if conf.ClientConfig.AuthenticateHeartBeats {
|
|
out.Auth.AdditionalScopes = append(out.Auth.AdditionalScopes, v1.AuthScopeHeartBeats)
|
|
}
|
|
if conf.ClientConfig.AuthenticateNewWorkConns {
|
|
out.Auth.AdditionalScopes = append(out.Auth.AdditionalScopes, v1.AuthScopeNewWorkConns)
|
|
}
|
|
out.Auth.OIDC.ClientID = conf.ClientConfig.OidcClientID
|
|
out.Auth.OIDC.ClientSecret = conf.ClientConfig.OidcClientSecret
|
|
out.Auth.OIDC.Audience = conf.ClientConfig.OidcAudience
|
|
out.Auth.OIDC.Scope = conf.ClientConfig.OidcScope
|
|
out.Auth.OIDC.TokenEndpointURL = conf.ClientConfig.OidcTokenEndpointURL
|
|
out.Auth.OIDC.AdditionalEndpointParams = conf.ClientConfig.OidcAdditionalEndpointParams
|
|
|
|
out.ServerAddr = conf.ServerAddr
|
|
out.ServerPort = conf.ServerPort
|
|
out.NatHoleSTUNServer = conf.NatHoleSTUNServer
|
|
out.Transport.DialServerTimeout = conf.DialServerTimeout
|
|
out.Transport.DialServerKeepAlive = conf.DialServerKeepAlive
|
|
out.Transport.ConnectServerLocalIP = conf.ConnectServerLocalIP
|
|
out.Transport.ProxyURL = conf.HTTPProxy
|
|
out.Transport.PoolCount = conf.PoolCount
|
|
out.Transport.TCPMux = lo.ToPtr(conf.TCPMux)
|
|
out.Transport.TCPMuxKeepaliveInterval = conf.TCPMuxKeepaliveInterval
|
|
out.Transport.Protocol = conf.Protocol
|
|
out.Transport.HeartbeatInterval = conf.HeartbeatInterval
|
|
out.Transport.HeartbeatTimeout = conf.HeartbeatTimeout
|
|
out.Transport.QUIC.KeepalivePeriod = conf.QUICKeepalivePeriod
|
|
out.Transport.QUIC.MaxIdleTimeout = conf.QUICMaxIdleTimeout
|
|
out.Transport.QUIC.MaxIncomingStreams = conf.QUICMaxIncomingStreams
|
|
out.Transport.TLS.Enable = lo.ToPtr(conf.TLSEnable)
|
|
out.Transport.TLS.DisableCustomTLSFirstByte = lo.ToPtr(conf.DisableCustomTLSFirstByte)
|
|
out.Transport.TLS.TLSConfig.CertFile = conf.TLSCertFile
|
|
out.Transport.TLS.TLSConfig.KeyFile = conf.TLSKeyFile
|
|
out.Transport.TLS.TLSConfig.TrustedCaFile = conf.TLSTrustedCaFile
|
|
out.Transport.TLS.TLSConfig.ServerName = conf.TLSServerName
|
|
|
|
out.Log.To = conf.LogFile
|
|
out.Log.Level = conf.LogLevel
|
|
out.Log.MaxDays = conf.LogMaxDays
|
|
out.Log.DisablePrintColor = conf.DisableLogColor
|
|
|
|
out.WebServer.Addr = conf.AdminAddr
|
|
out.WebServer.Port = conf.AdminPort
|
|
out.WebServer.User = conf.AdminUser
|
|
out.WebServer.Password = conf.AdminPwd
|
|
out.WebServer.AssetsDir = conf.AssetsDir
|
|
out.WebServer.PprofEnable = conf.PprofEnable
|
|
|
|
out.DNSServer = conf.DNSServer
|
|
out.LoginFailExit = lo.ToPtr(conf.LoginFailExit)
|
|
out.Start = conf.Start
|
|
out.UDPPacketSize = conf.UDPPacketSize
|
|
out.Metadatas = conf.Metas
|
|
out.IncludeConfigFiles = conf.IncludeConfigFiles
|
|
return out
|
|
}
|
|
|
|
func Convert_ServerCommonConf_To_v1(conf *ServerCommonConf) *v1.ServerConfig {
|
|
out := &v1.ServerConfig{}
|
|
out.Auth.Method = v1.AuthMethod(conf.ServerConfig.AuthenticationMethod)
|
|
out.Auth.Token = conf.ServerConfig.Token
|
|
if conf.ServerConfig.AuthenticateHeartBeats {
|
|
out.Auth.AdditionalScopes = append(out.Auth.AdditionalScopes, v1.AuthScopeHeartBeats)
|
|
}
|
|
if conf.ServerConfig.AuthenticateNewWorkConns {
|
|
out.Auth.AdditionalScopes = append(out.Auth.AdditionalScopes, v1.AuthScopeNewWorkConns)
|
|
}
|
|
out.Auth.OIDC.Audience = conf.ServerConfig.OidcAudience
|
|
out.Auth.OIDC.Issuer = conf.ServerConfig.OidcIssuer
|
|
out.Auth.OIDC.SkipExpiryCheck = conf.ServerConfig.OidcSkipExpiryCheck
|
|
out.Auth.OIDC.SkipIssuerCheck = conf.ServerConfig.OidcSkipIssuerCheck
|
|
|
|
out.BindAddr = conf.BindAddr
|
|
out.BindPort = conf.BindPort
|
|
out.KCPBindPort = conf.KCPBindPort
|
|
out.QUICBindPort = conf.QUICBindPort
|
|
out.Transport.QUIC.KeepalivePeriod = conf.QUICKeepalivePeriod
|
|
out.Transport.QUIC.MaxIdleTimeout = conf.QUICMaxIdleTimeout
|
|
out.Transport.QUIC.MaxIncomingStreams = conf.QUICMaxIncomingStreams
|
|
|
|
out.ProxyBindAddr = conf.ProxyBindAddr
|
|
out.VhostHTTPPort = conf.VhostHTTPPort
|
|
out.VhostHTTPSPort = conf.VhostHTTPSPort
|
|
out.TCPMuxHTTPConnectPort = conf.TCPMuxHTTPConnectPort
|
|
out.TCPMuxPassthrough = conf.TCPMuxPassthrough
|
|
out.VhostHTTPTimeout = conf.VhostHTTPTimeout
|
|
|
|
out.WebServer.Addr = conf.DashboardAddr
|
|
out.WebServer.Port = conf.DashboardPort
|
|
out.WebServer.User = conf.DashboardUser
|
|
out.WebServer.Password = conf.DashboardPwd
|
|
out.WebServer.AssetsDir = conf.AssetsDir
|
|
if conf.DashboardTLSMode {
|
|
out.WebServer.TLS = &v1.TLSConfig{}
|
|
out.WebServer.TLS.CertFile = conf.DashboardTLSCertFile
|
|
out.WebServer.TLS.KeyFile = conf.DashboardTLSKeyFile
|
|
out.WebServer.PprofEnable = conf.PprofEnable
|
|
}
|
|
|
|
out.EnablePrometheus = conf.EnablePrometheus
|
|
|
|
out.Log.To = conf.LogFile
|
|
out.Log.Level = conf.LogLevel
|
|
out.Log.MaxDays = conf.LogMaxDays
|
|
out.Log.DisablePrintColor = conf.DisableLogColor
|
|
|
|
out.DetailedErrorsToClient = lo.ToPtr(conf.DetailedErrorsToClient)
|
|
out.SubDomainHost = conf.SubDomainHost
|
|
out.Custom404Page = conf.Custom404Page
|
|
out.UserConnTimeout = conf.UserConnTimeout
|
|
out.UDPPacketSize = conf.UDPPacketSize
|
|
out.NatHoleAnalysisDataReserveHours = conf.NatHoleAnalysisDataReserveHours
|
|
|
|
out.Transport.TCPMux = lo.ToPtr(conf.TCPMux)
|
|
out.Transport.TCPMuxKeepaliveInterval = conf.TCPMuxKeepaliveInterval
|
|
out.Transport.TCPKeepAlive = conf.TCPKeepAlive
|
|
out.Transport.MaxPoolCount = conf.MaxPoolCount
|
|
out.Transport.HeartbeatTimeout = conf.HeartbeatTimeout
|
|
|
|
out.Transport.TLS.Force = conf.TLSOnly
|
|
out.Transport.TLS.CertFile = conf.TLSCertFile
|
|
out.Transport.TLS.KeyFile = conf.TLSKeyFile
|
|
out.Transport.TLS.TrustedCaFile = conf.TLSTrustedCaFile
|
|
|
|
out.MaxPortsPerClient = conf.MaxPortsPerClient
|
|
|
|
for _, v := range conf.HTTPPlugins {
|
|
out.HTTPPlugins = append(out.HTTPPlugins, v1.HTTPPluginOptions{
|
|
Name: v.Name,
|
|
Addr: v.Addr,
|
|
Path: v.Path,
|
|
Ops: v.Ops,
|
|
TLSVerify: v.TLSVerify,
|
|
})
|
|
}
|
|
|
|
out.AllowPorts, _ = types.NewPortsRangeSliceFromString(conf.AllowPortsStr)
|
|
return out
|
|
}
|
|
|
|
func transformHeadersFromPluginParams(params map[string]string) v1.HeaderOperations {
|
|
out := v1.HeaderOperations{}
|
|
for k, v := range params {
|
|
if !strings.HasPrefix(k, "plugin_header_") {
|
|
continue
|
|
}
|
|
if k = strings.TrimPrefix(k, "plugin_header_"); k != "" {
|
|
if out.Set == nil {
|
|
out.Set = make(map[string]string)
|
|
}
|
|
out.Set[k] = v
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func Convert_ProxyConf_To_v1_Base(conf ProxyConf) *v1.ProxyBaseConfig {
|
|
out := &v1.ProxyBaseConfig{}
|
|
base := conf.GetBaseConfig()
|
|
|
|
out.Name = base.ProxyName
|
|
out.Type = base.ProxyType
|
|
out.Metadatas = base.Metas
|
|
|
|
out.Transport.UseEncryption = base.UseEncryption
|
|
out.Transport.UseCompression = base.UseCompression
|
|
out.Transport.BandwidthLimit = base.BandwidthLimit
|
|
out.Transport.BandwidthLimitMode = base.BandwidthLimitMode
|
|
out.Transport.ProxyProtocolVersion = base.ProxyProtocolVersion
|
|
|
|
out.LoadBalancer.Group = base.Group
|
|
out.LoadBalancer.GroupKey = base.GroupKey
|
|
|
|
out.HealthCheck.Type = base.HealthCheckType
|
|
out.HealthCheck.TimeoutSeconds = base.HealthCheckTimeoutS
|
|
out.HealthCheck.MaxFailed = base.HealthCheckMaxFailed
|
|
out.HealthCheck.IntervalSeconds = base.HealthCheckIntervalS
|
|
out.HealthCheck.Path = base.HealthCheckURL
|
|
|
|
out.LocalIP = base.LocalIP
|
|
out.LocalPort = base.LocalPort
|
|
|
|
switch base.Plugin {
|
|
case "http2https":
|
|
out.Plugin.ClientPluginOptions = &v1.HTTP2HTTPSPluginOptions{
|
|
LocalAddr: base.PluginParams["plugin_local_addr"],
|
|
HostHeaderRewrite: base.PluginParams["plugin_host_header_rewrite"],
|
|
RequestHeaders: transformHeadersFromPluginParams(base.PluginParams),
|
|
}
|
|
case "http_proxy":
|
|
out.Plugin.ClientPluginOptions = &v1.HTTPProxyPluginOptions{
|
|
HTTPUser: base.PluginParams["plugin_http_user"],
|
|
HTTPPassword: base.PluginParams["plugin_http_passwd"],
|
|
}
|
|
case "https2http":
|
|
out.Plugin.ClientPluginOptions = &v1.HTTPS2HTTPPluginOptions{
|
|
LocalAddr: base.PluginParams["plugin_local_addr"],
|
|
HostHeaderRewrite: base.PluginParams["plugin_host_header_rewrite"],
|
|
RequestHeaders: transformHeadersFromPluginParams(base.PluginParams),
|
|
CrtPath: base.PluginParams["plugin_crt_path"],
|
|
KeyPath: base.PluginParams["plugin_key_path"],
|
|
}
|
|
case "https2https":
|
|
out.Plugin.ClientPluginOptions = &v1.HTTPS2HTTPSPluginOptions{
|
|
LocalAddr: base.PluginParams["plugin_local_addr"],
|
|
HostHeaderRewrite: base.PluginParams["plugin_host_header_rewrite"],
|
|
RequestHeaders: transformHeadersFromPluginParams(base.PluginParams),
|
|
CrtPath: base.PluginParams["plugin_crt_path"],
|
|
KeyPath: base.PluginParams["plugin_key_path"],
|
|
}
|
|
case "socks5":
|
|
out.Plugin.ClientPluginOptions = &v1.Socks5PluginOptions{
|
|
Username: base.PluginParams["plugin_user"],
|
|
Password: base.PluginParams["plugin_passwd"],
|
|
}
|
|
case "static_file":
|
|
out.Plugin.ClientPluginOptions = &v1.StaticFilePluginOptions{
|
|
LocalPath: base.PluginParams["plugin_local_path"],
|
|
StripPrefix: base.PluginParams["plugin_strip_prefix"],
|
|
HTTPUser: base.PluginParams["plugin_http_user"],
|
|
HTTPPassword: base.PluginParams["plugin_http_passwd"],
|
|
}
|
|
case "unix_domain_socket":
|
|
out.Plugin.ClientPluginOptions = &v1.UnixDomainSocketPluginOptions{
|
|
UnixPath: base.PluginParams["plugin_unix_path"],
|
|
}
|
|
}
|
|
out.Plugin.Type = base.Plugin
|
|
return out
|
|
}
|
|
|
|
func Convert_ProxyConf_To_v1(conf ProxyConf) v1.ProxyConfigurer {
|
|
outBase := Convert_ProxyConf_To_v1_Base(conf)
|
|
var out v1.ProxyConfigurer
|
|
switch v := conf.(type) {
|
|
case *TCPProxyConf:
|
|
c := &v1.TCPProxyConfig{ProxyBaseConfig: *outBase}
|
|
c.RemotePort = v.RemotePort
|
|
out = c
|
|
case *UDPProxyConf:
|
|
c := &v1.UDPProxyConfig{ProxyBaseConfig: *outBase}
|
|
c.RemotePort = v.RemotePort
|
|
out = c
|
|
case *HTTPProxyConf:
|
|
c := &v1.HTTPProxyConfig{ProxyBaseConfig: *outBase}
|
|
c.CustomDomains = v.CustomDomains
|
|
c.SubDomain = v.SubDomain
|
|
c.Locations = v.Locations
|
|
c.HTTPUser = v.HTTPUser
|
|
c.HTTPPassword = v.HTTPPwd
|
|
c.HostHeaderRewrite = v.HostHeaderRewrite
|
|
c.RequestHeaders.Set = v.Headers
|
|
c.RouteByHTTPUser = v.RouteByHTTPUser
|
|
out = c
|
|
case *HTTPSProxyConf:
|
|
c := &v1.HTTPSProxyConfig{ProxyBaseConfig: *outBase}
|
|
c.CustomDomains = v.CustomDomains
|
|
c.SubDomain = v.SubDomain
|
|
out = c
|
|
case *TCPMuxProxyConf:
|
|
c := &v1.TCPMuxProxyConfig{ProxyBaseConfig: *outBase}
|
|
c.CustomDomains = v.CustomDomains
|
|
c.SubDomain = v.SubDomain
|
|
c.HTTPUser = v.HTTPUser
|
|
c.HTTPPassword = v.HTTPPwd
|
|
c.RouteByHTTPUser = v.RouteByHTTPUser
|
|
c.Multiplexer = v.Multiplexer
|
|
out = c
|
|
case *STCPProxyConf:
|
|
c := &v1.STCPProxyConfig{ProxyBaseConfig: *outBase}
|
|
c.Secretkey = v.Sk
|
|
c.AllowUsers = v.AllowUsers
|
|
out = c
|
|
case *SUDPProxyConf:
|
|
c := &v1.SUDPProxyConfig{ProxyBaseConfig: *outBase}
|
|
c.Secretkey = v.Sk
|
|
c.AllowUsers = v.AllowUsers
|
|
out = c
|
|
case *XTCPProxyConf:
|
|
c := &v1.XTCPProxyConfig{ProxyBaseConfig: *outBase}
|
|
c.Secretkey = v.Sk
|
|
c.AllowUsers = v.AllowUsers
|
|
out = c
|
|
}
|
|
return out
|
|
}
|
|
|
|
func Convert_VisitorConf_To_v1_Base(conf VisitorConf) *v1.VisitorBaseConfig {
|
|
out := &v1.VisitorBaseConfig{}
|
|
base := conf.GetBaseConfig()
|
|
|
|
out.Name = base.ProxyName
|
|
out.Type = base.ProxyType
|
|
out.Transport.UseEncryption = base.UseEncryption
|
|
out.Transport.UseCompression = base.UseCompression
|
|
out.SecretKey = base.Sk
|
|
out.ServerUser = base.ServerUser
|
|
out.ServerName = base.ServerName
|
|
out.BindAddr = base.BindAddr
|
|
out.BindPort = base.BindPort
|
|
return out
|
|
}
|
|
|
|
func Convert_VisitorConf_To_v1(conf VisitorConf) v1.VisitorConfigurer {
|
|
outBase := Convert_VisitorConf_To_v1_Base(conf)
|
|
var out v1.VisitorConfigurer
|
|
switch v := conf.(type) {
|
|
case *STCPVisitorConf:
|
|
c := &v1.STCPVisitorConfig{VisitorBaseConfig: *outBase}
|
|
out = c
|
|
case *SUDPVisitorConf:
|
|
c := &v1.SUDPVisitorConfig{VisitorBaseConfig: *outBase}
|
|
out = c
|
|
case *XTCPVisitorConf:
|
|
c := &v1.XTCPVisitorConfig{VisitorBaseConfig: *outBase}
|
|
c.Protocol = v.Protocol
|
|
c.KeepTunnelOpen = v.KeepTunnelOpen
|
|
c.MaxRetriesAnHour = v.MaxRetriesAnHour
|
|
c.MinRetryInterval = v.MinRetryInterval
|
|
c.FallbackTo = v.FallbackTo
|
|
c.FallbackTimeoutMs = v.FallbackTimeoutMs
|
|
out = c
|
|
}
|
|
return out
|
|
}
|