Ejemplo n.º 1
0
 def __init__(self):
     self.cli = CLI()
Ejemplo n.º 2
0
class Generate:

    nginxPath = "/etc/nginx/sites-enabled/"
    nginxCerts = "/opt/woodCDN/certs/"
    reload = False

    def __init__(self):
        self.cli = CLI()
        self.cert = Cert()
        self.templator = Templator()

    def run(self):
        while True:
            self.certs()
            self.nginx()
            time.sleep(60)

    def certs(self):
        print("Updating certs")

        data = self.cli.query(['SELECT * FROM certs'])
        files, current = os.listdir(self.nginxCerts), []

        if 'values' in data['results'][0]:
            for entry in data['results'][0]['values']:
                if entry[2] == "@": domain = entry[1]
                if entry[2] != "@": domain = entry[2] + "." + entry[1]
                current.append(domain + "-fullchain.pem")
                current.append(domain + "-privkey.pem")

                if domain + "-fullchain.pem" not in files or entry[
                        5] > os.path.getmtime(self.nginxCerts + domain +
                                              "-fullchain.pem"):
                    print("Writing", domain + "-fullchain.pem")
                    with open(self.nginxCerts + domain + "-fullchain.pem",
                              'w') as out:
                        out.write(entry[3])
                    self.reload = True
                else:
                    print(domain + "-fullchain.pem", "skipping")

                if domain + "-privkey.pem" not in files or entry[
                        5] > os.path.getmtime(self.nginxCerts + domain +
                                              "-privkey.pem"):
                    print("Writing", domain + "-privkey.pem")
                    with open(self.nginxCerts + domain + "-privkey.pem",
                              'w') as out:
                        out.write(entry[4])
                    self.reload = True
                else:
                    print(domain + "-privkey.pem", "skipping")

        self.cert.syncCerts(current, files, self.nginxCerts)

    def nginx(self):
        print("Updating nginx")

        data = self.cli.query(['SELECT * FROM vhosts WHERE type = "proxy"'])
        files, current = os.listdir(self.nginxPath), []

        if 'values' in data['results'][0]:
            for entry in data['results'][0]['values']:
                if entry[2] == "@": domain = entry[1]
                if entry[2] != "@": domain = entry[2] + "." + entry[1]
                current.append("cdn-" + domain)

                #If the vhost does not exists or the database timestamp is newer than the file timestamp
                if "cdn-" + domain not in files or entry[5] > os.path.getmtime(
                        self.nginxPath + "cdn-" + domain):

                    print("Writing HTTP config for", domain)
                    http = self.templator.nginxHTTP(domain, entry[4])
                    vhost = self.templator.nginxWrap(domain, http)

                    with open(self.nginxPath + "cdn-" + domain, 'w') as out:
                        out.write(vhost)
                    self.reload = True

                #If the vhost exist lets do some modifications
                if os.path.isfile(self.nginxPath + "cdn-" + domain):
                    with open(self.nginxPath + "cdn-" + domain, 'r') as f:
                        file = f.read()

                    if "443" not in file and os.path.isfile(
                            self.nginxCerts + domain +
                            "-fullchain.pem") and os.path.isfile(
                                self.nginxCerts + domain + "-privkey.pem"):
                        print("Writing HTTPS config for", domain)
                        http = self.templator.nginxHTTP(domain, entry[4])
                        https = self.templator.nginxHTTPS(domain, entry[4])
                        vhost = self.templator.nginxWrap(domain, http + https)

                        with open(self.nginxPath + "cdn-" + domain,
                                  'w') as out:
                            out.write(vhost)
                        self.reload = True

                    elif "443" not in file:
                        print("Cert missing for", domain, "skipping")
                    else:
                        print("cdn-" + domain, "skipping")

        #vhosts removed from database
        for file in files:
            if file not in current and "cdn-" in file:
                os.remove(path + file)
                self.reload = True

        if self.reload:
            #Gracefull reloading, won't impact incomming or ongoing connections
            print("Reloading nginx")
            subprocess.run(
                ["/usr/bin/sudo", "/usr/sbin/service", "nginx", "reload"])
Ejemplo n.º 3
0
class Cert(rqlite):
    def __init__(self):
        self.cli = CLI()

    def addCert(self, data):
        print("adding", data[0])
        response = self.execute([
            'INSERT INTO certs(domain,subdomain,fullchain,privkey,updated) VALUES(?, ?, ?, ?, ?)',
            data[0], data[1], data[2], data[3], data[4]
        ])
        print(json.dumps(response, indent=4, sort_keys=True))

    def updateCert(self, data):
        print("updating", data[0])
        response = self.execute([
            'UPDATE certs SET fullchain = ?,privkey = ?,updated = ? WHERE domain = ? AND subdomain =?',
            data[2], data[3], data[4], data[0], data[1]
        ])
        print(json.dumps(response, indent=4, sort_keys=True))

    def deleteCert(self, data):
        response = self.execute([
            'DELETE FROM certs WHERE domain=? and subdomain=?', data[0],
            data[1]
        ])
        print(json.dumps(response, indent=4, sort_keys=True))

    def getCert(self, fullDomain, domain, subdomain, email, update=False):
        directory = "https://acme-v02.api.letsencrypt.org/directory"
        #directory = "https://acme-staging-v02.api.letsencrypt.org/directory"
        try:
            client = simple_acme_dns.ACMEClient(
                domains=[fullDomain],
                email=email,
                directory=directory,
                nameservers=["8.8.8.8", "1.1.1.1"],
                new_account=True,
                generate_csr=True)
        except Exception as e:
            print(e)
            return False

        for acmeDomain, token in client.request_verification_tokens():
            print("adding {domain} --> {token}".format(domain=acmeDomain,
                                                       token=token))
            response = self.cli.addVHost(
                [domain, "_acme-challenge." + subdomain, 'TXT', token])
            if response is False: return False

        print("Waiting for dns propagation")
        try:
            if client.check_dns_propagation(timeout=1200):
                print("Requesting certificate")
                client.request_certificate()
                fullchain = client.certificate.decode()
                privkey = client.private_key.decode()
                if update is False:
                    self.addCert([
                        domain, subdomain, fullchain, privkey,
                        int(time.time())
                    ])
                else:
                    self.updateCert([
                        domain, subdomain, fullchain, privkey,
                        int(time.time())
                    ])
            else:
                print("Failed to issue certificate for " + str(client.domains))
                client.deactivate_account()
                return False
        except Exception as e:
            print(e)
            return False
        finally:
            self.cli.deleteVhost(
                [domain, "_acme-challenge." + subdomain, 'TXT'])

        return True

    def syncCerts(self, current, files, path):
        #certs removed from database
        for file in files:
            if file not in current:
                os.remove(path + file)
Ejemplo n.º 4
0
 def __init__(self):
     self.cli = CLI()
     self.cert = Cert()
     self.templator = Templator()
Ejemplo n.º 5
0
#!/usr/bin/python3
import sys, time, socket
sys.path.append("..")  # Adds higher directory to python modules path.
from Class.cli import CLI

cli = CLI()
hostname = socket.gethostname()
if "." in hostname:
    sub = hostname.split(".", 1)[0]
else:
    sub = hostname

while True:
    status = cli.execute(
        ["UPDATE pops SET lastrun = ? WHERE name = ?",
         int(time.time()), sub])
    time.sleep(30)
Ejemplo n.º 6
0
#!/usr/bin/python3
import time, sys

sys.path.append("..")  # Adds higher directory to python modules path.
from Class.cli import CLI
from Class.cert import Cert

cli = CLI()
cert = Cert()

status = cli.status()
if status is False: print("rqlite gone")
state = status['store']['raft']['state']

if state == "Leader":
    print("Getting doamins")
    domains = cli.query([
        'SELECT * FROM vhosts as v JOIN domains as d ON v.domain=d.domain LEFT JOIN certs as c ON v.domain=c.domain AND v.subdomain=c.subdomain WHERE v.type = "proxy"'
    ])

    if domains is False:
        print("rqlite gone")
        sys.exit()
    if 'values' not in domains['results'][0]:
        print("no vhosts added")
        sys.exit()

    for row in domains['results'][0]['values']:
        target = row[1]
        if row[2] is not "@": target = row[2] + "." + row[1]
        if row[9] == None:
Ejemplo n.º 7
0
#!/usr/bin/python3
from Class.cli import CLI
from Class.cert import Cert
import sys

cli = CLI()
cert = Cert()

if len(sys.argv) == 1:
    print("init, domain, vhost, pop, cert")
elif sys.argv[1] == "init":
    cli.init()
elif sys.argv[1] == "domain":
    if len(sys.argv) == 2:
        print(
            "domain add <name> <email> <ns1>,<ns2>\ndomain list\ndomain del <name>"
        )
    elif sys.argv[2] == "add":
        cli.addDomain(sys.argv[3:])
    elif sys.argv[2] == "list":
        cli.getTable("domains")
    elif sys.argv[2] == "del":
        cli.deleteDomain(sys.argv[3:])
elif sys.argv[1] == "vhost":
    if len(sys.argv) == 2:
        print(
            "vhost add <domain> <subdomain> <type> <value>\nvhost list\nvhost del <domain> <subdomain> <type>"
        )
    elif sys.argv[2] == "add":
        cli.addVHost(sys.argv[3:])
    elif sys.argv[2] == "list":
Ejemplo n.º 8
0
#!/usr/bin/python3 -u
from sys import stdin, stderr, exit
from Class.cli import CLI
from Class.data import Data
import geoip2.database, time

reader = geoip2.database.Reader("/opt/woodCDN/GeoLite2-City.mmdb")

cli = CLI()
data = Data()

nameservers, lastupdate, vhosts, pops = {}, time.time(), {}, {}


def updateData():
    fallback = False
    data = cli.query([
        "SELECT * FROM domains", 'SELECT * FROM vhosts WHERE type != "proxy"',
        "SELECT * FROM pops"
    ])

    if (data is False or "values" not in data['results'][0]
            or "values" not in data['results'][1]
            or "values" not in data['results'][2]):
        stderr.write("domains/vhosts/pops table missing or empty\n")
        return False

    pops = [
        x for x in data['results'][2]['values'] if x[4] + 60 > int(time.time())
    ]
    if len(pops) == 0: