mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 16:13:59 +08:00
193 lines
5.8 KiB
Go
193 lines
5.8 KiB
Go
package server
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"os"
|
|
"syscall"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"github.com/1Panel-dev/1Panel/agent/app/repo"
|
|
"github.com/1Panel-dev/1Panel/agent/cron"
|
|
"github.com/1Panel-dev/1Panel/agent/global"
|
|
"github.com/1Panel-dev/1Panel/agent/i18n"
|
|
"github.com/1Panel-dev/1Panel/agent/init/app"
|
|
"github.com/1Panel-dev/1Panel/agent/init/business"
|
|
"github.com/1Panel-dev/1Panel/agent/init/cache"
|
|
"github.com/1Panel-dev/1Panel/agent/init/db"
|
|
"github.com/1Panel-dev/1Panel/agent/init/dir"
|
|
"github.com/1Panel-dev/1Panel/agent/init/firewall"
|
|
"github.com/1Panel-dev/1Panel/agent/init/hook"
|
|
"github.com/1Panel-dev/1Panel/agent/init/lang"
|
|
"github.com/1Panel-dev/1Panel/agent/init/log"
|
|
"github.com/1Panel-dev/1Panel/agent/init/migration"
|
|
"github.com/1Panel-dev/1Panel/agent/init/router"
|
|
"github.com/1Panel-dev/1Panel/agent/init/validator"
|
|
"github.com/1Panel-dev/1Panel/agent/init/viper"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
|
|
"github.com/1Panel-dev/1Panel/agent/utils/re"
|
|
)
|
|
|
|
const (
|
|
masterSocketDir = "/etc/1panel"
|
|
masterSocketPath = masterSocketDir + "/agent.sock"
|
|
masterSocketDirPerm = 0o700
|
|
masterSocketFilePerm = 0o600
|
|
masterSocketDirPermMask = 0o077
|
|
masterSocketFilePermMask = 0o077
|
|
)
|
|
|
|
func prepareMasterSocketDir(dir string) error {
|
|
if err := os.MkdirAll(dir, masterSocketDirPerm); err != nil {
|
|
return fmt.Errorf("create master socket dir %s failed: %w", dir, err)
|
|
}
|
|
if err := os.Chmod(dir, masterSocketDirPerm); err != nil {
|
|
return fmt.Errorf("chmod master socket dir %s failed: %w", dir, err)
|
|
}
|
|
info, err := os.Stat(dir)
|
|
if err != nil {
|
|
return fmt.Errorf("stat master socket dir %s failed: %w", dir, err)
|
|
}
|
|
if info.Mode().Perm()&masterSocketDirPermMask != 0 {
|
|
return fmt.Errorf("master socket dir %s permission %#o is too permissive", dir, info.Mode().Perm())
|
|
}
|
|
if stat, ok := info.Sys().(*syscall.Stat_t); ok {
|
|
if int(stat.Uid) != os.Geteuid() {
|
|
return fmt.Errorf(
|
|
"master socket dir %s owner uid %d does not match current process uid %d",
|
|
dir, stat.Uid, os.Geteuid(),
|
|
)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func secureMasterSocket(sockPath string) error {
|
|
if err := os.Chmod(sockPath, masterSocketFilePerm); err != nil {
|
|
return fmt.Errorf("chmod master socket %s failed: %w", sockPath, err)
|
|
}
|
|
info, err := os.Stat(sockPath)
|
|
if err != nil {
|
|
return fmt.Errorf("stat master socket %s failed: %w", sockPath, err)
|
|
}
|
|
if info.Mode().Perm()&masterSocketFilePermMask != 0 {
|
|
return fmt.Errorf("master socket %s permission %#o is too permissive", sockPath, info.Mode().Perm())
|
|
}
|
|
stat, ok := info.Sys().(*syscall.Stat_t)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
if int(stat.Uid) != os.Geteuid() {
|
|
return fmt.Errorf(
|
|
"master socket %s owner uid %d does not match current process uid %d",
|
|
sockPath, stat.Uid, os.Geteuid(),
|
|
)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func Start() {
|
|
re.Init()
|
|
viper.Init()
|
|
dir.Init()
|
|
log.Init()
|
|
global.LOG.Info("agent startup: logger initialized")
|
|
db.Init()
|
|
global.LOG.Info("agent startup: database initialized")
|
|
migration.Init()
|
|
global.LOG.Info("agent startup: migration initialized")
|
|
i18n.Init()
|
|
global.LOG.Info("agent startup: i18n initialized")
|
|
cache.Init()
|
|
global.LOG.Info("agent startup: cache initialized")
|
|
app.Init()
|
|
global.LOG.Info("agent startup: app initialized")
|
|
lang.Init()
|
|
global.LOG.Info("agent startup: language initialized")
|
|
validator.Init()
|
|
global.LOG.Info("agent startup: validator initialized")
|
|
cron.Run()
|
|
global.LOG.Info("agent startup: cron initialized")
|
|
hook.Init()
|
|
global.LOG.Info("agent startup: hook initialized")
|
|
go firewall.Init()
|
|
global.LOG.Info("agent startup: firewall init scheduled")
|
|
InitOthers()
|
|
global.LOG.Info("agent startup: edition initialized")
|
|
|
|
rootRouter := router.Routers()
|
|
global.LOG.Info("agent startup: router initialized")
|
|
|
|
server := &http.Server{
|
|
Handler: rootRouter,
|
|
}
|
|
|
|
if global.CONF.Base.Mode != "stable" {
|
|
gin.SetMode(gin.DebugMode)
|
|
} else {
|
|
gin.SetMode(gin.ReleaseMode)
|
|
}
|
|
|
|
if global.IsMaster {
|
|
global.LOG.Infof("agent startup: master mode, preparing unix socket %s", masterSocketPath)
|
|
if err := prepareMasterSocketDir(masterSocketDir); err != nil {
|
|
panic(err)
|
|
}
|
|
_ = os.Remove(masterSocketPath)
|
|
listener, err := net.Listen("unix", masterSocketPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if err := secureMasterSocket(masterSocketPath); err != nil {
|
|
_ = listener.Close()
|
|
panic(err)
|
|
}
|
|
global.LOG.Infof("agent startup: listening on unix socket %s", masterSocketPath)
|
|
business.Init()
|
|
global.LOG.Info("agent startup: business initialized")
|
|
_ = server.Serve(listener)
|
|
return
|
|
} else {
|
|
server.Addr = fmt.Sprintf("0.0.0.0:%s", global.CONF.Base.Port)
|
|
global.LOG.Infof("agent startup: node mode, preparing https listener %s", server.Addr)
|
|
settingRepo := repo.NewISettingRepo()
|
|
certItem, err := settingRepo.Get(settingRepo.WithByKey("ServerCrt"))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
cert, _ := encrypt.StringDecrypt(certItem.Value)
|
|
keyItem, err := settingRepo.Get(settingRepo.WithByKey("ServerKey"))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
key, _ := encrypt.StringDecrypt(keyItem.Value)
|
|
tlsCert, err := tls.X509KeyPair([]byte(cert), []byte(key))
|
|
if err != nil {
|
|
fmt.Printf("failed to load X.509 key pair: %s\n", err)
|
|
return
|
|
}
|
|
|
|
server.TLSConfig = &tls.Config{
|
|
Certificates: []tls.Certificate{tlsCert},
|
|
ClientAuth: tls.RequireAndVerifyClientCert,
|
|
}
|
|
caItem, _ := settingRepo.GetValueByKey("RootCrt")
|
|
if len(caItem) != 0 {
|
|
caCertPool := x509.NewCertPool()
|
|
rootCrt, _ := encrypt.StringDecrypt(caItem)
|
|
caCertPool.AppendCertsFromPEM([]byte(rootCrt))
|
|
server.TLSConfig.ClientCAs = caCertPool
|
|
}
|
|
business.Init()
|
|
global.LOG.Info("agent startup: business initialized")
|
|
global.LOG.Infof("listen at https://0.0.0.0:%s", global.CONF.Base.Port)
|
|
if err := server.ListenAndServeTLS("", ""); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|