forked from michael.heier/citadel-core
217 lines
6.1 KiB
Python
Executable File
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")
|