mirror of https://github.com/allinssl/allinssl
parent
5c061730af
commit
e31d5e2d04
|
@ -38,3 +38,12 @@ func Restart(c *gin.Context) {
|
|||
setting.Restart()
|
||||
public.SuccessMsg(c, "正在重启...")
|
||||
}
|
||||
|
||||
func GetVersion(c *gin.Context) {
|
||||
data, err := setting.GetVersion()
|
||||
if err != nil {
|
||||
public.FailMsg(c, err.Error())
|
||||
return
|
||||
}
|
||||
public.SuccessData(c, data, 0)
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ var CADirURLMap = map[string]string{
|
|||
"sslcom": "https://acme.ssl.com/sslcom-dv-rsa",
|
||||
"sslcom-rsa": "https://acme.ssl.com/sslcom-dv-rsa",
|
||||
"sslcom-ecc": "https://acme.ssl.com/sslcom-dv-ecc",
|
||||
"buypass": "https://api.buypass.com/acme/directory",
|
||||
}
|
||||
|
||||
func GetSqlite() (*public.Sqlite, error) {
|
||||
|
@ -152,15 +153,20 @@ func GetDNSProvider(providerName string, creds map[string]string, httpClient *ht
|
|||
}
|
||||
}
|
||||
|
||||
func GetAcmeClient(db *public.Sqlite, email, algorithm, eabId string, httpClient *http.Client, logger *public.Logger) (*lego.Client, error) {
|
||||
func GetAcmeClient(db *public.Sqlite, email, algorithm, eabId, ca string, httpClient *http.Client, logger *public.Logger) (*lego.Client, error) {
|
||||
var (
|
||||
ca string
|
||||
eabData map[string]any
|
||||
err error
|
||||
)
|
||||
switch eabId {
|
||||
case "let", "":
|
||||
case "":
|
||||
if ca == "" {
|
||||
ca = "Let's Encrypt"
|
||||
}
|
||||
case "let":
|
||||
ca = "Let's Encrypt"
|
||||
case "buy", "buypass":
|
||||
ca = "buypass"
|
||||
default:
|
||||
eabData, err = access.GetEAB(eabId)
|
||||
if err != nil {
|
||||
|
@ -189,7 +195,7 @@ func GetAcmeClient(db *public.Sqlite, email, algorithm, eabId string, httpClient
|
|||
user, err := LoadUserFromDB(db, email, ca)
|
||||
if err != nil {
|
||||
logger.Debug("acme账号不存在,注册新账号")
|
||||
privateKey, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||
privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
user = &MyUser{
|
||||
Email: email,
|
||||
key: privateKey,
|
||||
|
@ -358,6 +364,10 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
|||
default:
|
||||
eabId = ""
|
||||
}
|
||||
ca, ok := cfg["ca"].(string)
|
||||
if !ok {
|
||||
ca = ""
|
||||
}
|
||||
|
||||
var providerID string
|
||||
switch v := cfg["provider_id"].(type) {
|
||||
|
@ -465,7 +475,7 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
|||
logger.Debug("正在申请证书,域名: " + domains)
|
||||
os.Setenv("LEGO_DISABLE_CNAME_SUPPORT", strconv.FormatBool(closeCname))
|
||||
// 创建 ACME 客户端
|
||||
client, err := GetAcmeClient(db, email, algorithm, eabId, httpClient, logger)
|
||||
client, err := GetAcmeClient(db, email, algorithm, eabId, ca, httpClient, logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package deploy
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -63,3 +65,27 @@ func TestBtPanelSiteList(t *testing.T) {
|
|||
t.Logf("BtPanelSiteList success:%v", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeployBtSingleSite(t *testing.T) {
|
||||
err := os.Chdir("D:/code/ALLinSSL")
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "切换目录失败: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
cfg := map[string]any{
|
||||
"siteName": "www.sss.ad",
|
||||
"provider_id": "35",
|
||||
"certificate": map[string]any{
|
||||
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAxIjmAi/paC2OmG7nOqZ+OJx7spDrx7yZiWvn1XgLW/5ODONh\nWhMT6W+cx0WMC80yCRm5JshIIMzmMxN03pRD1h4u1fPNUnJmGtthRZIm3aU7TlSM\n4tz/Zh8a3kVyN4MtWDmV1/1MV8H0YBtT6K2gxZ7Fz/YKhVATdh8Fy+1qEz3gSrw1\nz6qqEDcM8FtHoAXAdxQBkS8xu34SIriwZiN2YlrtL8Qy73j4XiJLh2cc/NPp+mW9\ncMY1cCEBxpwQTJiJHbX9LcEqYgOkkhWIijW2dYlCLaLsnvJw0TCRd6PooR8XK7MU\nS89+DsixFf3HL+iWjr6yVnQ/mAGVPQ+HD4pwmQIDAQABAoIBAALpcFb59MBZZHJ3\nui9RRi96ig6kPQoRjkjN83pjM+/h/bANMmUOQU5FHBKLwj5uhN5Dpk2fzAnIX2TE\nVgfyNGsYuWLsIM+m6EJfm7pXJwJDr3RCpm+6DIKr1U8TwlR2OhbDi6fOlfH66q79\n2Klq4SXsa0vgfllpTVCDtydFVjwAuQV7Cf6DGRjbNpN3DPLeOC1wYFimNZwudSK0\nf8grWpPFXw2TPaf3TgeBGxwL7GCTYSKT+Eq9USbhG4RArrM9oQt+h7rzaH2bFEdg\n7tOM4KIgV+aw8r0TsYisDG9dfiHfHr5vQnkmWgt/rxAOvHlJ7/64pBVuET1ZF0mB\nP6gu4Y0CgYEAzkwXvfnHI5qx9BVP6e9lGrpWrm0RxCKr2iCCwrOVALbX1yfKCb5L\nrP/jSERMuLt6bIKg/AoVu9ogCTGzntyHTbZXFGg/y5Xoul+1af2arQ1rGZ7A/Im7\nnteZePg2U6UiDRy07F94FF5aL/v97D4BffiSA+0atlgH6tpKyYfY6NsCgYEA8+Ku\nGQqX9kHDd5bbzPhLelNmHVnAjnMaHEhvzVtBA737F10Oqg9wyffqe/i/DvdUSx9r\nafKGUfzB2vVZjz//OpSQ8VhRzDTiyelKLsSTmzOokLBnwayyTxw85o9EDvTNrzfb\nYQbAjmAXWmnv5Xvx1KfvTaKFY3BmHsKYJDzwnJsCgYBK1SVjn2CSVMIqlTSI2nMl\nb+STnzLrn9wQ4uwr7nKlcK34+RD72dCfr67lfwkJldBB3lzBMHNT0jr+us26Waqn\nEPaji3Fgyz9BpAgtq3XZQl3QTFsbAGdTpkegrwEd9G/Wq8whVjw7v0Id193zPUbT\nSEDHNdITxPkSQx8P3bxcMwKBgQDO5EGk5KO9OFTFoqib3RbKku1RgM4lCefgjmKp\n5vvkXMohK8RA6BBahYHZ4U7TN2W+xMyueBsSekVJplFvgG7YFyhOVQovHb42Yz2X\nJxPA2bXp6HxchFBPZDkVrfuiZHIIbm4ghUXcgg/Nl4j3OIoSSNRtG63kiXlYJuRB\n+aB0eQKBgD79VrREpbOMS7HRlDTtfkDN94HY3T4MLErs26z/NLO/dC44tmBJGo2P\ngcQ+p7XxNjpWUnUbEiuz4R3Xgh6ULwuSseWtcQicolPHTkBjnc+6BEpyguZJ+FPZ\nGls3g3LxjGhdPlyd37CaWDvx/Jtjrd4Y9iGkGO2d9fXZD0Hg0ymX\n-----END RSA PRIVATE KEY-----",
|
||||
"cert": "-----BEGIN CERTIFICATE-----\nMIIG5DCCBMygAwIBAgIQBPQGlt81+4RKt3RAFXPvrjANBgkqhkiG9w0BAQsFADBb\nMQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywg\nSW5jLjElMCMGA1UEAxMcVHJ1c3RBc2lhIERWIFRMUyBSU0EgQ0EgMjAyNTAeFw0y\nNTA0MjIwMDAwMDBaFw0yNTA3MjAyMzU5NTlaMB8xHTAbBgNVBAMTFGFsbGluc3Ns\nLnphY2h5YW5nLmNuMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxIjm\nAi/paC2OmG7nOqZ+OJx7spDrx7yZiWvn1XgLW/5ODONhWhMT6W+cx0WMC80yCRm5\nJshIIMzmMxN03pRD1h4u1fPNUnJmGtthRZIm3aU7TlSM4tz/Zh8a3kVyN4MtWDmV\n1/1MV8H0YBtT6K2gxZ7Fz/YKhVATdh8Fy+1qEz3gSrw1z6qqEDcM8FtHoAXAdxQB\nkS8xu34SIriwZiN2YlrtL8Qy73j4XiJLh2cc/NPp+mW9cMY1cCEBxpwQTJiJHbX9\nLcEqYgOkkhWIijW2dYlCLaLsnvJw0TCRd6PooR8XK7MUS89+DsixFf3HL+iWjr6y\nVnQ/mAGVPQ+HD4pwmQIDAQABo4IC3jCCAtowHwYDVR0jBBgwFoAUtBIopbTAHZ8p\ncWk82RGWSnVpUMAwHQYDVR0OBBYEFHqqdlMVBlcadf7iJLJoLnLZ7h4tMB8GA1Ud\nEQQYMBaCFGFsbGluc3NsLnphY2h5YW5nLmNuMD4GA1UdIAQ3MDUwMwYGZ4EMAQIB\nMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAOBgNV\nHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHkGCCsG\nAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t\nMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vVHJ1c3RB\nc2lhRFZUTFNSU0FDQTIwMjUuY3J0MAwGA1UdEwEB/wQCMAAwggF9BgorBgEEAdZ5\nAgQCBIIBbQSCAWkBZwB2ABLxTjS9U3JMhAYZw48/ehP457Vih4icbTAFhOvlhiY6\nAAABll0w/o0AAAQDAEcwRQIgd24jCPm+fbHq3grMIxtvQhzkv7dvYPM/BGjPEsy1\nQ70CIQC5jXADjBh+dH50T+atn3lktBEqQhedOl6cAaP/XXmk6gB2AO08S9boBsKk\nogBX28sk4jgB31Ev7cSGxXAPIN23Pj/gAAABll0w/rUAAAQDAEcwRQIgU2GDVEH1\ns5i/RC1RhqvJjn72PAZOlDtJyLdg29vC9HECIQCj78GATYK5quitLxbn3HvD8BeT\noOz+3tacgyN6+TdvugB1AKRCxQZJYGFUjw/U6pz7ei0mRU2HqX8v30VZ9idPOoRU\nAAABll0w/sYAAAQDAEYwRAIgCvU/iBRPKoJLjmU4edBYObWAO/aJp2mWnfJ4ieAr\nrXsCIBsAppYu28h8YEOl0N9yEeF9G05IMxwkCjZKonQs2SKMMA0GCSqGSIb3DQEB\nCwUAA4ICAQB3wFou51Qvl4apMhencuQUnWF3UpYP49e0WQ72DVT3pYjYsozkSuqb\nQZcwMB6HDoHdFicxvQ/yxKyTu/nw3rXjUWYuSxXYd7lJcQ/R0tR00m6AFeinY4Aq\nq4QqoA+lriK1XqO5MomAL4FbSysT1ow/gaG9pYuXEdT4pr05I/NumjXdkwBRZOd4\nrhol2grKf3y37Qla5hUbbG3ab9nf/csJSWkCoESeXr3MB1oAU/aL9pGSagvMXSKQ\nsFs2cn2Fi8ZmJPJXIP114lgvFuFDO+C1yTNbHap/FufvAKGryfPDuPecCF6FSXej\n+bwg4/BNz5lcHbNo2XXjLgoPg4VE6mG/SQQZQEDBk5DowwMVMvh77t9RBNrHozah\nHGtQz2hCuIX7rZQYnSlvW8T75FhI/Sd+HEfU/iyTIELXBUjypnK2bOJL7+jE7f79\nuljhXlCcP52fGHCjexNBz5gIZr82KVxsfxKuZjfioPkhmWleVNMdMWYJRXu618E6\nNtNjUVsDCuMOOMNs1qScqxOT60MeDZLX+vnC93fdd/t2hLEAWWNNMkWeX2qLCE1q\nGarop9U1mJpiBWkW5cBiqnNIbhuV2fcwFIR8mVT5f1Qcw+WxE2nEjY2h75bKv8T5\n3RBngmaX8PcyLAP2s0/4UyzAnMYfioJBh37VpUYBrdriBkRds/AMZw==\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIFnjCCBIagAwIBAgIQCSYyO0lk42hGFRLe8aXVLDANBgkqhkiG9w0BAQsFADBh\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\nd3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\nMjAeFw0yNTAxMDgwMDAwMDBaFw0zNTAxMDcyMzU5NTlaMFsxCzAJBgNVBAYTAkNO\nMSUwIwYDVQQKExxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSUwIwYDVQQD\nExxUcnVzdEFzaWEgRFYgVExTIFJTQSBDQSAyMDI1MIICIjANBgkqhkiG9w0BAQEF\nAAOCAg8AMIICCgKCAgEA0fuEmuBIsN6ZZVq+gRobMorOGIilTCIfQrxNpR8FUZ9R\n/GfbiekbiIKphQXEZ7N1uBnn6tXUuZ32zl6jPkZpHzN/Bmgk1BWSIzVc0npMzrWq\n/hrbk5+KddXJdsNpeG1+Q8lc8uVMBrztnxaPb7Rh7yQCsMrcO4hgVaqLJWkVvEfW\nULtoCHQnNaj4IroG6VxQf1oArQ8bPbwpI02lieSahRa78FQuXdoGVeQcrkhtVjZs\nON98vq5fPWZX2LFv7e5J6P9IHbzvOl8yyQjv+2/IOwhNSkaXX3bI+//bqF9XW/p7\n+gsUmHiK5YsvLjmXcvDmoDEGrXMzgX31Zl2nJ+umpRbLjwP8rxYIUsKoEwEdFoto\nAid59UEBJyw/GibwXQ5xTyKD/N6C8SFkr1+myOo4oe1UB+YgvRu6qSxIABo5kYdX\nFodLP4IgoVJdeUFs1Usa6bxYEO6EgMf5lCWt9hGZszvXYZwvyZGq3ogNXM7eKyi2\n20WzJXYMmi9TYFq2Fa95aZe4wki6YhDhhOO1g0sjITGVaB73G+JOCI9yJhv6+REN\nD40ZpboUHE8JNgMVWbG1isAMVCXqiADgXtuC+tmJWPEH9cR6OuJLEpwOzPfgAbnn\n2MRu7Tsdr8jPjTPbD0FxblX1ydW3RG30vwLF5lkTTRkHG9epMgpPMdYP7nY/08MC\nAwEAAaOCAVYwggFSMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLQSKKW0\nwB2fKXFpPNkRlkp1aVDAMB8GA1UdIwQYMBaAFE4iVCAYlebjbuYP+vq5Eu0GF485\nMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\ndgYIKwYBBQUHAQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy\ndC5jb20wQAYIKwYBBQUHMAKGNGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E\naWdpQ2VydEdsb2JhbFJvb3RHMi5jcnQwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov\nL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9vdEcyLmNybDARBgNV\nHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQELBQADggEBAJ4a3svh316GY2+Z7EYx\nmBIsOwjJSnyoEfzx2T699ctLLrvuzS79Mg3pPjxSLlUgyM8UzrFc5tgVU3dZ1sFQ\nI4RM+ysJdvIAX/7Yx1QbooVdKhkdi9X7QN7yVkjqwM3fY3WfQkRTzhIkM7mYIQbR\nr+y2Vkju61BLqh7OCRpPMiudjEpP1kEtRyGs2g0aQpEIqKBzxgitCXSayO1hoO6/\n71ts801OzYlqYW9OQQQ2GCJyFbD6XHDjdpn+bWUxTKWaMY0qedSCbHE3Kl2QEF0C\nynZ7SbC03yR+gKZQDeTXrNP1kk5Qhe7jSXgw+nhbspe0q/M1ZcNCz+sPxeOwdCcC\ngJE=\n-----END CERTIFICATE-----",
|
||||
"issuer": "cert-issuer",
|
||||
},
|
||||
}
|
||||
err = DeployBtSingleSite(cfg)
|
||||
if err != nil {
|
||||
t.Fatalf("DeployBtSingleSite failed: %v", err)
|
||||
} else {
|
||||
t.Log("DeployBtSingleSite success")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,6 +130,8 @@ func NotifyTest(id string) error {
|
|||
err = NotifyFeishu(params)
|
||||
case "dingtalk":
|
||||
err = NotifyDingtalk(params)
|
||||
case "workwx":
|
||||
err = NotifyWorkWx(params)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -153,6 +155,8 @@ func Notify(params map[string]any) error {
|
|||
return NotifyFeishu(params)
|
||||
case "dingtalk":
|
||||
return NotifyDingtalk(params)
|
||||
case "workwx":
|
||||
return NotifyWorkWx(params)
|
||||
default:
|
||||
return fmt.Errorf("不支持的通知类型")
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"fmt"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
@ -183,6 +184,10 @@ func NotifyWebHook(params map[string]any) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("解析配置失败: %v", err)
|
||||
}
|
||||
config.Data, err = ReplaceJSONPlaceholders(config.Data, params)
|
||||
if err != nil {
|
||||
return fmt.Errorf("替换JSON占位符失败: %w", err)
|
||||
}
|
||||
|
||||
reporter := NewWebHookReporter(&config, logger)
|
||||
httpctx := context.Background()
|
||||
|
@ -192,3 +197,16 @@ func NotifyWebHook(params map[string]any) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ReplaceJSONPlaceholders(jsonStr string, vars map[string]any) (string, error) {
|
||||
re := regexp.MustCompile(`__([a-zA-Z0-9_]+)__`)
|
||||
result := re.ReplaceAllStringFunc(jsonStr, func(match string) string {
|
||||
key := re.FindStringSubmatch(match)[1]
|
||||
if val, ok := vars[key]; ok {
|
||||
return fmt.Sprintf("%v", val) // 将 any 类型转换为字符串
|
||||
}
|
||||
return match // 未匹配到变量则保留原样
|
||||
})
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
package report
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func PostHeader(url string, msg []byte, headers map[string]string) (string, error) {
|
||||
client := &http.Client{}
|
||||
|
||||
req, err := http.NewRequest("POST", url, strings.NewReader(string(msg)))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for key, header := range headers {
|
||||
req.Header.Set(key, header)
|
||||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(body), nil
|
||||
}
|
||||
|
||||
func PostJson(url string, msg []byte) (string, error) {
|
||||
headers := make(map[string]string)
|
||||
headers["Content-Type"] = "application/json;charset=utf-8"
|
||||
res, err := PostHeader(url, msg, headers)
|
||||
return res, err
|
||||
}
|
||||
|
||||
func NotifyWorkWx(params map[string]any) error {
|
||||
if params == nil {
|
||||
return fmt.Errorf("缺少参数")
|
||||
}
|
||||
providerID := params["provider_id"].(string)
|
||||
// fmt.Println(providerID)
|
||||
providerData, err := GetReport(providerID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
configStr := providerData["config"].(string)
|
||||
fmt.Println(configStr)
|
||||
var config map[string]string
|
||||
err = json.Unmarshal([]byte(configStr), &config)
|
||||
if err != nil {
|
||||
return fmt.Errorf("解析配置失败: %v", err)
|
||||
}
|
||||
url := config["url"]
|
||||
if url == "" {
|
||||
return fmt.Errorf("缺少企业微信URL配置")
|
||||
}
|
||||
if config["data"] == "" {
|
||||
config["data"] = `
|
||||
{
|
||||
"msgtype": "news",
|
||||
"news": {
|
||||
"articles" : [
|
||||
{
|
||||
"title" : "__subject__",
|
||||
"description" : "__body__。",
|
||||
"url" : "https://allinssl.com/",
|
||||
"picurl" : "https://allinssl.com/logo.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
msg, err := ReplaceJSONPlaceholders(config["data"], params)
|
||||
if err != nil {
|
||||
return fmt.Errorf("替换JSON占位符失败: %v", err)
|
||||
}
|
||||
_, err = PostJson(url, []byte(msg))
|
||||
if err != nil {
|
||||
return fmt.Errorf("发送企业微信消息失败: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -4,8 +4,11 @@ import (
|
|||
"ALLinSSL/backend/public"
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/joho/godotenv"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"syscall"
|
||||
|
@ -183,3 +186,27 @@ func Restart() {
|
|||
}()
|
||||
return
|
||||
}
|
||||
|
||||
func GetVersion() (map[string]string, error) {
|
||||
version := "v1.0.4"
|
||||
update := "0"
|
||||
newVersionObj, err := http.Get("https://download.allinssl.com/version.json")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to fetch version: %v", err)
|
||||
}
|
||||
defer newVersionObj.Body.Close()
|
||||
|
||||
var newVersionData map[string]string
|
||||
body, _ := io.ReadAll(newVersionObj.Body)
|
||||
err = json.Unmarshal(body, &newVersionData)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse version data: %v", err)
|
||||
}
|
||||
if version != newVersionData["version"] {
|
||||
update = "1"
|
||||
}
|
||||
newVersionData["new_version"] = newVersionData["version"]
|
||||
newVersionData["version"] = version
|
||||
newVersionData["update"] = update
|
||||
return newVersionData, nil
|
||||
}
|
||||
|
|
|
@ -192,28 +192,35 @@ func UpdInfo(id, domain string, s *public.Sqlite, reportType string) error {
|
|||
func CheckWebsite(target string) (*SSLInfo, error) {
|
||||
result := &SSLInfo{Target: target}
|
||||
|
||||
// 拆分 host 和 port
|
||||
host, port, err := net.SplitHostPort(target)
|
||||
if err != nil {
|
||||
// 没有显式端口,默认 443
|
||||
host = target
|
||||
port = "443"
|
||||
}
|
||||
|
||||
// 验证格式是否是 IP 或域名
|
||||
if net.ParseIP(target) == nil {
|
||||
if _, err := net.LookupHost(target); err != nil {
|
||||
if net.ParseIP(host) == nil {
|
||||
if _, err := net.LookupHost(host); err != nil {
|
||||
return result, fmt.Errorf("无效域名或 IP:%v", err)
|
||||
}
|
||||
}
|
||||
|
||||
hostPort := net.JoinHostPort(target, "443")
|
||||
|
||||
// result := &SSLInfo{Target: target}
|
||||
|
||||
// 1. TLS 连接(先做,否则无 HTTPS 支持直接失败)
|
||||
conn, err := tls.Dial("tcp", hostPort, &tls.Config{
|
||||
// TLS 连接(支持所有 TLS 版本)
|
||||
conn, err := tls.Dial("tcp", net.JoinHostPort(host, port), &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
MinVersion: tls.VersionTLS10, // 显式支持所有版本
|
||||
MaxVersion: tls.VersionTLS13,
|
||||
})
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("目标不支持 HTTPS:%v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// 发送 HTTPS 请求检测状态
|
||||
resp, err := http.Get("https://" + target)
|
||||
// HTTP 状态检测(构造 URL,保留端口)
|
||||
url := fmt.Sprintf("https://%s", net.JoinHostPort(host, port))
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
result.HTTPStatus = 0
|
||||
result.HTTPStatusText = "异常"
|
||||
|
|
|
@ -73,6 +73,7 @@ func Register(r *gin.Engine) {
|
|||
setting.POST("/save_setting", api.SaveSetting)
|
||||
setting.POST("/shutdown", api.Shutdown)
|
||||
setting.POST("/restart", api.Restart)
|
||||
setting.POST("/get_version", api.GetVersion)
|
||||
}
|
||||
overview := v1.Group("/overview")
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue