This commit is contained in:
fatedier 2016-12-21 01:01:44 +08:00
parent 0573ddcd84
commit 10fc6c67e0
7 changed files with 83 additions and 37 deletions

View File

@ -4,18 +4,24 @@
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80" # in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
server_addr = 0.0.0.0 server_addr = 0.0.0.0
server_port = 7000 server_port = 7000
# if you want to connect frps by http proxy, you can set http_proxy here or in global environment variables # if you want to connect frps by http proxy, you can set http_proxy here or in global environment variables
# http_proxy = http://user:pwd@192.168.1.128:8080 # http_proxy = http://user:pwd@192.168.1.128:8080
# console or real logFile path like ./frpc.log # console or real logFile path like ./frpc.log
log_file = ./frpc.log log_file = ./frpc.log
# debug, info, warn, error # debug, info, warn, error
log_level = info log_level = info
log_max_days = 3 log_max_days = 3
# for authentication # for authentication
auth_token = 123 auth_token = 123
# for privilege mode # for privilege mode
privilege_token = 12345678 privilege_token = 12345678
# ssh is the proxy name same as server's configuration # ssh is the proxy name same as server's configuration
[ssh] [ssh]
# tcp | http, default is tcp # tcp | http, default is tcp

View File

@ -4,33 +4,45 @@
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80" # in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
bind_addr = 0.0.0.0 bind_addr = 0.0.0.0
bind_port = 7000 bind_port = 7000
# if you want to support virtual host, you must set the http port for listening (optional) # if you want to support virtual host, you must set the http port for listening (optional)
vhost_http_port = 80 vhost_http_port = 80
vhost_https_port = 443 vhost_https_port = 443
# if you want to configure or reload frps by dashboard, dashboard_port must be set # if you want to configure or reload frps by dashboard, dashboard_port must be set
dashboard_port = 7500 dashboard_port = 7500
# dashboard username and password for basic protect, if not set, both default value is admin
dashboard_username = abc # dashboard user and pwd for basic auth protect, if not set, both default value is admin
dashboard_password = abc dashboard_user = admin
dashboard_pwd = admin
# dashboard assets directory(only for debug mode) # dashboard assets directory(only for debug mode)
# assets_dir = ./static # assets_dir = ./static
# console or real logFile path like ./frps.log # console or real logFile path like ./frps.log
log_file = ./frps.log log_file = ./frps.log
# debug, info, warn, error # debug, info, warn, error
log_level = info log_level = info
log_max_days = 3 log_max_days = 3
# if you enable privilege mode, frpc can create a proxy without pre-configure in frps when privilege_token is correct # if you enable privilege mode, frpc can create a proxy without pre-configure in frps when privilege_token is correct
privilege_mode = true privilege_mode = true
privilege_token = 12345678 privilege_token = 12345678
# only allow frpc to bind ports you list, if you set nothing, there won't be any limit # only allow frpc to bind ports you list, if you set nothing, there won't be any limit
privilege_allow_ports = 2000-3000,3001,3003,4000-50000 privilege_allow_ports = 2000-3000,3001,3003,4000-50000
# pool_count in each proxy will change to max_pool_count if they exceed the maximum value # pool_count in each proxy will change to max_pool_count if they exceed the maximum value
max_pool_count = 100 max_pool_count = 100
# authentication_timeout means the timeout interval (minute units) when the frpc connects frps
# if authentication_timeout set zero, the time is not verified # authentication_timeout means the timeout interval (seconds) when the frpc connects frps
authentication_timeout = 15 # if authentication_timeout is zero, the time is not verified, default is 900s
# domain for frps authentication_timeout = 900
domain = frps.com
# if subdomain_host is not empty, you can set subdomain when type is http or https in frpc's configure file
# when subdomain is test, the host used by routing is test.frps.com
subdomain_host = frps.com
# ssh is the proxy name, client will use this name and auth_token to connect to server # ssh is the proxy name, client will use this name and auth_token to connect to server
[ssh] [ssh]

View File

@ -267,6 +267,14 @@ func doLogin(req *msg.ControlReq, c *conn.Conn) (ret int64, info string) {
return return
} }
} }
} else if s.Type == "http" || s.Type == "https" {
for _, domain := range s.CustomDomains {
if server.SubDomainHost != "" && strings.Contains(domain, server.SubDomainHost) {
info = fmt.Sprintf("ProxyName [%s], custom domain [%s] should not belong to subdomain_host [%s]", req.ProxyName, domain, server.SubDomainHost)
log.Warn(info)
return
}
}
} }
err := server.CreateProxy(s) err := server.CreateProxy(s)
if err != nil { if err != nil {
@ -294,14 +302,20 @@ func doLogin(req *msg.ControlReq, c *conn.Conn) (ret int64, info string) {
s.HostHeaderRewrite = req.HostHeaderRewrite s.HostHeaderRewrite = req.HostHeaderRewrite
s.HttpUserName = req.HttpUserName s.HttpUserName = req.HttpUserName
s.HttpPassWord = req.HttpPassWord s.HttpPassWord = req.HttpPassWord
// package URL // package URL
if req.SubDomain != "" { if req.SubDomain != "" {
if strings.Contains(req.SubDomain, ".") || strings.Contains(req.SubDomain, "*") { if strings.Contains(req.SubDomain, ".") || strings.Contains(req.SubDomain, "*") {
info = fmt.Sprintf("ProxyName [%s], type [%s] not support when subdomain is not set", req.ProxyName, req.Type) info = fmt.Sprintf("ProxyName [%s], '.' or '*' is not supported in subdomain", req.ProxyName)
log.Warn(info) log.Warn(info)
return return
} }
s.SubDomain = req.SubDomain + "." + server.Domain if server.SubDomainHost == "" {
info = fmt.Sprintf("ProxyName [%s], subdomain in not supported because this feature is not enabled by remote server", req.ProxyName)
log.Warn(info)
return
}
s.SubDomain = req.SubDomain + "." + server.SubDomainHost
} }
if req.PoolCount > server.MaxPoolCount { if req.PoolCount > server.MaxPoolCount {
s.PoolCount = server.MaxPoolCount s.PoolCount = server.MaxPoolCount

View File

@ -94,7 +94,7 @@ func main() {
res := &server.GeneralResponse{} res := &server.GeneralResponse{}
err = json.Unmarshal(body, &res) err = json.Unmarshal(body, &res)
if err != nil { if err != nil {
fmt.Printf("http response error: %v\n", err) fmt.Printf("http response error: %s\n", strings.TrimSpace(string(body)))
os.Exit(1) os.Exit(1)
} else if res.Code != 0 { } else if res.Code != 0 {
fmt.Printf("reload error: %s\n", res.Msg) fmt.Printf("reload error: %s\n", res.Msg)

View File

@ -216,30 +216,33 @@ func LoadConf(confFile string) (err error) {
if ok { if ok {
proxyClient.CustomDomains = strings.Split(domainStr, ",") proxyClient.CustomDomains = strings.Split(domainStr, ",")
if len(proxyClient.CustomDomains) == 0 { if len(proxyClient.CustomDomains) == 0 {
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals http", proxyClient.Name) ok = false
} } else {
for i, domain := range proxyClient.CustomDomains { for i, domain := range proxyClient.CustomDomains {
proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain)) proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain))
} }
} else { }
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals http", proxyClient.Name)
} }
// subdomain if !ok && proxyClient.SubDomain == "" {
proxyClient.SubDomain, ok = section["subdomain"] return fmt.Errorf("Parse conf error: proxy [%s] custom_domains and subdomain should set at least one of them when type is http", proxyClient.Name)
}
} else if proxyClient.Type == "https" { } else if proxyClient.Type == "https" {
// custom_domains // custom_domains
domainStr, ok := section["custom_domains"] domainStr, ok := section["custom_domains"]
if ok { if ok {
proxyClient.CustomDomains = strings.Split(domainStr, ",") proxyClient.CustomDomains = strings.Split(domainStr, ",")
if len(proxyClient.CustomDomains) == 0 { if len(proxyClient.CustomDomains) == 0 {
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals https", proxyClient.Name) ok = false
} } else {
for i, domain := range proxyClient.CustomDomains { for i, domain := range proxyClient.CustomDomains {
proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain)) proxyClient.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain))
} }
} else { }
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals http", proxyClient.Name) }
if !ok && proxyClient.SubDomain == "" {
return fmt.Errorf("Parse conf error: proxy [%s] custom_domains and subdomain should set at least one of them when type is https", proxyClient.Name)
} }
} }
} }

View File

@ -45,8 +45,8 @@ var (
LogMaxDays int64 = 3 LogMaxDays int64 = 3
PrivilegeMode bool = false PrivilegeMode bool = false
PrivilegeToken string = "" PrivilegeToken string = ""
AuthTimeout int64 = 15 AuthTimeout int64 = 900
Domain string = "" SubDomainHost string = ""
// if PrivilegeAllowPorts is not nil, tcp proxies which remote port exist in this map can be connected // if PrivilegeAllowPorts is not nil, tcp proxies which remote port exist in this map can be connected
PrivilegeAllowPorts map[int64]struct{} PrivilegeAllowPorts map[int64]struct{}
@ -123,12 +123,12 @@ func loadCommonConf(confFile string) error {
DashboardPort = 0 DashboardPort = 0
} }
tmpStr, ok = conf.Get("common", "dashboard_username") tmpStr, ok = conf.Get("common", "dashboard_user")
if ok { if ok {
DashboardUsername = tmpStr DashboardUsername = tmpStr
} }
tmpStr, ok = conf.Get("common", "dashboard_password") tmpStr, ok = conf.Get("common", "dashboard_pwd")
if ok { if ok {
DashboardPassword = tmpStr DashboardPassword = tmpStr
} }
@ -233,7 +233,10 @@ func loadCommonConf(confFile string) error {
AuthTimeout = v AuthTimeout = v
} }
} }
Domain, ok = conf.Get("common", "domain") SubDomainHost, ok = conf.Get("common", "subdomain_host")
if ok {
SubDomainHost = strings.ToLower(strings.TrimSpace(SubDomainHost))
}
return nil return nil
} }
@ -288,13 +291,18 @@ func loadProxyConf(confFile string) (proxyServers map[string]*ProxyServer, err e
if ok { if ok {
proxyServer.CustomDomains = strings.Split(domainStr, ",") proxyServer.CustomDomains = strings.Split(domainStr, ",")
if len(proxyServer.CustomDomains) == 0 { if len(proxyServer.CustomDomains) == 0 {
return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals http", proxyServer.Name) return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type is http", proxyServer.Name)
} }
for i, domain := range proxyServer.CustomDomains { for i, domain := range proxyServer.CustomDomains {
proxyServer.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain)) domain = strings.ToLower(strings.TrimSpace(domain))
// custom domain should not belong to subdomain_host
if SubDomainHost != "" && strings.Contains(domain, SubDomainHost) {
return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom domain should not belong to subdomain_host", proxyServer.Name)
}
proxyServer.CustomDomains[i] = domain
} }
} else { } else {
return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals http", proxyServer.Name) return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type is http", proxyServer.Name)
} }
} else if proxyServer.Type == "https" { } else if proxyServer.Type == "https" {
// for https // for https
@ -304,13 +312,17 @@ func loadProxyConf(confFile string) (proxyServers map[string]*ProxyServer, err e
if ok { if ok {
proxyServer.CustomDomains = strings.Split(domainStr, ",") proxyServer.CustomDomains = strings.Split(domainStr, ",")
if len(proxyServer.CustomDomains) == 0 { if len(proxyServer.CustomDomains) == 0 {
return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals https", proxyServer.Name) return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type is https", proxyServer.Name)
} }
for i, domain := range proxyServer.CustomDomains { for i, domain := range proxyServer.CustomDomains {
proxyServer.CustomDomains[i] = strings.ToLower(strings.TrimSpace(domain)) domain = strings.ToLower(strings.TrimSpace(domain))
if SubDomainHost != "" && strings.Contains(domain, SubDomainHost) {
return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom domain should not belong to subdomain_host", proxyServer.Name)
}
proxyServer.CustomDomains[i] = domain
} }
} else { } else {
return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type equals https", proxyServer.Name) return proxyServers, fmt.Errorf("Parse conf error: proxy [%s] custom_domains must be set when type is https", proxyServer.Name)
} }
} }
proxyServers[proxyServer.Name] = proxyServer proxyServers[proxyServer.Name] = proxyServer

View File

@ -34,7 +34,6 @@ func RunDashboardServer(addr string, port int64) (err error) {
// url router // url router
mux := http.NewServeMux() mux := http.NewServeMux()
// api, see dashboard_api.go // api, see dashboard_api.go
// mux.HandleFunc("/api/reload", apiReload)
mux.HandleFunc("/api/reload", use(apiReload, basicAuth)) mux.HandleFunc("/api/reload", use(apiReload, basicAuth))
mux.HandleFunc("/api/proxies", apiProxies) mux.HandleFunc("/api/proxies", apiProxies)