diff --git a/cmd/frps/root.go b/cmd/frps/root.go
index abad271f..4ab1edf0 100644
--- a/cmd/frps/root.go
+++ b/cmd/frps/root.go
@@ -20,7 +20,6 @@ import (
 
 	"github.com/spf13/cobra"
 
-	"github.com/fatedier/frp/g"
 	"github.com/fatedier/frp/models/config"
 	"github.com/fatedier/frp/server"
 	"github.com/fatedier/frp/utils/log"
@@ -98,6 +97,7 @@ var rootCmd = &cobra.Command{
 			return nil
 		}
 
+		var cfg config.ServerCommonConf
 		var err error
 		if cfgFile != "" {
 			var content string
@@ -105,16 +105,15 @@ var rootCmd = &cobra.Command{
 			if err != nil {
 				return err
 			}
-			g.GlbServerCfg.CfgFile = cfgFile
-			err = parseServerCommonCfg(CfgFileTypeIni, content)
+			cfg, err = parseServerCommonCfg(CfgFileTypeIni, content)
 		} else {
-			err = parseServerCommonCfg(CfgFileTypeCmd, "")
+			cfg, err = parseServerCommonCfg(CfgFileTypeCmd, "")
 		}
 		if err != nil {
 			return err
 		}
 
-		err = runServer()
+		err = runServer(cfg)
 		if err != nil {
 			fmt.Println(err)
 			os.Exit(1)
@@ -129,52 +128,51 @@ func Execute() {
 	}
 }
 
-func parseServerCommonCfg(fileType int, content string) (err error) {
+func parseServerCommonCfg(fileType int, content string) (cfg config.ServerCommonConf, err error) {
 	if fileType == CfgFileTypeIni {
-		err = parseServerCommonCfgFromIni(content)
+		cfg, err = parseServerCommonCfgFromIni(content)
 	} else if fileType == CfgFileTypeCmd {
-		err = parseServerCommonCfgFromCmd()
+		cfg, err = parseServerCommonCfgFromCmd()
 	}
 	if err != nil {
 		return
 	}
 
-	err = g.GlbServerCfg.ServerCommonConf.Check()
+	err = cfg.Check()
 	if err != nil {
 		return
 	}
-
-	config.InitServerCfg(&g.GlbServerCfg.ServerCommonConf)
 	return
 }
 
-func parseServerCommonCfgFromIni(content string) (err error) {
-	cfg, err := config.UnmarshalServerConfFromIni(&g.GlbServerCfg.ServerCommonConf, content)
+func parseServerCommonCfgFromIni(content string) (config.ServerCommonConf, error) {
+	cfg, err := config.UnmarshalServerConfFromIni(content)
 	if err != nil {
-		return err
+		return config.ServerCommonConf{}, err
 	}
-	g.GlbServerCfg.ServerCommonConf = *cfg
-	return
+	return cfg, nil
 }
 
-func parseServerCommonCfgFromCmd() (err error) {
-	g.GlbServerCfg.BindAddr = bindAddr
-	g.GlbServerCfg.BindPort = bindPort
-	g.GlbServerCfg.BindUdpPort = bindUdpPort
-	g.GlbServerCfg.KcpBindPort = kcpBindPort
-	g.GlbServerCfg.ProxyBindAddr = proxyBindAddr
-	g.GlbServerCfg.VhostHttpPort = vhostHttpPort
-	g.GlbServerCfg.VhostHttpsPort = vhostHttpsPort
-	g.GlbServerCfg.VhostHttpTimeout = vhostHttpTimeout
-	g.GlbServerCfg.DashboardAddr = dashboardAddr
-	g.GlbServerCfg.DashboardPort = dashboardPort
-	g.GlbServerCfg.DashboardUser = dashboardUser
-	g.GlbServerCfg.DashboardPwd = dashboardPwd
-	g.GlbServerCfg.LogFile = logFile
-	g.GlbServerCfg.LogLevel = logLevel
-	g.GlbServerCfg.LogMaxDays = logMaxDays
-	g.GlbServerCfg.Token = token
-	g.GlbServerCfg.SubDomainHost = subDomainHost
+func parseServerCommonCfgFromCmd() (cfg config.ServerCommonConf, err error) {
+	cfg = config.GetDefaultServerConf()
+
+	cfg.BindAddr = bindAddr
+	cfg.BindPort = bindPort
+	cfg.BindUdpPort = bindUdpPort
+	cfg.KcpBindPort = kcpBindPort
+	cfg.ProxyBindAddr = proxyBindAddr
+	cfg.VhostHttpPort = vhostHttpPort
+	cfg.VhostHttpsPort = vhostHttpsPort
+	cfg.VhostHttpTimeout = vhostHttpTimeout
+	cfg.DashboardAddr = dashboardAddr
+	cfg.DashboardPort = dashboardPort
+	cfg.DashboardUser = dashboardUser
+	cfg.DashboardPwd = dashboardPwd
+	cfg.LogFile = logFile
+	cfg.LogLevel = logLevel
+	cfg.LogMaxDays = logMaxDays
+	cfg.Token = token
+	cfg.SubDomainHost = subDomainHost
 	if len(allowPorts) > 0 {
 		// e.g. 1000-2000,2001,2002,3000-4000
 		ports, errRet := util.ParseRangeNumbers(allowPorts)
@@ -184,24 +182,23 @@ func parseServerCommonCfgFromCmd() (err error) {
 		}
 
 		for _, port := range ports {
-			g.GlbServerCfg.AllowPorts[int(port)] = struct{}{}
+			cfg.AllowPorts[int(port)] = struct{}{}
 		}
 	}
-	g.GlbServerCfg.MaxPortsPerClient = maxPortsPerClient
+	cfg.MaxPortsPerClient = maxPortsPerClient
 
 	if logFile == "console" {
-		g.GlbServerCfg.LogWay = "console"
+		cfg.LogWay = "console"
 	} else {
-		g.GlbServerCfg.LogWay = "file"
+		cfg.LogWay = "file"
 	}
-	g.GlbServerCfg.DisableLogColor = disableLogColor
+	cfg.DisableLogColor = disableLogColor
 	return
 }
 
-func runServer() (err error) {
-	log.InitLog(g.GlbServerCfg.LogWay, g.GlbServerCfg.LogFile, g.GlbServerCfg.LogLevel,
-		g.GlbServerCfg.LogMaxDays, g.GlbServerCfg.DisableLogColor)
-	svr, err := server.NewService()
+func runServer(cfg config.ServerCommonConf) (err error) {
+	log.InitLog(cfg.LogWay, cfg.LogFile, cfg.LogLevel, cfg.LogMaxDays, cfg.DisableLogColor)
+	svr, err := server.NewService(cfg)
 	if err != nil {
 		return err
 	}
diff --git a/g/g.go b/g/g.go
index 3c7385f1..ecd2471d 100644
--- a/g/g.go
+++ b/g/g.go
@@ -6,16 +6,12 @@ import (
 
 var (
 	GlbClientCfg *ClientCfg
-	GlbServerCfg *ServerCfg
 )
 
 func init() {
 	GlbClientCfg = &ClientCfg{
 		ClientCommonConf: *config.GetDefaultClientConf(),
 	}
-	GlbServerCfg = &ServerCfg{
-		ServerCommonConf: *config.GetDefaultServerConf(),
-	}
 }
 
 type ClientCfg struct {
@@ -24,9 +20,3 @@ type ClientCfg struct {
 	CfgFile       string
 	ServerUdpPort int // this is configured by login response from frps
 }
-
-type ServerCfg struct {
-	config.ServerCommonConf
-
-	CfgFile string
-}
diff --git a/go.sum b/go.sum
index 3eeac454..5ddda4ef 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,6 @@
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb h1:wCrNShQidLmvVWn/0PikGmpdP0vtQmnvyRg3ZBEhczw=
 github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb/go.mod h1:wx3gB6dbIfBRcucp94PI9Bt3I0F2c/MyNEWuhzpWiwk=
@@ -27,6 +28,7 @@ github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc h1:lNOt1SMsgHX
 github.com/pires/go-proxyproto v0.0.0-20190111085350-4d51b51e3bfc/go.mod h1:6/gX3+E/IYGa0wMORlSMla999awQFdbaeQCHjSMKIzY=
 github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/rakyll/statik v0.1.1 h1:fCLHsIMajHqD5RKigbFXpvX3dN7c80Pm12+NCrI3kvg=
 github.com/rakyll/statik v0.1.1/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs=
diff --git a/models/config/proxy.go b/models/config/proxy.go
index a27416f9..758d5631 100644
--- a/models/config/proxy.go
+++ b/models/config/proxy.go
@@ -58,11 +58,11 @@ type ProxyConf interface {
 	UnmarshalFromIni(prefix string, name string, conf ini.Section) error
 	MarshalToMsg(pMsg *msg.NewProxy)
 	CheckForCli() error
-	CheckForSvr() error
+	CheckForSvr(serverCfg ServerCommonConf) error
 	Compare(conf ProxyConf) bool
 }
 
-func NewProxyConfFromMsg(pMsg *msg.NewProxy) (cfg ProxyConf, err error) {
+func NewProxyConfFromMsg(pMsg *msg.NewProxy, serverCfg ServerCommonConf) (cfg ProxyConf, err error) {
 	if pMsg.ProxyType == "" {
 		pMsg.ProxyType = consts.TcpProxy
 	}
@@ -73,7 +73,7 @@ func NewProxyConfFromMsg(pMsg *msg.NewProxy) (cfg ProxyConf, err error) {
 		return
 	}
 	cfg.UnmarshalFromMsg(pMsg)
-	err = cfg.CheckForSvr()
+	err = cfg.CheckForSvr(serverCfg)
 	return
 }
 
@@ -308,21 +308,21 @@ func (cfg *DomainConf) checkForCli() (err error) {
 	return
 }
 
-func (cfg *DomainConf) checkForSvr() (err error) {
+func (cfg *DomainConf) checkForSvr(serverCfg ServerCommonConf) (err error) {
 	if err = cfg.check(); err != nil {
 		return
 	}
 
 	for _, domain := range cfg.CustomDomains {
-		if subDomainHost != "" && len(strings.Split(subDomainHost, ".")) < len(strings.Split(domain, ".")) {
-			if strings.Contains(domain, subDomainHost) {
-				return fmt.Errorf("custom domain [%s] should not belong to subdomain_host [%s]", domain, subDomainHost)
+		if serverCfg.SubDomainHost != "" && len(strings.Split(serverCfg.SubDomainHost, ".")) < len(strings.Split(domain, ".")) {
+			if strings.Contains(domain, serverCfg.SubDomainHost) {
+				return fmt.Errorf("custom domain [%s] should not belong to subdomain_host [%s]", domain, serverCfg.SubDomainHost)
 			}
 		}
 	}
 
 	if cfg.SubDomain != "" {
-		if subDomainHost == "" {
+		if serverCfg.SubDomainHost == "" {
 			return fmt.Errorf("subdomain is not supported because this feature is not enabled in remote frps")
 		}
 		if strings.Contains(cfg.SubDomain, ".") || strings.Contains(cfg.SubDomain, "*") {
@@ -504,7 +504,7 @@ func (cfg *TcpProxyConf) CheckForCli() (err error) {
 	return
 }
 
-func (cfg *TcpProxyConf) CheckForSvr() error { return nil }
+func (cfg *TcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
 
 // UDP
 type UdpProxyConf struct {
@@ -552,7 +552,7 @@ func (cfg *UdpProxyConf) CheckForCli() (err error) {
 	return
 }
 
-func (cfg *UdpProxyConf) CheckForSvr() error { return nil }
+func (cfg *UdpProxyConf) CheckForSvr(serverCfg ServerCommonConf) error { return nil }
 
 // HTTP
 type HttpProxyConf struct {
@@ -657,11 +657,11 @@ func (cfg *HttpProxyConf) CheckForCli() (err error) {
 	return
 }
 
-func (cfg *HttpProxyConf) CheckForSvr() (err error) {
-	if vhostHttpPort == 0 {
+func (cfg *HttpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
+	if serverCfg.VhostHttpPort == 0 {
 		return fmt.Errorf("type [http] not support when vhost_http_port is not set")
 	}
-	if err = cfg.DomainConf.checkForSvr(); err != nil {
+	if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
 		err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
 		return
 	}
@@ -717,11 +717,11 @@ func (cfg *HttpsProxyConf) CheckForCli() (err error) {
 	return
 }
 
-func (cfg *HttpsProxyConf) CheckForSvr() (err error) {
-	if vhostHttpsPort == 0 {
+func (cfg *HttpsProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
+	if serverCfg.VhostHttpsPort == 0 {
 		return fmt.Errorf("type [https] not support when vhost_https_port is not set")
 	}
-	if err = cfg.DomainConf.checkForSvr(); err != nil {
+	if err = cfg.DomainConf.checkForSvr(serverCfg); err != nil {
 		err = fmt.Errorf("proxy [%s] domain conf check error: %v", cfg.ProxyName, err)
 		return
 	}
@@ -790,7 +790,7 @@ func (cfg *StcpProxyConf) CheckForCli() (err error) {
 	return
 }
 
-func (cfg *StcpProxyConf) CheckForSvr() (err error) {
+func (cfg *StcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
 	return
 }
 
@@ -857,7 +857,7 @@ func (cfg *XtcpProxyConf) CheckForCli() (err error) {
 	return
 }
 
-func (cfg *XtcpProxyConf) CheckForSvr() (err error) {
+func (cfg *XtcpProxyConf) CheckForSvr(serverCfg ServerCommonConf) (err error) {
 	return
 }
 
diff --git a/models/config/server_common.go b/models/config/server_common.go
index 8e54f24b..8a486fba 100644
--- a/models/config/server_common.go
+++ b/models/config/server_common.go
@@ -24,21 +24,6 @@ import (
 	"github.com/fatedier/frp/utils/util"
 )
 
-var (
-	// server global configure used for generate proxy conf used in frps
-	proxyBindAddr  string
-	subDomainHost  string
-	vhostHttpPort  int
-	vhostHttpsPort int
-)
-
-func InitServerCfg(cfg *ServerCommonConf) {
-	proxyBindAddr = cfg.ProxyBindAddr
-	subDomainHost = cfg.SubDomainHost
-	vhostHttpPort = cfg.VhostHttpPort
-	vhostHttpsPort = cfg.VhostHttpsPort
-}
-
 // common config
 type ServerCommonConf struct {
 	BindAddr      string `json:"bind_addr"`
@@ -79,8 +64,8 @@ type ServerCommonConf struct {
 	UserConnTimeout   int64 `json:"user_conn_timeout"`
 }
 
-func GetDefaultServerConf() *ServerCommonConf {
-	return &ServerCommonConf{
+func GetDefaultServerConf() ServerCommonConf {
+	return ServerCommonConf{
 		BindAddr:          "0.0.0.0",
 		BindPort:          7000,
 		BindUdpPort:       0,
@@ -111,16 +96,13 @@ func GetDefaultServerConf() *ServerCommonConf {
 	}
 }
 
-func UnmarshalServerConfFromIni(defaultCfg *ServerCommonConf, content string) (cfg *ServerCommonConf, err error) {
-	cfg = defaultCfg
-	if cfg == nil {
-		cfg = GetDefaultServerConf()
-	}
+func UnmarshalServerConfFromIni(content string) (cfg ServerCommonConf, err error) {
+	cfg = GetDefaultServerConf()
 
 	conf, err := ini.Load(strings.NewReader(content))
 	if err != nil {
 		err = fmt.Errorf("parse ini conf file error: %v", err)
-		return nil, err
+		return ServerCommonConf{}, err
 	}
 
 	var (
diff --git a/server/control.go b/server/control.go
index 8374ab20..4e13cf2a 100644
--- a/server/control.go
+++ b/server/control.go
@@ -21,7 +21,6 @@ import (
 	"sync"
 	"time"
 
-	"github.com/fatedier/frp/g"
 	"github.com/fatedier/frp/models/config"
 	"github.com/fatedier/frp/models/consts"
 	frpErr "github.com/fatedier/frp/models/errors"
@@ -129,10 +128,14 @@ type Control struct {
 	allShutdown     *shutdown.Shutdown
 
 	mu sync.RWMutex
+
+	// Server configuration information
+	serverCfg config.ServerCommonConf
 }
 
 func NewControl(rc *controller.ResourceController, pxyManager *proxy.ProxyManager,
-	statsCollector stats.Collector, ctlConn net.Conn, loginMsg *msg.Login) *Control {
+	statsCollector stats.Collector, ctlConn net.Conn, loginMsg *msg.Login,
+	serverCfg config.ServerCommonConf) *Control {
 
 	return &Control{
 		rc:              rc,
@@ -153,6 +156,7 @@ func NewControl(rc *controller.ResourceController, pxyManager *proxy.ProxyManage
 		writerShutdown:  shutdown.New(),
 		managerShutdown: shutdown.New(),
 		allShutdown:     shutdown.New(),
+		serverCfg:       serverCfg,
 	}
 }
 
@@ -161,7 +165,7 @@ func (ctl *Control) Start() {
 	loginRespMsg := &msg.LoginResp{
 		Version:       version.Full(),
 		RunId:         ctl.runId,
-		ServerUdpPort: g.GlbServerCfg.BindUdpPort,
+		ServerUdpPort: ctl.serverCfg.BindUdpPort,
 		Error:         "",
 	}
 	msg.WriteMsg(ctl.conn, loginRespMsg)
@@ -232,7 +236,7 @@ func (ctl *Control) GetWorkConn() (workConn net.Conn, err error) {
 				return
 			}
 
-		case <-time.After(time.Duration(g.GlbServerCfg.UserConnTimeout) * time.Second):
+		case <-time.After(time.Duration(ctl.serverCfg.UserConnTimeout) * time.Second):
 			err = fmt.Errorf("timeout trying to get work connection")
 			ctl.conn.Warn("%v", err)
 			return
@@ -263,7 +267,7 @@ func (ctl *Control) writer() {
 	defer ctl.allShutdown.Start()
 	defer ctl.writerShutdown.Done()
 
-	encWriter, err := crypto.NewWriter(ctl.conn, []byte(g.GlbServerCfg.Token))
+	encWriter, err := crypto.NewWriter(ctl.conn, []byte(ctl.serverCfg.Token))
 	if err != nil {
 		ctl.conn.Error("crypto new writer error: %v", err)
 		ctl.allShutdown.Start()
@@ -293,7 +297,7 @@ func (ctl *Control) reader() {
 	defer ctl.allShutdown.Start()
 	defer ctl.readerShutdown.Done()
 
-	encReader := crypto.NewReader(ctl.conn, []byte(g.GlbServerCfg.Token))
+	encReader := crypto.NewReader(ctl.conn, []byte(ctl.serverCfg.Token))
 	for {
 		if m, err := msg.ReadMsg(encReader); err != nil {
 			if err == io.EOF {
@@ -374,7 +378,7 @@ func (ctl *Control) manager() {
 	for {
 		select {
 		case <-heartbeat.C:
-			if time.Since(ctl.lastPing) > time.Duration(g.GlbServerCfg.HeartBeatTimeout)*time.Second {
+			if time.Since(ctl.lastPing) > time.Duration(ctl.serverCfg.HeartBeatTimeout)*time.Second {
 				ctl.conn.Warn("heartbeat timeout")
 				return
 			}
@@ -417,22 +421,22 @@ func (ctl *Control) manager() {
 func (ctl *Control) RegisterProxy(pxyMsg *msg.NewProxy) (remoteAddr string, err error) {
 	var pxyConf config.ProxyConf
 	// Load configures from NewProxy message and check.
-	pxyConf, err = config.NewProxyConfFromMsg(pxyMsg)
+	pxyConf, err = config.NewProxyConfFromMsg(pxyMsg, ctl.serverCfg)
 	if err != nil {
 		return
 	}
 
 	// NewProxy will return a interface Proxy.
 	// In fact it create different proxies by different proxy type, we just call run() here.
-	pxy, err := proxy.NewProxy(ctl.runId, ctl.rc, ctl.statsCollector, ctl.poolCount, ctl.GetWorkConn, pxyConf)
+	pxy, err := proxy.NewProxy(ctl.runId, ctl.rc, ctl.statsCollector, ctl.poolCount, ctl.GetWorkConn, pxyConf, ctl.serverCfg)
 	if err != nil {
 		return remoteAddr, err
 	}
 
 	// Check ports used number in each client
-	if g.GlbServerCfg.MaxPortsPerClient > 0 {
+	if ctl.serverCfg.MaxPortsPerClient > 0 {
 		ctl.mu.Lock()
-		if ctl.portsUsedNum+pxy.GetUsedPortsNum() > int(g.GlbServerCfg.MaxPortsPerClient) {
+		if ctl.portsUsedNum+pxy.GetUsedPortsNum() > int(ctl.serverCfg.MaxPortsPerClient) {
 			ctl.mu.Unlock()
 			err = fmt.Errorf("exceed the max_ports_per_client")
 			return
@@ -478,7 +482,7 @@ func (ctl *Control) CloseProxy(closeMsg *msg.CloseProxy) (err error) {
 		return
 	}
 
-	if g.GlbServerCfg.MaxPortsPerClient > 0 {
+	if ctl.serverCfg.MaxPortsPerClient > 0 {
 		ctl.portsUsedNum = ctl.portsUsedNum - pxy.GetUsedPortsNum()
 	}
 	pxy.Close()
diff --git a/server/dashboard.go b/server/dashboard.go
index d682aeb9..0a65dbb2 100644
--- a/server/dashboard.go
+++ b/server/dashboard.go
@@ -21,7 +21,6 @@ import (
 	"time"
 
 	"github.com/fatedier/frp/assets"
-	"github.com/fatedier/frp/g"
 	frpNet "github.com/fatedier/frp/utils/net"
 
 	"github.com/gorilla/mux"
@@ -36,7 +35,7 @@ func (svr *Service) RunDashboardServer(addr string, port int) (err error) {
 	// url router
 	router := mux.NewRouter()
 
-	user, passwd := g.GlbServerCfg.DashboardUser, g.GlbServerCfg.DashboardPwd
+	user, passwd := svr.cfg.DashboardUser, svr.cfg.DashboardPwd
 	router.Use(frpNet.NewHttpAuthMiddleware(user, passwd).Middleware)
 
 	// api, see dashboard_api.go
diff --git a/server/dashboard_api.go b/server/dashboard_api.go
index dcea7e61..30ee9a68 100644
--- a/server/dashboard_api.go
+++ b/server/dashboard_api.go
@@ -18,7 +18,6 @@ import (
 	"encoding/json"
 	"net/http"
 
-	"github.com/fatedier/frp/g"
 	"github.com/fatedier/frp/models/config"
 	"github.com/fatedier/frp/models/consts"
 	"github.com/fatedier/frp/utils/log"
@@ -63,19 +62,18 @@ func (svr *Service) ApiServerInfo(w http.ResponseWriter, r *http.Request) {
 	}()
 
 	log.Info("Http request: [%s]", r.URL.Path)
-	cfg := &g.GlbServerCfg.ServerCommonConf
 	serverStats := svr.statsCollector.GetServer()
 	svrResp := ServerInfoResp{
 		Version:           version.Full(),
-		BindPort:          cfg.BindPort,
-		BindUdpPort:       cfg.BindUdpPort,
-		VhostHttpPort:     cfg.VhostHttpPort,
-		VhostHttpsPort:    cfg.VhostHttpsPort,
-		KcpBindPort:       cfg.KcpBindPort,
-		SubdomainHost:     cfg.SubDomainHost,
-		MaxPoolCount:      cfg.MaxPoolCount,
-		MaxPortsPerClient: cfg.MaxPortsPerClient,
-		HeartBeatTimeout:  cfg.HeartBeatTimeout,
+		BindPort:          svr.cfg.BindPort,
+		BindUdpPort:       svr.cfg.BindUdpPort,
+		VhostHttpPort:     svr.cfg.VhostHttpPort,
+		VhostHttpsPort:    svr.cfg.VhostHttpsPort,
+		KcpBindPort:       svr.cfg.KcpBindPort,
+		SubdomainHost:     svr.cfg.SubDomainHost,
+		MaxPoolCount:      svr.cfg.MaxPoolCount,
+		MaxPortsPerClient: svr.cfg.MaxPortsPerClient,
+		HeartBeatTimeout:  svr.cfg.HeartBeatTimeout,
 
 		TotalTrafficIn:  serverStats.TotalTrafficIn,
 		TotalTrafficOut: serverStats.TotalTrafficOut,
diff --git a/server/proxy/http.go b/server/proxy/http.go
index 1fa8765e..5bd3139d 100644
--- a/server/proxy/http.go
+++ b/server/proxy/http.go
@@ -19,7 +19,6 @@ import (
 	"net"
 	"strings"
 
-	"github.com/fatedier/frp/g"
 	"github.com/fatedier/frp/models/config"
 	"github.com/fatedier/frp/server/stats"
 	frpNet "github.com/fatedier/frp/utils/net"
@@ -88,13 +87,13 @@ func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
 					pxy.rc.HttpReverseProxy.UnRegister(tmpDomain, tmpLocation)
 				})
 			}
-			addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(g.GlbServerCfg.VhostHttpPort)))
+			addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(pxy.serverCfg.VhostHttpPort)))
 			pxy.Info("http proxy listen for host [%s] location [%s] group [%s]", routeConfig.Domain, routeConfig.Location, pxy.cfg.Group)
 		}
 	}
 
 	if pxy.cfg.SubDomain != "" {
-		routeConfig.Domain = pxy.cfg.SubDomain + "." + g.GlbServerCfg.SubDomainHost
+		routeConfig.Domain = pxy.cfg.SubDomain + "." + pxy.serverCfg.SubDomainHost
 		for _, location := range locations {
 			routeConfig.Location = location
 			tmpDomain := routeConfig.Domain
@@ -119,7 +118,7 @@ func (pxy *HttpProxy) Run() (remoteAddr string, err error) {
 					pxy.rc.HttpReverseProxy.UnRegister(tmpDomain, tmpLocation)
 				})
 			}
-			addrs = append(addrs, util.CanonicalAddr(tmpDomain, g.GlbServerCfg.VhostHttpPort))
+			addrs = append(addrs, util.CanonicalAddr(tmpDomain, pxy.serverCfg.VhostHttpPort))
 
 			pxy.Info("http proxy listen for host [%s] location [%s] group [%s]", routeConfig.Domain, routeConfig.Location, pxy.cfg.Group)
 		}
@@ -147,7 +146,7 @@ func (pxy *HttpProxy) GetRealConn(remoteAddr string) (workConn frpNet.Conn, err
 
 	var rwc io.ReadWriteCloser = tmpConn
 	if pxy.cfg.UseEncryption {
-		rwc, err = frpIo.WithEncryption(rwc, []byte(g.GlbServerCfg.Token))
+		rwc, err = frpIo.WithEncryption(rwc, []byte(pxy.serverCfg.Token))
 		if err != nil {
 			pxy.Error("create encryption stream error: %v", err)
 			return
diff --git a/server/proxy/https.go b/server/proxy/https.go
index cb5ce928..87840421 100644
--- a/server/proxy/https.go
+++ b/server/proxy/https.go
@@ -17,7 +17,6 @@ package proxy
 import (
 	"strings"
 
-	"github.com/fatedier/frp/g"
 	"github.com/fatedier/frp/models/config"
 	"github.com/fatedier/frp/utils/util"
 	"github.com/fatedier/frp/utils/vhost"
@@ -51,11 +50,11 @@ func (pxy *HttpsProxy) Run() (remoteAddr string, err error) {
 		l.AddLogPrefix(pxy.name)
 		pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
 		pxy.listeners = append(pxy.listeners, l)
-		addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, g.GlbServerCfg.VhostHttpsPort))
+		addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, pxy.serverCfg.VhostHttpsPort))
 	}
 
 	if pxy.cfg.SubDomain != "" {
-		routeConfig.Domain = pxy.cfg.SubDomain + "." + g.GlbServerCfg.SubDomainHost
+		routeConfig.Domain = pxy.cfg.SubDomain + "." + pxy.serverCfg.SubDomainHost
 		l, errRet := pxy.rc.VhostHttpsMuxer.Listen(routeConfig)
 		if errRet != nil {
 			err = errRet
@@ -64,7 +63,7 @@ func (pxy *HttpsProxy) Run() (remoteAddr string, err error) {
 		l.AddLogPrefix(pxy.name)
 		pxy.Info("https proxy listen for host [%s]", routeConfig.Domain)
 		pxy.listeners = append(pxy.listeners, l)
-		addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(g.GlbServerCfg.VhostHttpsPort)))
+		addrs = append(addrs, util.CanonicalAddr(routeConfig.Domain, int(pxy.serverCfg.VhostHttpsPort)))
 	}
 
 	pxy.startListenHandler(pxy, HandleUserTcpConnection)
diff --git a/server/proxy/proxy.go b/server/proxy/proxy.go
index 1a9a28e1..627b0e15 100644
--- a/server/proxy/proxy.go
+++ b/server/proxy/proxy.go
@@ -21,7 +21,6 @@ import (
 	"strconv"
 	"sync"
 
-	"github.com/fatedier/frp/g"
 	"github.com/fatedier/frp/models/config"
 	"github.com/fatedier/frp/models/msg"
 	"github.com/fatedier/frp/server/controller"
@@ -52,6 +51,7 @@ type BaseProxy struct {
 	usedPortsNum   int
 	poolCount      int
 	getWorkConnFn  GetWorkConnFn
+	serverCfg      config.ServerCommonConf
 
 	mu sync.RWMutex
 	log.Logger
@@ -126,7 +126,7 @@ func (pxy *BaseProxy) GetWorkConnFromPool(src, dst net.Addr) (workConn frpNet.Co
 // startListenHandler start a goroutine handler for each listener.
 // p: p will just be passed to handler(Proxy, frpNet.Conn).
 // handler: each proxy type can set different handler function to deal with connections accepted from listeners.
-func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, frpNet.Conn, stats.Collector)) {
+func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, frpNet.Conn, stats.Collector, config.ServerCommonConf)) {
 	for _, listener := range pxy.listeners {
 		go func(l frpNet.Listener) {
 			for {
@@ -138,14 +138,14 @@ func (pxy *BaseProxy) startListenHandler(p Proxy, handler func(Proxy, frpNet.Con
 					return
 				}
 				pxy.Debug("get a user connection [%s]", c.RemoteAddr().String())
-				go handler(p, c, pxy.statsCollector)
+				go handler(p, c, pxy.statsCollector, pxy.serverCfg)
 			}
 		}(listener)
 	}
 }
 
 func NewProxy(runId string, rc *controller.ResourceController, statsCollector stats.Collector, poolCount int,
-	getWorkConnFn GetWorkConnFn, pxyConf config.ProxyConf) (pxy Proxy, err error) {
+	getWorkConnFn GetWorkConnFn, pxyConf config.ProxyConf, serverCfg config.ServerCommonConf) (pxy Proxy, err error) {
 
 	basePxy := BaseProxy{
 		name:           pxyConf.GetBaseInfo().ProxyName,
@@ -155,6 +155,7 @@ func NewProxy(runId string, rc *controller.ResourceController, statsCollector st
 		poolCount:      poolCount,
 		getWorkConnFn:  getWorkConnFn,
 		Logger:         log.NewPrefixLogger(runId),
+		serverCfg:      serverCfg,
 	}
 	switch cfg := pxyConf.(type) {
 	case *config.TcpProxyConf:
@@ -198,7 +199,7 @@ func NewProxy(runId string, rc *controller.ResourceController, statsCollector st
 
 // HandleUserTcpConnection is used for incoming tcp user connections.
 // It can be used for tcp, http, https type.
-func HandleUserTcpConnection(pxy Proxy, userConn frpNet.Conn, statsCollector stats.Collector) {
+func HandleUserTcpConnection(pxy Proxy, userConn frpNet.Conn, statsCollector stats.Collector, serverCfg config.ServerCommonConf) {
 	defer userConn.Close()
 
 	// try all connections from the pool
@@ -211,7 +212,7 @@ func HandleUserTcpConnection(pxy Proxy, userConn frpNet.Conn, statsCollector sta
 	var local io.ReadWriteCloser = workConn
 	cfg := pxy.GetConf().GetBaseInfo()
 	if cfg.UseEncryption {
-		local, err = frpIo.WithEncryption(local, []byte(g.GlbServerCfg.Token))
+		local, err = frpIo.WithEncryption(local, []byte(serverCfg.Token))
 		if err != nil {
 			pxy.Error("create encryption stream error: %v", err)
 			return
diff --git a/server/proxy/tcp.go b/server/proxy/tcp.go
index e00e3a0e..388531a6 100644
--- a/server/proxy/tcp.go
+++ b/server/proxy/tcp.go
@@ -17,7 +17,6 @@ package proxy
 import (
 	"fmt"
 
-	"github.com/fatedier/frp/g"
 	"github.com/fatedier/frp/models/config"
 	frpNet "github.com/fatedier/frp/utils/net"
 )
@@ -31,7 +30,7 @@ type TcpProxy struct {
 
 func (pxy *TcpProxy) Run() (remoteAddr string, err error) {
 	if pxy.cfg.Group != "" {
-		l, realPort, errRet := pxy.rc.TcpGroupCtl.Listen(pxy.name, pxy.cfg.Group, pxy.cfg.GroupKey, g.GlbServerCfg.ProxyBindAddr, pxy.cfg.RemotePort)
+		l, realPort, errRet := pxy.rc.TcpGroupCtl.Listen(pxy.name, pxy.cfg.Group, pxy.cfg.GroupKey, pxy.serverCfg.ProxyBindAddr, pxy.cfg.RemotePort)
 		if errRet != nil {
 			err = errRet
 			return
@@ -56,7 +55,7 @@ func (pxy *TcpProxy) Run() (remoteAddr string, err error) {
 				pxy.rc.TcpPortManager.Release(pxy.realPort)
 			}
 		}()
-		listener, errRet := frpNet.ListenTcp(g.GlbServerCfg.ProxyBindAddr, pxy.realPort)
+		listener, errRet := frpNet.ListenTcp(pxy.serverCfg.ProxyBindAddr, pxy.realPort)
 		if errRet != nil {
 			err = errRet
 			return
diff --git a/server/proxy/udp.go b/server/proxy/udp.go
index b5dd5fbb..453c7b56 100644
--- a/server/proxy/udp.go
+++ b/server/proxy/udp.go
@@ -20,7 +20,6 @@ import (
 	"net"
 	"time"
 
-	"github.com/fatedier/frp/g"
 	"github.com/fatedier/frp/models/config"
 	"github.com/fatedier/frp/models/msg"
 	"github.com/fatedier/frp/models/proto/udp"
@@ -67,7 +66,7 @@ func (pxy *UdpProxy) Run() (remoteAddr string, err error) {
 
 	remoteAddr = fmt.Sprintf(":%d", pxy.realPort)
 	pxy.cfg.RemotePort = pxy.realPort
-	addr, errRet := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", g.GlbServerCfg.ProxyBindAddr, pxy.realPort))
+	addr, errRet := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", pxy.serverCfg.ProxyBindAddr, pxy.realPort))
 	if errRet != nil {
 		err = errRet
 		return
diff --git a/server/service.go b/server/service.go
index e3a1d117..2d16a2b7 100644
--- a/server/service.go
+++ b/server/service.go
@@ -29,7 +29,7 @@ import (
 	"time"
 
 	"github.com/fatedier/frp/assets"
-	"github.com/fatedier/frp/g"
+	"github.com/fatedier/frp/models/config"
 	"github.com/fatedier/frp/models/msg"
 	"github.com/fatedier/frp/models/nathole"
 	"github.com/fatedier/frp/server/controller"
@@ -86,10 +86,11 @@ type Service struct {
 	statsCollector stats.Collector
 
 	tlsConfig *tls.Config
+
+	cfg config.ServerCommonConf
 }
 
-func NewService() (svr *Service, err error) {
-	cfg := &g.GlbServerCfg.ServerCommonConf
+func NewService(cfg config.ServerCommonConf) (svr *Service, err error) {
 	svr = &Service{
 		ctlManager: NewControlManager(),
 		pxyManager: proxy.NewProxyManager(),
@@ -100,6 +101,7 @@ func NewService() (svr *Service, err error) {
 		},
 		httpVhostRouter: vhost.NewVhostRouters(),
 		tlsConfig:       generateTLSConfig(),
+		cfg:             cfg,
 	}
 
 	// Init group controller
@@ -248,7 +250,7 @@ func (svr *Service) Run() {
 	if svr.rc.NatHoleController != nil {
 		go svr.rc.NatHoleController.Run()
 	}
-	if g.GlbServerCfg.KcpBindPort > 0 {
+	if svr.cfg.KcpBindPort > 0 {
 		go svr.HandleListener(svr.kcpListener)
 	}
 
@@ -324,7 +326,7 @@ func (svr *Service) HandleListener(l frpNet.Listener) {
 				}
 			}
 
-			if g.GlbServerCfg.TcpMux {
+			if svr.cfg.TcpMux {
 				fmuxCfg := fmux.DefaultConfig()
 				fmuxCfg.KeepAliveInterval = 20 * time.Second
 				fmuxCfg.LogOutput = ioutil.Discard
@@ -363,7 +365,7 @@ func (svr *Service) RegisterControl(ctlConn frpNet.Conn, loginMsg *msg.Login) (e
 	}
 
 	// Check auth.
-	if util.GetAuthKey(g.GlbServerCfg.Token, loginMsg.Timestamp) != loginMsg.PrivilegeKey {
+	if util.GetAuthKey(svr.cfg.Token, loginMsg.Timestamp) != loginMsg.PrivilegeKey {
 		err = fmt.Errorf("authorization failed")
 		return
 	}
@@ -377,7 +379,7 @@ func (svr *Service) RegisterControl(ctlConn frpNet.Conn, loginMsg *msg.Login) (e
 		}
 	}
 
-	ctl := NewControl(svr.rc, svr.pxyManager, svr.statsCollector, ctlConn, loginMsg)
+	ctl := NewControl(svr.rc, svr.pxyManager, svr.statsCollector, ctlConn, loginMsg, svr.cfg)
 
 	if oldCtl := svr.ctlManager.Add(loginMsg.RunId, ctl); oldCtl != nil {
 		oldCtl.allShutdown.WaitDone()