Skip to content

Commit

Permalink
feat: 优化https证书签发
Browse files Browse the repository at this point in the history
  • Loading branch information
devhaozi committed Jun 22, 2024
1 parent f2e8ff8 commit 7ec3788
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 36 deletions.
12 changes: 9 additions & 3 deletions app/http/controllers/website_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,9 +549,12 @@ server
# waf标记位结束
# 错误页配置,可自行设置
#error_page 404 /404.html;
error_page 404 /404.html;
#error_page 502 /502.html;
# acme证书签发配置,不可修改
include /www/server/vhost/acme/%s.conf;
# 伪静态规则引入,修改后将导致面板设置的伪静态规则失效
include /www/server/vhost/rewrite/%s.conf;
Expand All @@ -572,11 +575,14 @@ server
error_log /www/wwwlogs/%s.log;
}
`, website.Path, website.Php, website.Name, website.Name, website.Name)
`, website.Path, website.Php, website.Name, website.Name, website.Name, website.Name)
if err := io.Write("/www/server/vhost/"+website.Name+".conf", raw, 0644); err != nil {
return nil
}
if err := io.Write("/www/server/vhost/rewrite"+website.Name+".conf", "", 0644); err != nil {
if err := io.Write("/www/server/vhost/rewrite/"+website.Name+".conf", "", 0644); err != nil {
return nil
}
if err := io.Write("/www/server/vhost/acme/"+website.Name+".conf", "", 0644); err != nil {
return nil
}
if err := systemctl.Reload("openresty"); err != nil {
Expand Down
7 changes: 5 additions & 2 deletions internal/services/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package services
import (
"context"
"errors"
"fmt"
"strings"
"time"

Expand Down Expand Up @@ -255,7 +256,8 @@ func (s *CertImpl) ObtainAuto(ID uint) (acme.Certificate, error) {
return acme.Certificate{}, errors.New("通配符域名无法使用 HTTP 验证")
}
}
client.UseHTTP(cert.Website.Path)
conf := fmt.Sprintf("/www/server/vhost/acme/%s.conf", cert.Website.Name)
client.UseHTTP(conf, cert.Website.Path)
}
}

Expand Down Expand Up @@ -380,7 +382,8 @@ func (s *CertImpl) Renew(ID uint) (acme.Certificate, error) {
return acme.Certificate{}, errors.New("通配符域名无法使用 HTTP 验证")
}
}
client.UseHTTP(cert.Website.Path)
conf := fmt.Sprintf("/www/server/vhost/acme/%s.conf", cert.Website.Name)
client.UseHTTP(conf, cert.Website.Path)
}
}

Expand Down
26 changes: 10 additions & 16 deletions internal/services/website.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ server
error_page 404 /404.html;
#error_page 502 /502.html;
# acme证书签发配置,不可修改
include /www/server/vhost/acme/%s.conf;
# 伪静态规则引入,修改后将导致面板设置的伪静态规则失效
include /www/server/vhost/rewrite/%s.conf;
Expand All @@ -259,7 +262,7 @@ server
access_log /www/wwwlogs/%s.log;
error_log /www/wwwlogs/%s.log;
}
`, portList, domainList, website.Path, website.Php, website.Name, website.Name, website.Name)
`, portList, domainList, website.Path, website.Php, website.Name, website.Name, website.Name, website.Name)

if err := io.Write("/www/server/vhost/"+website.Name+".conf", nginxConf, 0644); err != nil {
return models.Website{}, err
Expand Down Expand Up @@ -543,21 +546,12 @@ func (r *WebsiteImpl) Delete(id uint) error {
return err
}

if err := io.Remove("/www/server/vhost/" + website.Name + ".conf"); err != nil {
return err
}
if err := io.Remove("/www/server/vhost/rewrite/" + website.Name + ".conf"); err != nil {
return err
}
if err := io.Remove("/www/server/vhost/ssl/" + website.Name + ".pem"); err != nil {
return err
}
if err := io.Remove("/www/server/vhost/ssl/" + website.Name + ".key"); err != nil {
return err
}
if err := io.Remove(website.Path); err != nil {
return err
}
_ = io.Remove("/www/server/vhost/" + website.Name + ".conf")
_ = io.Remove("/www/server/vhost/rewrite/" + website.Name + ".conf")
_ = io.Remove("/www/server/vhost/acme/" + website.Name + ".conf")
_ = io.Remove("/www/server/vhost/ssl/" + website.Name + ".pem")
_ = io.Remove("/www/server/vhost/ssl/" + website.Name + ".key")
_ = io.Remove(website.Path)

return systemctl.Reload("openresty")
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/acme/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,12 @@ func (c *Client) UseManualDns(total int, check ...bool) {
}

// UseHTTP 使用 HTTP 验证
func (c *Client) UseHTTP(path string) {
// conf openresty 配置文件路径
// path 验证文件存放路径
func (c *Client) UseHTTP(conf, path string) {
c.zClient.ChallengeSolvers = map[string]acmez.Solver{
acme.ChallengeTypeHTTP01: httpSolver{
conf: conf,
path: path,
},
}
Expand Down
47 changes: 34 additions & 13 deletions pkg/acme/solvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ import (
"github.com/libdns/libdns"
"github.com/mholt/acmez/v2/acme"
"golang.org/x/net/publicsuffix"

"github.com/TheTNB/panel/pkg/systemctl"
)

type httpSolver struct {
conf string
path string
}

Expand All @@ -26,12 +29,24 @@ func (s httpSolver) Present(_ context.Context, challenge acme.Challenge) error {
}

challengeFilePath := filepath.Join(s.path, challenge.HTTP01ResourcePath())
if err = os.MkdirAll(filepath.Dir(challengeFilePath), 0o755); err != nil {
return fmt.Errorf("无法在网站目录创建 HTTP 挑战所需的目录: %w", err)
if err = os.MkdirAll(filepath.Dir(challengeFilePath), 0755); err != nil {
return fmt.Errorf("无法在网站目录创建HTTP挑战所需的目录: %w", err)
}

if err = os.WriteFile(challengeFilePath, []byte(challenge.KeyAuthorization), 0o644); err != nil {
return fmt.Errorf("无法在网站目录创建 HTTP 挑战所需的文件: %w", err)
if err = os.WriteFile(challengeFilePath, []byte(challenge.KeyAuthorization), 0644); err != nil {
return fmt.Errorf("无法在网站目录创建HTTP挑战所需的文件: %w", err)
}

conf := fmt.Sprintf(`location = /.well-known/acme-challenge/%s {
default_type text/plain;
return 200 %q;
}
`, challenge.Token, challenge.KeyAuthorization)
if err = os.WriteFile(s.conf, []byte(conf), 0644); err != nil {
return fmt.Errorf("无法写入OpenResty配置文件: %w", err)
}
if err = systemctl.Reload("openresty"); err != nil {
return fmt.Errorf("无法重载OpenResty: %w", err)
}

return nil
Expand All @@ -44,7 +59,13 @@ func (s httpSolver) CleanUp(_ context.Context, challenge acme.Challenge) error {
}

if err := os.Remove(filepath.Join(s.path, challenge.HTTP01ResourcePath())); err != nil {
return fmt.Errorf("无法删除 HTTP 挑战文件: %w", err)
return fmt.Errorf("无法删除HTTP挑战文件: %w", err)
}
if err := os.WriteFile(s.conf, []byte{}, 0644); err != nil {
return fmt.Errorf("无法清空OpenResty配置文件: %w", err)
}
if err := systemctl.Reload("openresty"); err != nil {
return fmt.Errorf("无法重载OpenResty: %w", err)
}

return nil
Expand All @@ -61,11 +82,11 @@ func (s dnsSolver) Present(ctx context.Context, challenge acme.Challenge) error
keyAuth := challenge.DNS01KeyAuthorization()
provider, err := s.getDNSProvider()
if err != nil {
return fmt.Errorf("获取 DNS 提供商失败: %w", err)
return fmt.Errorf("获取DNS提供商失败: %w", err)
}
zone, err := publicsuffix.EffectiveTLDPlusOne(dnsName)
if err != nil {
return fmt.Errorf("获取域名 %q 的顶级域失败: %w", dnsName, err)
return fmt.Errorf("获取域名%q的顶级域失败: %w", dnsName, err)
}

rec := libdns.Record{
Expand All @@ -76,10 +97,10 @@ func (s dnsSolver) Present(ctx context.Context, challenge acme.Challenge) error

results, err := provider.AppendRecords(ctx, zone+".", []libdns.Record{rec})
if err != nil {
return fmt.Errorf("域名 %q 添加临时记录 %q 失败: %w", zone, dnsName, err)
return fmt.Errorf("域名%q添加临时记录%q失败: %w", zone, dnsName, err)
}
if len(results) != 1 {
return fmt.Errorf("预期添加 1 条记录,但实际添加了 %d 条记录", len(results))
return fmt.Errorf("预期添加1条记录,但实际添加了%d条记录", len(results))
}

s.records = &results
Expand All @@ -90,19 +111,19 @@ func (s dnsSolver) CleanUp(ctx context.Context, challenge acme.Challenge) error
dnsName := challenge.DNS01TXTRecordName()
provider, err := s.getDNSProvider()
if err != nil {
return fmt.Errorf("获取 DNS 提供商失败: %w", err)
return fmt.Errorf("获取DNS提供商失败: %w", err)
}
zone, err := publicsuffix.EffectiveTLDPlusOne(dnsName)
if err != nil {
return fmt.Errorf("获取域名 %q 的顶级域失败: %w", dnsName, err)
return fmt.Errorf("获取域名%q的顶级域失败: %w", dnsName, err)
}

ctx, cancel := context.WithTimeout(ctx, 2*time.Minute)
defer cancel()

_, err = provider.DeleteRecords(ctx, zone+".", *s.records)
if err != nil {
return fmt.Errorf("域名 %q 删除临时记录 %q 失败: %w", zone, dnsName, err)
return fmt.Errorf("域名%q删除临时记录%q失败: %w", zone, dnsName, err)
}

return nil
Expand All @@ -126,7 +147,7 @@ func (s dnsSolver) getDNSProvider() (DNSProvider, error) {
APIToken: s.param.APIkey,
}
default:
return nil, fmt.Errorf("未知的 DNS 提供商 %q", s.dns)
return nil, fmt.Errorf("未知的DNS提供商 %q", s.dns)
}

return dns, nil
Expand Down
3 changes: 2 additions & 1 deletion scripts/openresty/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ mkdir -p /www/server/vhost
mkdir -p /www/server/vhost
mkdir -p /www/server/vhost/rewrite
mkdir -p /www/server/vhost/ssl
mkdir -p /www/server/vhost/acme

# 写入主配置文件
cat > ${openrestyPath}/conf/nginx.conf << EOF
Expand Down Expand Up @@ -561,7 +562,7 @@ cat > ${openrestyPath}/html/block.html << EOF
<div class="container">
<h1>耗子面板</h1>
<p>本次请求判断为危险的攻击请求,已被拦截!</p>
<p>当您看到此页面,说明您的请求被WAF拦截,可能是由于您的请求中包含了危险的攻击内容,或者您的请求被误判为攻击请求。</p>
<p>可能您的请求中包含了危险的攻击内容,或者您的请求被误判为攻击请求。</p>
<p>如果您认为这是误判,请联系服务器管理员解决。</p>
</div>
</body>
Expand Down
9 changes: 9 additions & 0 deletions scripts/update_panel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ if version_lt "$oldVersion" "2.2.10"; then
fi
fi

if version_lt "$oldVersion" "2.2.14"; then
echo "更新面板到 v2.2.14 ..."
echo "Update panel to v2.2.14 ..."
if [ -f "/www/server/openresty/bin/openresty" ]; then
mkdir -p /www/server/vhost/acme
chmod -R 644 /www/server/vhost/acme
fi
fi

echo $HR
echo "更新结束"
echo "Update finished"

0 comments on commit 7ec3788

Please sign in to comment.