From b3a0d0971a639652bec6869282dabc1ab1c95d8f Mon Sep 17 00:00:00 2001 From: iluobei Date: Thu, 12 Mar 2026 17:20:16 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4acme-go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/mmw-agent/main.go | 1 + go.mod | 21 --- go.sum | 265 +---------------------------- internal/acme/client.go | 300 --------------------------------- internal/acme/deployer.go | 68 -------- internal/acme/dns_providers.go | 100 ----------- internal/acme/webroot.go | 55 ------ internal/agent/client.go | 161 +++++------------- internal/handler/manage.go | 82 +++++++++ 9 files changed, 126 insertions(+), 927 deletions(-) delete mode 100644 internal/acme/client.go delete mode 100644 internal/acme/deployer.go delete mode 100644 internal/acme/dns_providers.go delete mode 100644 internal/acme/webroot.go diff --git a/cmd/mmw-agent/main.go b/cmd/mmw-agent/main.go index 8ed000d..d61c9c2 100644 --- a/cmd/mmw-agent/main.go +++ b/cmd/mmw-agent/main.go @@ -74,6 +74,7 @@ func main() { mux.HandleFunc("/api/child/outbounds", manageHandler.HandleOutbounds) mux.HandleFunc("/api/child/routing", manageHandler.HandleRouting) mux.HandleFunc("/api/child/scan", manageHandler.HandleScan) + mux.HandleFunc("/api/child/cert/deploy", manageHandler.HandleCertDeploy) // Health check mux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { diff --git a/go.mod b/go.mod index 4390da4..6299020 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module mmw-agent go 1.25.6 require ( - github.com/go-acme/lego/v4 v4.31.0 github.com/gorilla/websocket v1.5.3 github.com/xtls/xray-core v1.260123.0 google.golang.org/grpc v1.78.0 @@ -11,32 +10,15 @@ require ( ) require ( - github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect - github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.13 // indirect - github.com/alibabacloud-go/debug v1.0.1 // indirect - github.com/alibabacloud-go/tea v1.4.0 // indirect - github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect - github.com/aliyun/credentials-go v1.4.7 // indirect github.com/andybalholm/brotli v1.0.6 // indirect github.com/apernet/quic-go v0.57.2-0.20260111184307-eec823306178 // indirect - github.com/cenkalti/backoff/v5 v5.0.3 // indirect - github.com/clbanning/mxj/v2 v2.7.0 // indirect github.com/cloudflare/circl v1.6.3 // indirect github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect - github.com/go-acme/alidns-20150109/v4 v4.7.0 // indirect - github.com/go-acme/tencentclouddnspod v1.1.25 // indirect - github.com/go-jose/go-jose/v4 v4.1.3 // indirect github.com/google/btree v1.1.2 // indirect - github.com/google/go-querystring v1.2.0 // indirect - github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 // indirect github.com/juju/ratelimit v1.0.2 // indirect github.com/klauspost/compress v1.17.4 // indirect github.com/klauspost/cpuid/v2 v2.0.12 // indirect github.com/miekg/dns v1.1.72 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/nrdcg/dnspod-go v0.4.0 // indirect - github.com/nrdcg/namesilo v0.5.0 // indirect github.com/pires/go-proxyproto v0.9.0 // indirect github.com/quic-go/qpack v0.6.0 // indirect github.com/refraction-networking/utls v1.8.2 // indirect @@ -44,8 +26,6 @@ require ( github.com/sagernet/sing v0.5.1 // indirect github.com/sagernet/sing-shadowsocks v0.2.7 // indirect github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.28 // indirect - github.com/tjfoc/gmsm v1.4.1 // indirect github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect github.com/vishvananda/netlink v1.3.1 // indirect github.com/vishvananda/netns v0.0.5 // indirect @@ -64,7 +44,6 @@ require ( golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect google.golang.org/protobuf v1.36.11 // indirect - gopkg.in/ini.v1 v1.67.0 // indirect gvisor.dev/gvisor v0.0.0-20260109181451-4be7c433dae2 // indirect lukechampine.com/blake3 v1.4.1 // indirect ) diff --git a/go.sum b/go.sum index d3c7992..0522f95 100644 --- a/go.sum +++ b/go.sum @@ -1,125 +1,32 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6 h1:eIf+iGJxdU4U9ypaUfbtOWCsZSbTb8AUHvyPrxu6mAA= -github.com/alibabacloud-go/alibabacloud-gateway-pop v0.0.6/go.mod h1:4EUIoxs/do24zMOGGqYVWgw0s9NtiylnJglOeEB5UJo= -github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4/go.mod h1:sCavSAvdzOjul4cEqeVtvlSaSScfNsTQ+46HwlTL1hc= -github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 h1:zE8vH9C7JiZLNJJQ5OwjU9mSi4T9ef9u3BURT6LCLC8= -github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5/go.mod h1:tWnyE9AjF8J8qqLk645oUmVUnFybApTQWklQmi5tY6g= -github.com/alibabacloud-go/darabonba-array v0.1.0 h1:vR8s7b1fWAQIjEjWnuF0JiKsCvclSRTfDzZHTYqfufY= -github.com/alibabacloud-go/darabonba-array v0.1.0/go.mod h1:BLKxr0brnggqOJPqT09DFJ8g3fsDshapUD3C3aOEFaI= -github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC2NG0Ax+GpOM5gtupki31XE= -github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F4PKuMgEUETNZasrDM6vqVr/Can7H8= -github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc= -github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc= -github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.13 h1:Q00FU3H94Ts0ZIHDmY+fYGgB7dV9D/YX6FGsgorQPgw= -github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.13/go.mod h1:lxFGfobinVsQ49ntjpgWghXmIF0/Sm4+wvBJ1h5RtaE= -github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg= -github.com/alibabacloud-go/darabonba-signature-util v0.0.7/go.mod h1:oUzCYV2fcCH797xKdL6BDH8ADIHlzrtKVjeRtunBNTQ= -github.com/alibabacloud-go/darabonba-string v1.0.2 h1:E714wms5ibdzCqGeYJ9JCFywE5nDyvIXIIQbZVFkkqo= -github.com/alibabacloud-go/darabonba-string v1.0.2/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA= -github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY= -github.com/alibabacloud-go/debug v1.0.0/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= -github.com/alibabacloud-go/debug v1.0.1 h1:MsW9SmUtbb1Fnt3ieC6NNZi6aEwrXfDksD4QA6GSbPg= -github.com/alibabacloud-go/debug v1.0.1/go.mod h1:8gfgZCCAC3+SCzjWtY053FrOcd4/qlH6IHTI4QyICOc= -github.com/alibabacloud-go/endpoint-util v1.1.0 h1:r/4D3VSw888XGaeNpP994zDUaxdgTSHBbVfZlzf6b5Q= -github.com/alibabacloud-go/endpoint-util v1.1.0/go.mod h1:O5FuCALmCKs2Ff7JFJMudHs0I5EBgecXXxZRyswlEjE= -github.com/alibabacloud-go/openapi-util v0.1.0/go.mod h1:sQuElr4ywwFRlCCberQwKRFhRzIyG4QTP/P4y1CJ6Ws= -github.com/alibabacloud-go/openapi-util v0.1.1 h1:ujGErJjG8ncRW6XtBBMphzHTvCxn4DjrVw4m04HsS28= -github.com/alibabacloud-go/openapi-util v0.1.1/go.mod h1:/UehBSE2cf1gYT43GV4E+RxTdLRzURImCYY0aRmlXpw= -github.com/alibabacloud-go/tea v1.1.0/go.mod h1:IkGyUSX4Ba1V+k4pCtJUc6jDpZLFph9QMy2VUPTwukg= -github.com/alibabacloud-go/tea v1.1.7/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= -github.com/alibabacloud-go/tea v1.1.8/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= -github.com/alibabacloud-go/tea v1.1.11/go.mod h1:/tmnEaQMyb4Ky1/5D+SE1BAsa5zj/KeGOFfwYm3N/p4= -github.com/alibabacloud-go/tea v1.1.17/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= -github.com/alibabacloud-go/tea v1.1.20/go.mod h1:nXxjm6CIFkBhwW4FQkNrolwbfon8Svy6cujmKFUq98A= -github.com/alibabacloud-go/tea v1.2.2/go.mod h1:CF3vOzEMAG+bR4WOql8gc2G9H3EkH3ZLAQdpmpXMgwk= -github.com/alibabacloud-go/tea v1.3.13/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg= -github.com/alibabacloud-go/tea v1.4.0 h1:MSKhu/kWLPX7mplWMngki8nNt+CyUZ+kfkzaR5VpMhA= -github.com/alibabacloud-go/tea v1.4.0/go.mod h1:A560v/JTQ1n5zklt2BEpurJzZTI8TUT+Psg2drWlxRg= -github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE= -github.com/alibabacloud-go/tea-utils/v2 v2.0.5/go.mod h1:dL6vbUT35E4F4bFTHL845eUloqaerYBYPsdWR2/jhe4= -github.com/alibabacloud-go/tea-utils/v2 v2.0.7 h1:WDx5qW3Xa5ZgJ1c8NfqJkF6w+AU5wB8835UdhPr6Ax0= -github.com/alibabacloud-go/tea-utils/v2 v2.0.7/go.mod h1:qxn986l+q33J5VkialKMqT/TTs3E+U9MJpd001iWQ9I= -github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6qTJya2bDq4X1Tw= -github.com/aliyun/credentials-go v1.3.1/go.mod h1:8jKYhQuDawt8x2+fusqa1Y6mPxemTsBEN04dgcAcYz0= -github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM= -github.com/aliyun/credentials-go v1.4.5/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U= -github.com/aliyun/credentials-go v1.4.7 h1:T17dLqEtPUFvjDRRb5giVvLh6dFT8IcNFJJb7MeyCxw= -github.com/aliyun/credentials-go v1.4.7/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/apernet/quic-go v0.57.2-0.20260111184307-eec823306178 h1:bSq8n+gX4oO/qnM3MKf4kroW75n+phO9Qp6nigJKZ1E= github.com/apernet/quic-go v0.57.2-0.20260111184307-eec823306178/go.mod h1:N1WIjPphkqs4efXWuyDNQ6OjjIK04vM3h+bEgwV+eVU= -github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= -github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME= -github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8= github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 h1:BS21ZUJ/B5X2UVUbczfmdWH7GapPWAhxcMsDnjJTU1E= github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4= github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= -github.com/go-acme/alidns-20150109/v4 v4.7.0 h1:PqJ/wR0JTpL4v0Owu1uM7bPQ1Yww0eQLAuuSdLjjQaQ= -github.com/go-acme/alidns-20150109/v4 v4.7.0/go.mod h1:btQvB6xZoN6ykKB74cPhiR+uvhrEE2AFVXm6RDmCHm0= -github.com/go-acme/lego/v4 v4.31.0 h1:gd4oUYdfs83PR1/SflkNdit9xY1iul2I4EystnU8NXM= -github.com/go-acme/lego/v4 v4.31.0/go.mod h1:m6zcfX/zcbMYDa8s6AnCMnoORWNP8Epnei+6NBCTUGs= -github.com/go-acme/tencentclouddnspod v1.1.25 h1:7H3ZKshkaHzCXfRpAHVB5nvxeDDl2XLeNZfrNHiZj/s= -github.com/go-acme/tencentclouddnspod v1.1.25/go.mod h1:XXfzp0AYV7UAUsHKT6R0KAUJFhqAUXmWGF07Elpa5cE= -github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs= -github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U= github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/go-querystring v1.2.0 h1:yhqkPbu2/OH+V9BfpCVPZkNmUXhb2gBxJArfhIxNtP0= -github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12 h1:9Nu54bhS/H/Kgo2/7xNSUuC5G28VR8ljfrLKU2G4IjU= -github.com/json-iterator/go v1.1.13-0.20220915233716-71ac16282d12/go.mod h1:TBzl5BIHNXfS9+C35ZyJaklL7mLDbgUkcgXzSLa8Tk0= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI= github.com/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= @@ -128,32 +35,16 @@ github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0 github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI= github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nrdcg/dnspod-go v0.4.0 h1:c/jn1mLZNKF3/osJ6mz3QPxTudvPArXTjpkmYj0uK6U= -github.com/nrdcg/dnspod-go v0.4.0/go.mod h1:vZSoFSFeQVm2gWLMkyX61LZ8HI3BaqtHZWgPTGKr6KQ= -github.com/nrdcg/namesilo v0.5.0 h1:6QNxT/XxE+f5B+7QlfWorthNzOzcGlBLRQxqi6YeBrE= -github.com/nrdcg/namesilo v0.5.0/go.mod h1:4UkwlwQfDt74kSGmhLaDylnBrD94IfflnpoEaj6T2qw= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pires/go-proxyproto v0.9.0 h1:3Qg3CLxWx4wJOw5uxhTvc0VrgsJeerDbGTvexu4UK1E= github.com/pires/go-proxyproto v0.9.0/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= github.com/refraction-networking/utls v1.8.2 h1:j4Q1gJj0xngdeH+Ox/qND11aEfhpgoEvV+S9iJ2IdQo= @@ -168,25 +59,10 @@ github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegE github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE= github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4= github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v1.1.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.25/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.28 h1:Rj1WXXNPm9AsPf0PJhWCvlsqfcKPUYdyVnkmEc3O8sI= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.28/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tjfoc/gmsm v1.3.2/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w= -github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= -github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE= github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI= github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU= github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0= @@ -197,9 +73,6 @@ github.com/xtls/reality v0.0.0-20251014195629-e4eec4520535 h1:nwobseOLLRtdbP6z7Z github.com/xtls/reality v0.0.0-20251014195629-e4eec4520535/go.mod h1:vbHCV/3VWUvy1oKvTxxWJRPEWSeR1sYgQHIh6u/JiZQ= github.com/xtls/xray-core v1.260123.0 h1:FCaIDJ1ThRaG9b8TpqNNq3hIcPTN+24vPWQY3s9lSXg= github.com/xtls/xray-core v1.260123.0/go.mod h1:xfHDVg861cIAR5WjwEVKHr/G/HMHSGSC9j3LZmt6sKM= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= @@ -216,173 +89,41 @@ go.uber.org/mock v0.5.2 h1:LbtPTcP8A5k9WPXj54PPPbjcI4Y6lhyOZXn+VS7wNko= go.uber.org/mock v0.5.2/go.mod h1:wLlUxC2vVTPTaE3UD51E0BGOAElKrILxhVSDYQLld5o= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20241210194714-1829a127f884 h1:Y/Mj/94zIQQGHVSv1tTtQBDaQaJe62U9bkDZKKyhPCU= golang.org/x/exp v0.0.0-20241210194714-1829a127f884/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI= golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= -golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.40.0 h1:yLkxfA+Qnul4cs9QA3KnlFu0lVmd8JJfoq+E41uSutA= golang.org/x/tools v0.40.0/go.mod h1:Ik/tzLRlbscWpqqMRjyWYDisX8bG13FrdXp3o4Sr9lc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= -gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -391,7 +132,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gvisor.dev/gvisor v0.0.0-20260109181451-4be7c433dae2 h1:fr6L00yGG2RP5NMea6njWpdC+bm+cMdFClrSpaicp1c= gvisor.dev/gvisor v0.0.0-20260109181451-4be7c433dae2/go.mod h1:QkHjoMIBaYtpVufgwv3keYAbln78mBoCuShZrPrer1Q= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= lukechampine.com/blake3 v1.4.1 h1:I3Smz7gso8w4/TunLKec6K2fn+kyKtDxr/xcQEN84Wg= lukechampine.com/blake3 v1.4.1/go.mod h1:QFosUxmjB8mnrWFSNwKmvxHpfY72bmD2tQ0kBMM3kwo= diff --git a/internal/acme/client.go b/internal/acme/client.go deleted file mode 100644 index bd92bb4..0000000 --- a/internal/acme/client.go +++ /dev/null @@ -1,300 +0,0 @@ -package acme - -import ( - "context" - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/x509" - "encoding/pem" - "errors" - "fmt" - "os" - "path/filepath" - "time" - - "github.com/go-acme/lego/v4/certcrypto" - "github.com/go-acme/lego/v4/certificate" - "github.com/go-acme/lego/v4/challenge/http01" - "github.com/go-acme/lego/v4/lego" - "github.com/go-acme/lego/v4/registration" -) - -// CertResult represents the result of a certificate issuance. -type CertResult struct { - Domain string - CertPath string - KeyPath string - CertPEM string - KeyPEM string - IssueDate time.Time - ExpiryDate time.Time -} - -// CertRequest contains all parameters for a certificate request. -type CertRequest struct { - Email string - Domain string - Provider string - ChallengeMode string - WebrootPath string - DNSProvider string - DNSCredentials map[string]string - EABKid string - EABHmacKey string -} - -// User implements the acme.User interface for lego. -type User struct { - Email string - Registration *registration.Resource - key *ecdsa.PrivateKey -} - -func (u *User) GetEmail() string { return u.Email } -func (u *User) GetRegistration() *registration.Resource { return u.Registration } -func (u *User) GetPrivateKey() crypto.PrivateKey { return u.key } - -// Client wraps the lego ACME client. -type Client struct { - certDir string - staging bool - httpPort string - webrootDir string -} - -// ClientOption configures the Client. -type ClientOption func(*Client) - -func WithCertDir(dir string) ClientOption { - return func(c *Client) { c.certDir = dir } -} - -func WithStaging(staging bool) ClientOption { - return func(c *Client) { c.staging = staging } -} - -func WithHTTPPort(port string) ClientOption { - return func(c *Client) { c.httpPort = port } -} - -func WithWebrootDir(dir string) ClientOption { - return func(c *Client) { c.webrootDir = dir } -} - -// NewClient creates a new ACME client. -func NewClient(opts ...ClientOption) *Client { - c := &Client{ - certDir: "/etc/miaomiaowu/certs", - staging: false, - httpPort: ":80", - } - for _, opt := range opts { - opt(c) - } - return c -} - -// ObtainCertificate requests a new certificate (backward-compatible HTTP-01 only). -func (c *Client) ObtainCertificate(ctx context.Context, email, domain string, useWebroot bool) (*CertResult, error) { - mode := "standalone" - if useWebroot { - mode = "webroot" - } - return c.ObtainCertificateV2(ctx, CertRequest{ - Email: email, - Domain: domain, - Provider: CALetsEncrypt, - ChallengeMode: mode, - WebrootPath: c.webrootDir, - }) -} - -// ObtainCertificateV2 requests a new certificate with full options support. -func (c *Client) ObtainCertificateV2(ctx context.Context, req CertRequest) (*CertResult, error) { - if req.Email == "" { - return nil, errors.New("email is required") - } - if req.Domain == "" { - return nil, errors.New("domain is required") - } - - client, err := c.buildLegoClient(req) - if err != nil { - return nil, err - } - - obtainReq := certificate.ObtainRequest{ - Domains: []string{req.Domain}, - Bundle: true, - } - - certificates, err := client.Certificate.Obtain(obtainReq) - if err != nil { - return nil, fmt.Errorf("obtain certificate: %w", err) - } - - return c.processCertResult(req.Domain, certificates.Certificate, certificates.PrivateKey) -} - -func (c *Client) buildLegoClient(req CertRequest) (*lego.Client, error) { - privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - return nil, fmt.Errorf("generate private key: %w", err) - } - - user := &User{Email: req.Email, key: privateKey} - - config := lego.NewConfig(user) - provider := req.Provider - if provider == "" { - provider = CALetsEncrypt - } - config.CADirURL = ResolveCADirectoryURL(provider, c.staging) - config.Certificate.KeyType = certcrypto.EC256 - - client, err := lego.NewClient(config) - if err != nil { - return nil, fmt.Errorf("create lego client: %w", err) - } - - switch req.ChallengeMode { - case "dns": - if err := c.setupDNSChallenge(client, req); err != nil { - return nil, err - } - case "webroot": - if err := c.setupWebrootChallenge(client, req); err != nil { - return nil, err - } - default: - p := http01.NewProviderServer("", c.httpPort) - if err := client.Challenge.SetHTTP01Provider(p); err != nil { - return nil, fmt.Errorf("set http01 provider: %w", err) - } - } - - regOpts := registration.RegisterOptions{TermsOfServiceAgreed: true} - if req.EABKid != "" && req.EABHmacKey != "" { - reg, err := client.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{ - TermsOfServiceAgreed: true, - Kid: req.EABKid, - HmacEncoded: req.EABHmacKey, - }) - if err != nil { - return nil, fmt.Errorf("register with EAB: %w", err) - } - user.Registration = reg - } else { - reg, err := client.Registration.Register(regOpts) - if err != nil { - return nil, fmt.Errorf("register with ACME: %w", err) - } - user.Registration = reg - } - - return client, nil -} - -func (c *Client) setupDNSChallenge(client *lego.Client, req CertRequest) error { - if req.DNSProvider == "" { - return errors.New("dns_provider is required for DNS-01 challenge") - } - - if len(req.DNSCredentials) > 0 { - cleanup, err := SetDNSCredentialEnv(req.DNSProvider, req.DNSCredentials) - if err != nil { - return fmt.Errorf("set DNS credentials: %w", err) - } - defer cleanup() - } - - provider, err := NewDNSProviderByName(req.DNSProvider) - if err != nil { - return fmt.Errorf("create DNS provider %s: %w", req.DNSProvider, err) - } - - if err := client.Challenge.SetDNS01Provider(provider); err != nil { - return fmt.Errorf("set DNS-01 provider: %w", err) - } - return nil -} - -func (c *Client) setupWebrootChallenge(client *lego.Client, req CertRequest) error { - webrootDir := req.WebrootPath - if webrootDir == "" { - webrootDir = c.webrootDir - } - if webrootDir == "" { - return errors.New("webroot_path is required for webroot challenge") - } - provider, err := NewWebrootProvider(webrootDir) - if err != nil { - return fmt.Errorf("create webroot provider: %w", err) - } - if err := client.Challenge.SetHTTP01Provider(provider); err != nil { - return fmt.Errorf("set webroot provider: %w", err) - } - return nil -} - -func (c *Client) processCertResult(domain string, certPEMBytes, keyPEMBytes []byte) (*CertResult, error) { - expiryDate, issueDate, err := parseCertificateDates(certPEMBytes) - if err != nil { - return nil, fmt.Errorf("parse certificate: %w", err) - } - - certPath, keyPath, err := c.saveCertificate(domain, certPEMBytes, keyPEMBytes) - if err != nil { - return nil, fmt.Errorf("save certificate: %w", err) - } - - return &CertResult{ - Domain: domain, - CertPath: certPath, - KeyPath: keyPath, - CertPEM: string(certPEMBytes), - KeyPEM: string(keyPEMBytes), - IssueDate: issueDate, - ExpiryDate: expiryDate, - }, nil -} - -func (c *Client) saveCertificate(domain string, certPEM, keyPEM []byte) (string, string, error) { - domainDir := filepath.Join(c.certDir, domain) - if err := os.MkdirAll(domainDir, 0700); err != nil { - return "", "", fmt.Errorf("create cert directory: %w", err) - } - - certPath := filepath.Join(domainDir, "fullchain.pem") - keyPath := filepath.Join(domainDir, "privkey.pem") - - if err := os.WriteFile(certPath, certPEM, 0644); err != nil { - return "", "", fmt.Errorf("write certificate: %w", err) - } - if err := os.WriteFile(keyPath, keyPEM, 0600); err != nil { - return "", "", fmt.Errorf("write private key: %w", err) - } - - return certPath, keyPath, nil -} - -func parseCertificateDates(certPEM []byte) (expiryDate, issueDate time.Time, err error) { - block, _ := pem.Decode(certPEM) - if block == nil { - return time.Time{}, time.Time{}, errors.New("failed to decode PEM block") - } - - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - return time.Time{}, time.Time{}, fmt.Errorf("parse certificate: %w", err) - } - - return cert.NotAfter, cert.NotBefore, nil -} - -// GetCertDir returns the certificate storage directory. -func (c *Client) GetCertDir() string { - return c.certDir -} diff --git a/internal/acme/deployer.go b/internal/acme/deployer.go deleted file mode 100644 index 8c9a6f1..0000000 --- a/internal/acme/deployer.go +++ /dev/null @@ -1,68 +0,0 @@ -package acme - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" -) - -// DeployCertFiles writes cert and key PEM to the specified paths. -func DeployCertFiles(certPEM, keyPEM, certPath, keyPath string) error { - if certPath == "" || keyPath == "" { - return fmt.Errorf("deploy paths are required") - } - - if err := os.MkdirAll(filepath.Dir(certPath), 0755); err != nil { - return fmt.Errorf("create cert dir: %w", err) - } - if err := os.MkdirAll(filepath.Dir(keyPath), 0755); err != nil { - return fmt.Errorf("create key dir: %w", err) - } - - if err := os.WriteFile(certPath, []byte(certPEM), 0644); err != nil { - return fmt.Errorf("write cert: %w", err) - } - if err := os.WriteFile(keyPath, []byte(keyPEM), 0600); err != nil { - return fmt.Errorf("write key: %w", err) - } - return nil -} - -// ReloadNginx sends a reload signal to nginx. -func ReloadNginx() error { - cmd := exec.Command("nginx", "-s", "reload") - if output, err := cmd.CombinedOutput(); err != nil { - return fmt.Errorf("nginx reload: %s: %w", string(output), err) - } - return nil -} - -// RestartXray restarts the xray service via systemctl. -func RestartXray() error { - cmd := exec.Command("systemctl", "restart", "xray") - if output, err := cmd.CombinedOutput(); err != nil { - return fmt.Errorf("xray restart: %s: %w", string(output), err) - } - return nil -} - -// Deploy writes cert files and optionally reloads services. -func Deploy(certPEM, keyPEM, certPath, keyPath, reloadTarget string) error { - if err := DeployCertFiles(certPEM, keyPEM, certPath, keyPath); err != nil { - return err - } - - switch reloadTarget { - case "nginx": - return ReloadNginx() - case "xray": - return RestartXray() - case "both": - if err := ReloadNginx(); err != nil { - return err - } - return RestartXray() - } - return nil -} diff --git a/internal/acme/dns_providers.go b/internal/acme/dns_providers.go deleted file mode 100644 index adf5829..0000000 --- a/internal/acme/dns_providers.go +++ /dev/null @@ -1,100 +0,0 @@ -package acme - -import ( - "fmt" - "os" - - "github.com/go-acme/lego/v4/challenge" - "github.com/go-acme/lego/v4/providers/dns/alidns" - "github.com/go-acme/lego/v4/providers/dns/cloudflare" - "github.com/go-acme/lego/v4/providers/dns/dnspod" - "github.com/go-acme/lego/v4/providers/dns/godaddy" - "github.com/go-acme/lego/v4/providers/dns/namesilo" - "github.com/go-acme/lego/v4/providers/dns/tencentcloud" -) - -var DNSProviderEnvKeys = map[string][]string{ - "cloudflare": {"CF_API_EMAIL", "CF_API_KEY", "CF_DNS_API_TOKEN"}, - "alidns": {"ALICLOUD_ACCESS_KEY", "ALICLOUD_SECRET_KEY"}, - "tencentcloud": {"TENCENTCLOUD_SECRET_ID", "TENCENTCLOUD_SECRET_KEY"}, - "dnspod": {"DNSPOD_API_KEY"}, - "namesilo": {"NAMESILO_API_KEY"}, - "godaddy": {"GODADDY_API_KEY", "GODADDY_API_SECRET"}, -} - -func NewDNSProviderByName(name string) (challenge.Provider, error) { - switch name { - case "cloudflare": - return cloudflare.NewDNSProvider() - case "alidns": - return alidns.NewDNSProvider() - case "tencentcloud": - return tencentcloud.NewDNSProvider() - case "dnspod": - return dnspod.NewDNSProvider() - case "namesilo": - return namesilo.NewDNSProvider() - case "godaddy": - return godaddy.NewDNSProvider() - default: - return nil, fmt.Errorf("unsupported DNS provider: %s", name) - } -} - -func SetDNSCredentialEnv(providerType string, credentials map[string]string) (cleanup func(), err error) { - keys, ok := DNSProviderEnvKeys[providerType] - if !ok { - return nil, fmt.Errorf("unsupported DNS provider type: %s", providerType) - } - - var setKeys []string - for _, key := range keys { - if val, exists := credentials[key]; exists && val != "" { - os.Setenv(key, val) - setKeys = append(setKeys, key) - } - } - - if len(setKeys) == 0 { - return nil, fmt.Errorf("no valid credentials provided for DNS provider %s", providerType) - } - - cleanup = func() { - for _, key := range setKeys { - os.Unsetenv(key) - } - } - return cleanup, nil -} - -const ( - CALetsEncrypt = "letsencrypt" - CALetsEncryptStaging = "letsencrypt-staging" - CAZeroSSL = "zerossl" - CABuypass = "buypass" - CABuypassTest = "buypass-test" -) - -var CADirectoryURLs = map[string]string{ - CALetsEncrypt: "https://acme-v02.api.letsencrypt.org/directory", - CALetsEncryptStaging: "https://acme-staging-v02.api.letsencrypt.org/directory", - CAZeroSSL: "https://acme.zerossl.com/v2/DV90", - CABuypass: "https://api.buypass.com/acme/directory", - CABuypassTest: "https://api.test4.buypass.no/acme/directory", -} - -func ResolveCADirectoryURL(provider string, staging bool) string { - if staging { - if url, ok := CADirectoryURLs[provider+"-staging"]; ok { - return url - } - if url, ok := CADirectoryURLs[provider+"-test"]; ok { - return url - } - return CADirectoryURLs[CALetsEncryptStaging] - } - if url, ok := CADirectoryURLs[provider]; ok { - return url - } - return CADirectoryURLs[CALetsEncrypt] -} diff --git a/internal/acme/webroot.go b/internal/acme/webroot.go deleted file mode 100644 index 2af23e5..0000000 --- a/internal/acme/webroot.go +++ /dev/null @@ -1,55 +0,0 @@ -package acme - -import ( - "fmt" - "os" - "path/filepath" - - "github.com/go-acme/lego/v4/challenge/http01" -) - -// WebrootProvider implements the HTTP-01 challenge using a webroot directory. -type WebrootProvider struct { - path string -} - -// NewWebrootProvider creates a new webroot provider. -func NewWebrootProvider(path string) (*WebrootProvider, error) { - if path == "" { - return nil, fmt.Errorf("webroot path is required") - } - - // Ensure the webroot directory exists - challengeDir := filepath.Join(path, http01.ChallengePath("")) - if err := os.MkdirAll(challengeDir, 0755); err != nil { - return nil, fmt.Errorf("create challenge directory: %w", err) - } - - return &WebrootProvider{path: path}, nil -} - -// Present writes the challenge token to the webroot directory. -func (w *WebrootProvider) Present(domain, token, keyAuth string) error { - challengePath := filepath.Join(w.path, http01.ChallengePath(token)) - - // Ensure parent directory exists - if err := os.MkdirAll(filepath.Dir(challengePath), 0755); err != nil { - return fmt.Errorf("create challenge directory: %w", err) - } - - // Write the key authorization to the challenge file - if err := os.WriteFile(challengePath, []byte(keyAuth), 0644); err != nil { - return fmt.Errorf("write challenge file: %w", err) - } - - return nil -} - -// CleanUp removes the challenge token file. -func (w *WebrootProvider) CleanUp(domain, token, keyAuth string) error { - challengePath := filepath.Join(w.path, http01.ChallengePath(token)) - if err := os.Remove(challengePath); err != nil && !os.IsNotExist(err) { - return fmt.Errorf("remove challenge file: %w", err) - } - return nil -} diff --git a/internal/agent/client.go b/internal/agent/client.go index 0c74047..36adb42 100644 --- a/internal/agent/client.go +++ b/internal/agent/client.go @@ -10,12 +10,13 @@ import ( "net/http" "net/url" "os" + "os/exec" + "path/filepath" "strconv" "strings" "sync" "time" - "mmw-agent/internal/acme" "mmw-agent/internal/collector" "mmw-agent/internal/config" @@ -919,26 +920,10 @@ func (e *AuthError) IsTokenInvalid() bool { // WebSocket message types const ( - WSMsgTypeCertRequest = "cert_request" - WSMsgTypeCertUpdate = "cert_update" WSMsgTypeCertDeploy = "cert_deploy" WSMsgTypeTokenUpdate = "token_update" ) -// WSCertRequestPayload represents a certificate request from master -type WSCertRequestPayload struct { - CertID int64 `json:"cert_id"` - Domain string `json:"domain"` - Email string `json:"email"` - Provider string `json:"provider"` - ChallengeMode string `json:"challenge_mode"` - WebrootPath string `json:"webroot_path,omitempty"` - DNSProvider string `json:"dns_provider,omitempty"` - DNSCredentials string `json:"dns_credentials,omitempty"` // JSON string - EABKid string `json:"eab_kid,omitempty"` - EABHmacKey string `json:"eab_hmac_key,omitempty"` -} - // WSCertDeployPayload represents a certificate deploy command from master type WSCertDeployPayload struct { Domain string `json:"domain"` @@ -949,20 +934,6 @@ type WSCertDeployPayload struct { Reload string `json:"reload"` } -// WSCertUpdatePayload represents a certificate update response to master -type WSCertUpdatePayload struct { - CertID int64 `json:"cert_id"` - Domain string `json:"domain"` - Success bool `json:"success"` - CertPath string `json:"cert_path,omitempty"` - KeyPath string `json:"key_path,omitempty"` - CertPEM string `json:"cert_pem,omitempty"` - KeyPEM string `json:"key_pem,omitempty"` - IssueDate time.Time `json:"issue_date,omitempty"` - ExpiryDate time.Time `json:"expiry_date,omitempty"` - Error string `json:"error,omitempty"` -} - // WSTokenUpdatePayload represents a token update from master type WSTokenUpdatePayload struct { ServerToken string `json:"server_token"` @@ -982,13 +953,6 @@ func (c *Client) handleMessage(conn *websocket.Conn, message []byte) { } switch msg.Type { - case WSMsgTypeCertRequest: - var payload WSCertRequestPayload - if err := json.Unmarshal(msg.Payload, &payload); err != nil { - log.Printf("[Agent] Failed to parse cert_request payload: %v", err) - return - } - go c.handleCertRequest(conn, payload) case WSMsgTypeCertDeploy: var payload WSCertDeployPayload if err := json.Unmarshal(msg.Payload, &payload); err != nil { @@ -1008,98 +972,55 @@ func (c *Client) handleMessage(conn *websocket.Conn, message []byte) { } } -// handleCertRequest processes a certificate request from master -func (c *Client) handleCertRequest(conn *websocket.Conn, req WSCertRequestPayload) { - log.Printf("[Agent] Received certificate request for domain: %s", req.Domain) - - result := c.requestCertificate(req) - - // Send result back to master - payload, _ := json.Marshal(result) - msg := map[string]interface{}{ - "type": WSMsgTypeCertUpdate, - "payload": json.RawMessage(payload), - } - - c.wsMu.Lock() - err := conn.WriteJSON(msg) - c.wsMu.Unlock() - - if err != nil { - log.Printf("[Agent] Failed to send cert_update: %v", err) - } else { - log.Printf("[Agent] Sent cert_update for domain %s, success=%v", req.Domain, result.Success) - } -} - -// requestCertificate performs the actual certificate request using ACME -func (c *Client) requestCertificate(req WSCertRequestPayload) WSCertUpdatePayload { - result := WSCertUpdatePayload{ - CertID: req.CertID, - Domain: req.Domain, - } - - opts := []acme.ClientOption{} - if req.ChallengeMode == "webroot" && req.WebrootPath != "" { - opts = append(opts, acme.WithWebrootDir(req.WebrootPath)) - } - - acmeClient := acme.NewClient(opts...) - - // Build V2 cert request - certReq := acme.CertRequest{ - Email: req.Email, - Domain: req.Domain, - Provider: req.Provider, - ChallengeMode: req.ChallengeMode, - WebrootPath: req.WebrootPath, - DNSProvider: req.DNSProvider, - EABKid: req.EABKid, - EABHmacKey: req.EABHmacKey, - } - - // Parse DNS credentials from JSON string - if req.DNSCredentials != "" { - var creds map[string]string - if err := json.Unmarshal([]byte(req.DNSCredentials), &creds); err == nil { - certReq.DNSCredentials = creds - } - } - - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) - defer cancel() - - certResult, err := acmeClient.ObtainCertificateV2(ctx, certReq) - if err != nil { - result.Success = false - result.Error = err.Error() - log.Printf("[Agent] Certificate request failed for %s: %v", req.Domain, err) - return result - } - - result.Success = true - result.CertPath = certResult.CertPath - result.KeyPath = certResult.KeyPath - result.CertPEM = certResult.CertPEM - result.KeyPEM = certResult.KeyPEM - result.IssueDate = certResult.IssueDate - result.ExpiryDate = certResult.ExpiryDate - - log.Printf("[Agent] Certificate obtained for %s, expires: %s", req.Domain, certResult.ExpiryDate) - return result -} - // handleCertDeploy deploys a certificate received from master func (c *Client) handleCertDeploy(payload WSCertDeployPayload) { log.Printf("[Agent] Received cert_deploy for domain: %s, target: %s", payload.Domain, payload.Reload) - if err := acme.Deploy(payload.CertPEM, payload.KeyPEM, payload.CertPath, payload.KeyPath, payload.Reload); err != nil { + if err := deployCert(payload.CertPEM, payload.KeyPEM, payload.CertPath, payload.KeyPath, payload.Reload); err != nil { log.Printf("[Agent] cert_deploy failed for %s: %v", payload.Domain, err) } else { log.Printf("[Agent] cert_deploy succeeded for %s", payload.Domain) } } +func deployCert(certPEM, keyPEM, certPath, keyPath, reloadTarget string) error { + if certPath == "" || keyPath == "" { + return fmt.Errorf("deploy paths are required") + } + if err := os.MkdirAll(filepath.Dir(certPath), 0755); err != nil { + return fmt.Errorf("create cert dir: %w", err) + } + if err := os.MkdirAll(filepath.Dir(keyPath), 0755); err != nil { + return fmt.Errorf("create key dir: %w", err) + } + if err := os.WriteFile(certPath, []byte(certPEM), 0644); err != nil { + return fmt.Errorf("write cert: %w", err) + } + if err := os.WriteFile(keyPath, []byte(keyPEM), 0600); err != nil { + return fmt.Errorf("write key: %w", err) + } + + switch reloadTarget { + case "nginx": + return runCmd("nginx", "-s", "reload") + case "xray": + return runCmd("systemctl", "restart", "xray") + case "both": + if err := runCmd("nginx", "-s", "reload"); err != nil { + return err + } + return runCmd("systemctl", "restart", "xray") + } + return nil +} + +func runCmd(name string, args ...string) error { + if output, err := exec.Command(name, args...).CombinedOutput(); err != nil { + return fmt.Errorf("%s: %s: %w", name, string(output), err) + } + return nil +} + // handleTokenUpdate processes a token update from master func (c *Client) handleTokenUpdate(payload WSTokenUpdatePayload) { log.Printf("[Agent] Received token update from master, new token expires at %s", payload.ExpiresAt.Format(time.RFC3339)) diff --git a/internal/handler/manage.go b/internal/handler/manage.go index f1a869e..39f9372 100644 --- a/internal/handler/manage.go +++ b/internal/handler/manage.go @@ -2415,3 +2415,85 @@ func (h *ManageHandler) addAPIRoutingRule(config map[string]interface{}) { } routing["rules"] = append([]interface{}{apiRule}, rules...) } + +// ================== Certificate Deploy ================== + +// CertDeployRequest represents a certificate deploy request from master +type CertDeployRequest struct { + Domain string `json:"domain"` + CertPEM string `json:"cert_pem"` + KeyPEM string `json:"key_pem"` + CertPath string `json:"cert_path"` + KeyPath string `json:"key_path"` + Reload string `json:"reload"` // nginx, xray, both, none +} + +// HandleCertDeploy handles POST /api/child/cert/deploy +func (h *ManageHandler) HandleCertDeploy(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + writeError(w, http.StatusMethodNotAllowed, "method not allowed") + return + } + if !h.authenticate(r) { + writeError(w, http.StatusUnauthorized, "unauthorized") + return + } + + var req CertDeployRequest + if err := json.NewDecoder(r.Body).Decode(&req); err != nil { + writeError(w, http.StatusBadRequest, "invalid request body") + return + } + + if req.CertPEM == "" || req.KeyPEM == "" || req.CertPath == "" || req.KeyPath == "" { + writeError(w, http.StatusBadRequest, "cert_pem, key_pem, cert_path, key_path are required") + return + } + + if err := deployCertFiles(req.CertPEM, req.KeyPEM, req.CertPath, req.KeyPath, req.Reload); err != nil { + log.Printf("[CertDeploy] Failed to deploy cert for %s: %v", req.Domain, err) + writeError(w, http.StatusInternalServerError, fmt.Sprintf("deploy failed: %v", err)) + return + } + + log.Printf("[CertDeploy] Successfully deployed cert for %s to %s", req.Domain, req.CertPath) + writeJSON(w, http.StatusOK, map[string]interface{}{ + "success": true, + "message": fmt.Sprintf("certificate for %s deployed", req.Domain), + }) +} + +func deployCertFiles(certPEM, keyPEM, certPath, keyPath, reloadTarget string) error { + if err := os.MkdirAll(filepath.Dir(certPath), 0755); err != nil { + return fmt.Errorf("create cert dir: %w", err) + } + if err := os.MkdirAll(filepath.Dir(keyPath), 0755); err != nil { + return fmt.Errorf("create key dir: %w", err) + } + if err := os.WriteFile(certPath, []byte(certPEM), 0644); err != nil { + return fmt.Errorf("write cert: %w", err) + } + if err := os.WriteFile(keyPath, []byte(keyPEM), 0600); err != nil { + return fmt.Errorf("write key: %w", err) + } + + switch reloadTarget { + case "nginx": + return runCommand("nginx", "-s", "reload") + case "xray": + return runCommand("systemctl", "restart", "xray") + case "both": + if err := runCommand("nginx", "-s", "reload"); err != nil { + return err + } + return runCommand("systemctl", "restart", "xray") + } + return nil +} + +func runCommand(name string, args ...string) error { + if output, err := exec.Command(name, args...).CombinedOutput(); err != nil { + return fmt.Errorf("%s: %s: %w", name, string(output), err) + } + return nil +}