Skip to content

Commit 218b354

Browse files
authored
Server Dashboard SSL Support (fatedier#2982)
1 parent c652b8e commit 218b354

File tree

5 files changed

+93
-28
lines changed

5 files changed

+93
-28
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,21 @@ dashboard_pwd = admin
477477

478478
Then visit `http://[server_addr]:7500` to see the dashboard, with username and password both being `admin`.
479479

480+
Additionally, you can use HTTPS port by using your domains wildcard or normal SSL certificate:
481+
482+
```ini
483+
[common]
484+
dashboard_port = 7500
485+
# dashboard's username and password are both optional
486+
dashboard_user = admin
487+
dashboard_pwd = admin
488+
dashboard_tls_mode = true
489+
dashboard_tls_cert_file = server.crt
490+
dashboard_tls_key_file = server.key
491+
```
492+
493+
Then visit `https://[server_addr]:7500` to see the dashboard in secure HTTPS connection, with username and password both being `admin`.
494+
480495
![dashboard](/doc/pic/dashboard.png)
481496

482497
### Admin UI

cmd/frps/root.go

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,31 +37,34 @@ var (
3737
cfgFile string
3838
showVersion bool
3939

40-
bindAddr string
41-
bindPort int
42-
bindUDPPort int
43-
kcpBindPort int
44-
proxyBindAddr string
45-
vhostHTTPPort int
46-
vhostHTTPSPort int
47-
vhostHTTPTimeout int64
48-
dashboardAddr string
49-
dashboardPort int
50-
dashboardUser string
51-
dashboardPwd string
52-
enablePrometheus bool
53-
assetsDir string
54-
logFile string
55-
logLevel string
56-
logMaxDays int64
57-
disableLogColor bool
58-
token string
59-
subDomainHost string
60-
tcpMux bool
61-
allowPorts string
62-
maxPoolCount int64
63-
maxPortsPerClient int64
64-
tlsOnly bool
40+
bindAddr string
41+
bindPort int
42+
bindUDPPort int
43+
kcpBindPort int
44+
proxyBindAddr string
45+
vhostHTTPPort int
46+
vhostHTTPSPort int
47+
vhostHTTPTimeout int64
48+
dashboardAddr string
49+
dashboardPort int
50+
dashboardUser string
51+
dashboardPwd string
52+
enablePrometheus bool
53+
assetsDir string
54+
logFile string
55+
logLevel string
56+
logMaxDays int64
57+
disableLogColor bool
58+
token string
59+
subDomainHost string
60+
tcpMux bool
61+
allowPorts string
62+
maxPoolCount int64
63+
maxPortsPerClient int64
64+
tlsOnly bool
65+
dashboardTLSMode bool
66+
dashboardTLSCertFile string
67+
dashboardTLSKeyFile string
6568
)
6669

6770
func init() {
@@ -91,6 +94,9 @@ func init() {
9194
rootCmd.PersistentFlags().StringVarP(&allowPorts, "allow_ports", "", "", "allow ports")
9295
rootCmd.PersistentFlags().Int64VarP(&maxPortsPerClient, "max_ports_per_client", "", 0, "max ports per client")
9396
rootCmd.PersistentFlags().BoolVarP(&tlsOnly, "tls_only", "", false, "frps tls only")
97+
rootCmd.PersistentFlags().BoolVarP(&dashboardTLSMode, "dashboard_tls_mode", "", false, "dashboard tls mode")
98+
rootCmd.PersistentFlags().StringVarP(&dashboardTLSCertFile, "dashboard_tls_cert_file", "", "", "dashboard tls cert file")
99+
rootCmd.PersistentFlags().StringVarP(&dashboardTLSKeyFile, "dashboard_tls_key_file", "", "", "dashboard tls key file")
94100
}
95101

96102
var rootCmd = &cobra.Command{
@@ -167,6 +173,9 @@ func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) {
167173
cfg.DashboardUser = dashboardUser
168174
cfg.DashboardPwd = dashboardPwd
169175
cfg.EnablePrometheus = enablePrometheus
176+
cfg.DashboardTLSCertFile = dashboardTLSCertFile
177+
cfg.DashboardTLSKeyFile = dashboardTLSKeyFile
178+
cfg.DashboardTLSMode = dashboardTLSMode
170179
cfg.LogFile = logFile
171180
cfg.LogLevel = logLevel
172181
cfg.LogMaxDays = logMaxDays

conf/frps_full.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ dashboard_port = 7500
4343
dashboard_user = admin
4444
dashboard_pwd = admin
4545

46+
# dashboard TLS mode
47+
dashboard_tls_mode = false
48+
# dashboard_tls_cert_file = server.crt
49+
# dashboard_tls_key_file = server.key
50+
4651
# enable_prometheus will export prometheus metrics on {dashboard_addr}:{dashboard_port} in /metrics api.
4752
enable_prometheus = true
4853

pkg/config/server.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,17 @@ type ServerCommonConf struct {
7474
// value is 0, the dashboard will not be started. By default, this value is
7575
// 0.
7676
DashboardPort int `ini:"dashboard_port" json:"dashboard_port" validate:"gte=0,lte=65535"`
77+
// DashboardTLSCertFile specifies the path of the cert file that the server will
78+
// load. If "dashboard_tls_cert_file", "dashboard_tls_key_file" are valid, the server will use this
79+
// supplied tls configuration.
80+
DashboardTLSCertFile string `ini:"dashboard_tls_cert_file" json:"dashboard_tls_cert_file"`
81+
// DashboardTLSKeyFile specifies the path of the secret key that the server will
82+
// load. If "dashboard_tls_cert_file", "dashboard_tls_key_file" are valid, the server will use this
83+
// supplied tls configuration.
84+
DashboardTLSKeyFile string `ini:"dashboard_tls_key_file" json:"dashboard_tls_key_file"`
85+
// DashboardTLSMode specifies the mode of the dashboard between HTTP or HTTPS modes. By
86+
// default, this value is false, which is HTTP mode.
87+
DashboardTLSMode bool `ini:"dashboard_tls_mode" json:"dashboard_tls_mode"`
7788
// DashboardUser specifies the username that the dashboard will use for
7889
// login.
7990
DashboardUser string `ini:"dashboard_user" json:"dashboard_user"`
@@ -297,6 +308,23 @@ func (cfg *ServerCommonConf) Complete() {
297308
}
298309

299310
func (cfg *ServerCommonConf) Validate() error {
311+
if cfg.DashboardTLSMode == false {
312+
if cfg.DashboardTLSCertFile != "" {
313+
fmt.Println("WARNING! dashboard_tls_cert_file is invalid when dashboard_tls_mode is false")
314+
}
315+
316+
if cfg.DashboardTLSKeyFile != "" {
317+
fmt.Println("WARNING! dashboard_tls_key_file is invalid when dashboard_tls_mode is false")
318+
}
319+
} else {
320+
if cfg.DashboardTLSCertFile == "" {
321+
return fmt.Errorf("ERROR! dashboard_tls_cert_file must be specified when dashboard_tls_mode is true")
322+
}
323+
324+
if cfg.DashboardTLSKeyFile == "" {
325+
return fmt.Errorf("ERROR! dashboard_tls_cert_file must be specified when dashboard_tls_mode is true")
326+
}
327+
}
300328
return validator.New().Struct(cfg)
301329
}
302330

server/dashboard.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
package server
1616

1717
import (
18+
"crypto/tls"
1819
"net"
1920
"net/http"
2021
"net/http/pprof"
@@ -76,14 +77,21 @@ func (svr *Service) RunDashboardServer(address string) (err error) {
7677
ReadTimeout: httpServerReadTimeout,
7778
WriteTimeout: httpServerWriteTimeout,
7879
}
79-
if address == "" || address == ":" {
80-
address = ":http"
81-
}
8280
ln, err := net.Listen("tcp", address)
8381
if err != nil {
8482
return err
8583
}
8684

85+
if svr.cfg.DashboardTLSMode {
86+
cert, err := tls.LoadX509KeyPair(svr.cfg.DashboardTLSCertFile, svr.cfg.DashboardTLSKeyFile)
87+
if err != nil {
88+
return err
89+
}
90+
tlsCfg := &tls.Config{
91+
Certificates: []tls.Certificate{cert},
92+
}
93+
ln = tls.NewListener(ln, tlsCfg)
94+
}
8795
go server.Serve(ln)
8896
return
8997
}

0 commit comments

Comments
 (0)