@ -6,6 +6,7 @@ import (
"crypto/tls"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
@ -19,9 +20,9 @@ import (
func writeDomains ( ) error {
b := new ( bytes . Buffer )
err := json . NewEncoder ( b ) . Encode ( domain s)
err := json . NewEncoder ( b ) . Encode ( certgroup s)
if err != nil {
return errors . New ( "Couldn't encode domains lis t into JSON: " + err . Error ( ) )
return errors . New ( "Couldn't encode certgroups struc t into JSON: " + err . Error ( ) )
}
err = ioutil . WriteFile ( configDir + "/domains.json" , b . Bytes ( ) , 0644 )
@ -47,7 +48,7 @@ func writeServers() error {
return nil
}
func sendFileToAllServers ( filePath string ) error {
func sendFileToAllServers ( filePath , cert_idx string ) error {
var theError error
numservers := len ( servers )
c := make ( chan string )
@ -64,7 +65,7 @@ func sendFileToAllServers(filePath string) error {
}
log . Println ( "Parallel execution send file to server: " + srv + "..." )
err := sendFileToServer ( filePath , srv )
err := sendFileToServer ( filePath , srv , cert_idx )
if err != nil {
log . Println ( err . Error ( ) )
theError = err
@ -91,17 +92,18 @@ func sendFileToAllServers(filePath string) error {
return theError //if any one or more fail, return an error for it (the last one that fails)
}
func sendFileToServer ( filePath , server string ) error {
func sendFileToServer ( filePath , server , cert_idx string ) error {
log . Println ( "Send file " + filePath + " to " + server + " starting..." )
_ , fileName := path . Split ( filePath )
dest := strings . SplitN ( fileName , "__" , 2 ) [ 0 ] //cert__abcdef1234567890.tmpfile --> "cert"
fileType := strings . SplitN ( fileName , "__" , 2 ) [ 0 ] //cert__abcdef1234567890.tmpfile --> "cert"
data , err := os . Open ( filePath )
if err != nil {
return errors . New ( "sendFileToServer: Could not open temporary file " + filePath + ": " + err . Error ( ) )
}
url := syncScheme + server + ":" + syncPort + "/api/file/upload/" + dest
log . Println ( "Send file " + filePath + " to " + url + "..." )
//url := syncScheme + server + ":" + syncPort + "/api/file/upload/" + fileType + "/" + fmt.Sprintf("%02d", cert_idx)
url := syncScheme + server + ":" + syncPort + "/api/file/upload/" + fileType + "/" + cert_idx
log . Println ( "Send file '" + filePath + "' to " + url + "..." )
req , err := http . NewRequest ( "PUT" , url , data )
if err != nil {
@ -132,18 +134,20 @@ func sendFileToServer(filePath, server string) error {
log . Println ( errorString )
return errors . New ( errorString )
}
log . Println ( "Upload [" + dest + "] to " + server + " success!" )
log . Println ( "Upload [" + fileType + "] to " + server + " success!" )
return nil
}
func renew ( ) error {
func renew ( cert_idx int ) error {
log . Println ( "Renew operation initiated..." )
//BUILD/SET GETSSL ENVIRONMENT VARIABLES THEN EXECUTE GETSSL
//domain list
var domainlist string
cg := certgroups [ cert_idx ]
domains := cg . Domains
for _ , d := range domains {
if d == appconf . PrimaryDomain { //ignore primary domain
if d == cg . PrimaryDomain { //ignore primary domain
continue
}
domainlist = domainlist + "," + d
@ -157,6 +161,9 @@ func renew() error {
log . Println ( domainlist )
}
// GetSSL Expected WebDAV Format: (HTTPS ONLY!)
// ";davs:davsuser:davspassword:{DOMAIN}:443:/path"
//ACL string
aclstring := appconf . LetsEncryptValidationPath
if appconf . SyncType == "ssh" {
@ -165,7 +172,6 @@ func renew() error {
continue
}
aclstring += ";ssh:" + appconf . Username + "@" + server + ":" + appconf . LetsEncryptValidationPath
//aclstring += ";davs:leapi:" + appconf.SecretKey + ":" + server + ":" + syncPort + ":/api/file/upload/"
}
} else { //file sync type is HTTPS
aclstring += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync"
@ -182,86 +188,87 @@ func renew() error {
}
//Cert and key locations
domain_cert_location := appconf . TLSCertFile
domain_cert_location := appconf . TLSCertPath + fmt . Sprintf ( "%02d" , cert_idx ) + ".crt"
if appconf . SyncType == "ssh" {
for _ , server := range servers {
if server == appconf . Hostname {
continue
}
domain_cert_location += ";ssh:" + appconf . Username + "@" + server + ":" + appconf . TLSCertFile
//domain_cert_location += ";davs:leapi:" + appconf.SecretKey + ":" + server + ":" + syncPort + ":/api/file/upload/cert"
domain_cert_location += ";ssh:" + appconf . Username + "@" + server + ":" + appconf . TLSCertPath + fmt . Sprintf ( "%02d" , cert_idx ) + ".crt"
}
} else { //file sync type is HTTPS
domain_cert_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/cert"
// ;davs:user:pass:hostname:port:/api/file/sync/cert/{cert_idx}
domain_cert_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/cert/" + fmt . Sprintf ( "%02d" , cert_idx )
}
err = os . Setenv ( "DOMAIN_CERT_LOCATION" , domain_cert_location )
if err != nil {
return errors . New ( "RENEW: error setting DOMAIN_CERT_LOCATION environment variable: " + err . Error ( ) )
}
domain_key_location := appconf . TLSKeyFile
domain_key_location := appconf . TLSKeyPath + fmt . Sprintf ( "%02d" , cert_idx ) + ".key"
if appconf . SyncType == "ssh" {
for _ , server := range servers {
if server == appconf . Hostname {
continue
}
domain_key_location += ";ssh:" + appconf . Username + "@" + server + ":" + appconf . TLSKeyFile
//domain_key_location += ";davs:leapi:" + appconf.SecretKey + ":" + server + ":" + syncPort + ":/api/file/upload/key"
domain_key_location += ";ssh:" + appconf . Username + "@" + server + ":" + appconf . TLSKeyPath + fmt . Sprintf ( "%02d" , cert_idx ) + ".key"
}
} else { //file sync type is HTTPS
domain_key_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/key"
domain_key_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/key/ " + fmt . Sprintf ( "%02d" , cert_idx )
}
err = os . Setenv ( "DOMAIN_KEY_LOCATION" , domain_key_location )
if err != nil {
return errors . New ( "RENEW: error setting DOMAIN_KEY_LOCATION environment variable: " + err . Error ( ) )
}
domain_chain_location := appconf . TLSChainFile
domain_chain_location := appconf . TLSChainPath + fmt . Sprintf ( "%02d" , cert_idx ) + ".crt"
if appconf . SyncType == "ssh" {
for _ , server := range servers {
if server == appconf . Hostname {
continue
}
//domain_chain_location += ";ssh:" + appconf.Username + "@" + server + ":" + appconf.TLSChainFile
domain_chain_location += ";davs:leapi :" + appconf . SecretKey + ": " + server + ":" + syncPort + ":/api/file/upload/chain "
//domain_chain_location += ";davs:leapi:" + appconf.SecretKey + ":" + server + ":" + syncPort + ":/api/file/upload/chain"
domain_chain_location += ";ssh :" + appconf . Username + "@ " + server + ":" + appconf . TLSChainPath + fmt . Sprintf ( "%02d" , cert_idx ) + ".crt "
}
} else { //file sync type is HTTPS
domain_chain_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/chain"
domain_chain_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/chain/ " + fmt . Sprintf ( "%02d" , cert_idx )
}
err = os . Setenv ( "DOMAIN_CHAIN_LOCATION" , domain_chain_location )
if err != nil {
return errors . New ( "RENEW: error setting DOMAIN_CHAIN_LOCATION environment variable: " + err . Error ( ) )
}
domain_pem_location := appconf . TLSPEMFile
domain_pem_location := appconf . TLSPEMPath + fmt . Sprintf ( "%02d" , cert_idx ) + ".pem"
if appconf . SyncType == "ssh" {
for _ , server := range servers {
if server == appconf . Hostname {
continue
}
domain_pem_location += ";ssh:" + appconf . Username + "@" + server + ":" + appconf . TLSPEMFile
//domain_pem_location += ";davs:leapi:" + appconf.SecretKey + ":" + server + ":" + syncPort + ":/api/file/upload/pem"
domain_pem_location += ";ssh:" + appconf . Username + "@" + server + ":" + appconf . TLSPEMPath + fmt . Sprintf ( "%02d" , cert_idx ) + ".pem"
}
} else { //file sync type is HTTPS
domain_pem_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/pem"
domain_pem_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/pem/ " + fmt . Sprintf ( "%02d" , cert_idx )
}
err = os . Setenv ( "DOMAIN_PEM_LOCATION" , domain_pem_location )
if err != nil {
return errors . New ( "RENEW: error setting DOMAIN_PEM_LOCATION environment variable: " + err . Error ( ) )
}
//these parameters don't seem to be respected by gettssl from environment variables, so write them to config file:
ca_cert_location := appconf . TLSCAFile
//these parameters don't seem to be respected by GetSSL from environment variables, so write them to config file:
ca_cert_location := appconf . TLSCAPath + ".crt"
if appconf . SyncType == "ssh" {
for _ , server := range servers {
if server == appconf . Hostname {
continue
}
ca_cert_location += ";ssh:" + appconf . Username + "@" + server + ":" + appconf . TLSCAFile
//ca_cert_location += ";davs:leapi:" + appconf.SecretKey + ":" + server + ":" + syncPort + ":/api/file/upload/ca"
ca_cert_location += ";ssh:" + appconf . Username + "@" + server + ":" + appconf . TLSCAPath + fmt . Sprintf ( "%02d" , cert_idx ) + ".crt"
}
} else { //file sync type is HTTPS
ca_cert_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/ca"
ca_cert_location += ";davs:" + appconf . Username + ":" + appconf . SecretKey + ":" + appconf . Hostname + ":" + appconf . HTTPS_ServerPort + ":/api/file/sync/ca/ " + fmt . Sprintf ( "%02d" , cert_idx )
}
reload_command := appconf . ReloadCommand
@ -285,7 +292,7 @@ func renew() error {
configFile = "CA=\"" + ca_server + "\"\n"
configFile += "USE_SINGLE_ACL=\"true\"\n"
configFile += "CA_CERT_LOCATION=\"" + appconf . TLSCAFile + "\"\n"
configFile += "CA_CERT_LOCATION=\"" + appconf . TLSCAPath + "\"\n"
configFile += "RELOAD_CMD=\"" + reload_command + "\"\n"
configFile += "RENEW_ALLOW=\"" + appconf . RenewAllow + "\"\n"
configFile += "CHECK_REMOTE=\"true\"\n"
@ -293,9 +300,9 @@ func renew() error {
configFile += "CHECK_REMOTE_WAIT=\"5\"\n"
//write config file
err = ioutil . WriteFile ( configDir + "/" + appconf . PrimaryDomain + "/getssl.cfg" , [ ] byte ( configFile ) , 0644 )
err = ioutil . WriteFile ( configDir + "/" + cg . PrimaryDomain + "/getssl.cfg" , [ ] byte ( configFile ) , 0644 )
if err != nil {
return errors . New ( "Couldn't write getssl config file: " + configDir + "/" + appconf . PrimaryDomain + "/getssl.cfg" )
return errors . New ( "Couldn't write getssl config file: " + configDir + "/" + cg . PrimaryDomain + "/getssl.cfg" )
}
if appconf . Debug {
@ -316,9 +323,9 @@ func renew() error {
//RUN getssl on primary domain to renew
//cmd = exec.Command(appconf.SrvDir+"/getssl", "-u", "-w", appconf.SrvDir, appconf.PrimaryDomain)
if appconf . Debug {
cmd = exec . Command ( appconf . SrvDir + "/getssl" , "-d" , "-w" , appconf . SrvDir , appconf . PrimaryDomain )
cmd = exec . Command ( appconf . SrvDir + "/getssl" , "-d" , "-w" , appconf . SrvDir , cg . PrimaryDomain )
} else {
cmd = exec . Command ( appconf . SrvDir + "/getssl" , "-w" , appconf . SrvDir , appconf . PrimaryDomain )
cmd = exec . Command ( appconf . SrvDir + "/getssl" , "-w" , appconf . SrvDir , cg . PrimaryDomain )
}
output , err = cmd . CombinedOutput ( )
if err != nil {