diff --git a/btcpay-setup.sh b/btcpay-setup.sh index 951d014..b524d44 100755 --- a/btcpay-setup.sh +++ b/btcpay-setup.sh @@ -94,7 +94,7 @@ Environment variables: BTCPAYGEN_LIGHTNING: Lightning network implementation to use (eg. clightning, lnd, none) BTCPAYGEN_ADDITIONAL_FRAGMENTS: Semi colon separated list of additional fragments you want to use (eg. opt-save-storage) ACME_CA_URI: The API endpoint to ask for HTTPS certificate (default: https://acme-v01.api.letsencrypt.org/directory) - BTCPAY_HOST_SSHKEYFILE: Optional, SSH private key that BTCPay can use to connect to this VM's SSH server. This key will be copied on BTCPay's data directory + BTCPAY_ENABLE_SSH: Optional, gives BTCPay Server SSH access to the host by allowing it to edit authorized_keys of the host, it can be used for managing the authorized_keys or updating BTCPay Server directly through the website. (Default: false) BTCPAYGEN_DOCKER_IMAGE: Allows you to specify a custom docker image for the generator (Default: btcpayserver/docker-compose-generator) BTCPAY_IMAGE: Allows you to specify the btcpayserver docker image to use over the default version. (Default: current stable version of btcpayserver) BTCPAY_PROTOCOL: Allows you to specify the external transport protocol of BTCPayServer. (Default: https) @@ -197,6 +197,7 @@ fi : "${BTCPAY_ADDITIONAL_HOSTS:=}" : "${REVERSEPROXY_HTTP_PORT:=80}" : "${REVERSEPROXY_HTTPS_PORT:=443}" +: "${BTCPAY_ENABLE_SSH:=false}" OLD_BTCPAY_DOCKER_COMPOSE="$BTCPAY_DOCKER_COMPOSE" ORIGINAL_DIRECTORY="$(pwd)" @@ -218,8 +219,29 @@ BTCPAY_ENV_FILE="$BTCPAY_BASE_DIRECTORY/.env" BTCPAY_SSHKEYFILE="" BTCPAY_SSHTRUSTEDFINGERPRINTS="" +use_ssh=false + +if $BTCPAY_ENABLE_SSH && ! [[ "$BTCPAY_HOST_SSHAUTHORIZEDKEYS" ]]; then + BTCPAY_HOST_SSHAUTHORIZEDKEYS=~/.ssh/authorized_keys + BTCPAY_HOST_SSHKEYFILE="" +fi + if [[ -f "$BTCPAY_HOST_SSHKEYFILE" ]]; then + echo -e "\033[33mWARNING: BTCPAY_HOST_SSHKEYFILE is now deprecated, use instead BTCPAY_ENABLE_SSH=true and run again '. btcpay-setup.sh -i'\033[0m" BTCPAY_SSHKEYFILE="/datadir/id_rsa" + use_ssh=true +fi + +if $BTCPAY_ENABLE_SSH && [[ "$BTCPAY_HOST_SSHAUTHORIZEDKEYS" ]]; then + if ! [[ -f "$BTCPAY_HOST_SSHAUTHORIZEDKEYS" ]]; then + mkdir -p "$(dirname $BTCPAY_HOST_SSHAUTHORIZEDKEYS)" + touch $BTCPAY_HOST_SSHAUTHORIZEDKEYS + fi + BTCPAY_SSHAUTHORIZEDKEYS="/datadir/host_authorized_keys" + use_ssh=true +fi + +if $use_ssh; then for pubkey in /etc/ssh/ssh_host_*.pub; do fingerprint="$(ssh-keygen -l -f $pubkey | awk '{print $2}')" BTCPAY_SSHTRUSTEDFINGERPRINTS="$fingerprint;$BTCPAY_SSHTRUSTEDFINGERPRINTS" @@ -262,6 +284,7 @@ REVERSEPROXY_DEFAULT_HOST:$REVERSEPROXY_DEFAULT_HOST LIBREPATRON_HOST:$LIBREPATRON_HOST WOOCOMMERCE_HOST:$WOOCOMMERCE_HOST BTCTRANSMUTER_HOST:$BTCTRANSMUTER_HOST +BTCPAY_ENABLE_SSH:$BTCPAY_ENABLE_SSH BTCPAY_HOST_SSHKEYFILE:$BTCPAY_HOST_SSHKEYFILE LETSENCRYPT_EMAIL:$LETSENCRYPT_EMAIL NBITCOIN_NETWORK:$NBITCOIN_NETWORK @@ -288,6 +311,8 @@ BTCPAY_BASE_DIRECTORY=$BTCPAY_BASE_DIRECTORY BTCPAY_ENV_FILE=$BTCPAY_ENV_FILE BTCPAYGEN_OLD_PREGEN=$BTCPAYGEN_OLD_PREGEN BTCPAY_SSHKEYFILE=$BTCPAY_SSHKEYFILE +BTCPAY_SSHAUTHORIZEDKEYS=$BTCPAY_SSHAUTHORIZEDKEYS +BTCPAY_HOST_SSHAUTHORIZEDKEYS:$BTCPAY_HOST_SSHAUTHORIZEDKEYS BTCPAY_SSHTRUSTEDFINGERPRINTS:$BTCPAY_SSHTRUSTEDFINGERPRINTS BTCPAY_CRYPTOS:$BTCPAY_CRYPTOS BTCPAY_ANNOUNCEABLE_HOST:$BTCPAY_ANNOUNCEABLE_HOST @@ -328,6 +353,7 @@ export BTCPAY_DOCKER_COMPOSE=\"$BTCPAY_DOCKER_COMPOSE\" export BTCPAY_BASE_DIRECTORY=\"$BTCPAY_BASE_DIRECTORY\" export BTCPAY_ENV_FILE=\"$BTCPAY_ENV_FILE\" export BTCPAY_HOST_SSHKEYFILE=\"$BTCPAY_HOST_SSHKEYFILE\" +export BTCPAY_ENABLE_SSH=$BTCPAY_ENABLE_SSH if cat \"\$BTCPAY_ENV_FILE\" &> /dev/null; then while IFS= read -r line; do ! [[ \"\$line\" == \"#\"* ]] && [[ \"\$line\" == *\"=\"* ]] && export \"\$line\" @@ -520,6 +546,7 @@ fi # Give SSH key to BTCPay if $START && [[ -f "$BTCPAY_HOST_SSHKEYFILE" ]]; then + echo -e "\033[33mWARNING: BTCPAY_HOST_SSHKEYFILE is now deprecated, use instead BTCPAY_ENABLE_SSH=true and run again '. btcpay-setup.sh -i'\033[0m" echo "Copying $BTCPAY_SSHKEYFILE to BTCPayServer container" docker cp "$BTCPAY_HOST_SSHKEYFILE" $(docker ps --filter "name=_btcpayserver_" -q):$BTCPAY_SSHKEYFILE fi diff --git a/build.ps1 b/build.ps1 index 44e5a61..2e72e99 100755 --- a/build.ps1 +++ b/build.ps1 @@ -24,6 +24,7 @@ docker run -v "$(Get-Location)\Generated:/app/Generated" ` -e "BTCPAYGEN_EXCLUDE_FRAGMENTS=$BTCPAYGEN_EXCLUDE_FRAGMENTS" ` -e "BTCPAYGEN_LIGHTNING=$BTCPAYGEN_LIGHTNING" ` -e "BTCPAYGEN_SUBNAME=$BTCPAYGEN_SUBNAME" ` + -e "BTCPAY_HOST_SSHAUTHORIZEDKEYS=$BTCPAY_HOST_SSHAUTHORIZEDKEYS" ` --rm $BTCPAYGEN_DOCKER_IMAGE If ($BTCPAYGEN_REVERSEPROXY -eq "nginx") { diff --git a/build.sh b/build.sh index 5494bed..bb993c3 100755 --- a/build.sh +++ b/build.sh @@ -25,6 +25,7 @@ docker run -v "$(pwd)/Generated:/app/Generated" \ -e "BTCPAYGEN_EXCLUDE_FRAGMENTS=$BTCPAYGEN_EXCLUDE_FRAGMENTS" \ -e "BTCPAYGEN_LIGHTNING=$BTCPAYGEN_LIGHTNING" \ -e "BTCPAYGEN_SUBNAME=$BTCPAYGEN_SUBNAME" \ + -e "BTCPAY_HOST_SSHAUTHORIZEDKEYS=$BTCPAY_HOST_SSHAUTHORIZEDKEYS" \ --rm $BTCPAYGEN_DOCKER_IMAGE if [ "$BTCPAYGEN_REVERSEPROXY" == "nginx" ]; then diff --git a/docker-compose-generator/docker-fragments/btcpayserver.yml b/docker-compose-generator/docker-fragments/btcpayserver.yml index 942f112..98b032e 100644 --- a/docker-compose-generator/docker-fragments/btcpayserver.yml +++ b/docker-compose-generator/docker-fragments/btcpayserver.yml @@ -16,12 +16,14 @@ services: BTCPAY_SSHCONNECTION: "root@host.docker.internal" BTCPAY_SSHTRUSTEDFINGERPRINTS: ${BTCPAY_SSHTRUSTEDFINGERPRINTS} BTCPAY_SSHKEYFILE: ${BTCPAY_SSHKEYFILE} + BTCPAY_SSHAUTHORIZEDKEYS: ${BTCPAY_SSHAUTHORIZEDKEYS} BTCPAY_DEBUGLOG: btcpay.log links: - postgres volumes: - "btcpay_datadir:/datadir" - "nbxplorer_datadir:/root/.nbxplorer" + - "$?:${BTCPAY_SSHAUTHORIZEDKEYS}" volumes: btcpay_datadir: \ No newline at end of file diff --git a/docker-compose-generator/src/BuildTimeVariableVisitor.cs b/docker-compose-generator/src/BuildTimeVariableVisitor.cs new file mode 100644 index 0000000..7d6a010 --- /dev/null +++ b/docker-compose-generator/src/BuildTimeVariableVisitor.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +using YamlDotNet.RepresentationModel; + +namespace DockerGenerator +{ + // Replace built time variable ( $? ) in the docker generator + class BuildTimeVariableVisitor : YamlVisitorBase + { + class Context + { + public List ToRemove = new List(); + } + Stack _Contexts = new Stack(); + Context CurrentContext + { + get + { + return _Contexts.TryPeek(out var ctx) ? ctx : null; + } + } + + protected override void VisitChildren(YamlSequenceNode sequence) + { + _Contexts.Push(new Context()); + base.VisitChildren(sequence); + var ctx = _Contexts.Pop(); + foreach (var child in ctx.ToRemove) + { + sequence.Children.Remove(child); + } + } + public override void Visit(YamlScalarNode scalar) + { + bool removeNode = false; + scalar.Value = Regex.Replace(scalar.Value, "\\$<(.*?)>\\?", (match) => + { + var replacedBy = Environment.GetEnvironmentVariable(match.Groups[1].Value); + if (string.IsNullOrEmpty(replacedBy)) + { + removeNode = true; + } + return replacedBy; + }); + if (removeNode) + CurrentContext?.ToRemove.Add(scalar); + base.Visit(scalar); + } + } +} diff --git a/docker-compose-generator/src/DockerComposeDefinition.cs b/docker-compose-generator/src/DockerComposeDefinition.cs index ce85307..09e2353 100644 --- a/docker-compose-generator/src/DockerComposeDefinition.cs +++ b/docker-compose-generator/src/DockerComposeDefinition.cs @@ -87,7 +87,7 @@ namespace DockerGenerator output.Add("services", new YamlMappingNode(Merge(services))); output.Add("volumes", new YamlMappingNode(volumes)); output.Add("networks", new YamlMappingNode(networks)); - + PostProcess(output); var dockerImages = ((YamlMappingNode)output["services"]).Children.Select(kv => kv.Value["image"].ToString()).ToList(); dockerImages.Add("btcpayserver/docker-compose-builder:1.24.1"); @@ -119,6 +119,11 @@ namespace DockerGenerator Console.WriteLine(); } + private void PostProcess(YamlMappingNode output) + { + new BuildTimeVariableVisitor().Visit(output); + } + private KeyValuePair[] Merge(List> services) { return services diff --git a/docker-compose-generator/src/Properties/launchSettings.json b/docker-compose-generator/src/Properties/launchSettings.json index b29a0ab..4ae2376 100644 --- a/docker-compose-generator/src/Properties/launchSettings.json +++ b/docker-compose-generator/src/Properties/launchSettings.json @@ -4,6 +4,7 @@ "commandName": "Project", "commandLineArgs": "pregen", "environmentVariables": { + "BTCPAY_HOST_SSHKEYFILE": "test.rsa", "BTCPAYGEN_LIGHTNING": "clightning", "BTCPAYGEN_CRYPTO4": "ftc", "BTCPAYGEN_CRYPTO3": "btg", @@ -13,4 +14,4 @@ } } } -} +} \ No newline at end of file diff --git a/helpers.sh b/helpers.sh index 8c3cd1c..43a3964 100755 --- a/helpers.sh +++ b/helpers.sh @@ -83,6 +83,7 @@ LETSENCRYPT_EMAIL=$LETSENCRYPT_EMAIL LIGHTNING_ALIAS=$LIGHTNING_ALIAS BTCPAY_SSHTRUSTEDFINGERPRINTS=$BTCPAY_SSHTRUSTEDFINGERPRINTS BTCPAY_SSHKEYFILE=$BTCPAY_SSHKEYFILE +BTCPAY_SSHAUTHORIZEDKEYS=$BTCPAY_SSHAUTHORIZEDKEYS LIBREPATRON_HOST=$LIBREPATRON_HOST BTCTRANSMUTER_HOST=$BTCTRANSMUTER_HOST BTCPAY_CRYPTOS=$BTCPAY_CRYPTOS