mirror of https://github.com/allinssl/allinssl
parent
eb302776a8
commit
f64d2b2764
|
@ -135,6 +135,148 @@ func DelAccess(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAllEAB(c *gin.Context) {
|
||||||
|
var form struct {
|
||||||
|
CA string `form:"ca"`
|
||||||
|
}
|
||||||
|
err := c.Bind(&form)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
eabList, err := access.GetAllEAB(form.CA)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
public.SuccessData(c, eabList, 0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetEABList(c *gin.Context) {
|
||||||
|
var form struct {
|
||||||
|
Search string `form:"search"`
|
||||||
|
Page int64 `form:"p"`
|
||||||
|
Limit int64 `form:"limit"`
|
||||||
|
}
|
||||||
|
err := c.Bind(&form)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
eabList, count, err := access.GetEABList(form.Search, form.Page, form.Limit)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
public.SuccessData(c, eabList, count)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddEAB(c *gin.Context) {
|
||||||
|
var form struct {
|
||||||
|
Name string `form:"name"`
|
||||||
|
Kid string `form:"Kid"`
|
||||||
|
HmacEncoded string `form:"HmacEncoded"`
|
||||||
|
CA string `form:"ca"`
|
||||||
|
}
|
||||||
|
err := c.Bind(&form)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
form.Name = strings.TrimSpace(form.Name)
|
||||||
|
form.Kid = strings.TrimSpace(form.Kid)
|
||||||
|
form.HmacEncoded = strings.TrimSpace(form.HmacEncoded)
|
||||||
|
form.CA = strings.TrimSpace(form.CA)
|
||||||
|
if form.Name == "" {
|
||||||
|
public.FailMsg(c, "名称不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if form.Kid == "" {
|
||||||
|
public.FailMsg(c, "ID不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if form.HmacEncoded == "" {
|
||||||
|
public.FailMsg(c, "HmacEncoded不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if form.CA == "" {
|
||||||
|
public.FailMsg(c, "CA不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = access.AddEAB(form.Name, form.Kid, form.HmacEncoded, form.CA)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
}
|
||||||
|
public.SuccessMsg(c, "添加成功")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdEAB(c *gin.Context) {
|
||||||
|
var form struct {
|
||||||
|
ID string `form:"id"`
|
||||||
|
Name string `form:"name"`
|
||||||
|
Kid string `form:"Kid"`
|
||||||
|
HmacEncoded string `form:"HmacEncoded"`
|
||||||
|
CA string `form:"ca"`
|
||||||
|
}
|
||||||
|
err := c.Bind(&form)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
form.Name = strings.TrimSpace(form.Name)
|
||||||
|
form.Kid = strings.TrimSpace(form.Kid)
|
||||||
|
form.HmacEncoded = strings.TrimSpace(form.HmacEncoded)
|
||||||
|
form.CA = strings.TrimSpace(form.CA)
|
||||||
|
if form.Name == "" {
|
||||||
|
public.FailMsg(c, "名称不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if form.Kid == "" {
|
||||||
|
public.FailMsg(c, "ID不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if form.HmacEncoded == "" {
|
||||||
|
public.FailMsg(c, "HmacEncoded不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if form.CA == "" {
|
||||||
|
public.FailMsg(c, "CA不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = access.UpdEAB(form.ID, form.Name, form.Kid, form.HmacEncoded, form.CA)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
}
|
||||||
|
public.SuccessMsg(c, "修改成功")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func DelEAB(c *gin.Context) {
|
||||||
|
var form struct {
|
||||||
|
ID string `form:"id"`
|
||||||
|
}
|
||||||
|
err := c.Bind(&form)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
form.ID = strings.TrimSpace(form.ID)
|
||||||
|
if form.ID == "" {
|
||||||
|
public.FailMsg(c, "ID不能为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = access.DelEAB(form.ID)
|
||||||
|
if err != nil {
|
||||||
|
public.FailMsg(c, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
public.SuccessMsg(c, "删除成功")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func TestAccess(c *gin.Context) {
|
func TestAccess(c *gin.Context) {
|
||||||
var form struct {
|
var form struct {
|
||||||
ID string `form:"id"`
|
ID string `form:"id"`
|
||||||
|
|
|
@ -32,7 +32,6 @@ func Sign(c *gin.Context) {
|
||||||
public.FailMsg(c, err.Error())
|
public.FailMsg(c, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
s.TableName = "users"
|
s.TableName = "users"
|
||||||
res, err := s.Where("username=?", []interface{}{form.Username}).Select()
|
res, err := s.Where("username=?", []interface{}{form.Username}).Select()
|
||||||
|
|
|
@ -12,7 +12,6 @@ func GetSqlite() (*public.Sqlite, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
s.TableName = "access"
|
s.TableName = "access"
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,6 @@ func GetSqliteAT() (*public.Sqlite, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
s.TableName = "access_type"
|
s.TableName = "access_type"
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
|
||||||
return u.key
|
return u.key
|
||||||
}
|
}
|
||||||
|
|
||||||
func SaveUserToDB(db *public.Sqlite, user *MyUser) error {
|
func SaveUserToDB(db *public.Sqlite, user *MyUser, Type string) error {
|
||||||
keyBytes, err := x509.MarshalPKCS8PrivateKey(user.key)
|
keyBytes, err := x509.MarshalPKCS8PrivateKey(user.key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -53,13 +53,13 @@ func SaveUserToDB(db *public.Sqlite, user *MyUser) error {
|
||||||
"reg": regBytes,
|
"reg": regBytes,
|
||||||
"create_time": now,
|
"create_time": now,
|
||||||
"update_time": now,
|
"update_time": now,
|
||||||
"type": "Let's Encrypt",
|
"type": Type,
|
||||||
})
|
})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadUserFromDB(db *public.Sqlite, email string) (*MyUser, error) {
|
func LoadUserFromDB(db *public.Sqlite, email string, Type string) (*MyUser, error) {
|
||||||
data, err := db.Where(`email=?`, []interface{}{email}).Select()
|
data, err := db.Where(`email=? and type=?`, []interface{}{email, Type}).Select()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,17 +22,33 @@ import (
|
||||||
"github.com/go-acme/lego/v4/providers/dns/volcengine"
|
"github.com/go-acme/lego/v4/providers/dns/volcengine"
|
||||||
"github.com/go-acme/lego/v4/providers/dns/westcn"
|
"github.com/go-acme/lego/v4/providers/dns/westcn"
|
||||||
"github.com/go-acme/lego/v4/registration"
|
"github.com/go-acme/lego/v4/registration"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var AlgorithmMap = map[string]certcrypto.KeyType{
|
||||||
|
"RSA2048": certcrypto.RSA2048,
|
||||||
|
"RSA3072": certcrypto.RSA3072,
|
||||||
|
"RSA4096": certcrypto.RSA4096,
|
||||||
|
"RSA8192": certcrypto.RSA8192,
|
||||||
|
"EC256": certcrypto.EC256,
|
||||||
|
"EC384": certcrypto.EC384,
|
||||||
|
}
|
||||||
|
|
||||||
|
var CADirURLMap = map[string]string{
|
||||||
|
"Let's Encrypt": "https://acme-v02.api.letsencrypt.org/directory",
|
||||||
|
"zerossl": "https://acme.zerossl.com/v2/DV90",
|
||||||
|
"google": "https://dv.acme-v02.api.pki.goog/directory",
|
||||||
|
}
|
||||||
|
|
||||||
func GetSqlite() (*public.Sqlite, error) {
|
func GetSqlite() (*public.Sqlite, error) {
|
||||||
s, err := public.NewSqlite("data/data.db", "")
|
s, err := public.NewSqlite("data/data.db", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
s.TableName = "_accounts"
|
s.TableName = "_accounts"
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
@ -77,17 +93,179 @@ func GetDNSProvider(providerName string, creds map[string]string) (challenge.Pro
|
||||||
config.SecretKey = creds["secret_key"]
|
config.SecretKey = creds["secret_key"]
|
||||||
return volcengine.NewDNSProviderConfig(config)
|
return volcengine.NewDNSProviderConfig(config)
|
||||||
|
|
||||||
// case "godaddy":
|
|
||||||
// config := godaddy.NewDefaultConfig()
|
|
||||||
// config.APIKey = creds["api_key"]
|
|
||||||
// config.APISecret = creds["api_secret"]
|
|
||||||
// return godaddy.NewDNSProviderConfig(config)
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("不支持的 DNS Provider: %s", providerName)
|
return nil, fmt.Errorf("不支持的 DNS Provider: %s", providerName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAcmeClient(db *public.Sqlite, email, algorithm, ca, proxy, eabId string, logger *public.Logger) (*lego.Client, error) {
|
||||||
|
user, err := LoadUserFromDB(db, email, ca)
|
||||||
|
if err != nil {
|
||||||
|
logger.Debug("acme账号不存在,注册新账号")
|
||||||
|
privateKey, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
||||||
|
user = &MyUser{
|
||||||
|
Email: email,
|
||||||
|
key: privateKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
config := lego.NewConfig(user)
|
||||||
|
config.Certificate.KeyType = AlgorithmMap[algorithm]
|
||||||
|
config.CADirURL = CADirURLMap[ca]
|
||||||
|
if proxy != "" {
|
||||||
|
// 构建代理 HTTP 客户端
|
||||||
|
proxyURL, err := url.Parse(proxy) // 替换为你的代理地址
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("无效的代理地址: %v", err)
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
Proxy: http.ProxyURL(proxyURL),
|
||||||
|
},
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
}
|
||||||
|
config.HTTPClient = httpClient
|
||||||
|
}
|
||||||
|
client, err := lego.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
logger.Debug("正在注册账号:" + email)
|
||||||
|
var reg *registration.Resource
|
||||||
|
switch ca {
|
||||||
|
case "Let's Encrypt":
|
||||||
|
reg, err = client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||||
|
case "zerossl", "google":
|
||||||
|
// 获取EAB参数
|
||||||
|
var eabData map[string]any
|
||||||
|
if eabId == "" {
|
||||||
|
data, err := access.GetAllEAB(ca)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(data) <= 0 {
|
||||||
|
return nil, fmt.Errorf("未找到EAB信息")
|
||||||
|
}
|
||||||
|
eabData = data[0]
|
||||||
|
} else {
|
||||||
|
eabData, err = access.GetEAB(eabId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if eabData == nil {
|
||||||
|
return nil, fmt.Errorf("未找到EAB信息")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Kid := eabData["kid"].(string)
|
||||||
|
HmacEncoded := eabData["HmacEncoded"].(string)
|
||||||
|
reg, err = client.Registration.RegisterWithExternalAccountBinding(registration.RegisterEABOptions{
|
||||||
|
TermsOfServiceAgreed: true,
|
||||||
|
Kid: Kid,
|
||||||
|
HmacEncoded: HmacEncoded,
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
reg, err = client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user.Registration = reg
|
||||||
|
|
||||||
|
err = SaveUserToDB(db, user, ca)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
logger.Debug("acme账号注册并保存成功")
|
||||||
|
return client, nil
|
||||||
|
} else {
|
||||||
|
config := lego.NewConfig(user)
|
||||||
|
config.Certificate.KeyType = AlgorithmMap[algorithm]
|
||||||
|
config.CADirURL = CADirURLMap[ca]
|
||||||
|
if proxy != "" {
|
||||||
|
// 构建代理 HTTP 客户端
|
||||||
|
proxyURL, err := url.Parse(proxy) // 替换为你的代理地址
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("无效的代理地址: %v", err)
|
||||||
|
}
|
||||||
|
httpClient := &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
Proxy: http.ProxyURL(proxyURL),
|
||||||
|
},
|
||||||
|
Timeout: 30 * time.Second,
|
||||||
|
}
|
||||||
|
config.HTTPClient = httpClient
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化 ACME 客户端
|
||||||
|
client, err := lego.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCert(runId string, domainArr []string, endDay int, logger *public.Logger) (map[string]any, error) {
|
||||||
|
if runId == "" {
|
||||||
|
return nil, fmt.Errorf("参数错误:_runId")
|
||||||
|
}
|
||||||
|
s, err := public.NewSqlite("data/data.db", "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
s.TableName = "workflow_history"
|
||||||
|
defer s.Close()
|
||||||
|
// 查询 workflowId
|
||||||
|
wh, err := s.Where("id=?", []interface{}{runId}).Select()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(wh) <= 0 {
|
||||||
|
return nil, fmt.Errorf("未获取到对应的workflowId")
|
||||||
|
}
|
||||||
|
s.TableName = "cert"
|
||||||
|
certs, err := s.Where("workflow_id=?", []interface{}{wh[0]["workflow_id"]}).Select()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(certs) <= 0 {
|
||||||
|
return nil, fmt.Errorf("未获取到当前工作流下的证书")
|
||||||
|
}
|
||||||
|
layout := "2006-01-02 15:04:05"
|
||||||
|
var maxDays float64
|
||||||
|
var maxItem map[string]any
|
||||||
|
for i := range certs {
|
||||||
|
if !public.ContainsAllIgnoreBRepeats(strings.Split(certs[i]["domains"].(string), ","), domainArr) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
endTimeStr, ok := certs[i]["end_time"].(string)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
endTime, err := time.Parse(layout, endTimeStr)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
diff := endTime.Sub(time.Now()).Hours() / 24
|
||||||
|
if diff > maxDays {
|
||||||
|
maxDays = diff
|
||||||
|
maxItem = certs[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if maxItem == nil {
|
||||||
|
return nil, fmt.Errorf("未获取到对应的证书")
|
||||||
|
}
|
||||||
|
if int(maxDays) <= endDay {
|
||||||
|
return nil, fmt.Errorf("证书已过期或即将过期,剩余天数:%d 小于%d天", int(maxDays), endDay)
|
||||||
|
}
|
||||||
|
// 证书未过期,直接返回
|
||||||
|
logger.Debug(fmt.Sprintf("上次证书申请成功,域名:%s,剩余天数:%d 大于%d天,已跳过申请复用此证书", maxItem["domains"], int(maxDays), endDay))
|
||||||
|
return map[string]any{
|
||||||
|
"cert": maxItem["cert"],
|
||||||
|
"key": maxItem["key"],
|
||||||
|
"issuerCert": maxItem["issuer_cert"],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||||
db, err := GetSqlite()
|
db, err := GetSqlite()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -107,6 +285,44 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("参数错误:provider")
|
return nil, fmt.Errorf("参数错误:provider")
|
||||||
}
|
}
|
||||||
|
endDay := 30
|
||||||
|
switch v := cfg["end_day"].(type) {
|
||||||
|
case float64:
|
||||||
|
endDay = int(v)
|
||||||
|
case int:
|
||||||
|
endDay = v
|
||||||
|
case string:
|
||||||
|
if v != "" {
|
||||||
|
endDay, err = strconv.Atoi(v)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("参数错误:end_day")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case int64:
|
||||||
|
endDay = int(v)
|
||||||
|
}
|
||||||
|
algorithm, ok := cfg["algorithm"].(string)
|
||||||
|
if !ok {
|
||||||
|
algorithm = "RSA2048"
|
||||||
|
}
|
||||||
|
ca, ok := cfg["ca"].(string)
|
||||||
|
if !ok {
|
||||||
|
ca = "Let's Encrypt"
|
||||||
|
}
|
||||||
|
proxy, ok := cfg["proxy"].(string)
|
||||||
|
if !ok {
|
||||||
|
proxy = ""
|
||||||
|
}
|
||||||
|
var eabId string
|
||||||
|
switch v := cfg["eabId"].(type) {
|
||||||
|
case float64:
|
||||||
|
eabId = strconv.Itoa(int(v))
|
||||||
|
case string:
|
||||||
|
eabId = v
|
||||||
|
default:
|
||||||
|
eabId = ""
|
||||||
|
}
|
||||||
|
|
||||||
var providerID string
|
var providerID string
|
||||||
switch v := cfg["provider_id"].(type) {
|
switch v := cfg["provider_id"].(type) {
|
||||||
case float64:
|
case float64:
|
||||||
|
@ -178,100 +394,15 @@ func Apply(cfg map[string]any, logger *public.Logger) (map[string]any, error) {
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("参数错误:_runId")
|
return nil, fmt.Errorf("参数错误:_runId")
|
||||||
}
|
}
|
||||||
if runId != "" {
|
certData, err := GetCert(runId, domainArr, endDay, logger)
|
||||||
s, err := public.NewSqlite("data/data.db", "")
|
if err != nil {
|
||||||
if err != nil {
|
logger.Debug("未获取到符合条件的本地证书:" + err.Error())
|
||||||
return nil, err
|
} else {
|
||||||
}
|
return certData, nil
|
||||||
s.Connect()
|
|
||||||
s.TableName = "workflow_history"
|
|
||||||
defer s.Close()
|
|
||||||
// 查询 workflowId
|
|
||||||
wh, err := s.Where("id=?", []interface{}{runId}).Select()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(wh) > 0 {
|
|
||||||
s.TableName = "cert"
|
|
||||||
certs, err := s.Where("workflow_id=?", []interface{}{wh[0]["workflow_id"]}).Select()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(certs) > 0 {
|
|
||||||
layout := "2006-01-02 15:04:05"
|
|
||||||
var maxDays float64
|
|
||||||
var maxItem map[string]any
|
|
||||||
for i := range certs {
|
|
||||||
if !public.ContainsAllIgnoreBRepeats(strings.Split(certs[i]["domains"].(string), ","), domainArr) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
endTimeStr, ok := certs[i]["end_time"].(string)
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
endTime, err := time.Parse(layout, endTimeStr)
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
diff := endTime.Sub(time.Now()).Hours() / 24
|
|
||||||
if diff > maxDays {
|
|
||||||
maxDays = diff
|
|
||||||
maxItem = certs[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
certObj := maxItem
|
|
||||||
// 判断证书是否过期
|
|
||||||
cfgEnd, ok := cfg["end_day"].(int)
|
|
||||||
if !ok || cfgEnd <= 0 {
|
|
||||||
cfgEnd = 30
|
|
||||||
}
|
|
||||||
|
|
||||||
if int(maxDays) > cfgEnd {
|
|
||||||
// 证书未过期,直接返回
|
|
||||||
logger.Debug(fmt.Sprintf("上次证书申请成功,域名:%s,剩余天数:%d 大于%d天,已跳过申请复用此证书", certObj["domains"], int(maxDays), cfgEnd))
|
|
||||||
return map[string]any{
|
|
||||||
"cert": certObj["cert"],
|
|
||||||
"key": certObj["key"],
|
|
||||||
"issuerCert": certObj["issuer_cert"],
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
logger.Debug("正在申请证书,域名: " + domains)
|
logger.Debug("正在申请证书,域名: " + domains)
|
||||||
|
// 创建 ACME 客户端
|
||||||
user, err := LoadUserFromDB(db, email)
|
client, err := GetAcmeClient(db, email, algorithm, ca, proxy, eabId, logger)
|
||||||
if err != nil {
|
|
||||||
logger.Debug("acme账号不存在,注册新账号")
|
|
||||||
privateKey, _ := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
|
|
||||||
user = &MyUser{
|
|
||||||
Email: email,
|
|
||||||
key: privateKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
config := lego.NewConfig(user)
|
|
||||||
config.Certificate.KeyType = certcrypto.EC384
|
|
||||||
|
|
||||||
client, err := lego.NewClient(config)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
logger.Debug("正在注册账号:" + email)
|
|
||||||
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
user.Registration = reg
|
|
||||||
|
|
||||||
err = SaveUserToDB(db, user)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
logger.Debug("账号注册并保存成功")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化 ACME 客户端
|
|
||||||
client, err := lego.NewClient(lego.NewConfig(user))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ func GetSqlite() (*public.Sqlite, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
s.TableName = "cert"
|
s.TableName = "cert"
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
@ -68,7 +67,6 @@ func AddCert(source, key, cert, issuer, issuerCert, domains, sha256, historyId,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
s.TableName = "workflow_history"
|
s.TableName = "workflow_history"
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
// 查询 workflowId
|
// 查询 workflowId
|
||||||
|
|
|
@ -12,7 +12,6 @@ func GetWorkflowCount() (map[string]any, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
workflow, err := s.Query(`select count(*) as count,
|
workflow, err := s.Query(`select count(*) as count,
|
||||||
count(case when exec_type='auto' then 1 end ) as active,
|
count(case when exec_type='auto' then 1 end ) as active,
|
||||||
|
@ -71,7 +70,6 @@ func GetSiteMonitorCount() (map[string]any, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
cert, err := s.Query(`select count(*) as count,
|
cert, err := s.Query(`select count(*) as count,
|
||||||
count(case when state='异常' then 1 end ) as exception
|
count(case when state='异常' then 1 end ) as exception
|
||||||
|
|
|
@ -16,7 +16,6 @@ func GetSqlite() (*public.Sqlite, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
s.TableName = "report"
|
s.TableName = "report"
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ func GetSqlite() (*public.Sqlite, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
s.TableName = "site_monitor"
|
s.TableName = "site_monitor"
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ func GetSqlite() (*public.Sqlite, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
s.TableName = "workflow"
|
s.TableName = "workflow"
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ func GetSqliteObjWH() (*public.Sqlite, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
s.TableName = "workflow_history"
|
s.TableName = "workflow_history"
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ func SessionAuthMiddleware() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
// 返回登录页
|
// 返回登录页
|
||||||
c.Redirect(http.StatusFound, "/login")
|
c.Redirect(http.StatusFound, "/login")
|
||||||
// c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
if session.Get("secure") == nil || last == nil {
|
if session.Get("secure") == nil || last == nil {
|
||||||
|
|
|
@ -167,7 +167,7 @@ func init() {
|
||||||
workflow_id TEXT not null
|
workflow_id TEXT not null
|
||||||
);
|
);
|
||||||
|
|
||||||
create table workflow_deploy
|
create table IF NOT EXISTS workflow_deploy
|
||||||
(
|
(
|
||||||
id TEXT,
|
id TEXT,
|
||||||
workflow_id TEXT,
|
workflow_id TEXT,
|
||||||
|
@ -177,6 +177,19 @@ func init() {
|
||||||
primary key (id, workflow_id)
|
primary key (id, workflow_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
create table IF NOT EXISTS _eab
|
||||||
|
(
|
||||||
|
id integer not null
|
||||||
|
constraint _eab_pk
|
||||||
|
primary key autoincrement,
|
||||||
|
name TEXT,
|
||||||
|
Kid TEXT not null,
|
||||||
|
HmacEncoded TEXT not null,
|
||||||
|
ca TEXT not null,
|
||||||
|
create_time TEXT,
|
||||||
|
update_time TEXT
|
||||||
|
);
|
||||||
|
|
||||||
`)
|
`)
|
||||||
insertDefaultData(db, "users", "INSERT INTO users (id, username, password, salt) VALUES (1, 'admin', 'xxxxxxx', '&*ghs^&%dag');")
|
insertDefaultData(db, "users", "INSERT INTO users (id, username, password, salt) VALUES (1, 'admin', 'xxxxxxx', '&*ghs^&%dag');")
|
||||||
insertDefaultData(db, "access_type", `
|
insertDefaultData(db, "access_type", `
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
|
@ -67,7 +68,7 @@ func VerifyCertificateAndKey(cert *x509.Certificate, privateKey crypto.PrivateKe
|
||||||
case *rsa.PrivateKey:
|
case *rsa.PrivateKey:
|
||||||
signature, err = rsa.SignPKCS1v15(nil, key, crypto.SHA256, message)
|
signature, err = rsa.SignPKCS1v15(nil, key, crypto.SHA256, message)
|
||||||
case *ecdsa.PrivateKey:
|
case *ecdsa.PrivateKey:
|
||||||
signature, err = key.Sign(nil, message, crypto.SHA256)
|
signature, err = key.Sign(rand.Reader, message, crypto.SHA256)
|
||||||
case ed25519.PrivateKey:
|
case ed25519.PrivateKey:
|
||||||
signature = ed25519.Sign(key, message)
|
signature = ed25519.Sign(key, message)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -36,7 +36,7 @@ func EnsureDatabaseWithTables(targetDBPath string, baseDBPath string, tables []s
|
||||||
query := "SELECT sql FROM sqlite_master WHERE type='table' AND name=?"
|
query := "SELECT sql FROM sqlite_master WHERE type='table' AND name=?"
|
||||||
err = baseDB.QueryRow(query, table).Scan(&createSQL)
|
err = baseDB.QueryRow(query, table).Scan(&createSQL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("获取表 %s 的结构失败: %v", table, err)
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2.2 在目标库中创建表
|
// 2.2 在目标库中创建表
|
||||||
|
|
|
@ -22,7 +22,6 @@ func GetSettingIgnoreError(key string) string {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
s.TableName = "settings"
|
s.TableName = "settings"
|
||||||
res, err := s.Where("key=?", []interface{}{key}).Select()
|
res, err := s.Where("key=?", []interface{}{key}).Select()
|
||||||
|
@ -44,7 +43,6 @@ func UpdateSetting(key, val string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
s.TableName = "settings"
|
s.TableName = "settings"
|
||||||
_, err = s.Where("key=?", []interface{}{key}).Update(map[string]any{"value": val})
|
_, err = s.Where("key=?", []interface{}{key}).Update(map[string]any{"value": val})
|
||||||
|
@ -60,7 +58,6 @@ func GetSettingsFromType(typ string) ([]map[string]any, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.Connect()
|
|
||||||
defer s.Close()
|
defer s.Close()
|
||||||
s.TableName = "settings"
|
s.TableName = "settings"
|
||||||
res, err := s.Where("type=?", []interface{}{typ}).Select()
|
res, err := s.Where("type=?", []interface{}{typ}).Select()
|
||||||
|
|
|
@ -44,6 +44,12 @@ func Register(r *gin.Engine) {
|
||||||
access.POST("/upd_access", api.UpdateAccess)
|
access.POST("/upd_access", api.UpdateAccess)
|
||||||
access.POST("/get_all", api.GetAllAccess)
|
access.POST("/get_all", api.GetAllAccess)
|
||||||
access.POST("/test_access", api.TestAccess)
|
access.POST("/test_access", api.TestAccess)
|
||||||
|
|
||||||
|
access.POST("/get_eab_list", api.GetEABList)
|
||||||
|
access.POST("/add_eab", api.AddEAB)
|
||||||
|
access.POST("/del_eab", api.DelEAB)
|
||||||
|
access.POST("/upd_eab", api.UpdEAB)
|
||||||
|
access.POST("/get_all_eab", api.GetAllEAB)
|
||||||
}
|
}
|
||||||
cert := v1.Group("/cert")
|
cert := v1.Group("/cert")
|
||||||
{
|
{
|
||||||
|
|
|
@ -83,8 +83,8 @@ func SiteMonitor() {
|
||||||
os.Remove(path)
|
os.Remove(path)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
wg.Wait()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue