mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 06:47:20 +08:00
feat: 初步实现nginx配置解析器
This commit is contained in:
2
go.mod
2
go.mod
@@ -39,6 +39,7 @@ require (
|
||||
github.com/shirou/gopsutil v2.21.11+incompatible
|
||||
github.com/spf13/cast v1.7.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/tufanbarisyildirim/gonginx v0.0.0-20240907135031-d38eb71142ac
|
||||
github.com/urfave/cli/v3 v3.0.0-alpha9
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/crypto v0.28.0
|
||||
@@ -125,7 +126,6 @@ require (
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gotest.tools/v3 v3.5.1 // indirect
|
||||
modernc.org/libc v1.60.1 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
|
||||
2
go.sum
2
go.sum
@@ -297,6 +297,8 @@ github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZ
|
||||
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
|
||||
github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
|
||||
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
|
||||
github.com/tufanbarisyildirim/gonginx v0.0.0-20240907135031-d38eb71142ac h1:IXccMEFcB+UqGWae8OF9EoA0/8GCLlDj6s84LCU7y58=
|
||||
github.com/tufanbarisyildirim/gonginx v0.0.0-20240907135031-d38eb71142ac/go.mod h1:itu4KWRgrfEwGcfNka+rV4houuirUau53i0diN4lG5g=
|
||||
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
|
||||
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
|
||||
@@ -27,7 +27,7 @@ type WebsiteDelete struct {
|
||||
type WebsiteUpdate struct {
|
||||
ID uint `form:"id" json:"id" validate:"required"`
|
||||
Domains []string `form:"domains" json:"domains" validate:"required"`
|
||||
Ports []uint `form:"ports" json:"ports" validate:"required"`
|
||||
Listens []string `form:"listens" json:"listens" validate:"required"`
|
||||
SSLPorts []uint `form:"ssl_ports" json:"ssl_ports" validate:"required"`
|
||||
QUICPorts []uint `form:"quic_ports" json:"quic_ports" validate:"required"`
|
||||
OCSP bool `form:"ocsp" json:"ocsp"`
|
||||
|
||||
36
pkg/nginx/data.go
Normal file
36
pkg/nginx/data.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package nginx
|
||||
|
||||
var order = []string{"listen", "server_name", "index", "root",
|
||||
"ssl_certificate", "ssl_certificate_key", "ssl_session_timeout", "ssl_session_cache", "ssl_protocols", "ssl_ciphers", "ssl_prefer_server_ciphers", "ssl_early_data", "ssl_stapling", "ssl_stapling_verify", "ssl_trusted_certificate",
|
||||
"resolver", "error_page", "include", "if", "location", "access_log", "error_log"}
|
||||
|
||||
const defaultConf = `server
|
||||
{
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
index index.php index.html;
|
||||
root /www/wwwroot/default;
|
||||
# 错误页配置,可自行修改
|
||||
#error_page 502 /502.html;
|
||||
error_page 404 /404.html;
|
||||
include enable-php-0.conf;
|
||||
# acme证书签发配置,不可修改
|
||||
include /www/server/vhost/acme/test.conf;
|
||||
# 伪静态规则引入,修改后将导致面板设置的伪静态规则失效
|
||||
include /www/server/vhost/rewrite/test.conf;
|
||||
# 禁止访问部分敏感目录,可自行修改
|
||||
location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn)
|
||||
{
|
||||
return 404;
|
||||
}
|
||||
# 不记录静态资源的访问日志,可自行修改
|
||||
location ~ .*\.(js|css|ttf|otf|woff|woff2|eot)$
|
||||
{
|
||||
expires 1h;
|
||||
error_log /dev/null;
|
||||
access_log /dev/null;
|
||||
}
|
||||
access_log /www/wwwlogs/default.log;
|
||||
error_log /www/wwwlogs/default.log;
|
||||
}
|
||||
`
|
||||
163
pkg/nginx/getter.go
Normal file
163
pkg/nginx/getter.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package nginx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (p *Parser) GetListen() ([][]string, error) {
|
||||
directives, err := p.Find("server.listen")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result [][]string
|
||||
for _, dir := range directives {
|
||||
result = append(result, dir.GetParameters())
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (p *Parser) GetServerName() ([]string, error) {
|
||||
directive, err := p.FindOne("server.server_name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return directive.GetParameters(), nil
|
||||
}
|
||||
|
||||
func (p *Parser) GetIndex() ([]string, error) {
|
||||
directive, err := p.FindOne("server.index")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return directive.GetParameters(), nil
|
||||
}
|
||||
|
||||
func (p *Parser) GetRoot() (string, error) {
|
||||
directive, err := p.FindOne("server.root")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(directive.GetParameters()) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return directive.GetParameters()[0], nil
|
||||
}
|
||||
|
||||
func (p *Parser) GetIncludes() ([]string, error) {
|
||||
directives, err := p.Find("server.include")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []string
|
||||
for _, dir := range directives {
|
||||
result = append(result, dir.GetParameters()...)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (p *Parser) GetPHP() (int, error) {
|
||||
directives, err := p.Find("server.include")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var result int
|
||||
for _, dir := range directives {
|
||||
if slices.ContainsFunc(dir.GetParameters(), func(s string) bool {
|
||||
return strings.HasPrefix(s, "enable-php-") && strings.HasSuffix(s, ".conf")
|
||||
}) {
|
||||
_, err = fmt.Sscanf(dir.GetParameters()[0], "enable-php-%d.conf", &result)
|
||||
}
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (p *Parser) GetHTTPS() bool {
|
||||
directive, err := p.FindOne("server.ssl_certificate")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if len(directive.GetParameters()) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *Parser) GetOCSP() (bool, error) {
|
||||
directive, err := p.FindOne("server.ssl_stapling")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if len(directive.GetParameters()) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return directive.GetParameters()[0] == "on", nil
|
||||
}
|
||||
|
||||
func (p *Parser) GetHSTS() (bool, error) {
|
||||
directives, err := p.Find("server.add_header")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, dir := range directives {
|
||||
if slices.Contains(dir.GetParameters(), "Strict-Transport-Security") {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (p *Parser) GetHTTPRedirect() (bool, error) {
|
||||
directives, err := p.Find("server.if")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
for _, dir := range directives {
|
||||
for _, dir2 := range dir.GetBlock().GetDirectives() {
|
||||
if dir2.GetName() == "return" && slices.Contains(dir2.GetParameters(), "https://$host$request_uri") {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (p *Parser) GetAccessLog() (string, error) {
|
||||
directive, err := p.FindOne("server.access_log")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(directive.GetParameters()) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return directive.GetParameters()[0], nil
|
||||
}
|
||||
|
||||
func (p *Parser) GetErrorLog() (string, error) {
|
||||
directive, err := p.FindOne("server.error_log")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(directive.GetParameters()) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return directive.GetParameters()[0], nil
|
||||
}
|
||||
170
pkg/nginx/parser.go
Normal file
170
pkg/nginx/parser.go
Normal file
@@ -0,0 +1,170 @@
|
||||
package nginx
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/tufanbarisyildirim/gonginx/config"
|
||||
"github.com/tufanbarisyildirim/gonginx/dumper"
|
||||
"github.com/tufanbarisyildirim/gonginx/parser"
|
||||
)
|
||||
|
||||
// Parser Nginx vhost 配置解析器
|
||||
type Parser struct {
|
||||
c *config.Config
|
||||
orderIndex map[string]int
|
||||
}
|
||||
|
||||
func NewParser(str ...string) (*Parser, error) {
|
||||
if len(str) == 0 {
|
||||
str = append(str, defaultConf)
|
||||
}
|
||||
p := parser.NewStringParser(str[0], parser.WithSkipIncludeParsingErr(), parser.WithSkipValidDirectivesErr())
|
||||
c, err := p.Parse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
orderIndex := make(map[string]int)
|
||||
for i, name := range order {
|
||||
orderIndex[name] = i
|
||||
}
|
||||
|
||||
return &Parser{c: c, orderIndex: orderIndex}, nil
|
||||
}
|
||||
|
||||
func (p *Parser) Config() *config.Config {
|
||||
return p.c
|
||||
}
|
||||
|
||||
// Find 通过表达式查找配置
|
||||
// eg: Find("server.listen")
|
||||
func (p *Parser) Find(key string) ([]config.IDirective, error) {
|
||||
parts := strings.Split(key, ".")
|
||||
var block *config.Block
|
||||
var ok bool
|
||||
block = p.c.Block
|
||||
for i := 0; i < len(parts)-1; i++ {
|
||||
key = parts[i]
|
||||
directives := block.FindDirectives(key)
|
||||
if len(directives) == 0 {
|
||||
return nil, errors.New("given key not found")
|
||||
}
|
||||
if len(directives) > 1 {
|
||||
return nil, errors.New("multiple directives found")
|
||||
}
|
||||
block, ok = directives[0].GetBlock().(*config.Block)
|
||||
if !ok {
|
||||
return nil, errors.New("block is not *config.Block")
|
||||
}
|
||||
}
|
||||
|
||||
var result []config.IDirective
|
||||
for _, dir := range block.GetDirectives() {
|
||||
if dir.GetName() == parts[len(parts)-1] {
|
||||
result = append(result, dir)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// FindOne 通过表达式查找一个配置
|
||||
// eg: FindOne("server.server_name")
|
||||
func (p *Parser) FindOne(key string) (config.IDirective, error) {
|
||||
directives, err := p.Find(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(directives) == 0 {
|
||||
return nil, errors.New("given key not found")
|
||||
}
|
||||
|
||||
return directives[0], nil
|
||||
}
|
||||
|
||||
// Clear 通过表达式移除配置
|
||||
// eg: Clear("server.server_name")
|
||||
func (p *Parser) Clear(key string) error {
|
||||
parts := strings.Split(key, ".")
|
||||
last := parts[len(parts)-1]
|
||||
parts = parts[:len(parts)-1]
|
||||
|
||||
var block *config.Block
|
||||
var ok bool
|
||||
block = p.c.Block
|
||||
for i := 0; i < len(parts); i++ {
|
||||
directives := block.FindDirectives(parts[i])
|
||||
if len(directives) == 0 {
|
||||
return errors.New("given key not found")
|
||||
}
|
||||
if len(directives) > 1 {
|
||||
return errors.New("multiple directives found")
|
||||
}
|
||||
block, ok = directives[0].GetBlock().(*config.Block)
|
||||
if !ok {
|
||||
return errors.New("block is not *config.Block")
|
||||
}
|
||||
}
|
||||
|
||||
var newDirectives []config.IDirective
|
||||
for _, directive := range block.GetDirectives() {
|
||||
if directive.GetName() != last {
|
||||
newDirectives = append(newDirectives, directive)
|
||||
}
|
||||
}
|
||||
block.Directives = newDirectives
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set 通过表达式设置配置
|
||||
// eg: Set("server.server_name", []directive)
|
||||
func (p *Parser) Set(key string, directives []*config.Directive) error {
|
||||
parts := strings.Split(key, ".")
|
||||
|
||||
var block *config.Block
|
||||
var ok bool
|
||||
block = p.c.Block
|
||||
for i := 0; i < len(parts); i++ {
|
||||
sub := block.FindDirectives(parts[i])
|
||||
if len(sub) == 0 {
|
||||
return errors.New("given key not found")
|
||||
}
|
||||
if len(sub) > 1 {
|
||||
return errors.New("multiple directives found")
|
||||
}
|
||||
block, ok = sub[0].GetBlock().(*config.Block)
|
||||
if !ok {
|
||||
return errors.New("block is not *config.Block")
|
||||
}
|
||||
}
|
||||
|
||||
for _, directive := range directives {
|
||||
directive.SetParent(block)
|
||||
block.Directives = append(block.Directives, directive)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) Sort() {
|
||||
p.sortDirectives(p.c.Directives, p.orderIndex)
|
||||
}
|
||||
|
||||
func (p *Parser) Dump() string {
|
||||
p.Sort()
|
||||
return dumper.DumpConfig(p.c, dumper.IndentedStyle)
|
||||
}
|
||||
|
||||
func (p *Parser) sortDirectives(directives []config.IDirective, orderIndex map[string]int) {
|
||||
slices.SortFunc(directives, func(a config.IDirective, b config.IDirective) int {
|
||||
return orderIndex[a.GetName()] - orderIndex[b.GetName()]
|
||||
})
|
||||
for _, directive := range directives {
|
||||
if block, ok := directive.GetBlock().(*config.Block); ok {
|
||||
p.sortDirectives(block.Directives, orderIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
26
pkg/nginx/parser_test.go
Normal file
26
pkg/nginx/parser_test.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package nginx
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type NginxTestSuite struct {
|
||||
parser *Parser
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func TestNginxTestSuite(t *testing.T) {
|
||||
parser, err := NewParser()
|
||||
if err != nil {
|
||||
t.Errorf("parse error %v", err)
|
||||
}
|
||||
suite.Run(t, &NginxTestSuite{
|
||||
parser: parser,
|
||||
})
|
||||
}
|
||||
|
||||
func (suite *NginxTestSuite) TestA() {
|
||||
suite.NoError(suite.parser.SetPHP(81))
|
||||
}
|
||||
346
pkg/nginx/setter.go
Normal file
346
pkg/nginx/setter.go
Normal file
@@ -0,0 +1,346 @@
|
||||
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) 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) SetIncludes(includes []string) error {
|
||||
if err := p.Clear("server.include"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var directives []*config.Directive
|
||||
for _, i := range includes {
|
||||
directives = append(directives, &config.Directive{
|
||||
Name: "include",
|
||||
Parameters: []string{i},
|
||||
})
|
||||
}
|
||||
|
||||
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) UnSetHTTPS() 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.UnSetHTTPS(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return p.Set("server", []*config.Directive{
|
||||
{
|
||||
Name: "ssl_certificate",
|
||||
Parameters: []string{cert},
|
||||
Comment: []string{"# https配置"},
|
||||
},
|
||||
{
|
||||
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) 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"},
|
||||
Comment: []string{"# hsts配置"},
|
||||
})
|
||||
}
|
||||
|
||||
return p.Set("server", directives)
|
||||
}
|
||||
|
||||
func (p *Parser) SetHTTPRedirect(httpRedirect bool) error {
|
||||
old, 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 old {
|
||||
for _, dir2 := range dir.GetBlock().GetDirectives() { // if 中所有指令
|
||||
if block, ok := dir2.GetBlock().(*config.Block); ok {
|
||||
var newDirectives []config.IDirective
|
||||
for _, directive := range block.GetDirectives() {
|
||||
if !httpRedirect {
|
||||
// 不启用http重定向,则判断并移除特定的return指令
|
||||
if directive.GetName() != "return" && !slices.Contains(directive.GetParameters(), "https://$host$request_uri") {
|
||||
newDirectives = append(newDirectives, directive)
|
||||
}
|
||||
} else {
|
||||
// 启用http重定向,需要检查防止重复添加
|
||||
if directive.GetName() == "return" && slices.Contains(directive.GetParameters(), "https://$host$request_uri") {
|
||||
foundFlag = true
|
||||
}
|
||||
newDirectives = append(newDirectives, directive)
|
||||
}
|
||||
|
||||
}
|
||||
block.Directives = newDirectives
|
||||
}
|
||||
}
|
||||
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)"},
|
||||
Comment: []string{"# http重定向"},
|
||||
}
|
||||
redirectDir := &config.Directive{
|
||||
Name: "return",
|
||||
Parameters: []string{"301", "https://$host$request_uri"},
|
||||
}
|
||||
redirectDir.SetParent(ifDir.GetBlock())
|
||||
ifBlock := ifDir.GetBlock().(*config.Block)
|
||||
ifBlock.Directives = append(ifBlock.Directives, redirectDir)
|
||||
directives = append(directives, ifDir)
|
||||
}
|
||||
|
||||
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},
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user