mirror of
https://github.com/runcitadel/core.git
synced 2024-12-28 15:42:59 +00:00
Citadel 0.5.16
This commit is contained in:
parent
3beb2dec1d
commit
6b007479e0
|
@ -12,7 +12,7 @@ from lib.composegenerator.v1.types import Container
|
|||
def getFreePort(networkingFile: str, appId: str):
|
||||
# Ports used currently in Citadel
|
||||
# TODO: Update this list, currently it's outdated
|
||||
usedPorts = [80, 8333, 8332, 28332, 28333, 28334, 10009, 8080, 50001, 9050, 3002, 3000, 3300, 3001, 3004, 25441,
|
||||
usedPorts = [80, 433, 443, 8333, 8332, 28332, 28333, 28334, 10009, 8080, 50001, 9050, 3002, 3000, 3300, 3001, 3004, 25441,
|
||||
3003, 3007, 3006, 3009, 3005, 8898, 3008, 8081, 8082, 8083, 8085, 2222, 8086, 8087, 8008, 8088, 8089, 8091]
|
||||
networkingData = {}
|
||||
if os.path.isfile(networkingFile):
|
||||
|
|
|
@ -181,6 +181,9 @@ def compose(app, arguments):
|
|||
os.chmod(os.path.join(appDataDir, app), os.stat(os.path.join(appsDir, app)).st_mode)
|
||||
except Exception:
|
||||
pass
|
||||
if app == "nextcloud":
|
||||
subprocess.call("chown -R 33:33 {}".format(os.path.join(appDataDir, app, "data", "nextcloud")), shell=True)
|
||||
subprocess.call("chmod -R 770 {}".format(os.path.join(appDataDir, app, "data", "nextcloud")), shell=True)
|
||||
os.environ["BITCOIN_DATA_DIR"] = os.path.join(nodeRoot, "bitcoin")
|
||||
os.environ["LND_DATA_DIR"] = os.path.join(nodeRoot, "lnd")
|
||||
# List all hidden services for an app and put their hostname in the environment
|
||||
|
|
|
@ -58,6 +58,8 @@ services:
|
|||
stop_grace_period: 30s
|
||||
ports:
|
||||
- ${NGINX_PORT}:80
|
||||
- 433:433
|
||||
- 443:443
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: $NGINX_IP
|
||||
|
@ -102,7 +104,7 @@ services:
|
|||
ipv4_address: $LND_IP
|
||||
dashboard:
|
||||
container_name: dashboard
|
||||
image: ghcr.io/runcitadel/dashboard:main@sha256:9b5281968bb16109e17ec808fe6fe75e42c0e150a6a9667fd2c98ba4c472a5a2
|
||||
image: ghcr.io/runcitadel/dashboard:main@sha256:a07c84db6a19d6970527eb5bd8f0482239a8b09396fe7e9d6ef761a4f1e09bc5
|
||||
restart: on-failure
|
||||
stop_grace_period: 1m30s
|
||||
networks:
|
||||
|
@ -110,7 +112,7 @@ services:
|
|||
ipv4_address: $DASHBOARD_IP
|
||||
manager:
|
||||
container_name: manager
|
||||
image: ghcr.io/runcitadel/manager:main@sha256:26a021cff33d9f81217b1810a743024d5a7a03493abbec766dd88680720d7102
|
||||
image: ghcr.io/runcitadel/manager:main@sha256:b21cf3bd1224d4e1f7edb8e8a3941bca6b3f2c64c312809b5bbca4451cf580ea
|
||||
depends_on:
|
||||
- tor
|
||||
- redis
|
||||
|
@ -155,7 +157,7 @@ services:
|
|||
SHUTDOWN_SIGNAL_FILE: /signals/shutdown
|
||||
REBOOT_SIGNAL_FILE: /signals/reboot
|
||||
GITHUB_REPO: runcitadel/core
|
||||
GITHUB_BRANCH: main
|
||||
GITHUB_BRANCH: ${UPDATE_CHANNEL:-"main"}
|
||||
VERSION_FILE: /info.json
|
||||
UPDATE_STATUS_FILE: /statuses/update-status.json
|
||||
UPDATE_SIGNAL_FILE: /signals/update
|
||||
|
@ -165,16 +167,17 @@ services:
|
|||
TOR_PROXY_IP: ${TOR_PROXY_IP}
|
||||
TOR_PROXY_PORT: ${TOR_PROXY_PORT}
|
||||
TOR_HIDDEN_SERVICE_DIR: /var/lib/tor
|
||||
IS_CITADEL_OS: ${IS_CITADEL_OS:-"false"}
|
||||
IS_CITADEL_OS: ${IS_CITADEL_OS:-"true"}
|
||||
REDIS_PASSWORD: freedom
|
||||
REDIS_IP: $REDIS_IP
|
||||
REDIS_PORT: 6379
|
||||
UNSAFE_REMOVE_CORS_CHECK: true
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: $MANAGER_IP
|
||||
middleware:
|
||||
container_name: middleware
|
||||
image: ghcr.io/runcitadel/middleware:main@sha256:12870a6f6f0601cc7850e26613370b55d8b92a404ac7dcc88ab395051214882c
|
||||
image: ghcr.io/runcitadel/middleware:main@sha256:488daefc3eb26e53272107ae6a3045c16fa1138a9d277d92a67f18821df00a7e
|
||||
depends_on:
|
||||
- manager
|
||||
- bitcoin
|
||||
|
@ -199,6 +202,7 @@ services:
|
|||
LND_HOST: ${LND_IP}
|
||||
JWT_PUBLIC_KEY_FILE: /jwt-public-key/jwt.pem
|
||||
DEVICE_HOSTS: ${DEVICE_HOSTS:-"http://citadel.local"}
|
||||
UNSAFE_REMOVE_CORS_CHECK: true
|
||||
networks:
|
||||
default:
|
||||
ipv4_address: $MIDDLEWARE_IP
|
||||
|
@ -224,7 +228,7 @@ services:
|
|||
ipv4_address: $NEUTRINO_SWITCHER_IP
|
||||
electrs:
|
||||
container_name: electrs
|
||||
image: ghcr.io/runcitadel/electrs:v0.9.3@sha256:fd49202d1ddd3622415f81f4870bceccc77f7e0ce303ea3ac421c3366896b6a4
|
||||
image: ghcr.io/runcitadel/electrs:v0.9.4@sha256:e216736fa26ef8c8b9e9a0a1fb7bc759546f1a0b74ef5ef3022470495e68f3a1
|
||||
working_dir: /data
|
||||
volumes:
|
||||
- ${PWD}/bitcoin:/bitcoin:ro
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"version": "0.5.15",
|
||||
"name": "Citadel 0.5.15",
|
||||
"version": "0.5.16",
|
||||
"name": "Citadel 0.5.16",
|
||||
"requires": ">=0.5.5",
|
||||
"notes": "This update just fixes some bugs and updates some apps. Nothing new yet, updates will be kinda boring until 2022."
|
||||
"notes": "This update prepares Citadel for Alby integration. Soon, a connection to Citadel will be available there."
|
||||
}
|
||||
|
|
204
scripts/add-https
Executable file
204
scripts/add-https
Executable file
|
@ -0,0 +1,204 @@
|
|||
#!/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
|
||||
|
||||
|
||||
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')
|
||||
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)
|
||||
|
||||
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" or service == "lnbits":
|
||||
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")
|
|
@ -287,6 +287,12 @@ main () {
|
|||
echo "Checking SD Card root is bind mounted at /sd-root..."
|
||||
df -h "/sd-root${CITADEL_ROOT}" | grep --quiet "/dev/root"
|
||||
|
||||
if [[ $block_device != nvme* ]]; then
|
||||
echo "unknown" > "${CITADEL_ROOT}/statuses/external_storage"
|
||||
else
|
||||
echo "nvme" > "${CITADEL_ROOT}/statuses/external_storage"
|
||||
fi
|
||||
|
||||
echo "Starting external drive mount monitor..."
|
||||
echo
|
||||
${CITADEL_ROOT}/scripts/citadel-os/external-storage/monitor ${block_device} ${MOUNT_POINT} &
|
||||
|
|
13
scripts/configure
vendored
13
scripts/configure
vendored
|
@ -147,6 +147,7 @@ if os.path.isfile('../use-core-upstream') or os.path.isfile('./use-core-upstream
|
|||
##########################################################
|
||||
|
||||
NGINX_PORT=os.environ.get('NGINX_PORT') or "80"
|
||||
UPDATE_CHANNEL="main"
|
||||
|
||||
if reconfiguring:
|
||||
if os.path.isfile('../.citadel'):
|
||||
|
@ -169,6 +170,8 @@ if reconfiguring:
|
|||
TOR_PASSWORD=dotenv['TOR_PASSWORD']
|
||||
TOR_HASHED_PASSWORD=dotenv['TOR_HASHED_PASSWORD']
|
||||
NGINX_PORT=dotenv['NGINX_PORT']
|
||||
if 'UPDATE_CHANNEL' in dotenv:
|
||||
UPDATE_CHANNEL=dotenv['UPDATE_CHANNEL']
|
||||
else:
|
||||
# Generate RPC credentials
|
||||
print("Generating auth credentials")
|
||||
|
@ -273,7 +276,13 @@ ELECTRUM_PORT="50001"
|
|||
TOR_PROXY_PORT="9050"
|
||||
TOR_CONTROL_PORT="29051"
|
||||
|
||||
DEVICE_HOSTNAME=subprocess.check_output("hostname").decode("utf-8").strip()
|
||||
DEVICE_HOSTNAME=""
|
||||
try:
|
||||
subprocess.check_output("hostname").decode("utf-8").strip()
|
||||
except:
|
||||
# The content of /etc/hostname is the device's hostname
|
||||
DEVICE_HOSTNAME=open("/etc/hostname").read().strip()
|
||||
|
||||
DOCKER_EXECUTABLE=subprocess.check_output(["which", "docker"]).decode("utf-8").strip()
|
||||
# Get the real path by following symlinks
|
||||
DOCKER_BINARY=subprocess.check_output(["readlink", "-f", DOCKER_EXECUTABLE]).decode("utf-8").strip()
|
||||
|
@ -323,6 +332,8 @@ print()
|
|||
|
||||
# Loop through templates_to_build and build them
|
||||
for template_path, output_path in templates_to_build.items():
|
||||
if output_path == "./nginx/nginx.conf" and os.path.isfile(output_path):
|
||||
continue
|
||||
data = replace_vars(template_path)
|
||||
# If output path is a list, then it is a list of output paths
|
||||
if isinstance(output_path, list):
|
||||
|
|
|
@ -66,8 +66,8 @@ else
|
|||
fi
|
||||
|
||||
# Whitelist device IP, hostname and hidden service for CORS
|
||||
DEVICE_IP=$(hostname -I | awk '{print $1}')
|
||||
DEVICE_HOSTNAME="$(hostname)"
|
||||
DEVICE_IP=$(hostname -I | awk '{print $1}') || DEVICE_IP="$(ip addr show $(ip route | awk '/default/ { print $5 }') | grep "inet" | head -n 1 | awk '/inet/ {print $2}' | cut -d'/' -f1)"
|
||||
DEVICE_HOSTNAME="$(hostname)" || DEVICE_HOSTNAME="$(cat /etc/hostname)"
|
||||
DEVICE_HOSTS="http://${DEVICE_IP},http://${DEVICE_HOSTNAME}.local,https://${DEVICE_HOSTNAME}.local,http://${DEVICE_HOSTNAME},https://${DEVICE_HOSTNAME}"
|
||||
if [[ -f "${CITADEL_ROOT}/tor/data/web/hostname" ]]; then
|
||||
hidden_service_url=$(cat "${CITADEL_ROOT}/tor/data/web/hostname")
|
||||
|
|
|
@ -10,3 +10,4 @@ logs/*
|
|||
app-data/*
|
||||
apps/networking.json
|
||||
use-core-upstream
|
||||
nginx/*
|
||||
|
|
|
@ -22,6 +22,7 @@ check_dependencies () {
|
|||
check_dependencies jq curl rsync
|
||||
|
||||
CITADEL_ROOT="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../..)"
|
||||
[[ -f "${CITADEL_ROOT}/.env" ]] && source "${CITADEL_ROOT}/.env"
|
||||
|
||||
update_type=""
|
||||
if [[ "${1}" == "--ota" ]]; then
|
||||
|
@ -33,7 +34,7 @@ elif [[ "${1}" == "--repo" ]]; then
|
|||
update_type="repo"
|
||||
descriptor="${2}"
|
||||
if [[ "${descriptor}" != *"#"* ]]; then
|
||||
descriptor="${descriptor}#main"
|
||||
descriptor="${descriptor}#${UPDATE_CHANNEL:-"main"}"
|
||||
fi
|
||||
repo="${descriptor%%#*}"
|
||||
branch="${descriptor#*#}"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
electrs:
|
||||
container_name: electrs
|
||||
image: ghcr.io/runcitadel/electrs:v0.9.3@sha256:fd49202d1ddd3622415f81f4870bceccc77f7e0ce303ea3ac421c3366896b6a4
|
||||
image: ghcr.io/runcitadel/electrs:v0.9.4@sha256:e216736fa26ef8c8b9e9a0a1fb7bc759546f1a0b74ef5ef3022470495e68f3a1
|
||||
working_dir: /data
|
||||
volumes:
|
||||
- ${PWD}/bitcoin:/bitcoin:ro
|
||||
|
|
|
@ -36,3 +36,4 @@ APPS_TOR_IP=<apps-tor-ip>
|
|||
APPS_2_TOR_IP=<apps-2-tor-ip>
|
||||
APPS_3_TOR_IP=<apps-3-tor-ip>
|
||||
DOCKER_BINARY=<docker-binary>
|
||||
UPDATE_CHANNEL=<update-channel>
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
# Please note: This file can't be changed, it will be overwritten.
|
||||
# A few modifications will be kept, including alias, color, channel size limitations and more if you contact us.
|
||||
|
||||
verbose = 2
|
||||
network = "bitcoin"
|
||||
db_dir = "/data/db"
|
||||
daemon_dir = "/bitcoin"
|
||||
|
|
Loading…
Reference in New Issue
Block a user