重构
This commit is contained in:
parent
191d14cd74
commit
5c2a435597
4
main.go
4
main.go
|
@ -4,8 +4,4 @@ import "acme-mana/src"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
src.Start()
|
src.Start()
|
||||||
//test.TestParseCert()
|
|
||||||
//test.TestValidExist()
|
|
||||||
//test.TestParseCertInfo()
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,12 +27,12 @@ func Apply(domain Domain) {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
acmeUser := AcmeUser{
|
acmeUser := &AcmeUser{
|
||||||
Email: email,
|
Email: email,
|
||||||
key: privateKey,
|
key: privateKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
config := lego.NewConfig(&acmeUser)
|
config := lego.NewConfig(acmeUser)
|
||||||
|
|
||||||
client, err := lego.NewClient(config)
|
client, err := lego.NewClient(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitSocket /*
|
// InitSocket 初始化 socket 文件
|
||||||
func InitSocket() {
|
func InitSocket() {
|
||||||
log.Println("Start listen command")
|
log.Println("Start listen command")
|
||||||
// 删除旧的 socket 文件
|
// 删除旧的 socket 文件
|
||||||
|
|
139
src/config.go
139
src/config.go
|
@ -2,19 +2,22 @@ package src
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"acme-mana/src/crypto"
|
"acme-mana/src/crypto"
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
"github.com/go-acme/lego/v4/log"
|
"github.com/go-acme/lego/v4/log"
|
||||||
"github.com/go-acme/lego/v4/platform/config/env"
|
"github.com/go-acme/lego/v4/platform/config/env"
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ReadConfig() AppConfig {
|
func ReadConfig() *AppConfig {
|
||||||
InitConfig()
|
InitConfig()
|
||||||
file, err := os.ReadFile(GetEnvConf().ConfFile)
|
file, err := os.ReadFile(GetEnvConf().ConfFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
var conf AppConfig
|
var conf *AppConfig
|
||||||
err = yaml.Unmarshal(file, &conf)
|
err = yaml.Unmarshal(file, &conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -31,7 +34,7 @@ func InitConfig() {
|
||||||
// 配置文件不存在,则创建一个
|
// 配置文件不存在,则创建一个
|
||||||
log.Infof("配置文件不存在,自动创建默认配置文件")
|
log.Infof("配置文件不存在,自动创建默认配置文件")
|
||||||
// 生成默认配置
|
// 生成默认配置
|
||||||
conf := defaultConf()
|
conf := readNewConf()
|
||||||
// 创建一个默认的配置文件
|
// 创建一个默认的配置文件
|
||||||
file, err := os.Create(GetEnvConf().ConfFile)
|
file, err := os.Create(GetEnvConf().ConfFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -50,6 +53,121 @@ func InitConfig() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func readNewConf() *AppConfig {
|
||||||
|
conf := defaultConf()
|
||||||
|
log.Println("无配置文件, 生成配置文件")
|
||||||
|
|
||||||
|
conf.CertDir = scanConfDefault("请输入证书保存目录; 默认为 cert", "cert")
|
||||||
|
isGenMsg := "是否需要自动生成用于数据传输加密的RSA密钥对? \n请输入yes(Y)/no(N) 默认为 yes"
|
||||||
|
isGenErrMsg := "请输入yes(Y)/no(N)"
|
||||||
|
isGenValues := []string{"yes", "no", "Y", "N"}
|
||||||
|
isGenEncrypt := scanConfDefaultCheck(isGenMsg, "yes", isGenValues, isGenErrMsg)
|
||||||
|
if isGenEncrypt == "no" || isGenEncrypt == "N" {
|
||||||
|
conf.Encrypt.PriKey = scanConf("请输入RSA私钥", "请输入RSA私钥")
|
||||||
|
conf.Encrypt.PubKey = scanConf("请输入RSA公钥", "请输入RSA公钥")
|
||||||
|
}
|
||||||
|
|
||||||
|
codes := []string{"alidns", "tencentcloud", "cloudflare"}
|
||||||
|
msg := fmt.Sprintf("请输入DNS提供商; 当前支持的: %s", strings.Join(codes, ","))
|
||||||
|
errMsg := fmt.Sprintf("不支持的DNS提供商; 当前支持的: %s", strings.Join(codes, ","))
|
||||||
|
conf.Use = scanConfDefaultCheck(msg, "", codes, errMsg)
|
||||||
|
switch conf.Use {
|
||||||
|
case "alidns":
|
||||||
|
fmt.Printf("阿里云DNS配置帮助页: \n%s\n", "https://go-acme.github.io/lego/dns/alidns/index.html")
|
||||||
|
fmt.Printf("阿里云令牌获取方式:\n%s\n", "https://usercenter.console.aliyun.com/#/manage/ak")
|
||||||
|
fmt.Printf("阿里云SDK客户端项目地址:\n%s\n", "https://github.com/aliyun/alibaba-cloud-sdk-go?tab=readme-ov-file")
|
||||||
|
conf.Provider.Ali.RegionID = scanConf("请输入阿里云Region ID", "请输入阿里云Region ID")
|
||||||
|
conf.Provider.Ali.APIKey = scanConf("请输入阿里云API Key", "请输入阿里云API Key")
|
||||||
|
conf.Provider.Ali.SecretKey = scanConf("请输入阿里云Secret Key", "请输入阿里云Secret Key")
|
||||||
|
case "tencentcloud":
|
||||||
|
fmt.Printf("腾讯云DNS配置帮助页: \n%s\n", "https://go-acme.github.io/lego/dns/tencentcloud/index.html")
|
||||||
|
fmt.Printf("腾讯云令牌获取方式: \n%s\n", "https://console.cloud.tencent.com/cam/capi")
|
||||||
|
fmt.Printf("腾讯云SDK客户端项目地址: \n%s\n", "https://github.com/tencentcloud/tencentcloud-sdk-go?tab=readme-ov-file")
|
||||||
|
conf.Provider.Tencent.SecretId = scanConf("请输入腾讯云Secret Id", "请输入腾讯云Secret Id")
|
||||||
|
conf.Provider.Tencent.SecretKey = scanConf("请输入腾讯云Secret Key", "请输入腾讯云Secret Key")
|
||||||
|
case "cloudflare":
|
||||||
|
fmt.Printf("Cloudflare DNS配置帮助页: \n%s\n", "https://go-acme.github.io/lego/dns/tencentcloud/index.html")
|
||||||
|
fmt.Printf("Cloudflare 令牌获取方式: \n%s\n", "https://blog.cloudflare.com/zh-cn/api-tokens-general-availability/")
|
||||||
|
fmt.Printf("Cloudflare SDK客户端项目地址: \n%s\n", "https://github.com/cloudflare/cloudflare-go")
|
||||||
|
conf.Provider.CloudFlare.Token = scanConf("请输入CloudFlare DNS API Token", "请输入CloudFlare Token")
|
||||||
|
}
|
||||||
|
isAddDomainMsg := "是否需要添加证书获取配置?\n您可以在此处通过控制台交互添加;也可以在配置文件创建后,直接修改配置文件.\n请输入yes(Y)/no(N) 默认为 yes"
|
||||||
|
isAddDomain := scanConfDefaultCheck(isAddDomainMsg, "yes", isGenValues, isGenErrMsg)
|
||||||
|
if isAddDomain == "no" || isAddDomain == "N" {
|
||||||
|
fmt.Printf("您可以通过手动修改%s文件, 调整证书获取配置.", GetEnvConf().ConfFile)
|
||||||
|
conf.Domains = []Domain{}
|
||||||
|
return conf
|
||||||
|
}
|
||||||
|
conf.Domains = []Domain{}
|
||||||
|
for {
|
||||||
|
name := scanConf("请输入配置名称", "配置名称不能为空")
|
||||||
|
email := scanConf("请输入邮箱", "邮箱不能为空")
|
||||||
|
host := scanConf("请输入主机名;支持泛解析;\n支持多个域名,多个域名用,(英文逗号)分割;\n如: example.com,*.example.com\n", "主机名不能为空")
|
||||||
|
// 将host通过,分割为数组
|
||||||
|
hosts := strings.Split(host, ",")
|
||||||
|
conf.Domains = append(conf.Domains, Domain{
|
||||||
|
Name: name,
|
||||||
|
Email: email,
|
||||||
|
Host: hosts,
|
||||||
|
})
|
||||||
|
isAddNextDomainMsg := "是否需要继续添加证书获取配置?\n请输入yes(Y)/no(N) 默认为 yes"
|
||||||
|
isAddNextDomain := scanConfDefaultCheck(isAddNextDomainMsg, "yes", isGenValues, isGenErrMsg)
|
||||||
|
if isAddNextDomain == "no" || isAddNextDomain == "N" {
|
||||||
|
fmt.Printf("您后续可以通过手动修改%s文件, 调整证书获取配置.", GetEnvConf().ConfFile)
|
||||||
|
return conf
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取用户输入
|
||||||
|
func scanConf(msg string, errMsg string) string {
|
||||||
|
for {
|
||||||
|
log.Println(msg)
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
name, err := reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("读取失败;", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name = strings.Trim(name, "\r\n")
|
||||||
|
if name == "" {
|
||||||
|
fmt.Println(errMsg)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func scanConfDefault(msg string, defaultContent string) string {
|
||||||
|
for {
|
||||||
|
log.Println(msg)
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
name, err := reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("读取失败;", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
name = strings.Trim(name, "\r\n")
|
||||||
|
if name == "" {
|
||||||
|
return defaultContent
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func scanConfDefaultCheck(msg string, defaultContent string, values []string, errMsg string) string {
|
||||||
|
for {
|
||||||
|
content := scanConfDefault(msg, defaultContent)
|
||||||
|
// 判断内容是否在values中
|
||||||
|
for _, value := range values {
|
||||||
|
if value == content {
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.Println(errMsg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func defaultConf() *AppConfig {
|
func defaultConf() *AppConfig {
|
||||||
//priKey, pubKey, err := GenRsa()
|
//priKey, pubKey, err := GenRsa()
|
||||||
priKey, pubKey, err := crypto.GenRSA()
|
priKey, pubKey, err := crypto.GenRSA()
|
||||||
|
@ -69,6 +187,9 @@ func defaultConf() *AppConfig {
|
||||||
SecretId: "secret_id",
|
SecretId: "secret_id",
|
||||||
SecretKey: "secret_key",
|
SecretKey: "secret_key",
|
||||||
},
|
},
|
||||||
|
CloudFlare: CloudFlareProvider{
|
||||||
|
Token: "token",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Domains: []Domain{
|
Domains: []Domain{
|
||||||
{
|
{
|
||||||
|
@ -97,8 +218,9 @@ type AppConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type AppProvider struct {
|
type AppProvider struct {
|
||||||
Ali AliProvider
|
Ali AliProvider
|
||||||
Tencent TencentProvider
|
Tencent TencentProvider
|
||||||
|
CloudFlare CloudFlareProvider
|
||||||
}
|
}
|
||||||
type AliProvider struct {
|
type AliProvider struct {
|
||||||
RegionID string
|
RegionID string
|
||||||
|
@ -109,6 +231,9 @@ type TencentProvider struct {
|
||||||
SecretId string
|
SecretId string
|
||||||
SecretKey string
|
SecretKey string
|
||||||
}
|
}
|
||||||
|
type CloudFlareProvider struct {
|
||||||
|
Token string
|
||||||
|
}
|
||||||
type Domain struct {
|
type Domain struct {
|
||||||
Name string
|
Name string
|
||||||
Email string
|
Email string
|
||||||
|
@ -130,8 +255,8 @@ func (conf AppConfig) FindDomain(name string) *Domain {
|
||||||
|
|
||||||
const ENV_CONF_FILE = "ACME_MANA_CONF_FILE"
|
const ENV_CONF_FILE = "ACME_MANA_CONF_FILE"
|
||||||
|
|
||||||
func InitRuntimeConf() EnvConf {
|
func InitRuntimeConf() *EnvConf {
|
||||||
return EnvConf{
|
return &EnvConf{
|
||||||
ConfFile: env.GetOrDefaultString(ENV_CONF_FILE, "config.yml"),
|
ConfFile: env.GetOrDefaultString(ENV_CONF_FILE, "config.yml"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ var stderr *os.File
|
||||||
// Start 启动/*
|
// Start 启动/*
|
||||||
func Start() {
|
func Start() {
|
||||||
initLog()
|
initLog()
|
||||||
log.Println("Run Acme Mana...")
|
|
||||||
args := os.Args
|
args := os.Args
|
||||||
if len(args) <= 1 {
|
if len(args) <= 1 {
|
||||||
//daemonStart()
|
//daemonStart()
|
||||||
|
@ -79,6 +78,7 @@ func initLog() {
|
||||||
守护进程启动
|
守护进程启动
|
||||||
*/
|
*/
|
||||||
func daemonStart() {
|
func daemonStart() {
|
||||||
|
GetAppConfig()
|
||||||
isDaemon := os.Getenv("GO_DAEMON")
|
isDaemon := os.Getenv("GO_DAEMON")
|
||||||
log.Println("Run Daemon, DAEMON Is " + isDaemon)
|
log.Println("Run Daemon, DAEMON Is " + isDaemon)
|
||||||
if isDaemon != "1" {
|
if isDaemon != "1" {
|
||||||
|
@ -200,31 +200,15 @@ func showPubkey() {
|
||||||
log.Println(key)
|
log.Println(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// 守护进程接收命令
|
||||||
守护进程接收名称
|
|
||||||
*/
|
|
||||||
func daemonCommand() {
|
func daemonCommand() {
|
||||||
log.Println("Sending command...")
|
log.Println("Sending command...")
|
||||||
//pid, err := readPID()
|
|
||||||
//if err != nil {
|
|
||||||
// log.Fatalf("Failed to send command: %v", err)
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//_, err = os.FindProcess(pid)
|
|
||||||
//if err != nil {
|
|
||||||
// log.Fatalf("Failed to find process: %v", err)
|
|
||||||
//}
|
|
||||||
//if len(os.Args) < 3 {
|
|
||||||
// log.Fatalf("No command specified")
|
|
||||||
//}
|
|
||||||
command := os.Args[2]
|
command := os.Args[2]
|
||||||
sendCommand(command)
|
sendCommand(command)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// 发送命令
|
||||||
发送命令
|
|
||||||
*/
|
|
||||||
func sendCommand(command string) {
|
func sendCommand(command string) {
|
||||||
conn, err := net.Dial("unix", SocketFile)
|
conn, err := net.Dial("unix", SocketFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -245,16 +229,8 @@ func sendCommand(command string) {
|
||||||
log.Printf("Sending command '%s' to daemon with PID: %d", command, 0)
|
log.Printf("Sending command '%s' to daemon with PID: %d", command, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// 业务进程执行任务
|
||||||
*
|
|
||||||
业务进程执行任务
|
|
||||||
*/
|
|
||||||
func doTask() {
|
func doTask() {
|
||||||
// 示例:每隔10秒打印一条日志
|
|
||||||
//for {
|
|
||||||
// log.Println("Daemon is running...")
|
|
||||||
// time.Sleep(10 * time.Second)
|
|
||||||
//}
|
|
||||||
|
|
||||||
// 监听主进程下发的指令
|
// 监听主进程下发的指令
|
||||||
go InitSocket()
|
go InitSocket()
|
||||||
|
|
25
src/util.go
25
src/util.go
|
@ -1,25 +0,0 @@
|
||||||
package src
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"crypto/rsa"
|
|
||||||
"crypto/x509"
|
|
||||||
"encoding/base64"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GenRsa() (priKey string, pubKey string, err error) {
|
|
||||||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
publicKey := &privateKey.PublicKey
|
|
||||||
publicKeyBytes := x509.MarshalPKCS1PublicKey(publicKey)
|
|
||||||
pubKey = base64.StdEncoding.EncodeToString(publicKeyBytes)
|
|
||||||
privateKeyBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
|
|
||||||
if err != nil {
|
|
||||||
return "", "", err
|
|
||||||
}
|
|
||||||
priKey = base64.StdEncoding.EncodeToString(privateKeyBytes)
|
|
||||||
err = nil
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -7,15 +7,15 @@ const CertFileName = "fullchain.pem"
|
||||||
const KeyFileName = "privkey.pem"
|
const KeyFileName = "privkey.pem"
|
||||||
const CertInfoFileName = "info.json"
|
const CertInfoFileName = "info.json"
|
||||||
|
|
||||||
var appConfig AppConfig = ReadConfig()
|
var appConfig *AppConfig = ReadConfig()
|
||||||
|
|
||||||
func GetAppConfig() AppConfig {
|
func GetAppConfig() *AppConfig {
|
||||||
return appConfig
|
return appConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
var envConf EnvConf = InitRuntimeConf()
|
var envConf *EnvConf = InitRuntimeConf()
|
||||||
|
|
||||||
func GetEnvConf() EnvConf {
|
func GetEnvConf() *EnvConf {
|
||||||
return envConf
|
return envConf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user