commit f1ceb79ee3cea5ee53040c9d5b3ce3a3b674e211
parent 5628e6c244a0c8064b0676e325bf10432477bb23
Author: Florian Dold <dold@taler.net>
Date: Thu, 27 Aug 2026 17:03:46 +0200
sandcastle: expose services over Unix sockets
Diffstat:
8 files changed, 204 insertions(+), 209 deletions(-)
diff --git a/README.md b/README.md
@@ -14,8 +14,8 @@ You need (on your host system):
* bash
* Python 3.10 or newer
-The sandcastle-ng container exposes the merchant backend through a Unix domain
-socket and exposes TCP ports for the other GNU Taler APIs / Web interfaces.
+The sandcastle-ng container exposes the GNU Taler APIs and Web interfaces
+through Unix domain sockets.
Some of these services expect to be accessed via a certain hostname,
so it is recommended that you set up the following domain names:
@@ -29,7 +29,7 @@ so it is recommended that you set up the following domain names:
* `paivana.$MYDOMAIN` for the demo Paivana paywall
Your host system should reverse-proxy HTTP(s) traffic to the respective service
-port for each of the services.
+socket.
# Upgrading Component Versions
@@ -106,12 +106,8 @@ Currently there is not much configuration.
The main adjustments to be made are:
* scripts/demo/setup-sandcastle.sh has the currency on top of the file
-* `sandcastle-run` has variables for the ports that'll be exposed ("published")
- on the host. They can be overwritten with environment variables named
- `SANDCASTLE_PORT_$COMPONENT`.
-* The merchant backend uses the Unix socket
- `sockets/merchant-backend.sock` by default. Set `SANDCASTLE_SOCKET_DIR` to
- choose a different host directory for the socket.
+* Services use Unix sockets below `sockets/` by default. Set
+ `SANDCASTLE_SOCKET_DIR` to choose a different host directory.
To make adjustments for an environment without changing the
``setup-sandcastle.sh`` script, you can use an override file
@@ -165,12 +161,32 @@ These will be passed on to ``podman run``. Example:
./sandcastle-run --log-level=debug
-The running container publishes ports to the host as defined in
-`./sandcastle-run`. You can manually verify these port mappings via
-`podman port taler-sandcastle`.
-
-The merchant backend is instead available through a bind-mounted Unix socket:
-
+The running container exposes these services through bind-mounted Unix sockets:
+
+| Service | Socket |
+| --- | --- |
+| Bank | `bank.sock` |
+| Exchange | `exchange.sock` |
+| Merchant backend | `merchant-backend.sock` |
+| Landing page | `landing.sock` |
+| Blog shop | `blog.sock` |
+| Donations | `donations.sock` |
+| Challenger | `challenger.sock` |
+| Auditor | `auditor.sock` |
+| Donau | `donau.sock` |
+| Drupal | `drupal.sock` |
+| Paivana | `paivana.sock` |
+
+Exchange, Merchant, the Blog and Donations demos, Auditor, Donau, and Paivana
+are exposed directly through their native listener or packaged systemd socket
+activation. Caddy owns the bank socket to bridge libeufin-bank's internal TCP
+listener, the landing socket to add the Sandcastle status endpoint, the
+Challenger socket to serve the insecure demo challenges, and the Drupal socket
+because it is Drupal's HTTP server.
+
+For example, query the Exchange and merchant configuration endpoints with:
+
+ curl --unix-socket ./sockets/exchange.sock http://localhost/config
curl --unix-socket ./sockets/merchant-backend.sock http://localhost/config
The socket directory defaults to `./sockets`, relative to the repository, and
@@ -178,19 +194,18 @@ can be changed when starting the deployment:
SANDCASTLE_SOCKET_DIR=/run/taler-sandcastle ./sandcastle-run
-Missing socket directories are created with mode `1777`, and the merchant
-socket has mode `0666`, so a host reverse proxy running as a different user can
-connect to it. A pre-existing custom directory must allow the container's
-`caddy` user to create the socket. The bind mount uses Podman's shared SELinux
-label; deployments with a confined host reverse proxy may additionally need an
-appropriate local SELinux policy.
-
-To retain the previous dedicated TCP exposure for the merchant backend, set
-its port explicitly:
+Missing socket directories are created with mode `1777`, and the sockets have
+mode `0666`, so a host reverse proxy running as a different user can connect to
+them. A pre-existing custom directory must allow the relevant container
+service users to create sockets. The bind mount uses Podman's shared SELinux
+label; deployments with a confined host reverse proxy may additionally need
+an appropriate local SELinux policy.
- SANDCASTLE_PORT_MERCHANT=127.0.0.1:16000 ./sandcastle-run
+libeufin-bank does not yet support Unix sockets, so it listens on localhost
+inside the container and Caddy exposes it through `bank.sock`.
-This keeps the Unix socket available as well.
+Overrides that define `EXTERNAL_PORT`, such as `taler.localhost`, continue to
+publish that single Caddy ingress port for local integration testing.
When starting sandcastle like
@@ -339,8 +354,6 @@ touch exported/import-request
* Do self-tests of the deployment using the wallet CLI
* Running the auditor
* Running a currency conversion setup with multiple libeufin-bank instances
-* Migrate the remaining HTTP port exposures to Unix domain sockets, avoiding
- port collision problems.
* Instead of requiring the reverse proxy to handle TLS,
the sandcastle container itself could do TLS termination with caddy.
* To improve performance, allow connecting to an external database
diff --git a/host/container-taler-sandcastle-demo.service b/host/container-taler-sandcastle-demo.service
@@ -8,18 +8,6 @@ After=network-online.target
RequiresMountsFor=%t/containers
[Service]
-Environment=SANDCASTLE_PORT_MERCHANT=127.0.0.1:5556
-Environment=SANDCASTLE_PORT_EXCHANGE=127.0.0.1:5555
-Environment=SANDCASTLE_PORT_BLOG=127.0.0.1:5559
-Environment=SANDCASTLE_PORT_DONATIONS=127.0.0.1:5560
-Environment=SANDCASTLE_PORT_SURVEY=127.0.0.1:5561
-Environment=SANDCASTLE_PORT_LANDING=127.0.0.1:5562
-Environment=SANDCASTLE_PORT_LIBEUFIN_BANK=127.0.0.1:15000
-Environment=SANDCASTLE_PORT_CHALLENGER=127.0.0.1:15003
-Environment=SANDCASTLE_PORT_AUDITOR=127.0.0.1:15004
-Environment=SANDCASTLE_PORT_DONAU=127.0.0.1:15005
-Environment=SANDCASTLE_PORT_DRUPAL=127.0.0.1:15006
-Environment=SANDCASTLE_PORT_PAIVANA=127.0.0.1:15007
Restart=on-failure
TimeoutStopSec=70
ExecStart=%h/sandcastle-ng/sandcastle-run
diff --git a/host/container-taler-sandcastle-froscon.service b/host/container-taler-sandcastle-froscon.service
@@ -9,17 +9,6 @@ RequiresMountsFor=%t/containers
[Service]
Environment=SANDCASTLE_OVERRIDE_NAME=froscon.taler.net
-Environment=SANDCASTLE_PORT_MERCHANT=127.0.0.1:18000
-Environment=SANDCASTLE_PORT_EXCHANGE=127.0.0.1:18001
-Environment=SANDCASTLE_PORT_BLOG=127.0.0.1:18002
-Environment=SANDCASTLE_PORT_DONATIONS=127.0.0.1:18003
-Environment=SANDCASTLE_PORT_LANDING=127.0.0.1:18005
-Environment=SANDCASTLE_PORT_LIBEUFIN_BANK=127.0.0.1:18007
-Environment=SANDCASTLE_PORT_CHALLENGER=127.0.0.1:18010
-Environment=SANDCASTLE_PORT_AUDITOR=127.0.0.1:18011
-Environment=SANDCASTLE_PORT_DONAU=127.0.0.1:18012
-Environment=SANDCASTLE_PORT_DRUPAL=127.0.0.1:18013
-Environment=SANDCASTLE_PORT_PAIVANA=127.0.0.1:18014
Restart=on-failure
TimeoutStopSec=70
ExecStart=%h/sandcastle-ng/sandcastle-run
diff --git a/host/container-taler-sandcastle-test.service b/host/container-taler-sandcastle-test.service
@@ -9,17 +9,6 @@ RequiresMountsFor=%t/containers
[Service]
Environment=SANDCASTLE_OVERRIDE_NAME=test.taler.net
-Environment=SANDCASTLE_PORT_MERCHANT=127.0.0.1:16000
-Environment=SANDCASTLE_PORT_EXCHANGE=127.0.0.1:16001
-Environment=SANDCASTLE_PORT_BLOG=127.0.0.1:16002
-Environment=SANDCASTLE_PORT_DONATIONS=127.0.0.1:16003
-Environment=SANDCASTLE_PORT_LANDING=127.0.0.1:16005
-Environment=SANDCASTLE_PORT_LIBEUFIN_BANK=127.0.0.1:16007
-Environment=SANDCASTLE_PORT_CHALLENGER=127.0.0.1:16010
-Environment=SANDCASTLE_PORT_AUDITOR=127.0.0.1:16011
-Environment=SANDCASTLE_PORT_DONAU=127.0.0.1:16012
-Environment=SANDCASTLE_PORT_DRUPAL=127.0.0.1:16013
-Environment=SANDCASTLE_PORT_PAIVANA=127.0.0.1:16014
Restart=on-failure
TimeoutStopSec=70
ExecStart=%h/sandcastle-ng/sandcastle-run
diff --git a/sandcastle-run b/sandcastle-run
@@ -4,34 +4,6 @@
set -exou
-# Ports where individual services are published to the host. The merchant
-# backend is exposed through a Unix socket by default, but can still be
-# published on a TCP port by setting SANDCASTLE_PORT_MERCHANT.
-SANDCASTLE_PORT_MERCHANT=${SANDCASTLE_PORT_MERCHANT:-}
-SANDCASTLE_PORT_EXCHANGE=${SANDCASTLE_PORT_EXCHANGE:-127.0.0.1:16001}
-SANDCASTLE_PORT_BLOG=${SANDCASTLE_PORT_BLOG:-127.0.0.1:16002}
-SANDCASTLE_PORT_DONATIONS=${SANDCASTLE_PORT_DONATIONS:-127.0.0.1:16003}
-SANDCASTLE_PORT_LANDING=${SANDCASTLE_PORT_LANDING:-127.0.0.1:16005}
-SANDCASTLE_PORT_LIBEUFIN_BANK=${SANDCASTLE_PORT_LIBEUFIN_BANK:-127.0.0.1:16007}
-SANDCASTLE_PORT_CHALLENGER=${SANDCASTLE_PORT_CHALLENGER:-127.0.0.1:16010}
-SANDCASTLE_PORT_AUDITOR=${SANDCASTLE_PORT_AUDITOR:-127.0.0.1:16011}
-SANDCASTLE_PORT_DONAU=${SANDCASTLE_PORT_DONAU:-127.0.0.1:16012}
-SANDCASTLE_PORT_DRUPAL=${SANDCASTLE_PORT_DRUPAL:-127.0.0.1:16013}
-SANDCASTLE_PORT_PAIVANA=${SANDCASTLE_PORT_PAIVANA:-127.0.0.1:16014}
-
-# Container-internal ports, should by synced with scripts/setup-sandcastle.sh
-PORT_INTERNAL_EXCHANGE=8201
-PORT_INTERNAL_MERCHANT=8301
-PORT_INTERNAL_LIBEUFIN_BANK=8080
-PORT_INTERNAL_LANDING=8501
-PORT_INTERNAL_BLOG=8502
-PORT_INTERNAL_DONATIONS=8503
-PORT_INTERNAL_CHALLENGER=8506
-PORT_INTERNAL_AUDITOR=8507
-PORT_INTERNAL_DONAU=8508
-PORT_INTERNAL_DRUPAL=8509
-PORT_INTERNAL_PAIVANA=8510
-
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
cd "$SCRIPT_DIR"
@@ -42,11 +14,6 @@ if [[ ! -d $SANDCASTLE_SOCKET_DIR ]]; then
fi
SANDCASTLE_SOCKET_DIR=$(realpath "$SANDCASTLE_SOCKET_DIR")
-PUBLISH_MERCHANT_PORT=()
-if [[ -n $SANDCASTLE_PORT_MERCHANT ]]; then
- PUBLISH_MERCHANT_PORT=("-p=$SANDCASTLE_PORT_MERCHANT:$PORT_INTERNAL_MERCHANT")
-fi
-
existing_id=$(podman ps -q -a -f=name=taler-sandcastle)
if [[ -n $existing_id ]]; then
@@ -92,17 +59,6 @@ NETWORK="--network slirp4netns"
exec podman run \
-d \
- "${PUBLISH_MERCHANT_PORT[@]}" \
- -p=$SANDCASTLE_PORT_EXCHANGE:$PORT_INTERNAL_EXCHANGE \
- -p=$SANDCASTLE_PORT_LIBEUFIN_BANK:$PORT_INTERNAL_LIBEUFIN_BANK \
- -p=$SANDCASTLE_PORT_LANDING:$PORT_INTERNAL_LANDING \
- -p=$SANDCASTLE_PORT_BLOG:$PORT_INTERNAL_BLOG \
- -p=$SANDCASTLE_PORT_DONATIONS:$PORT_INTERNAL_DONATIONS \
- -p=$SANDCASTLE_PORT_CHALLENGER:$PORT_INTERNAL_CHALLENGER \
- -p=$SANDCASTLE_PORT_AUDITOR:$PORT_INTERNAL_AUDITOR \
- -p=$SANDCASTLE_PORT_DONAU:$PORT_INTERNAL_DONAU \
- -p=$SANDCASTLE_PORT_DRUPAL:$PORT_INTERNAL_DRUPAL \
- -p=$SANDCASTLE_PORT_PAIVANA:$PORT_INTERNAL_PAIVANA \
--privileged \
--name taler-sandcastle \
--systemd=always \
diff --git a/scripts/demo/setup-sandcastle.sh b/scripts/demo/setup-sandcastle.sh
@@ -176,20 +176,9 @@ PAIVANA_DOMAIN=paivana.$MYDOMAIN
# served by the sandcastle itself.
PAIVANA_DESTINATION=${PAIVANA_DESTINATION:-https://docs.taler.net/}
-# Ports of the services running inside the container.
+# Port of libeufin-bank running inside the container.
# Should be synchronized with the sandcastle-run script.
-PORT_INTERNAL_EXCHANGE=8201
-PORT_INTERNAL_MERCHANT=8301
PORT_INTERNAL_LIBEUFIN_BANK=8080
-PORT_INTERNAL_LANDING=8501
-PORT_INTERNAL_LANDING_SERVICE=8511
-PORT_INTERNAL_BLOG=8502
-PORT_INTERNAL_DONATIONS=8503
-PORT_INTERNAL_CHALLENGER=8506
-PORT_INTERNAL_AUDITOR=8507
-PORT_INTERNAL_DONAU=8508
-PORT_INTERNAL_DRUPAL=8509
-PORT_INTERNAL_PAIVANA=8510
ENABLE_AUDITOR=0
@@ -197,15 +186,19 @@ ENABLE_AUDITOR=0
# Just make sure the services are stopped
systemctl stop postgresql.service
systemctl stop taler-auditor.target
+systemctl stop taler-auditor-httpd.socket
systemctl stop taler-exchange.target
+systemctl stop taler-exchange-httpd.socket
systemctl stop taler-exchange-offline.timer
systemctl stop taler-merchant-httpd.service
+systemctl stop taler-merchant-httpd.socket
systemctl stop taler-merchant.target
systemctl stop taler-demo-landing.service
systemctl stop taler-demo-blog.service
systemctl stop taler-demo-donations.service
systemctl stop libeufin-bank.service
systemctl stop donau-httpd.service
+systemctl stop donau-httpd.socket
systemctl stop paivana-httpd.service
systemctl stop paivana-httpd.socket
@@ -311,6 +304,29 @@ AUTH_COMMAND = /data/sandcastle-challenger-auth
ADDRESS_RESTRICTIONS = {"email":{"hint":"not an e-mail address","regex":"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$"}}
EOF
+# Move systemd-activated HTTP listeners into the bind-mounted directory so the
+# host can use them directly without an extra reverse-proxy hop.
+configure_public_socket() {
+ local unit=$1
+ local socket_path=$2
+ local drop_in_dir=/etc/systemd/system/$unit.d
+
+ mkdir -p "$drop_in_dir"
+ cat <<EOF >"$drop_in_dir/sandcastle.conf"
+[Socket]
+ListenStream=
+ListenStream=$socket_path
+SocketMode=0666
+RemoveOnStop=yes
+EOF
+}
+
+configure_public_socket taler-exchange-httpd.socket /sockets/exchange.sock
+configure_public_socket taler-merchant-httpd.socket /sockets/merchant-backend.sock
+configure_public_socket taler-auditor-httpd.socket /sockets/auditor.sock
+configure_public_socket donau-httpd.socket /sockets/donau.sock
+configure_public_socket paivana-httpd.socket /sockets/paivana.sock
+
mkdir -p /etc/paivana
cat <<EOF >/etc/paivana/paivana.conf
[paivana]
@@ -340,7 +356,7 @@ EOF
chown paivana-httpd:root /etc/paivana/paivana.conf
chmod 640 /etc/paivana/paivana.conf
-# The paywall runs behind the caddy reverse proxy, so we need
+# The paywall runs behind a reverse proxy, so we need
# '-f' to get the client address from X-Forwarded-For. With '-g'
# a single payment unlocks the entire site instead of just the
# URL that was paid for.
@@ -369,10 +385,10 @@ SPA_CAPTCHA_URL = $PROTO://$BANK_DOMAIN$PORT_SUFFIX/webui/#/operation/{woid}
SUGGESTED_WITHDRAWAL_EXCHANGE = $PROTO://$EXCHANGE_DOMAIN$PORT_SUFFIX/
ALLOW_REGISTRATION = yes
SERVE = tcp
-PORT = 8080
+PORT = $PORT_INTERNAL_LIBEUFIN_BANK
# Bind address.
# Option soon to be deprecated!
-ADDRESS = 0.0.0.0
+ADDRESS = 127.0.0.1
WIRE_TYPE = $WIRE_METHOD
# Compat mode for now
@@ -525,6 +541,7 @@ EOF
[[ $(type -t hook_merchant_config) == function ]] && hook_merchant_config
mkdir -p /etc/taler-merchant-demos
+install -d -o taler-merchant-demos -g taler-merchant-demos /run/taler-merchant-demos
cat <<EOF >/etc/taler-merchant-demos/taler-merchant-demos.conf
[taler]
@@ -537,20 +554,23 @@ BLOG_URL = $PROTO://$BLOG_DOMAIN$PORT_SUFFIX/
DONATIONS_URL = $PROTO://$DONATIONS_DOMAIN$PORT_SUFFIX/
[frontend-demo-landing]
-HTTP_SERVE = tcp
-HTTP_PORT = $PORT_INTERNAL_LANDING_SERVICE
+HTTP_SERVE = unix
+HTTP_UNIXPATH = /run/taler-merchant-demos/landing.sock
+HTTP_UNIXPATH_MODE = 666
[frontend-demo-blog]
-HTTP_SERVE = tcp
-HTTP_PORT = $PORT_INTERNAL_BLOG
+HTTP_SERVE = unix
+HTTP_UNIXPATH = /sockets/blog.sock
+HTTP_UNIXPATH_MODE = 666
BACKEND_URL = $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/blog/
BACKEND_APIKEY = secret-token:$(get_credential_pw merchant/blog)
ENABLE_TOKENS = ${ENABLE_SUBSCRIPTIONS:-no}
[frontend-demo-donations]
DONAU_URL = $PROTO://$DONAU_DOMAIN$PORT_SUFFIX/
-HTTP_SERVE = tcp
-HTTP_PORT = $PORT_INTERNAL_DONATIONS
+HTTP_SERVE = unix
+HTTP_UNIXPATH = /sockets/donations.sock
+HTTP_UNIXPATH_MODE = 666
BACKEND_URL_TOR = $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/tor/
BACKEND_APIKEY_TOR = secret-token:$(get_credential_pw merchant/tor)
BACKEND_URL_TALER = $PROTO://$MERCHANT_DOMAIN$PORT_SUFFIX/instances/taler/
@@ -705,6 +725,14 @@ cat <<EOF >/etc/caddy/Caddyfile
}
}
+(sandcastle_bank) {
+ reverse_proxy 127.0.0.1:$PORT_INTERNAL_LIBEUFIN_BANK {
+ # libeufin-bank should eventually not require this anymore,
+ # but currently doesn't work without this header.
+ header_up X-Forwarded-Prefix ""
+ }
+}
+
(sandcastle_landing) {
handle /metrics/sandcastle-status {
root * /var/www/sandcastle
@@ -712,60 +740,19 @@ cat <<EOF >/etc/caddy/Caddyfile
file_server
}
handle {
- reverse_proxy :$PORT_INTERNAL_LANDING_SERVICE
- }
-}
-
-(sandcastle_merchant) {
- reverse_proxy unix//run/taler-merchant/httpd/merchant-http.sock {
- # Set this, or otherwise wrong taler://pay URIs will be generated.
- header_up X-Forwarded-Proto "https"
- }
-}
-
-# Services that only listen on unix domain sockets
-# are reverse-proxied to public listeners.
-
-:$PORT_INTERNAL_EXCHANGE {
- reverse_proxy unix//run/taler-exchange/httpd/exchange-http.sock
-}
-
-:$PORT_INTERNAL_MERCHANT {
- import sandcastle_merchant
-}
-
-http:// {
- bind unix//sockets/merchant-backend.sock|0666
- import sandcastle_merchant
-}
-
-:$PORT_INTERNAL_DONAU {
- reverse_proxy unix//run/donau/httpd/http.sock {
- header_up X-Forwarded-Proto "https"
+ reverse_proxy unix//run/taler-merchant-demos/landing.sock
}
}
-:$PORT_INTERNAL_LANDING {
- import sandcastle_landing
-}
-
-:$PORT_INTERNAL_DRUPAL {
+(sandcastle_drupal) {
root * /talerdata/sandcastle-drupal/web/
php_fastcgi unix/var/run/php/php8.4-fpm.sock
file_server
}
-:$PORT_INTERNAL_AUDITOR {
- reverse_proxy unix//run/taler-auditor/httpd/auditor-http.sock
-}
-
-:$PORT_INTERNAL_PAIVANA {
- reverse_proxy unix//run/paivana/httpd/paivana-http.sock
-}
-
-:$PORT_INTERNAL_CHALLENGER {
+(sandcastle_challenger) {
handle {
- reverse_proxy unix//run/challenger/httpd/challenger.http {
+ reverse_proxy unix//run/challenger/httpd/challenger-http.sock {
# Set this, or otherwise wrong taler://pay URIs will be generated.
header_up X-Forwarded-Proto "https"
}
@@ -781,6 +768,30 @@ http:// {
}
}
}
+
+# Caddy owns sockets only where it bridges a TCP-only service, composes
+# additional routing, or serves the application itself. Native services or
+# their socket units own the others.
+
+http:// {
+ bind unix//sockets/bank.sock|0666
+ import sandcastle_bank
+}
+
+http:// {
+ bind unix//sockets/landing.sock|0666
+ import sandcastle_landing
+}
+
+http:// {
+ bind unix//sockets/challenger.sock|0666
+ import sandcastle_challenger
+}
+
+http:// {
+ bind unix//sockets/drupal.sock|0666
+ import sandcastle_drupal
+}
EOF
if [[ $PROTO = https ]]; then
@@ -792,11 +803,7 @@ if [[ $PROTO = https ]]; then
https://$BANK_DOMAIN {
tls internal
- reverse_proxy :8080 {
- # libeufin-bank should eventually not require this anymore,
- # but currently doesn't work without this header.
- header_up X-Forwarded-Prefix ""
- }
+ import sandcastle_bank
}
https://$LANDING_DOMAIN {
@@ -806,12 +813,12 @@ https://$LANDING_DOMAIN {
https://$EXCHANGE_DOMAIN {
tls internal
- reverse_proxy unix//run/taler-exchange/httpd/exchange-http.sock
+ reverse_proxy unix//sockets/exchange.sock
}
https://$MERCHANT_DOMAIN {
tls internal
- reverse_proxy unix//run/taler-merchant/httpd/merchant-http.sock {
+ reverse_proxy unix//sockets/merchant-backend.sock {
# Set this, or otherwise wrong taler://pay URIs will be generated.
header_up X-Forwarded-Proto "https"
}
@@ -819,24 +826,24 @@ https://$MERCHANT_DOMAIN {
https://$DONAU_DOMAIN {
tls internal
- reverse_proxy unix//run/donau/httpd/http.sock {
+ reverse_proxy unix//sockets/donau.sock {
header_up X-Forwarded-Proto "https"
}
}
https://$AUDITOR_DOMAIN {
tls internal
- reverse_proxy unix//run/taler-auditor/httpd/auditor-http.sock
+ reverse_proxy unix//sockets/auditor.sock
}
https://$CHALLENGER_DOMAIN {
tls internal
- reverse_proxy unix//run/challenger/httpd/challenger.http
+ reverse_proxy unix//run/challenger/httpd/challenger-http.sock
}
https://$PAIVANA_DOMAIN {
tls internal
- reverse_proxy unix//run/paivana/httpd/paivana-http.sock
+ reverse_proxy unix//sockets/paivana.sock
}
EOF
@@ -847,31 +854,27 @@ else
cat <<EOF >>/etc/caddy/Caddyfile
http://$BANK_DOMAIN$PORT_SUFFIX {
- reverse_proxy :8080 {
- # libeufin-bank should eventually not require this anymore,
- # but currently doesn't work without this header.
- header_up X-Forwarded-Prefix ""
- }
+ import sandcastle_bank
}
http://$EXCHANGE_DOMAIN$PORT_SUFFIX {
- reverse_proxy unix//run/taler-exchange/httpd/exchange-http.sock
+ reverse_proxy unix//sockets/exchange.sock
}
http://$MERCHANT_DOMAIN$PORT_SUFFIX {
- reverse_proxy unix//run/taler-merchant/httpd/merchant-http.sock
+ reverse_proxy unix//sockets/merchant-backend.sock
}
http://$DONAU_DOMAIN$PORT_SUFFIX {
- reverse_proxy unix//run/donau/httpd/http.sock
+ reverse_proxy unix//sockets/donau.sock
}
http://$AUDITOR_DOMAIN$PORT_SUFFIX {
- reverse_proxy unix//run/taler-auditor/httpd/auditor-http.sock
+ reverse_proxy unix//sockets/auditor.sock
}
http://$CHALLENGER_DOMAIN$PORT_SUFFIX {
- reverse_proxy unix//run/challenger/httpd/challenger.http
+ reverse_proxy unix//run/challenger/httpd/challenger-http.sock
}
http://$LANDING_DOMAIN$PORT_SUFFIX {
@@ -879,19 +882,19 @@ http://$LANDING_DOMAIN$PORT_SUFFIX {
}
http://$BLOG_DOMAIN$PORT_SUFFIX {
- reverse_proxy :$PORT_INTERNAL_BLOG
+ reverse_proxy unix//sockets/blog.sock
}
http://$DONATIONS_DOMAIN$PORT_SUFFIX {
- reverse_proxy :$PORT_INTERNAL_DONATIONS
+ reverse_proxy unix//sockets/donations.sock
}
http://$DRUPAL_DOMAIN$PORT_SUFFIX {
- reverse_proxy :$PORT_INTERNAL_DRUPAL
+ import sandcastle_drupal
}
http://$PAIVANA_DOMAIN$PORT_SUFFIX {
- reverse_proxy unix//run/paivana/httpd/paivana-http.sock
+ reverse_proxy unix//sockets/paivana.sock
}
EOF
diff --git a/tests/test_sandcastle_run.py b/tests/test_sandcastle_run.py
@@ -59,12 +59,13 @@ class SandcastleRunTests(unittest.TestCase):
)
for variable in (
"SANDCASTLE_OVERRIDE_NAME",
- "SANDCASTLE_PORT_MERCHANT",
"SANDCASTLE_SOCKET_DIR",
):
environment.pop(variable, None)
environment.update(settings)
+ self.log.unlink(missing_ok=True)
+
result = subprocess.run(
[str(self.repository / "sandcastle-run")],
env=environment,
@@ -82,15 +83,17 @@ class SandcastleRunTests(unittest.TestCase):
self.assertEqual("run", calls[1][0])
return calls[1]
- def test_default_uses_socket_without_publishing_merchant_port(self):
+ def test_default_uses_sockets_without_publishing_ports(self):
arguments = self.run_sandcastle()
socket_dir = self.repository / "sockets"
self.assertTrue(socket_dir.is_dir())
self.assertEqual(0o1777, stat.S_IMODE(socket_dir.stat().st_mode))
self.assertIn(f"{socket_dir}:/sockets:z", arguments)
- self.assertNotIn("-p=127.0.0.1:16000:8301", arguments)
- self.assertIn("-p=127.0.0.1:16001:8201", arguments)
+ published_ports = [
+ argument for argument in arguments if argument.startswith("-p=")
+ ]
+ self.assertEqual([], published_ports)
def test_custom_socket_directory_is_mounted_as_one_argument(self):
socket_dir = self.root / "custom socket directory"
@@ -100,13 +103,5 @@ class SandcastleRunTests(unittest.TestCase):
self.assertEqual(0o1777, stat.S_IMODE(socket_dir.stat().st_mode))
self.assertIn(f"{socket_dir}:/sockets:z", arguments)
- def test_explicit_merchant_port_is_published(self):
- arguments = self.run_sandcastle(
- SANDCASTLE_PORT_MERCHANT="127.0.0.1:26000"
- )
-
- self.assertIn("-p=127.0.0.1:26000:8301", arguments)
-
-
if __name__ == "__main__":
unittest.main()
diff --git a/tests/test_socket_configuration.py b/tests/test_socket_configuration.py
@@ -0,0 +1,62 @@
+# This file is in the public domain.
+
+import re
+import unittest
+from pathlib import Path
+
+
+REPOSITORY = Path(__file__).resolve().parents[1]
+SETUP_SCRIPT = (REPOSITORY / "scripts/demo/setup-sandcastle.sh").read_text(
+ encoding="utf-8"
+)
+
+
+class SocketConfigurationTests(unittest.TestCase):
+ def test_systemd_activated_services_use_public_sockets(self):
+ sockets = {
+ "taler-exchange-httpd.socket": "exchange.sock",
+ "taler-merchant-httpd.socket": "merchant-backend.sock",
+ "taler-auditor-httpd.socket": "auditor.sock",
+ "donau-httpd.socket": "donau.sock",
+ "paivana-httpd.socket": "paivana.sock",
+ }
+
+ for unit, socket in sockets.items():
+ with self.subTest(unit=unit):
+ self.assertIn(
+ f"configure_public_socket {unit} /sockets/{socket}",
+ SETUP_SCRIPT,
+ )
+
+ def test_demo_applications_use_unix_sockets(self):
+ sockets = {
+ "landing": "/run/taler-merchant-demos/landing.sock",
+ "blog": "/sockets/blog.sock",
+ "donations": "/sockets/donations.sock",
+ }
+
+ for application, socket in sockets.items():
+ with self.subTest(application=application):
+ section = re.search(
+ rf"\[frontend-demo-{application}\]\n(.*?)(?=\n\[)",
+ SETUP_SCRIPT,
+ re.DOTALL,
+ )
+ self.assertIsNotNone(section)
+ self.assertIn("HTTP_SERVE = unix", section.group(1))
+ self.assertIn(f"HTTP_UNIXPATH = {socket}", section.group(1))
+
+ def test_caddy_only_owns_bridge_or_composed_service_sockets(self):
+ sockets = re.findall(
+ r"bind unix//sockets/([^|]+)\|0666",
+ SETUP_SCRIPT,
+ )
+
+ self.assertEqual(
+ ["bank.sock", "landing.sock", "challenger.sock", "drupal.sock"],
+ sockets,
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()