Small tool to convert acme.json certificates from Traefik, to standard PEM certificates, PLUS the full chain file (for software which needs it).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
zumba/zumba.go

148 lines
3.1 KiB

package main
import (
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"time"
)
type AcmeJson struct {
Letsencryptresolver struct {
Account struct {
Email string `json:"Email"`
Registration struct {
Body struct {
Status string `json:"status"`
Contact []string `json:"contact"`
} `json:"body"`
URI string `json:"uri"`
} `json:"Registration"`
PrivateKey string `json:"PrivateKey"`
KeyType string `json:"KeyType"`
} `json:"Account"`
Certificates []struct {
Domain struct {
Main string `json:"main"`
} `json:"domain"`
Certificate string `json:"certificate"`
Key string `json:"key"`
Store string `json:"Store"`
} `json:"Certificates"`
} `json:"letsencryptresolver"`
}
// Squelch
var MyAcme AcmeJson
var AcmeFile, CertPath string
func init() {
AcmeFile = os.Getenv("ACME_FILE")
CertPath = os.Getenv("CERT_PATH")
if AcmeFile == "" {
log.Println("Missing ENV VAR ACME_FILE")
os.Exit(2)
}
if CertPath == "" {
log.Println("Missing ENV VAR CERT_PATH")
os.Exit(2)
}
}
func loadAcme() {
file, err := ioutil.ReadFile(AcmeFile)
if err != nil {
log.Println("Cannot open config file", err.Error())
os.Exit(1)
} else {
log.Println("Json File open")
}
err = json.Unmarshal([]byte(file), &MyAcme)
if err != nil {
log.Println("Cannot marshal json: ", err.Error())
os.Exit(1)
} else {
log.Println("Json Syntax OK")
}
log.Println("Acme file Loaded")
}
func main() {
ticker := time.NewTicker(12 * time.Hour)
defer ticker.Stop()
loadAcme()
for ; true; <-ticker.C {
for _, k := range MyAcme.Letsencryptresolver.Certificates {
// Decode
decoded, err := base64.StdEncoding.DecodeString(k.Certificate)
if err != nil {
fmt.Println("Unable to decode certificate", k.Domain.Main)
continue
} else {
fmt.Println("Decoded certificate ok: ", k.Domain.Main)
}
// Write chain
name := fmt.Sprintf("%s/%s.chain.crt", CertPath, k.Domain.Main)
fmt.Println("Writing file", name)
err = ioutil.WriteFile(name, decoded, 0644)
if err != nil {
fmt.Println("Error writing file", name)
} else {
fmt.Println("Decoded chain written at: ", name)
}
// Write cert
name = fmt.Sprintf("%s/%s.crt", CertPath, k.Domain.Main)
fmt.Println("Writing file", name)
parts := strings.Split(string(decoded), "\n\n")
err = ioutil.WriteFile(name, []byte(parts[0]), 0644)
if err != nil {
fmt.Println("Error writing file", name)
} else {
fmt.Println("Decoded cert written at: ", name)
}
// Decode key
decoded, err = base64.StdEncoding.DecodeString(k.Key)
if err != nil {
fmt.Println("Unable to decode Key", k.Domain.Main)
continue
} else {
fmt.Println("Decoded key for ", k.Domain.Main)
}
// Write key
name = fmt.Sprintf("%s/%s.key", CertPath, k.Domain.Main)
fmt.Println("Writing key file", name)
err = ioutil.WriteFile(name, []byte(decoded), 0644)
if err != nil {
fmt.Println("Error writing file", name)
} else {
fmt.Println("Decoded key written at: ", name)
}
}
}
os.Exit(0)
}