mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 05:31:44 +08:00
453 lines
11 KiB
Go
453 lines
11 KiB
Go
package nginx
|
||
|
||
import (
|
||
"fmt"
|
||
"slices"
|
||
"strings"
|
||
|
||
"github.com/tufanbarisyildirim/gonginx/config"
|
||
)
|
||
|
||
func (p *Parser) SetListen(listen [][]string) error {
|
||
var directives []*config.Directive
|
||
for _, l := range listen {
|
||
directives = append(directives, &config.Directive{
|
||
Name: "listen",
|
||
Parameters: l,
|
||
})
|
||
}
|
||
|
||
if err := p.Clear("server.listen"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", directives)
|
||
}
|
||
|
||
func (p *Parser) SetServerName(serverName []string) error {
|
||
if err := p.Clear("server.server_name"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "server_name",
|
||
Parameters: serverName,
|
||
},
|
||
})
|
||
}
|
||
|
||
func (p *Parser) SetIndex(index []string) error {
|
||
if err := p.Clear("server.index"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "index",
|
||
Parameters: index,
|
||
},
|
||
})
|
||
}
|
||
|
||
func (p *Parser) SetIndexWithComment(index []string, comment []string) error {
|
||
if err := p.Clear("server.index"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "index",
|
||
Parameters: index,
|
||
Comment: comment,
|
||
},
|
||
})
|
||
}
|
||
|
||
func (p *Parser) SetRoot(root string) error {
|
||
if err := p.Clear("server.root"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "root",
|
||
Parameters: []string{root},
|
||
},
|
||
})
|
||
}
|
||
|
||
func (p *Parser) SetRootWithComment(root string, comment []string) error {
|
||
if err := p.Clear("server.root"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "root",
|
||
Parameters: []string{root},
|
||
Comment: comment,
|
||
},
|
||
})
|
||
}
|
||
|
||
func (p *Parser) SetIncludes(includes []string, comments [][]string) error {
|
||
if err := p.Clear("server.include"); err != nil {
|
||
return err
|
||
}
|
||
|
||
var directives []*config.Directive
|
||
for i, item := range includes {
|
||
var comment []string
|
||
if i < len(comments) {
|
||
comment = comments[i]
|
||
}
|
||
directives = append(directives, &config.Directive{
|
||
Name: "include",
|
||
Parameters: []string{item},
|
||
Comment: comment,
|
||
})
|
||
}
|
||
|
||
return p.Set("server", directives)
|
||
}
|
||
|
||
func (p *Parser) SetPHP(php int) error {
|
||
old, err := p.Find("server.include")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if err = p.Clear("server.include"); err != nil {
|
||
return err
|
||
}
|
||
|
||
var directives []*config.Directive
|
||
var foundFlag bool
|
||
for _, item := range old {
|
||
// 查找enable-php的配置
|
||
if slices.ContainsFunc(item.GetParameters(), func(s string) bool {
|
||
return strings.HasPrefix(s, "enable-php-") && strings.HasSuffix(s, ".conf")
|
||
}) {
|
||
foundFlag = true
|
||
directives = append(directives, &config.Directive{
|
||
Name: item.GetName(),
|
||
Parameters: []string{fmt.Sprintf("enable-php-%d.conf", php)},
|
||
Comment: item.GetComment(),
|
||
})
|
||
} else {
|
||
// 其余的原样保留
|
||
directives = append(directives, &config.Directive{
|
||
Name: item.GetName(),
|
||
Parameters: item.GetParameters(),
|
||
Comment: item.GetComment(),
|
||
})
|
||
}
|
||
}
|
||
|
||
// 如果没有找到enable-php的配置,直接添加一个
|
||
if !foundFlag {
|
||
directives = append(directives, &config.Directive{
|
||
Name: "include",
|
||
Parameters: []string{fmt.Sprintf("enable-php-%d.conf", php)},
|
||
})
|
||
}
|
||
|
||
return p.Set("server", directives)
|
||
}
|
||
|
||
func (p *Parser) ClearSetHTTPS() error {
|
||
if err := p.Clear("server.ssl_certificate"); err != nil {
|
||
return err
|
||
}
|
||
if err := p.Clear("server.ssl_certificate_key"); err != nil {
|
||
return err
|
||
}
|
||
if err := p.Clear("server.ssl_session_timeout"); err != nil {
|
||
return err
|
||
}
|
||
if err := p.Clear("server.ssl_session_cache"); err != nil {
|
||
return err
|
||
}
|
||
if err := p.Clear("server.ssl_protocols"); err != nil {
|
||
return err
|
||
}
|
||
if err := p.Clear("server.ssl_ciphers"); err != nil {
|
||
return err
|
||
}
|
||
if err := p.Clear("server.ssl_prefer_server_ciphers"); err != nil {
|
||
return err
|
||
}
|
||
if err := p.Clear("server.ssl_early_data"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func (p *Parser) SetHTTPS(cert, key string) error {
|
||
if err := p.ClearSetHTTPS(); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "ssl_certificate",
|
||
Parameters: []string{cert},
|
||
},
|
||
{
|
||
Name: "ssl_certificate_key",
|
||
Parameters: []string{key},
|
||
},
|
||
{
|
||
Name: "ssl_session_timeout",
|
||
Parameters: []string{"1d"},
|
||
},
|
||
{
|
||
Name: "ssl_session_cache",
|
||
Parameters: []string{"shared:SSL:10m"},
|
||
},
|
||
{
|
||
Name: "ssl_protocols",
|
||
Parameters: []string{"TLSv1.2", "TLSv1.3"},
|
||
},
|
||
{
|
||
Name: "ssl_ciphers",
|
||
Parameters: []string{"ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305"},
|
||
},
|
||
{
|
||
Name: "ssl_prefer_server_ciphers",
|
||
Parameters: []string{"off"},
|
||
},
|
||
{
|
||
Name: "ssl_early_data",
|
||
Parameters: []string{"on"},
|
||
},
|
||
})
|
||
}
|
||
|
||
func (p *Parser) SetHTTPSProtocols(protocols []string) error {
|
||
if err := p.Clear("server.ssl_protocols"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "ssl_protocols",
|
||
Parameters: protocols,
|
||
},
|
||
})
|
||
}
|
||
|
||
func (p *Parser) SetHTTPSCiphers(ciphers string) error {
|
||
if err := p.Clear("server.ssl_ciphers"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "ssl_ciphers",
|
||
Parameters: []string{ciphers},
|
||
},
|
||
})
|
||
}
|
||
|
||
func (p *Parser) SetOCSP(ocsp bool) error {
|
||
if err := p.Clear("server.ssl_stapling"); err != nil {
|
||
return err
|
||
}
|
||
if err := p.Clear("server.ssl_stapling_verify"); err != nil {
|
||
return err
|
||
}
|
||
|
||
if ocsp {
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "ssl_stapling",
|
||
Parameters: []string{"on"},
|
||
},
|
||
{
|
||
Name: "ssl_stapling_verify",
|
||
Parameters: []string{"on"},
|
||
},
|
||
})
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func (p *Parser) SetHSTS(hsts bool) error {
|
||
old, err := p.Find("server.add_header")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if err = p.Clear("server.add_header"); err != nil {
|
||
return err
|
||
}
|
||
|
||
var directives []*config.Directive
|
||
var foundFlag bool
|
||
for _, dir := range old {
|
||
if slices.Contains(dir.GetParameters(), "Strict-Transport-Security") {
|
||
foundFlag = true
|
||
if hsts {
|
||
directives = append(directives, &config.Directive{
|
||
Name: dir.GetName(),
|
||
Parameters: []string{"Strict-Transport-Security", "max-age=31536000"},
|
||
Comment: dir.GetComment(),
|
||
})
|
||
}
|
||
} else {
|
||
directives = append(directives, &config.Directive{
|
||
Name: dir.GetName(),
|
||
Parameters: dir.GetParameters(),
|
||
Comment: dir.GetComment(),
|
||
})
|
||
}
|
||
}
|
||
|
||
if !foundFlag && hsts {
|
||
directives = append(directives, &config.Directive{
|
||
Name: "add_header",
|
||
Parameters: []string{"Strict-Transport-Security", "max-age=31536000"},
|
||
})
|
||
}
|
||
|
||
return p.Set("server", directives)
|
||
}
|
||
|
||
func (p *Parser) SetHTTPRedirect(httpRedirect bool) error {
|
||
// if 重定向
|
||
ifs, err := p.Find("server.if")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if err = p.Clear("server.if"); err != nil {
|
||
return err
|
||
}
|
||
|
||
var directives []*config.Directive
|
||
var foundFlag bool
|
||
for _, dir := range ifs { // 所有 if
|
||
if !httpRedirect {
|
||
if len(dir.GetParameters()) == 3 && dir.GetParameters()[0] == "($scheme" && dir.GetParameters()[1] == "=" && dir.GetParameters()[2] == "http)" {
|
||
continue
|
||
}
|
||
}
|
||
var ifDirectives []config.IDirective
|
||
for _, dir2 := range dir.GetBlock().GetDirectives() { // 每个 if 中所有指令
|
||
if !httpRedirect {
|
||
// 不启用http重定向,则判断并移除特定的return指令
|
||
if dir2.GetName() != "return" && !slices.Contains(dir2.GetParameters(), "https://$host$request_uri") {
|
||
ifDirectives = append(ifDirectives, dir2)
|
||
}
|
||
} else {
|
||
// 启用http重定向,需要检查防止重复添加
|
||
if dir2.GetName() == "return" && slices.Contains(dir2.GetParameters(), "https://$host$request_uri") {
|
||
foundFlag = true
|
||
}
|
||
ifDirectives = append(ifDirectives, dir2)
|
||
}
|
||
}
|
||
// 写回 if 指令
|
||
if block, ok := dir.GetBlock().(*config.Block); ok {
|
||
block.Directives = ifDirectives
|
||
}
|
||
directives = append(directives, &config.Directive{
|
||
Block: dir.GetBlock(),
|
||
Name: dir.GetName(),
|
||
Parameters: dir.GetParameters(),
|
||
Comment: dir.GetComment(),
|
||
})
|
||
}
|
||
|
||
if !foundFlag && httpRedirect {
|
||
ifDir := &config.Directive{
|
||
Name: "if",
|
||
Block: &config.Block{},
|
||
Parameters: []string{"($scheme", "=", "http)"},
|
||
}
|
||
redirectDir := &config.Directive{
|
||
Name: "return",
|
||
Parameters: []string{"308", "https://$host$request_uri"},
|
||
}
|
||
redirectDir.SetParent(ifDir.GetBlock())
|
||
ifBlock := ifDir.GetBlock().(*config.Block)
|
||
ifBlock.Directives = append(ifBlock.Directives, redirectDir)
|
||
directives = append(directives, ifDir)
|
||
}
|
||
|
||
if err = p.Set("server", directives); err != nil {
|
||
return err
|
||
}
|
||
|
||
// error_page 497 重定向
|
||
directives = nil
|
||
errorPages, err := p.Find("server.error_page")
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if err = p.Clear("server.error_page"); err != nil {
|
||
return err
|
||
}
|
||
var found497 bool
|
||
for _, dir := range errorPages {
|
||
if !httpRedirect {
|
||
// 不启用https重定向,则判断并移除特定的return指令
|
||
if !slices.Contains(dir.GetParameters(), "497") && !slices.Contains(dir.GetParameters(), "https://$host:$server_port$request_uri") {
|
||
directives = append(directives, &config.Directive{
|
||
Block: dir.GetBlock(),
|
||
Name: dir.GetName(),
|
||
Parameters: dir.GetParameters(),
|
||
Comment: dir.GetComment(),
|
||
})
|
||
}
|
||
} else {
|
||
// 启用https重定向,需要检查防止重复添加
|
||
if slices.Contains(dir.GetParameters(), "497") && slices.Contains(dir.GetParameters(), "https://$host:$server_port$request_uri") {
|
||
found497 = true
|
||
}
|
||
directives = append(directives, &config.Directive{
|
||
Block: dir.GetBlock(),
|
||
Name: dir.GetName(),
|
||
Parameters: dir.GetParameters(),
|
||
Comment: dir.GetComment(),
|
||
})
|
||
}
|
||
}
|
||
|
||
if !found497 && httpRedirect {
|
||
directives = append(directives, &config.Directive{
|
||
Name: "error_page",
|
||
Parameters: []string{"497", "=307", "https://$host:$server_port$request_uri"},
|
||
})
|
||
}
|
||
|
||
return p.Set("server", directives)
|
||
}
|
||
|
||
func (p *Parser) SetAccessLog(accessLog string) error {
|
||
if err := p.Clear("server.access_log"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "access_log",
|
||
Parameters: []string{accessLog},
|
||
},
|
||
})
|
||
}
|
||
|
||
func (p *Parser) SetErrorLog(errorLog string) error {
|
||
if err := p.Clear("server.error_log"); err != nil {
|
||
return err
|
||
}
|
||
|
||
return p.Set("server", []*config.Directive{
|
||
{
|
||
Name: "error_log",
|
||
Parameters: []string{errorLog},
|
||
},
|
||
})
|
||
}
|