mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 06:47:20 +08:00
493 lines
12 KiB
Go
493 lines
12 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: p.slices2Parameters(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: p.slices2Parameters(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: p.slices2Parameters(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: p.slices2Parameters(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: []config.Parameter{{Value: 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: []config.Parameter{{Value: 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: []config.Parameter{{Value: 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(p.parameters2Slices(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: []config.Parameter{{Value: 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: []config.Parameter{{Value: 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: []config.Parameter{{Value: cert}},
|
||
},
|
||
{
|
||
Name: "ssl_certificate_key",
|
||
Parameters: []config.Parameter{{Value: key}},
|
||
},
|
||
{
|
||
Name: "ssl_session_timeout",
|
||
Parameters: []config.Parameter{{Value: "1d"}},
|
||
},
|
||
{
|
||
Name: "ssl_session_cache",
|
||
Parameters: []config.Parameter{{Value: "shared:SSL:10m"}},
|
||
},
|
||
{
|
||
Name: "ssl_protocols",
|
||
Parameters: []config.Parameter{{Value: "TLSv1.2"}, {Value: "TLSv1.3"}},
|
||
},
|
||
{
|
||
Name: "ssl_ciphers",
|
||
Parameters: []config.Parameter{{Value: "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: []config.Parameter{{Value: "off"}},
|
||
},
|
||
{
|
||
Name: "ssl_early_data",
|
||
Parameters: []config.Parameter{{Value: "on"}},
|
||
},
|
||
}, "root")
|
||
}
|
||
|
||
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: p.slices2Parameters(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: []config.Parameter{{Value: 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: []config.Parameter{{Value: "on"}},
|
||
},
|
||
{
|
||
Name: "ssl_stapling_verify",
|
||
Parameters: []config.Parameter{{Value: "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(p.parameters2Slices(dir.GetParameters()), "Strict-Transport-Security") {
|
||
foundFlag = true
|
||
if hsts {
|
||
directives = append(directives, &config.Directive{
|
||
Name: dir.GetName(),
|
||
Parameters: []config.Parameter{{Value: "Strict-Transport-Security"}, {Value: "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: []config.Parameter{{Value: "Strict-Transport-Security"}, {Value: "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].GetValue() == "($scheme" && dir.GetParameters()[1].GetValue() == "=" && dir.GetParameters()[2].GetValue() == "http)" {
|
||
continue
|
||
}
|
||
}
|
||
var ifDirectives []config.IDirective
|
||
for _, dir2 := range dir.GetBlock().GetDirectives() { // 每个 if 中所有指令
|
||
if !httpRedirect {
|
||
// 不启用http重定向,则判断并移除特定的return指令
|
||
if dir2.GetName() != "return" && !slices.Contains(p.parameters2Slices(dir2.GetParameters()), "https://$host$request_uri") {
|
||
ifDirectives = append(ifDirectives, dir2)
|
||
}
|
||
} else {
|
||
// 启用http重定向,需要检查防止重复添加
|
||
if dir2.GetName() == "return" && slices.Contains(p.parameters2Slices(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: []config.Parameter{{Value: "($scheme"}, {Value: "="}, {Value: "http)"}},
|
||
}
|
||
redirectDir := &config.Directive{
|
||
Name: "return",
|
||
Parameters: []config.Parameter{{Value: "308"}, {Value: "https://$host$request_uri"}},
|
||
}
|
||
redirectDir.SetParent(ifDir.GetParent())
|
||
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(p.parameters2Slices(dir.GetParameters()), "497") && !slices.Contains(p.parameters2Slices(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(p.parameters2Slices(dir.GetParameters()), "497") && slices.Contains(p.parameters2Slices(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: []config.Parameter{{Value: "497"}, {Value: "=308"}, {Value: "https://$host:$server_port$request_uri"}},
|
||
})
|
||
}
|
||
|
||
return p.Set("server", directives)
|
||
}
|
||
|
||
func (p *Parser) SetAltSvc(altSvc string) 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(p.parameters2Slices(dir.GetParameters()), "Alt-Svc") {
|
||
foundFlag = true
|
||
if altSvc != "" { // 为空表示要删除
|
||
directives = append(directives, &config.Directive{
|
||
Name: dir.GetName(),
|
||
Parameters: []config.Parameter{{Value: "Alt-Svc"}, {Value: altSvc}},
|
||
Comment: dir.GetComment(),
|
||
})
|
||
}
|
||
} else {
|
||
directives = append(directives, &config.Directive{
|
||
Name: dir.GetName(),
|
||
Parameters: dir.GetParameters(),
|
||
Comment: dir.GetComment(),
|
||
})
|
||
}
|
||
}
|
||
|
||
if !foundFlag && altSvc != "" {
|
||
directives = append(directives, &config.Directive{
|
||
Name: "add_header",
|
||
Parameters: []config.Parameter{{Value: "Alt-Svc"}, {Value: altSvc}},
|
||
})
|
||
}
|
||
|
||
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: []config.Parameter{{Value: 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: []config.Parameter{{Value: errorLog}},
|
||
},
|
||
})
|
||
}
|