def assign(self, assign): """ Assign a TLS certificate to a website or service. :param dict assign: ``Assign`` object to assign :returns: self """ signals.emit("certificates", "pre_assign", (self, assign)) nginx_reload = False if assign["type"] == "genesis": config.set("genesis", "cert_file", self.cert_path) config.set("genesis", "cert_key", self.key_path) config.set("genesis", "ssl", True) config.save() self.assigns.append(assign) elif assign["type"] == "website": w = websites.get(assign["id"]) w.cert = self w.ssl_enable() self.assigns.append(assign) nginx_reload = True else: d = applications.get(assign["aid"]).ssl_enable(self, assign["sid"]) self.assigns.append(d) if nginx_reload: websites.nginx_reload() signals.emit("certificates", "post_assign", (self, assign)) return self
def install_updates(message=DefaultMessage()): updates = storage.updates.get("updates") if not updates: return signals.emit("updates", "pre_install") amount = len(updates) responses, ids = [], [] for z in enumerate(updates): message.update("info", "%s of %s..." % (z[0]+1, amount), head="Installing updates") for x in sorted(z[1]["tasks"], key=lambda y: y["step"]): getout = False if x["unit"] == "shell": s = shell(x["order"], stdin=x.get("data", None)) if s["code"] != 0: responses.append((x["step"], s["stderr"])) getout = True break elif x["unit"] == "fetch": try: download(x["order"], x["data"], True) except Exception, e: code = 1 if hasattr(e, "code"): code = e.code responses.append((x["step"], str(code))) getout = True break else: ids.append(z[1]["id"]) config.set("updates", "current_update", z[1]["id"]) config.save() continue message.complete("error", "Installation of update %s failed. See logs for details." % str(z[1]["id"])) print responses break
def unassign(self, assign): """ Unassign a TLS certificate from a website or service. :param dict assign: ``Assign`` object to unassign :returns: self """ signals.emit("certificates", "pre_unassign", (self, assign)) nginx_reload = False if assign["type"] == "website": websites.get(assign["id"]).ssl_disable() self.assigns.remove(assign) nginx_reload = True elif assign["type"] == "genesis": config.set("genesis", "cert_file", "") config.set("genesis", "cert_key", "") config.set("genesis", "ssl", False) config.save() self.assigns.remove(assign) else: applications.get(assign["aid"]).ssl_disable(assign["sid"]) self.assigns.remove(assign) if nginx_reload: websites.nginx_reload() signals.emit("certificates", "post_unassign", (self, assign)) return None
def ssl_enable(self): # Get server-preferred ciphers if config.get("certificates", "ciphers"): ciphers = config.get("certificates", "ciphers") else: config.set("certificates", "ciphers", ciphers) config.save() block = nginx.loadf(os.path.join("/etc/nginx/sites-available/", self.id)) # If the site is on port 80, setup an HTTP redirect to new port 443 server = block.servers[0] listen = server.filter("Key", "listen")[0] if listen.value == "80": listen.value = "443 ssl" block.add(nginx.Server( nginx.Key("listen", "80"), nginx.Key("server_name", self.addr), nginx.Key("return", "301 https://%s$request_uri" % self.addr) )) for x in block.servers: if x.filter("Key", "listen")[0].value == "443 ssl": server = x break else: listen.value = listen.value.split(" ssl")[0] + " ssl" # Clean up any pre-existing SSL directives that no longer apply for x in server.all(): if type(x) == nginx.Key and x.name.startswith("ssl_"): server.remove(x) # Add the necessary SSL directives to the serverblock and save server.add( nginx.Key("ssl_certificate", self.cert.cert_path), nginx.Key("ssl_certificate_key", self.cert.key_path), nginx.Key("ssl_protocols", "TLSv1 TLSv1.1 TLSv1.2"), nginx.Key("ssl_ciphers", ciphers), nginx.Key("ssl_session_timeout", "5m"), nginx.Key("ssl_prefer_server_ciphers", "on"), nginx.Key("ssl_dhparam", "/etc/arkos/ssl/dh_params.pem"), nginx.Key("ssl_session_cache", "shared:SSL:50m"), ) nginx.dumpf(block, os.path.join("/etc/nginx/sites-available/", self.id)) # Set the certificate name in the metadata file meta = ConfigParser.SafeConfigParser() meta.read(os.path.join(self.path, ".arkos")) meta.set("website", "ssl", self.cert.id) with open(os.path.join(self.path, ".arkos"), "w") as f: meta.write(f) # Call the website type's SSL enable hook self.enable_ssl(self.cert.cert_path, self.cert.key_path)
def install_updates(nthread=NotificationThread()): """ Install all available updates from arkOS repo server. :param message message: Message object to update with status """ nthread.title = "Installing updates" updates = storage.updates if not updates: return signals.emit("updates", "pre_install") amount = len(updates) responses, ids = [], [] for z in enumerate(updates.values()): msg = "{0} of {1}...".format(z[0] + 1, amount) nthread.update(Notification("info", "Updates", msg)) for x in sorted(z[1]["tasks"], key=lambda y: y["step"]): if x["unit"] == "shell": s = shell(x["order"], stdin=x.get("data", None)) if s["code"] != 0: responses.append((x["step"], s["stderr"])) break elif x["unit"] == "fetch": try: download(x["order"], x["data"], True) except Exception as e: code = getattr(e, "code", 1) responses.append((x["step"], str(code))) break else: ids.append(z[1]["id"]) config.set("updates", "current_update", z[1]["id"]) config.save() continue for x in responses: nthread.update(Notification("debug", "Updates", x)) msg = "Installation of update {0} failed. See logs for details." msg = msg.format(z[1]["id"]) nthread.complete(Notification("error", "Updates", msg)) break else: signals.emit("updates", "post_install") for x in responses: nthread.update(Notification("debug", "Updates", x)) msg = "Please restart your system for the updates to take effect." nthread.complete(Notification("success", "Updates", msg)) return ids
def unassign(self, assign): signals.emit("certificates", "pre_unassign", (self, assign)) nginx_reload = False if assign["type"] == "website": websites.get(assign["id"]).ssl_disable() self.assigns.remove(assign) nginx_reload = True elif assign["type"] == "genesis": config.set("genesis", "cert_file", "") config.set("genesis", "cert_key", "") config.set("genesis", "ssl", False) config.save() self.assigns.remove(assign) else: applications.get(assign["aid"]).ssl_disable(assign["sid"]) self.assigns.remove(assign) if nginx_reload: websites.nginx_reload() signals.emit("certificates", "post_unassign", (self, assign)) return None
def assign(self, assign): signals.emit("certificates", "pre_assign", (self, assign)) nginx_reload = False if assign["type"] == "genesis": config.set("genesis", "cert_file", self.cert_path) config.set("genesis", "cert_key", self.key_path) config.set("genesis", "ssl", True) config.save() self.assigns.append(assign) elif assign["type"] == "website": w = websites.get(assign["id"]) w.cert = self w.ssl_enable() self.assigns.append(assign) nginx_reload = True else: d = applications.get(assign["aid"]).ssl_enable(self, assign["sid"]) self.assigns.append(d) if nginx_reload: websites.nginx_reload() signals.emit("certificates", "post_assign", (self, assign)) return self
def arkos_config(): if request.method == "PUT": data = request.get_json() if data.get("config"): config.config = data["config"] config.save() if data.get("hostname"): sysconfig.set_hostname(data["hostname"]) if data.get("timezone"): sysconfig.set_timezone(**data["timezone"]) elif request.method == "PATCH": data = request.get_json() for x in data.get("config"): if type(data["config"][x]) == str: config.config[x] = data["config"][x] else: for y in data["config"][x]: config.config[x][y] = data["config"][x][y] config.save() return jsonify(config=config.config, hostname=sysconfig.get_hostname(), timezone=sysconfig.get_timezone())
def _ssl_enable(self): # Get server-preferred ciphers if config.get("certificates", "ciphers"): ciphers = config.get("certificates", "ciphers") else: config.set("certificates", "ciphers", ciphers) config.save() block = nginx.loadf( os.path.join("/etc/nginx/sites-available/", self.id)) # If the site is on port 80, setup an HTTP redirect to new port 443 server = block.server listens = server.filter("Key", "listen") for listen in listens: httport = "80" sslport = "443" if listen.value.startswith("[::]"): # IPv6 httport = "[::]:80" sslport = "[::]:443" if listen.value == httport: listen.value = (sslport + " ssl http2") block.add( nginx.Server( nginx.Key("listen", httport), nginx.Key("server_name", self.domain), nginx.Location( "/", nginx.Key("return", "301 https://$host$request_uri")), nginx.Location("/.well-known/acme-challenge/", nginx.Key("root", self.path)))) for x in block.servers: if " ssl" in x.filter("Key", "listen")[0].value: server = x break else: listen.value = listen.value.split(" ssl")[0] + " ssl http2" # Clean up any pre-existing SSL directives that no longer apply to_remove = [x for x in server.keys if x.name.startswith("ssl_")] server.remove(*to_remove) # Add the necessary SSL directives to the serverblock and save server.add( nginx.Key("ssl_certificate", self.cert.cert_path), nginx.Key("ssl_certificate_key", self.cert.key_path), nginx.Key("ssl_protocols", "TLSv1 TLSv1.1 TLSv1.2"), nginx.Key("ssl_ciphers", ciphers), nginx.Key("ssl_session_timeout", "5m"), nginx.Key("ssl_prefer_server_ciphers", "on"), nginx.Key("ssl_dhparam", "/etc/arkos/ssl/dh_params.pem"), nginx.Key("ssl_session_cache", "shared:SSL:50m"), ) nginx.dumpf(block, os.path.join("/etc/nginx/sites-available/", self.id)) # Set the certificate name in the metadata file if not os.path.exists(os.path.join(self.path, ".arkos")): raise errors.InvalidConfigError("Could not find metadata file") meta = configparser.SafeConfigParser() meta.read(os.path.join(self.path, ".arkos")) meta.set("website", "ssl", self.cert.id) with open(os.path.join(self.path, ".arkos"), "w") as f: meta.write(f) # Call the website type's SSL enable hook self.enable_ssl(self.cert.cert_path, self.cert.key_path)
def arkos_config(): if request.method == "PUT": config.config = json.loads(request.data)["config"] config.save() return jsonify(config=config.config)