2022-10-28 09:04:57 +00:00
|
|
|
package service
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2023-04-26 08:06:12 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/buserr"
|
2023-04-14 09:16:53 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/cmd"
|
2023-04-26 08:06:12 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx/components"
|
2022-12-21 04:21:27 +00:00
|
|
|
"path"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
2022-12-30 07:23:29 +00:00
|
|
|
"time"
|
2022-12-21 04:21:27 +00:00
|
|
|
|
2023-02-14 03:28:38 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/app/dto/request"
|
|
|
|
|
2022-11-03 10:02:07 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/app/dto"
|
2022-10-28 09:04:57 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/app/model"
|
|
|
|
"github.com/1Panel-dev/1Panel/backend/constant"
|
2022-11-02 07:19:14 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/files"
|
2022-10-28 09:04:57 +00:00
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx"
|
|
|
|
"github.com/1Panel-dev/1Panel/backend/utils/nginx/parser"
|
|
|
|
"github.com/1Panel-dev/1Panel/cmd/server/nginx_conf"
|
|
|
|
"github.com/pkg/errors"
|
2022-11-02 07:19:14 +00:00
|
|
|
"gorm.io/gorm"
|
2022-10-28 09:04:57 +00:00
|
|
|
)
|
|
|
|
|
2023-08-24 10:20:15 +00:00
|
|
|
func getDomain(domainStr string, defaultPort int) (model.WebsiteDomain, error) {
|
2023-04-12 13:52:30 +00:00
|
|
|
domain := model.WebsiteDomain{}
|
2022-10-28 09:04:57 +00:00
|
|
|
domainArray := strings.Split(domainStr, ":")
|
|
|
|
if len(domainArray) == 1 {
|
|
|
|
domain.Domain = domainArray[0]
|
2023-08-24 10:20:15 +00:00
|
|
|
domain.Port = defaultPort
|
2022-10-28 09:04:57 +00:00
|
|
|
return domain, nil
|
|
|
|
}
|
|
|
|
if len(domainArray) > 1 {
|
|
|
|
domain.Domain = domainArray[0]
|
|
|
|
portStr := domainArray[1]
|
|
|
|
portN, err := strconv.Atoi(portStr)
|
|
|
|
if err != nil {
|
2022-12-13 09:20:13 +00:00
|
|
|
return model.WebsiteDomain{}, err
|
2022-10-28 09:04:57 +00:00
|
|
|
}
|
|
|
|
domain.Port = portN
|
|
|
|
return domain, nil
|
|
|
|
}
|
2022-12-13 09:20:13 +00:00
|
|
|
return model.WebsiteDomain{}, nil
|
2022-10-28 09:04:57 +00:00
|
|
|
}
|
|
|
|
|
2023-04-03 09:47:23 +00:00
|
|
|
func createIndexFile(website *model.Website, runtime *model.Runtime) error {
|
2023-02-22 09:13:08 +00:00
|
|
|
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
2022-10-28 09:04:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-11-30 13:40:05 +00:00
|
|
|
|
2023-02-22 09:13:08 +00:00
|
|
|
indexFolder := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "www", "sites", website.Alias, "index")
|
2023-04-03 09:47:23 +00:00
|
|
|
indexPath := ""
|
|
|
|
indexContent := ""
|
|
|
|
switch website.Type {
|
|
|
|
case constant.Static:
|
|
|
|
indexPath = path.Join(indexFolder, "index.html")
|
|
|
|
indexContent = string(nginx_conf.Index)
|
|
|
|
case constant.Runtime:
|
|
|
|
if runtime.Type == constant.RuntimePHP {
|
|
|
|
indexPath = path.Join(indexFolder, "index.php")
|
|
|
|
indexContent = string(nginx_conf.IndexPHP)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-21 08:28:51 +00:00
|
|
|
fileOp := files.NewFileOp()
|
|
|
|
if !fileOp.Stat(indexFolder) {
|
|
|
|
if err := fileOp.CreateDir(indexFolder, 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !fileOp.Stat(indexPath) {
|
|
|
|
if err := fileOp.CreateFile(indexPath); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2023-04-17 08:54:34 +00:00
|
|
|
if website.Type == constant.Runtime && runtime.Resource == constant.ResourceAppstore {
|
2023-04-14 09:16:53 +00:00
|
|
|
if err := chownRootDir(indexFolder); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2022-11-21 08:28:51 +00:00
|
|
|
if err := fileOp.WriteFile(indexPath, strings.NewReader(indexContent), 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-04-26 08:06:12 +00:00
|
|
|
func createProxyFile(website *model.Website, runtime *model.Runtime) error {
|
|
|
|
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
proxyFolder := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "www", "sites", website.Alias, "proxy")
|
|
|
|
filePath := path.Join(proxyFolder, "root.conf")
|
|
|
|
fileOp := files.NewFileOp()
|
|
|
|
if !fileOp.Stat(proxyFolder) {
|
|
|
|
if err := fileOp.CreateDir(proxyFolder, 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !fileOp.Stat(filePath) {
|
|
|
|
if err := fileOp.CreateFile(filePath); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
config := parser.NewStringParser(string(nginx_conf.Proxy)).Parse()
|
|
|
|
config.FilePath = filePath
|
|
|
|
directives := config.Directives
|
|
|
|
location, ok := directives[0].(*components.Location)
|
|
|
|
if !ok {
|
|
|
|
return errors.New("error")
|
|
|
|
}
|
|
|
|
location.ChangePath("^~", "/")
|
|
|
|
location.UpdateDirective("proxy_pass", []string{website.Proxy})
|
|
|
|
location.UpdateDirective("proxy_set_header", []string{"Host", "$host"})
|
|
|
|
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
|
|
|
return buserr.WithErr(constant.ErrUpdateBuWebsite, err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-04-03 09:47:23 +00:00
|
|
|
func createWebsiteFolder(nginxInstall model.AppInstall, website *model.Website, runtime *model.Runtime) error {
|
2023-02-22 09:13:08 +00:00
|
|
|
nginxFolder := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name)
|
2022-11-30 13:40:05 +00:00
|
|
|
siteFolder := path.Join(nginxFolder, "www", "sites", website.Alias)
|
|
|
|
fileOp := files.NewFileOp()
|
|
|
|
if !fileOp.Stat(siteFolder) {
|
|
|
|
if err := fileOp.CreateDir(siteFolder, 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := fileOp.CreateDir(path.Join(siteFolder, "log"), 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := fileOp.CreateFile(path.Join(siteFolder, "log", "access.log")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-12-26 03:42:37 +00:00
|
|
|
if err := fileOp.CreateFile(path.Join(siteFolder, "log", "error.log")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-04-14 09:16:53 +00:00
|
|
|
if err := fileOp.CreateDir(path.Join(siteFolder, "index"), 0775); err != nil {
|
2022-11-30 13:40:05 +00:00
|
|
|
return err
|
|
|
|
}
|
2022-11-30 16:41:50 +00:00
|
|
|
if err := fileOp.CreateDir(path.Join(siteFolder, "ssl"), 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-04-14 09:16:53 +00:00
|
|
|
if website.Type == constant.Runtime {
|
|
|
|
if runtime.Type == constant.RuntimePHP && runtime.Resource == constant.ResourceLocal {
|
|
|
|
phpPoolDir := path.Join(siteFolder, "php-pool")
|
|
|
|
if err := fileOp.CreateDir(phpPoolDir, 0755); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := fileOp.CreateFile(path.Join(phpPoolDir, "php-fpm.sock")); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-04-04 10:54:04 +00:00
|
|
|
}
|
|
|
|
}
|
2023-10-08 09:02:23 +00:00
|
|
|
if website.Type == constant.Static || (website.Type == constant.Runtime && runtime.Type == constant.RuntimePHP) {
|
2023-04-03 09:47:23 +00:00
|
|
|
if err := createIndexFile(website, runtime); err != nil {
|
2022-12-21 08:17:46 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2023-04-26 08:06:12 +00:00
|
|
|
if website.Type == constant.Proxy {
|
|
|
|
if err := createProxyFile(website, runtime); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2022-11-30 13:40:05 +00:00
|
|
|
}
|
2022-12-04 07:59:34 +00:00
|
|
|
return fileOp.CopyDir(path.Join(nginxFolder, "www", "common", "waf", "rules"), path.Join(siteFolder, "waf"))
|
2022-11-30 13:40:05 +00:00
|
|
|
}
|
|
|
|
|
2023-04-12 13:52:30 +00:00
|
|
|
func configDefaultNginx(website *model.Website, domains []model.WebsiteDomain, appInstall *model.AppInstall, runtime *model.Runtime) error {
|
2023-02-22 09:13:08 +00:00
|
|
|
nginxInstall, err := getAppInstallByKey(constant.AppOpenresty)
|
2022-11-21 08:28:51 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-04-03 09:47:23 +00:00
|
|
|
if err := createWebsiteFolder(nginxInstall, website, runtime); err != nil {
|
2022-10-28 09:04:57 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-11-10 09:44:38 +00:00
|
|
|
nginxFileName := website.Alias + ".conf"
|
2023-02-22 09:13:08 +00:00
|
|
|
configPath := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "conf", "conf.d", nginxFileName)
|
2022-10-28 09:04:57 +00:00
|
|
|
nginxContent := string(nginx_conf.WebsiteDefault)
|
|
|
|
config := parser.NewStringParser(nginxContent).Parse()
|
|
|
|
servers := config.FindServers()
|
|
|
|
if len(servers) == 0 {
|
|
|
|
return errors.New("nginx config is not valid")
|
|
|
|
}
|
|
|
|
server := servers[0]
|
2023-08-24 10:20:15 +00:00
|
|
|
server.DeleteListen("80")
|
2022-10-28 09:04:57 +00:00
|
|
|
var serverNames []string
|
|
|
|
for _, domain := range domains {
|
|
|
|
serverNames = append(serverNames, domain.Domain)
|
2022-11-03 09:06:48 +00:00
|
|
|
server.UpdateListen(strconv.Itoa(domain.Port), false)
|
2023-05-30 06:22:57 +00:00
|
|
|
if website.IPV6 {
|
|
|
|
server.UpdateListen("[::]:"+strconv.Itoa(domain.Port), false)
|
|
|
|
}
|
2022-10-28 09:04:57 +00:00
|
|
|
}
|
|
|
|
server.UpdateServerName(serverNames)
|
2022-11-30 13:40:05 +00:00
|
|
|
|
|
|
|
siteFolder := path.Join("/www", "sites", website.Alias)
|
|
|
|
commonFolder := path.Join("/www", "common")
|
|
|
|
server.UpdateDirective("access_log", []string{path.Join(siteFolder, "log", "access.log")})
|
2022-12-26 03:42:37 +00:00
|
|
|
server.UpdateDirective("error_log", []string{path.Join(siteFolder, "log", "error.log")})
|
2022-11-30 13:40:05 +00:00
|
|
|
server.UpdateDirective("access_by_lua_file", []string{path.Join(commonFolder, "waf", "access.lua")})
|
|
|
|
server.UpdateDirective("set", []string{"$RulePath", path.Join(siteFolder, "waf", "rules")})
|
2022-11-30 16:41:50 +00:00
|
|
|
server.UpdateDirective("set", []string{"$logdir", path.Join(siteFolder, "log")})
|
2022-11-30 13:40:05 +00:00
|
|
|
|
2023-04-04 10:54:04 +00:00
|
|
|
rootIndex := path.Join("/www/sites", website.Alias, "index")
|
2022-12-12 07:36:45 +00:00
|
|
|
switch website.Type {
|
|
|
|
case constant.Deployment:
|
2022-11-21 08:28:51 +00:00
|
|
|
proxy := fmt.Sprintf("http://127.0.0.1:%d", appInstall.HttpPort)
|
|
|
|
server.UpdateRootProxy([]string{proxy})
|
2022-12-12 07:36:45 +00:00
|
|
|
case constant.Static:
|
2023-04-04 10:54:04 +00:00
|
|
|
server.UpdateRoot(rootIndex)
|
2022-12-12 07:36:45 +00:00
|
|
|
case constant.Proxy:
|
2023-04-26 08:06:12 +00:00
|
|
|
nginxInclude := fmt.Sprintf("/www/sites/%s/proxy/*.conf", website.Alias)
|
|
|
|
server.UpdateDirective("include", []string{nginxInclude})
|
2023-04-03 09:47:23 +00:00
|
|
|
case constant.Runtime:
|
2023-10-07 12:30:45 +00:00
|
|
|
switch runtime.Type {
|
|
|
|
case constant.RuntimePHP:
|
|
|
|
if runtime.Resource == constant.ResourceLocal {
|
|
|
|
switch runtime.Type {
|
|
|
|
case constant.RuntimePHP:
|
|
|
|
server.UpdateRoot(rootIndex)
|
|
|
|
localPath := path.Join(nginxInstall.GetPath(), rootIndex, "index.php")
|
|
|
|
server.UpdatePHPProxy([]string{website.Proxy}, localPath)
|
|
|
|
}
|
|
|
|
} else {
|
2023-04-04 10:54:04 +00:00
|
|
|
server.UpdateRoot(rootIndex)
|
2023-04-12 13:52:30 +00:00
|
|
|
server.UpdatePHPProxy([]string{website.Proxy}, "")
|
2023-04-03 09:47:23 +00:00
|
|
|
}
|
2023-10-07 12:30:45 +00:00
|
|
|
case constant.RuntimeNode:
|
|
|
|
proxy := fmt.Sprintf("http://127.0.0.1:%d", runtime.Port)
|
|
|
|
server.UpdateRootProxy([]string{proxy})
|
2023-04-03 09:47:23 +00:00
|
|
|
}
|
2022-11-21 08:28:51 +00:00
|
|
|
}
|
2022-10-28 09:04:57 +00:00
|
|
|
|
|
|
|
config.FilePath = configPath
|
|
|
|
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-11-30 13:40:05 +00:00
|
|
|
if err := opNginx(nginxInstall.ContainerName, constant.NginxCheck); err != nil {
|
2022-12-21 08:17:46 +00:00
|
|
|
_ = deleteWebsiteFolder(nginxInstall, website)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := opNginx(nginxInstall.ContainerName, constant.NginxReload); err != nil {
|
|
|
|
_ = deleteWebsiteFolder(nginxInstall, website)
|
2022-10-28 09:04:57 +00:00
|
|
|
return err
|
|
|
|
}
|
2022-12-21 08:17:46 +00:00
|
|
|
return nil
|
2022-10-28 09:04:57 +00:00
|
|
|
}
|
|
|
|
|
2022-12-13 09:20:13 +00:00
|
|
|
func delNginxConfig(website model.Website, force bool) error {
|
2023-02-22 09:13:08 +00:00
|
|
|
nginxApp, err := appRepo.GetFirst(appRepo.WithKey(constant.AppOpenresty))
|
2022-11-02 07:19:14 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
|
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-11-10 09:44:38 +00:00
|
|
|
nginxFileName := website.Alias + ".conf"
|
2023-02-22 09:13:08 +00:00
|
|
|
configPath := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "conf", "conf.d", nginxFileName)
|
2022-11-02 07:19:14 +00:00
|
|
|
fileOp := files.NewFileOp()
|
|
|
|
|
|
|
|
if !fileOp.Stat(configPath) {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
if err := fileOp.DeleteFile(configPath); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-02-22 09:13:08 +00:00
|
|
|
sitePath := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "www", "sites", website.PrimaryDomain)
|
2022-12-13 10:54:46 +00:00
|
|
|
if fileOp.Stat(sitePath) {
|
|
|
|
_ = fileOp.DeleteDir(sitePath)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := opNginx(nginxInstall.ContainerName, constant.NginxReload); err != nil {
|
2022-12-12 07:36:45 +00:00
|
|
|
if force {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
2022-11-02 07:19:14 +00:00
|
|
|
}
|
|
|
|
|
2022-12-13 09:20:13 +00:00
|
|
|
func addListenAndServerName(website model.Website, ports []int, domains []string) error {
|
2022-11-30 16:41:50 +00:00
|
|
|
nginxFull, err := getNginxFull(&website)
|
2022-11-03 10:02:07 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
2022-11-30 16:41:50 +00:00
|
|
|
nginxConfig := nginxFull.SiteConfig
|
|
|
|
config := nginxFull.SiteConfig.Config
|
2022-11-03 10:02:07 +00:00
|
|
|
server := config.FindServers()[0]
|
|
|
|
for _, port := range ports {
|
|
|
|
server.AddListen(strconv.Itoa(port), false)
|
2023-05-30 06:22:57 +00:00
|
|
|
if website.IPV6 {
|
|
|
|
server.UpdateListen("[::]:"+strconv.Itoa(port), false)
|
|
|
|
}
|
2022-11-03 10:02:07 +00:00
|
|
|
}
|
|
|
|
for _, domain := range domains {
|
|
|
|
server.AddServerName(domain)
|
|
|
|
}
|
|
|
|
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-11-30 16:41:50 +00:00
|
|
|
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxFull.Install.ContainerName)
|
2022-11-03 10:02:07 +00:00
|
|
|
}
|
|
|
|
|
2023-05-04 06:28:38 +00:00
|
|
|
func deleteListenAndServerName(website model.Website, binds []string, domains []string) error {
|
2022-11-30 16:41:50 +00:00
|
|
|
nginxFull, err := getNginxFull(&website)
|
2022-11-03 10:02:07 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
2022-11-30 16:41:50 +00:00
|
|
|
nginxConfig := nginxFull.SiteConfig
|
|
|
|
config := nginxFull.SiteConfig.Config
|
2022-11-03 09:06:48 +00:00
|
|
|
server := config.FindServers()[0]
|
2023-05-04 06:28:38 +00:00
|
|
|
for _, bind := range binds {
|
|
|
|
server.DeleteListen(bind)
|
2023-06-07 10:21:24 +00:00
|
|
|
server.DeleteListen("[::]:" + bind)
|
2022-11-03 09:06:48 +00:00
|
|
|
}
|
|
|
|
for _, domain := range domains {
|
|
|
|
server.DeleteServerName(domain)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-11-30 16:41:50 +00:00
|
|
|
return nginxCheckAndReload(nginxConfig.OldContent, nginxConfig.FilePath, nginxFull.Install.ContainerName)
|
2022-11-16 02:31:35 +00:00
|
|
|
}
|
|
|
|
|
2022-12-13 09:20:13 +00:00
|
|
|
func createPemFile(website model.Website, websiteSSL model.WebsiteSSL) error {
|
2023-02-22 09:13:08 +00:00
|
|
|
nginxApp, err := appRepo.GetFirst(appRepo.WithKey(constant.AppOpenresty))
|
2022-11-16 02:31:35 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
nginxInstall, err := appInstallRepo.GetFirst(appInstallRepo.WithAppId(nginxApp.ID))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2023-02-22 09:13:08 +00:00
|
|
|
configDir := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name, "www", "sites", website.Alias, "ssl")
|
2022-11-16 02:31:35 +00:00
|
|
|
fileOp := files.NewFileOp()
|
|
|
|
|
|
|
|
if !fileOp.Stat(configDir) {
|
|
|
|
if err := fileOp.CreateDir(configDir, 0775); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fullChainFile := path.Join(configDir, "fullchain.pem")
|
|
|
|
privatePemFile := path.Join(configDir, "privkey.pem")
|
|
|
|
|
|
|
|
if !fileOp.Stat(fullChainFile) {
|
|
|
|
if err := fileOp.CreateFile(fullChainFile); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !fileOp.Stat(privatePemFile) {
|
|
|
|
if err := fileOp.CreateFile(privatePemFile); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := fileOp.WriteFile(fullChainFile, strings.NewReader(websiteSSL.Pem), 0644); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := fileOp.WriteFile(privatePemFile, strings.NewReader(websiteSSL.PrivateKey), 0644); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-12-28 10:59:05 +00:00
|
|
|
func applySSL(website model.Website, websiteSSL model.WebsiteSSL, req request.WebsiteHTTPSOp) error {
|
2022-11-30 16:41:50 +00:00
|
|
|
nginxFull, err := getNginxFull(&website)
|
2022-11-24 09:50:47 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
2022-11-30 16:41:50 +00:00
|
|
|
config := nginxFull.SiteConfig.Config
|
2022-11-24 09:50:47 +00:00
|
|
|
server := config.FindServers()[0]
|
2023-08-24 10:20:15 +00:00
|
|
|
|
|
|
|
httpPort := strconv.Itoa(nginxFull.Install.HttpPort)
|
|
|
|
httpsPort := strconv.Itoa(nginxFull.Install.HttpsPort)
|
|
|
|
httpPortIPV6 := "[::]:" + httpPort
|
|
|
|
httpsPortIPV6 := "[::]:" + httpsPort
|
|
|
|
|
|
|
|
server.UpdateListen(httpsPort, website.DefaultServer, "ssl", "http2")
|
2023-05-30 06:22:57 +00:00
|
|
|
if website.IPV6 {
|
2023-08-24 10:20:15 +00:00
|
|
|
server.UpdateListen(httpsPortIPV6, website.DefaultServer, "ssl", "http2")
|
2023-05-30 06:22:57 +00:00
|
|
|
}
|
2022-12-28 08:07:43 +00:00
|
|
|
|
2022-12-28 10:59:05 +00:00
|
|
|
switch req.HttpConfig {
|
2022-12-28 08:07:43 +00:00
|
|
|
case constant.HTTPSOnly:
|
2023-08-24 10:20:15 +00:00
|
|
|
server.RemoveListenByBind(httpPort)
|
|
|
|
server.RemoveListenByBind(httpPortIPV6)
|
2022-12-28 08:07:43 +00:00
|
|
|
server.RemoveDirective("if", []string{"($scheme"})
|
|
|
|
case constant.HTTPToHTTPS:
|
2023-08-24 10:20:15 +00:00
|
|
|
server.UpdateListen(httpPort, website.DefaultServer)
|
2023-05-30 06:22:57 +00:00
|
|
|
if website.IPV6 {
|
2023-08-24 10:20:15 +00:00
|
|
|
server.UpdateListen(httpPortIPV6, website.DefaultServer)
|
2023-05-30 06:22:57 +00:00
|
|
|
}
|
2022-12-28 08:07:43 +00:00
|
|
|
server.AddHTTP2HTTPS()
|
|
|
|
case constant.HTTPAlso:
|
2023-08-24 10:20:15 +00:00
|
|
|
server.UpdateListen(httpPort, website.DefaultServer)
|
2022-12-28 08:07:43 +00:00
|
|
|
server.RemoveDirective("if", []string{"($scheme"})
|
2023-05-30 06:22:57 +00:00
|
|
|
if website.IPV6 {
|
2023-08-24 10:20:15 +00:00
|
|
|
server.UpdateListen(httpPortIPV6, website.DefaultServer)
|
2023-05-30 06:22:57 +00:00
|
|
|
}
|
2022-12-28 08:07:43 +00:00
|
|
|
}
|
|
|
|
|
2022-11-24 09:50:47 +00:00
|
|
|
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-11-20 10:32:56 +00:00
|
|
|
if err := createPemFile(website, websiteSSL); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2022-11-30 16:41:50 +00:00
|
|
|
nginxParams := getNginxParamsFromStaticFile(dto.SSL, []dto.NginxParam{})
|
2022-11-20 10:32:56 +00:00
|
|
|
for i, param := range nginxParams {
|
|
|
|
if param.Name == "ssl_certificate" {
|
2022-11-30 16:41:50 +00:00
|
|
|
nginxParams[i].Params = []string{path.Join("/www", "sites", website.Alias, "ssl", "fullchain.pem")}
|
2022-11-20 10:32:56 +00:00
|
|
|
}
|
|
|
|
if param.Name == "ssl_certificate_key" {
|
2022-11-30 16:41:50 +00:00
|
|
|
nginxParams[i].Params = []string{path.Join("/www", "sites", website.Alias, "ssl", "privkey.pem")}
|
2022-11-20 10:32:56 +00:00
|
|
|
}
|
2022-12-28 10:59:05 +00:00
|
|
|
if param.Name == "ssl_protocols" {
|
|
|
|
nginxParams[i].Params = req.SSLProtocol
|
|
|
|
}
|
|
|
|
if param.Name == "ssl_ciphers" {
|
|
|
|
nginxParams[i].Params = []string{req.Algorithm}
|
|
|
|
}
|
2022-11-20 10:32:56 +00:00
|
|
|
}
|
2022-11-30 16:41:50 +00:00
|
|
|
if err := updateNginxConfig(constant.NginxScopeServer, nginxParams, &website); err != nil {
|
2022-11-20 10:32:56 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-11-08 07:42:31 +00:00
|
|
|
func getParamArray(key string, param interface{}) []string {
|
2022-11-07 08:19:05 +00:00
|
|
|
var res []string
|
2022-11-18 10:02:14 +00:00
|
|
|
switch p := param.(type) {
|
2022-11-07 08:19:05 +00:00
|
|
|
case string:
|
|
|
|
if key == "index" {
|
2022-11-18 10:02:14 +00:00
|
|
|
res = strings.Split(p, "\n")
|
2022-11-08 07:42:31 +00:00
|
|
|
return res
|
2022-11-07 08:19:05 +00:00
|
|
|
}
|
2022-11-08 07:42:31 +00:00
|
|
|
|
2022-11-18 10:02:14 +00:00
|
|
|
res = strings.Split(p, " ")
|
2022-11-08 07:42:31 +00:00
|
|
|
return res
|
2022-11-07 08:19:05 +00:00
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|
2022-11-08 07:42:31 +00:00
|
|
|
|
|
|
|
func handleParamMap(paramMap map[string]string, keys []string) []dto.NginxParam {
|
|
|
|
var nginxParams []dto.NginxParam
|
|
|
|
for k, v := range paramMap {
|
|
|
|
for _, name := range keys {
|
|
|
|
if name == k {
|
|
|
|
param := dto.NginxParam{
|
|
|
|
Name: k,
|
|
|
|
Params: getParamArray(k, v),
|
|
|
|
}
|
|
|
|
nginxParams = append(nginxParams, param)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nginxParams
|
|
|
|
}
|
|
|
|
|
|
|
|
func getNginxParams(params interface{}, keys []string) []dto.NginxParam {
|
|
|
|
var nginxParams []dto.NginxParam
|
|
|
|
|
2022-11-18 10:02:14 +00:00
|
|
|
switch p := params.(type) {
|
2022-11-10 09:44:38 +00:00
|
|
|
case map[string]interface{}:
|
2022-11-18 10:02:14 +00:00
|
|
|
return handleParamMap(toMapStr(p), keys)
|
2022-11-08 07:42:31 +00:00
|
|
|
case []interface{}:
|
2022-11-18 10:02:14 +00:00
|
|
|
for _, mA := range p {
|
|
|
|
if m, ok := mA.(map[string]interface{}); ok {
|
|
|
|
nginxParams = append(nginxParams, handleParamMap(toMapStr(m), keys)...)
|
2022-11-08 07:42:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nginxParams
|
|
|
|
}
|
|
|
|
|
|
|
|
func toMapStr(m map[string]interface{}) map[string]string {
|
|
|
|
ret := make(map[string]string, len(m))
|
|
|
|
for k, v := range m {
|
|
|
|
ret[k] = fmt.Sprint(v)
|
|
|
|
}
|
|
|
|
return ret
|
|
|
|
}
|
2022-12-05 03:17:06 +00:00
|
|
|
|
2022-12-21 08:17:46 +00:00
|
|
|
func deleteWebsiteFolder(nginxInstall model.AppInstall, website *model.Website) error {
|
2023-02-22 09:13:08 +00:00
|
|
|
nginxFolder := path.Join(constant.AppInstallDir, constant.AppOpenresty, nginxInstall.Name)
|
2022-12-21 08:17:46 +00:00
|
|
|
siteFolder := path.Join(nginxFolder, "www", "sites", website.Alias)
|
|
|
|
fileOp := files.NewFileOp()
|
|
|
|
if fileOp.Stat(siteFolder) {
|
|
|
|
_ = fileOp.DeleteDir(siteFolder)
|
|
|
|
}
|
|
|
|
nginxFilePath := path.Join(nginxFolder, "conf", "conf.d", website.PrimaryDomain+".conf")
|
|
|
|
if fileOp.Stat(nginxFilePath) {
|
|
|
|
_ = fileOp.DeleteFile(nginxFilePath)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2022-12-26 08:09:21 +00:00
|
|
|
|
|
|
|
func opWebsite(website *model.Website, operate string) error {
|
|
|
|
nginxInstall, err := getNginxFull(website)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
config := nginxInstall.SiteConfig.Config
|
|
|
|
servers := config.FindServers()
|
|
|
|
if len(servers) == 0 {
|
|
|
|
return errors.New("nginx config is not valid")
|
|
|
|
}
|
|
|
|
server := servers[0]
|
|
|
|
if operate == constant.StopWeb {
|
2023-05-05 07:02:54 +00:00
|
|
|
proxyInclude := fmt.Sprintf("/www/sites/%s/proxy/*.conf", website.Alias)
|
|
|
|
server.RemoveDirective("include", []string{proxyInclude})
|
|
|
|
rewriteInclude := fmt.Sprintf("/www/sites/%s/rewrite/%s.conf", website.Alias, website.Alias)
|
|
|
|
server.RemoveDirective("include", []string{rewriteInclude})
|
|
|
|
|
|
|
|
switch website.Type {
|
|
|
|
case constant.Deployment:
|
2023-05-08 08:39:41 +00:00
|
|
|
server.RemoveDirective("location", []string{"/"})
|
2023-05-05 07:02:54 +00:00
|
|
|
case constant.Runtime:
|
2023-04-12 13:52:30 +00:00
|
|
|
server.RemoveDirective("location", []string{"~", "[^/]\\.php(/|$)"})
|
2022-12-26 08:09:21 +00:00
|
|
|
}
|
|
|
|
server.UpdateRoot("/usr/share/nginx/html/stop")
|
|
|
|
website.Status = constant.WebStopped
|
|
|
|
}
|
|
|
|
if operate == constant.StartWeb {
|
2023-05-05 07:02:54 +00:00
|
|
|
proxyInclude := fmt.Sprintf("/www/sites/%s/proxy/*.conf", website.Alias)
|
|
|
|
absoluteIncludeDir := path.Join(nginxInstall.Install.GetPath(), fmt.Sprintf("/www/sites/%s/proxy", website.Alias))
|
|
|
|
if files.NewFileOp().Stat(absoluteIncludeDir) {
|
|
|
|
server.UpdateDirective("include", []string{proxyInclude})
|
|
|
|
}
|
|
|
|
server.UpdateDirective("include", []string{proxyInclude})
|
|
|
|
rewriteInclude := fmt.Sprintf("/www/sites/%s/rewrite/%s.conf", website.Alias, website.Alias)
|
|
|
|
absoluteRewritePath := path.Join(nginxInstall.Install.GetPath(), rewriteInclude)
|
|
|
|
if files.NewFileOp().Stat(absoluteRewritePath) {
|
|
|
|
server.UpdateDirective("include", []string{rewriteInclude})
|
|
|
|
}
|
2023-07-14 06:20:19 +00:00
|
|
|
rootIndex := path.Join("/www/sites", website.Alias, "index")
|
|
|
|
if website.SiteDir != "/" {
|
|
|
|
rootIndex = path.Join(rootIndex, website.SiteDir)
|
|
|
|
}
|
2022-12-26 08:09:21 +00:00
|
|
|
switch website.Type {
|
|
|
|
case constant.Deployment:
|
|
|
|
server.RemoveDirective("root", nil)
|
|
|
|
appInstall, err := appInstallRepo.GetFirst(commonRepo.WithByID(website.AppInstallID))
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
proxy := fmt.Sprintf("http://127.0.0.1:%d", appInstall.HttpPort)
|
|
|
|
server.UpdateRootProxy([]string{proxy})
|
|
|
|
case constant.Static:
|
2023-07-14 06:20:19 +00:00
|
|
|
server.UpdateRoot(rootIndex)
|
2022-12-26 08:09:21 +00:00
|
|
|
server.UpdateRootLocation()
|
|
|
|
case constant.Proxy:
|
|
|
|
server.RemoveDirective("root", nil)
|
2023-04-12 13:52:30 +00:00
|
|
|
case constant.Runtime:
|
|
|
|
server.UpdateRoot(rootIndex)
|
|
|
|
localPath := ""
|
|
|
|
if website.ProxyType == constant.RuntimeProxyUnix {
|
|
|
|
localPath = path.Join(nginxInstall.Install.GetPath(), rootIndex, "index.php")
|
|
|
|
}
|
|
|
|
server.UpdatePHPProxy([]string{website.Proxy}, localPath)
|
2022-12-26 08:09:21 +00:00
|
|
|
}
|
|
|
|
website.Status = constant.WebRunning
|
2022-12-30 07:23:29 +00:00
|
|
|
now := time.Now()
|
|
|
|
if website.ExpireDate.Before(now) {
|
|
|
|
defaultDate, _ := time.Parse(constant.DateLayout, constant.DefaultDate)
|
|
|
|
website.ExpireDate = defaultDate
|
|
|
|
}
|
2022-12-26 08:09:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nginxCheckAndReload(nginxInstall.SiteConfig.OldContent, config.FilePath, nginxInstall.Install.ContainerName)
|
|
|
|
}
|
2023-04-10 09:32:22 +00:00
|
|
|
|
2023-07-22 14:04:17 +00:00
|
|
|
func changeIPV6(website model.Website, enable bool) error {
|
|
|
|
nginxFull, err := getNginxFull(&website)
|
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
config := nginxFull.SiteConfig.Config
|
|
|
|
server := config.FindServers()[0]
|
|
|
|
listens := server.Listens
|
|
|
|
if enable {
|
|
|
|
for _, listen := range listens {
|
|
|
|
if strings.HasPrefix(listen.Bind, "[::]:") {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
exist := false
|
|
|
|
ipv6Bind := fmt.Sprintf("[::]:%s", listen.Bind)
|
|
|
|
for _, li := range listens {
|
|
|
|
if li.Bind == ipv6Bind {
|
|
|
|
exist = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !exist {
|
|
|
|
server.UpdateListen(ipv6Bind, false, listen.GetParameters()[1:]...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for _, listen := range listens {
|
|
|
|
if strings.HasPrefix(listen.Bind, "[::]:") {
|
|
|
|
server.RemoveListenByBind(listen.Bind)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nginxCheckAndReload(nginxFull.SiteConfig.OldContent, config.FilePath, nginxFull.Install.ContainerName)
|
|
|
|
}
|
|
|
|
|
2023-04-10 09:32:22 +00:00
|
|
|
func checkIsLinkApp(website model.Website) bool {
|
|
|
|
if website.Type == constant.Deployment {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if website.Type == constant.Runtime {
|
|
|
|
runtime, _ := runtimeRepo.GetFirst(commonRepo.WithByID(website.RuntimeID))
|
2023-04-12 06:16:29 +00:00
|
|
|
return runtime.Resource == constant.ResourceAppstore
|
2023-04-10 09:32:22 +00:00
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
2023-04-14 09:16:53 +00:00
|
|
|
|
|
|
|
func chownRootDir(path string) error {
|
2023-09-06 03:32:11 +00:00
|
|
|
_, err := cmd.ExecWithTimeOut(fmt.Sprintf(`chown -R 1000:1000 "%s"`, path), 1*time.Second)
|
2023-04-14 09:16:53 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|