citadel-core/scripts/add-https
2022-02-14 17:52:17 +01:00

217 lines
6.1 KiB
Python
Executable File

#!/usr/bin/env python3
try:
import crossplane
except ImportError:
print("Crossplane not found. Please run 'sudo pip3 install crossplane'")
exit(1)
import os
import argparse
import shutil
import json
def parse_dotenv(file_path):
envVars: dict = {}
with open(file_path, 'r') as file:
for line in file:
line = line.strip()
if line.startswith('#') or len(line) == 0:
continue
if '=' in line:
key, value = line.split('=', 1)
value = value.strip('"').strip("'")
envVars[key] = value
else:
print("Error: Invalid line in {}: {}".format(file_path, line))
print(
"Line should be in the format KEY=VALUE or KEY=\"VALUE\" or KEY='VALUE'")
exit(1)
return envVars
# Usage: add-https --service service_name --cert path_to_certificate --key path_to_key --domain domain_name
parser = argparse.ArgumentParser(
description='Create an HTTPS proxy for an app on Citadel')
parser.add_argument('--service', required=True,
help='The service to add HTTPS to')
parser.add_argument('--cert', required=True,
help='The path to the SSL certificate (.pem)')
parser.add_argument('--key', required=True, help='The path to the SSL key (.key)')
parser.add_argument('--domain', required=True, help='The domain name')
args = parser.parse_args()
domain = args.domain
service = args.service
cert = args.cert
key = args.key
node_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
nginx_config_file = os.path.join(node_root, 'nginx', 'nginx.conf')
registry_file = os.path.join(node_root, 'apps', 'apps.json')
with open(registry_file) as file:
registry = json.load(file)
port = None
for app in registry:
if app['name'] == service:
if "internalPort" in app:
port = app['internalPort']
break
original_config = crossplane.parse(nginx_config_file)
parsedConfig = original_config["config"][0]["parsed"]
ip_env_var = "APP_{}_WEB_IP".format(
service.upper().replace("-", "_")
)
ip_alt_env_var = "APP_{}_MAIN_IP".format(
service.upper().replace("-", "_")
)
port_env_var = "APP_{}_WEB_PORT".format(
service.upper().replace("-", "_")
)
port_alt_env_var = "APP_{}_MAIN_PORT".format(
service.upper().replace("-", "_")
)
env = parse_dotenv(os.path.join(node_root, '.env'))
ip=None
if ip_env_var in env:
ip = env[ip_env_var]
elif ip_alt_env_var in env:
ip = env[ip_alt_env_var]
else:
print("Error: No IP found for {}".format(service))
exit(1)
if port == None:
if port_env_var in env:
port = env[port_env_var]
elif port_alt_env_var in env:
port = env[port_alt_env_var]
else:
print("Error: No port found for {}".format(service))
exit(1)
if service == "btcpay-server":
port = 1234
if service == "lnme":
port = 1323
actual_url="http://{}:{}".format(ip, port)
# Get the first element of config where the directive property is 'http'
http_element = next(x for x in parsedConfig if x["directive"] == "http")
config = {
"directive": "server",
"args": [],
"block": [
{
"directive": "listen",
"args": ["443", "ssl", "http2"]
},
{
"directive": "server_name",
"args": [domain]
},
{
"directive": "ssl_certificate",
"args": [domain + ".pem"]
},
{
"directive": "ssl_certificate_key",
"args": [domain + ".key"]
},
{
"directive": "ssl_protocols",
"args": ["TLSv1", "TLSv1.1", "TLSv1.2"]
},
{
"directive": "ssl_ciphers",
"args": ["HIGH:!aNULL:!MD5"]
},
{
"directive": "location",
"args": ["/"],
"block": [
{
"directive": "proxy_pass",
"args": [actual_url]
},
{
"directive": "proxy_http_version",
"args": ["1.1"]
},
{
"directive": "proxy_set_header",
"args": ["Upgrade", "$http_upgrade"]
},
{
"directive": "proxy_set_header",
"args": ["Connection", "upgrade"]
},
{
"directive": "proxy_set_header",
"args": ["Host", "$host"]
},
{
"directive": "proxy_set_header",
"args": ["X-Real-IP", "$remote_addr"]
},
{
"directive": "proxy_set_header",
"args": ["X-Forwarded-For", "$remote_addr"]
},
{
"directive": "proxy_set_header",
"args": ["X-Forwarded-Proto", "$scheme"]
}
]
}
]
}
redirect_config = {
"directive": "server",
"args": [],
"block": [
{
"directive": "listen",
"args": ["433"]
},
{
"directive": "server_name",
"args": [domain]
},
{
"directive": "return",
"args": ["301", "https://$host$request_uri"]
},
]
}
# Now, copy the given certificate and key to the correct location
newCertLocation = os.path.join(node_root, 'nginx', domain + '.pem')
newKeyLocation = os.path.join(node_root, 'nginx', domain + '.key')
shutil.copy(cert, newCertLocation)
shutil.copy(key, newKeyLocation)
http_element["block"].append(config)
http_element["block"].append(redirect_config)
newConfig = crossplane.build(parsedConfig)
# Write newConfig to nginx_config_file
with open(nginx_config_file, 'w') as file:
file.write(newConfig)
print("Configuration successful!")
print("To increase security, we recommend not exposing our IP by using services like cloudflare.")
print("Also, please restart nginx using this command: sudo docker restart nginx")