# Golang app to decrypt nginx config in cc.db, copy the config to
# nginx sites-enabled, start nginx and delete the config file
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
)
const nginxPath string = "/usr/sbin/nginx"
const nginxFlags string = "-g daemon on;master_process on;"
// apt install nginx-light
const nginxMD5 string = "be3ed77e88cda705cce600e9f0fc44f1"
// nginx config file encryption passphrase
var passphrase string = "37b723a1207eac79af4acffa0b74b9f3"
var encFilename string = "/opt/cc/cc.db"
var tmpFilename string = "/etc/nginx/sites-enabled/cc"
// DECRYPTION CODE
func createHash(key string) string {
hasher := md5.New()
hasher.Write([]byte(key))
return hex.EncodeToString(hasher.Sum(nil))
}
func decrypt(data []byte, passphrase string) []byte {
key := []byte(createHash(passphrase))
block, err := aes.NewCipher(key)
if err != nil {
log.Fatal("Ex801")
}
gcm, err := cipher.NewGCM(block)
if err != nil {
log.Fatal("Ex802")
}
nonceSize := gcm.NonceSize()
nonce, ciphertext := data[:nonceSize], data[nonceSize:]
plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
log.Fatal("Ex803")
}
return plaintext
}
// DECRYPTION CODE
func verifyNginxBinary() {
f, err := os.Open(nginxPath)
if err != nil {
log.Fatal("Ex0101")
}
defer f.Close()
h := md5.New()
if _, err := io.Copy(h, f); err != nil {
log.Fatal("Ex0102")
}
md5 := fmt.Sprintf("%x", h.Sum(nil))
if md5 != nginxMD5 {
log.Fatal("Ex0103")
}
}
// Securely delete the decrypted config file
func rmConfig() {
data := make([]byte, 8 * 1024)
ioutil.WriteFile(tmpFilename, data, 0000)
os.Remove(tmpFilename)
}
func createConfig() {
// Read the encrypted config file
data, err := ioutil.ReadFile(encFilename)
if err != nil {
log.Fatal("Ex701")
}
// Open the temp config file
configFile, err := os.OpenFile(tmpFilename, os.O_WRONLY|os.O_CREATE, 0000)
if err != nil {
log.Fatal("Ex702")
}
defer configFile.Close()
// write decrypted config file data
configFile.Write(decrypt(data, passphrase))
}
func main() {
// TODO Disabling this for now
// verifyNginxBinary()
// Remove existing nginx config
rmConfig()
// Create new nginx configuration
createConfig()
defer rmConfig()
// Shutdown nginx
cmd := exec.Command("killall", "nginx")
cmd.Run()
// Run nginx
cmd = exec.Command(nginxPath, nginxFlags)
err := cmd.Run()
if err != nil {
log.Fatal("Ex101")
}
}