HTTPS ueber die blanke IP: Standard-Server statt abgelehntem Handshake
https://<IP>/cmk/ endete im Browser mit ERR_SSL_UNRECOGNIZED_NAME_ALERT, waehrend dieselbe Adresse ueber http funktionierte. Die Ursache liegt nicht beim Zertifikat: RFC 6066 laesst in der SNI-Erweiterung keine IP-Adressen zu, der Browser schickt bei einer IP also gar keinen Namen. nginx kann den Server-Block dann nicht ueber den Namen waehlen und faellt auf den Standard-Server zurueck - bei NPM ist das der Block aus /etc/nginx/conf.d/default.conf mit "ssl_reject_handshake on". Ueber HTTP faellt das nicht auf, dort entscheidet der Host-Kopf, und der traegt die IP. Nachgeprueft am Image jc21/nginx-proxy-manager:2 (2.15.1): der Block steht dort in Zeile 36, und nginx.conf liest conf.d/*.conf vor den Proxy-Hosts ein - damit wird er zum Standard-Server, obwohl keiner der Bloecke "default_server" gesetzt hat. Mit einem eigenen Block, der das Kennzeichen ausdruecklich traegt, ist der Fall entschieden; Aufrufe mit Namen gehen unveraendert an ihren Proxy-Host. Neu ist "proxy default": proxy default Stand anzeigen proxy default --domain X Proxy-Host X spiegeln proxy default --off Spiegelung entfernen --restart Proxy Manager gleich neu starten Gespiegelt wird ueber die API: Ziel, Zertifikat und die zusaetzlichen Pfade des Proxy-Hosts landen in einem Standard-Server-Block in der Zusatzkonfiguration. Fuehrt das Zertifikat die IP nicht als Alternativnamen, sagt der Befehl das vorher - bei Lets Encrypt geht es prinzipbedingt nicht. Dabei aufgefallen: die Zusatzkonfiguration liegt im Datenverzeichnis des Proxy Managers und gehoert dem Container. Ohne Schreibrecht scheiterte bisher nur ein nacktes "touch" - jetzt sagt npm_conf_writable, woran es liegt, und nennt den sudo-Aufruf. Das gilt auch fuer "npm-port". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+329
-7
@@ -2753,25 +2753,54 @@ NPM_CUSTOM_CONF_REL="nginx/custom/http.conf"
|
||||
NPM_BLOCK_START="# >>> cmk-manage.sh: Admin-Port - nicht von Hand aendern >>>"
|
||||
NPM_BLOCK_END="# <<< cmk-manage.sh: Admin-Port <<<"
|
||||
|
||||
npm_custom_conf_path() {
|
||||
local base="${NPM_DATA_DIR:-$PROJECT_DIR/data/npm/data}"
|
||||
case "$base" in /*) : ;; *) base="$PROJECT_DIR/${base#./}" ;; esac
|
||||
printf '%s/%s\n' "$base" "$NPM_CUSTOM_CONF_REL"
|
||||
# Die Zusatzkonfiguration liegt im Datenverzeichnis des Proxy Managers,
|
||||
# und das gehoert dem Container - also root. Ohne Schreibrecht scheitert
|
||||
# sonst erst "touch" mit einer nackten Fehlermeldung.
|
||||
npm_conf_writable() { # datei
|
||||
local f="$1" d; d="$(dirname "$f")"
|
||||
if [ -e "$f" ]; then
|
||||
[ -w "$f" ] && return 0
|
||||
elif [ -d "$d" ]; then
|
||||
[ -w "$d" ] && return 0
|
||||
else
|
||||
mkdir -p "$d" 2>/dev/null && return 0
|
||||
fi
|
||||
err "Keine Schreibrechte auf $f"
|
||||
printf ' Das Verzeichnis gehoert dem Proxy-Manager-Container (root).
|
||||
Bitte mit sudo aufrufen:
|
||||
sudo %s %s\n' "$SELF" "${CMD_LINE:-<befehl>}" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
npm_data_dir_abs() {
|
||||
local base="${NPM_DATA_DIR:-$PROJECT_DIR/data/npm/data}"
|
||||
case "$base" in /*) : ;; *) base="$PROJECT_DIR/${base#./}" ;; esac
|
||||
printf '%s\n' "$base"
|
||||
}
|
||||
|
||||
npm_custom_conf_path() {
|
||||
printf '%s/%s\n' "$(npm_data_dir_abs)" "$NPM_CUSTOM_CONF_REL"
|
||||
}
|
||||
|
||||
NPM_DEF_START="# >>> cmk-manage.sh: HTTPS ohne SNI - nicht von Hand aendern >>>"
|
||||
NPM_DEF_END="# <<< cmk-manage.sh: HTTPS ohne SNI <<<"
|
||||
|
||||
# Vorhandenen verwalteten Block entfernen, Fremdinhalte bleiben erhalten
|
||||
npm_conf_strip_block() {
|
||||
local f="$1"
|
||||
npm_conf_strip_marked() {
|
||||
local f="$1" st="$2" en="$3"
|
||||
[ -f "$f" ] || return 0
|
||||
awk -v s="$NPM_BLOCK_START" -v e="$NPM_BLOCK_END" '
|
||||
awk -v s="$st" -v e="$en" '
|
||||
$0 == s { skip=1; next }
|
||||
$0 == e { skip=0; next }
|
||||
!skip { print }
|
||||
' "$f" > "$f.tmp" && mv "$f.tmp" "$f"
|
||||
}
|
||||
|
||||
npm_conf_strip_block() { npm_conf_strip_marked "$1" "$NPM_BLOCK_START" "$NPM_BLOCK_END"; }
|
||||
|
||||
npm_conf_write_block() {
|
||||
local f="$1" port="$2"
|
||||
npm_conf_writable "$f" || return 1
|
||||
mkdir -p "$(dirname "$f")"
|
||||
touch "$f"
|
||||
npm_conf_strip_block "$f"
|
||||
@@ -3555,6 +3584,144 @@ proxy_location_json() { # spec -> JSON-Objekt auf stdout
|
||||
}
|
||||
|
||||
# --- Proxy-Hosts ---------------------------------------------------------
|
||||
# =====================================================================
|
||||
# HTTPS ueber die blanke IP
|
||||
#
|
||||
# Ruft man den Server mit https://<IP>/ auf, sendet der Browser keinen
|
||||
# SNI-Namen - RFC 6066 laesst dort keine IP-Adressen zu. nginx kann den
|
||||
# passenden Server-Block dann nicht ueber den Namen auswaehlen und faellt
|
||||
# auf den Standard-Server zurueck. Bei NPM ist das der Block aus
|
||||
# /etc/nginx/conf.d/default.conf, und der antwortet mit
|
||||
# "ssl_reject_handshake on" - im Browser als
|
||||
# ERR_SSL_UNRECOGNIZED_NAME_ALERT.
|
||||
#
|
||||
# Ueber HTTP faellt das nicht auf: dort waehlt nginx den Server-Block
|
||||
# anhand des Host-Kopfes aus, und der traegt die IP.
|
||||
#
|
||||
# Abhilfe ist ein eigener Block mit "default_server" in der
|
||||
# Zusatzkonfiguration, die nginx nach den Proxy-Hosts einliest. Keiner
|
||||
# der NPM-Bloecke setzt das Kennzeichen selbst, deshalb gibt es keinen
|
||||
# Streit darum. Benannte Aufrufe gehen weiterhin an ihren Proxy-Host -
|
||||
# der Standard-Server greift nur, wenn kein Name passt.
|
||||
# =====================================================================
|
||||
|
||||
# Zertifikatspfade IM CONTAINER zu einer NPM-Zertifikats-ID
|
||||
npm_cert_paths() { # id -> "fullchain|privkey|anbieter"
|
||||
local cid="$1" o prov
|
||||
o="$(npm_api GET "/api/nginx/certificates/$cid")" || return 1
|
||||
prov="$(json_str "$o" provider)"
|
||||
if [ "$prov" = letsencrypt ]; then
|
||||
printf '/etc/letsencrypt/live/npm-%s/fullchain.pem|/etc/letsencrypt/live/npm-%s/privkey.pem|%s\n' \
|
||||
"$cid" "$cid" "$prov"
|
||||
else
|
||||
printf '/data/custom_ssl/npm-%s/fullchain.pem|/data/custom_ssl/npm-%s/privkey.pem|%s\n' \
|
||||
"$cid" "$cid" "${prov:-other}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Deckt das Zertifikat die IP ab? Nur pruefbar, wenn die Datei hier liegt.
|
||||
npm_cert_covers_ip() { # zertifikats-id ip
|
||||
local cid="$1" ip="$2" f
|
||||
f="$(npm_data_dir_abs)/custom_ssl/npm-$cid/fullchain.pem"
|
||||
[ -r "$f" ] || return 0 # nicht pruefbar - dann auch nicht meckern
|
||||
( set +o pipefail; openssl x509 -in "$f" -noout -text 2>/dev/null | grep -q "IP Address:$ip" )
|
||||
}
|
||||
|
||||
# Einen Proxy-Host in einen Standard-Server-Block spiegeln
|
||||
npm_default_write() { # conf objekt-json fullchain privkey domain
|
||||
local f="$1" o="$2" full="$3" key="$4" dom="$5"
|
||||
npm_conf_writable "$f" || return 1
|
||||
local sch host port seg lp lsch lh lpo
|
||||
sch="$(json_str "$o" forward_scheme)"; [ -n "$sch" ] || sch=http
|
||||
host="$(json_str "$o" forward_host)"
|
||||
port="$(json_num "$o" forward_port)"
|
||||
|
||||
mkdir -p "$(dirname "$f")"
|
||||
touch "$f"
|
||||
npm_conf_strip_marked "$f" "$NPM_DEF_START" "$NPM_DEF_END"
|
||||
{
|
||||
printf '%s\n' "$NPM_DEF_START"
|
||||
cat <<EOF
|
||||
# Standard-Server fuer HTTPS: greift, wenn der Browser keinen Namen
|
||||
# mitschickt - das ist beim Aufruf ueber die blanke IP der Fall.
|
||||
# Spiegelt den Proxy-Host "$dom".
|
||||
# Erzeugt von scripts/cmk-manage.sh proxy default --domain $dom
|
||||
server {
|
||||
listen 443 ssl default_server;
|
||||
EOF
|
||||
if [ "${NPM_DISABLE_IPV6:-false}" != true ]; then
|
||||
printf ' listen [::]:443 ssl default_server;\n'
|
||||
fi
|
||||
cat <<EOF
|
||||
server_name _;
|
||||
|
||||
ssl_certificate $full;
|
||||
ssl_certificate_key $key;
|
||||
include conf.d/include/ssl-ciphers.conf;
|
||||
|
||||
access_log /data/logs/default_ssl_access.log standard;
|
||||
error_log /data/logs/default_ssl_error.log warn;
|
||||
|
||||
client_max_body_size 0;
|
||||
proxy_read_timeout 300s;
|
||||
EOF
|
||||
# Zusaetzliche Pfade zuerst - laengster Treffer gewinnt bei nginx
|
||||
# ohnehin, aber so liest es sich wie im Proxy Manager.
|
||||
while IFS= read -r seg; do
|
||||
case "$seg" in *'"path"'*) : ;; *) continue ;; esac
|
||||
lp="$(printf '%s' "$seg" | sed -n 's/.*"path":"\([^"]*\)".*/\1/p')"
|
||||
lsch="$(printf '%s' "$seg" | sed -n 's/.*"forward_scheme":"\([^"]*\)".*/\1/p')"
|
||||
lh="$(printf '%s' "$seg" | sed -n 's/.*"forward_host":"\([^"]*\)".*/\1/p')"
|
||||
lpo="$(printf '%s' "$seg" | sed -n 's/.*"forward_port":\([0-9]*\).*/\1/p')"
|
||||
[ -n "$lp" ] && [ -n "$lh" ] && [ -n "$lpo" ] || continue
|
||||
[ -n "$lsch" ] || lsch=http
|
||||
cat <<EOF
|
||||
|
||||
location $lp {
|
||||
proxy_pass $lsch://$lh:$lpo;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
EOF
|
||||
done < <(printf '%s' "$o" | tr '}' '\n')
|
||||
|
||||
cat <<EOF
|
||||
|
||||
location / {
|
||||
proxy_pass $sch://$host:$port;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_set_header Upgrade \$http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
}
|
||||
EOF
|
||||
printf '%s\n' "$NPM_DEF_END"
|
||||
} >> "$f"
|
||||
sed -i '/./,$!d' "$f"
|
||||
}
|
||||
|
||||
npm_reload_hint() { # restart-flag
|
||||
if [ -n "${1:-}" ] && container_running "$NPM_CONTAINER_NAME"; then
|
||||
log "Starte '$NPM_CONTAINER_NAME' neu, damit nginx die Konfiguration liest ..."
|
||||
if $RUNTIME restart "$NPM_CONTAINER_NAME" >/dev/null; then
|
||||
ok "Proxy Manager neu gestartet."
|
||||
else
|
||||
warn "Neustart fehlgeschlagen - bitte manuell: $SELF restart"
|
||||
fi
|
||||
else
|
||||
log "Wirksam nach: $SELF restart (bzw. Neustart des Proxy Managers)"
|
||||
fi
|
||||
}
|
||||
|
||||
cmd_proxy() {
|
||||
local sub="${1:-list}"; [ $# -gt 0 ] && shift || true
|
||||
|
||||
@@ -3639,6 +3806,116 @@ cmd_proxy() {
|
||||
echo
|
||||
return 0 ;;
|
||||
|
||||
default|ip)
|
||||
local dom="" off="" restart="" conf
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--domain) dom="$2"; shift 2 ;;
|
||||
--off|--aus) off=1; shift ;;
|
||||
--restart) restart=1; shift ;;
|
||||
--help|-h)
|
||||
cat <<EOF
|
||||
|
||||
HTTPS ueber die blanke IP ermoeglichen.
|
||||
|
||||
$SELF proxy default Stand anzeigen
|
||||
$SELF proxy default --domain NAME Proxy-Host spiegeln
|
||||
$SELF proxy default --off Spiegelung entfernen
|
||||
|
||||
Ruft man den Server als https://<IP>/ auf, schickt der Browser keinen
|
||||
Namen mit (SNI kennt keine IP-Adressen). nginx kann den Proxy-Host dann
|
||||
nicht ueber den Namen finden und faellt auf seinen Standard-Server
|
||||
zurueck - der lehnt den Handshake ab: ERR_SSL_UNRECOGNIZED_NAME_ALERT.
|
||||
Ueber HTTP faellt das nicht auf, dort entscheidet der Host-Kopf.
|
||||
|
||||
Dieser Befehl legt einen Standard-Server an, der denselben Weg nimmt wie
|
||||
der genannte Proxy-Host - samt der zusaetzlichen Pfade. Aufrufe mit
|
||||
Namen gehen weiterhin an ihren eigenen Proxy-Host.
|
||||
EOF
|
||||
return 0 ;;
|
||||
*) dom="$1"; shift ;;
|
||||
esac
|
||||
done
|
||||
conf="$(npm_custom_conf_path)"
|
||||
|
||||
if [ -n "$off" ]; then
|
||||
if ! grep -qsF "$NPM_DEF_START" "$conf"; then
|
||||
ok "Es ist kein Standard-Server eingetragen."
|
||||
return 0
|
||||
fi
|
||||
npm_conf_strip_marked "$conf" "$NPM_DEF_START" "$NPM_DEF_END"
|
||||
[ -s "$conf" ] || rm -f "$conf"
|
||||
ok "Standard-Server entfernt: $conf"
|
||||
npm_reload_hint "$restart"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -z "$dom" ]; then
|
||||
printf '\n%sHTTPS ueber die blanke IP%s\n' "$C_BLD" "$C_RST"
|
||||
if grep -qsF "$NPM_DEF_START" "$conf"; then
|
||||
test_result ok "eingerichtet"
|
||||
printf ' Datei : %s\n' "$conf"
|
||||
printf ' Spiegelt: %s\n' \
|
||||
"$(sed -n 's/^# Spiegelt den Proxy-Host "\(.*\)"\.$/\1/p' "$conf" | head -1)"
|
||||
printf '\n Entfernen mit: %s proxy default --off\n\n' "$SELF"
|
||||
else
|
||||
test_result warn "nicht eingerichtet"
|
||||
printf ' https://<IP>/ endet dann in
|
||||
ERR_SSL_UNRECOGNIZED_NAME_ALERT, http://<IP>/ geht.\n'
|
||||
printf '\n Einrichten mit: %s proxy default --domain <name-des-proxy-hosts>\n' "$SELF"
|
||||
printf ' Vorhandene : %s proxy list\n\n' "$SELF"
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
|
||||
npm_require_running || return 1
|
||||
NPM_TOKEN="$(npm_api_token)" || return 1
|
||||
|
||||
# Proxy-Host zum Namen suchen
|
||||
local all pid="" i
|
||||
all="$(npm_api GET /api/nginx/proxy-hosts)"
|
||||
for i in $(json_ids "$all"); do
|
||||
if ( set +o pipefail; npm_api GET "/api/nginx/proxy-hosts/$i" | grep -qF "\"$dom\"" ); then
|
||||
pid="$i"; break
|
||||
fi
|
||||
done
|
||||
[ -n "$pid" ] || die "Kein Proxy-Host fuer '$dom' gefunden - '$SELF proxy list' zeigt die vorhandenen."
|
||||
|
||||
local o cid
|
||||
o="$(npm_api GET "/api/nginx/proxy-hosts/$pid")"
|
||||
cid="$(json_num "$o" certificate_id)"
|
||||
if [ -z "$cid" ] || [ "$cid" = 0 ]; then
|
||||
die "Der Proxy-Host '$dom' hat kein Zertifikat.
|
||||
Ohne Zertifikat gibt es nichts, was ohne SNI ausgeliefert werden koennte.
|
||||
Erst eines zuweisen: $SELF proxy add --domain $dom --cert ... --update"
|
||||
fi
|
||||
|
||||
local paths full key prov
|
||||
paths="$(npm_cert_paths "$cid")" || die "Zertifikat $cid nicht abrufbar."
|
||||
full="${paths%%|*}"; paths="${paths#*|}"
|
||||
key="${paths%%|*}"; prov="${paths##*|}"
|
||||
|
||||
local ip; ip="$(primary_ip)"
|
||||
if [ "$prov" = letsencrypt ]; then
|
||||
warn "Das Zertifikat stammt von Lets Encrypt und lautet auf '$dom'.
|
||||
Beim Aufruf ueber die IP meldet der Browser deshalb einen
|
||||
Namensfehler (anklickbar, aber unschoen). Fuer den IP-Zugang ist
|
||||
ein selbstsigniertes Zertifikat mit der IP als Alternativname
|
||||
besser: $SELF cert --domain $dom --alt $ip"
|
||||
elif [ -n "$ip" ] && ! npm_cert_covers_ip "$cid" "$ip"; then
|
||||
warn "Das Zertifikat fuehrt die IP $ip nicht als Alternativnamen.
|
||||
Der Browser meldet dann einen Namensfehler. Neu erzeugen mit:
|
||||
$SELF cert --domain $dom --alt $ip
|
||||
und dem Proxy-Host zuweisen."
|
||||
fi
|
||||
|
||||
CMD_LINE="proxy default --domain $dom" npm_default_write "$conf" "$o" "$full" "$key" "$dom" || return 1
|
||||
ok "Standard-Server geschrieben: $conf"
|
||||
printf ' Spiegelt Proxy-Host %s (%s), Zertifikat %s (%s)\n' "$pid" "$dom" "$cid" "$prov"
|
||||
if [ -n "$ip" ]; then printf ' Danach erreichbar unter: https://%s/\n' "$ip"; fi
|
||||
npm_reload_hint "$restart"
|
||||
return 0 ;;
|
||||
|
||||
del|delete|rm)
|
||||
local pid=""
|
||||
while [ $# -gt 0 ]; do
|
||||
@@ -4970,6 +5247,7 @@ Ziel : ${PROXY_FORWARD_HOST:-127.0.0.1}:${PROXY_FORWARD_PORT:-5000}" \
|
||||
list "Vorhandene Proxy-Hosts anzeigen" \
|
||||
show "Einzelheiten eines Proxy-Hosts (mit Pfaden)" \
|
||||
certs "Vorhandene Zertifikate anzeigen" \
|
||||
ipzugang "HTTPS ueber die blanke IP (ohne Namen) ermoeglichen" \
|
||||
del "Proxy-Host loeschen" \
|
||||
status "Anmeldung pruefen" \
|
||||
reset "Datenbank zuruecksetzen (Konto neu anlegen lassen)" \
|
||||
@@ -4985,6 +5263,7 @@ Ziel : ${PROXY_FORWARD_HOST:-127.0.0.1}:${PROXY_FORWARD_PORT:-5000}" \
|
||||
ui_text "Proxy-Host $d3" "$f3"; rm -f "$f3" ;;
|
||||
certs) local f2; f2="$(mktemp)"; NO_COLOR=1 cmd_proxy certs >"$f2" 2>&1 || true
|
||||
ui_text "Zertifikate" "$f2"; rm -f "$f2" ;;
|
||||
ipzugang) gui_proxy_default || true ;;
|
||||
del) gui_proxy_del || true ;;
|
||||
status) ui_run "Anmeldung pruefen" bash -c "cd '$PROJECT_DIR' && NO_COLOR=1 '$SELF' proxy status" ;;
|
||||
reset) gui_npm_reset || true ;;
|
||||
@@ -4993,6 +5272,49 @@ Ziel : ${PROXY_FORWARD_HOST:-127.0.0.1}:${PROXY_FORWARD_PORT:-5000}" \
|
||||
done
|
||||
}
|
||||
|
||||
gui_proxy_default() {
|
||||
local f rc=0
|
||||
f="$(mktemp)"
|
||||
NO_COLOR=1 cmd_proxy default >"$f" 2>&1 || true
|
||||
ui_text "HTTPS ueber die blanke IP" "$f"; rm -f "$f"
|
||||
|
||||
local sel
|
||||
sel="$(ui_menu "HTTPS ueber die blanke IP" \
|
||||
"Ruft man den Server als https://<IP>/ auf, schickt der Browser keinen
|
||||
Namen mit - SNI kennt keine IP-Adressen. nginx findet den Proxy-Host
|
||||
dann nicht und lehnt den Handshake ab (ERR_SSL_UNRECOGNIZED_NAME_ALERT).
|
||||
Ueber http://<IP>/ faellt das nicht auf, dort zaehlt der Host-Kopf.
|
||||
|
||||
Ein Standard-Server nimmt genau diese Aufrufe an und geht denselben Weg
|
||||
wie der gewaehlte Proxy-Host, samt seiner zusaetzlichen Pfade.
|
||||
Aufrufe mit Namen bleiben unberuehrt." \
|
||||
ein "Einrichten - Proxy-Host spiegeln" \
|
||||
aus "Entfernen" \
|
||||
back "zurueck")" || return 0
|
||||
|
||||
case "$sel" in
|
||||
back) return 0 ;;
|
||||
aus) ui_run "Standard-Server entfernen" bash -c \
|
||||
"cd '$PROJECT_DIR' && NO_COLOR=1 '$SELF' proxy default --off --restart" || true
|
||||
return 0 ;;
|
||||
esac
|
||||
|
||||
local dom
|
||||
dom="$(ui_input "Einrichten" "Name des Proxy-Hosts, der gespiegelt werden soll:" \
|
||||
"${PROXY_DOMAIN:-}")" || return 0
|
||||
[ -n "$dom" ] || return 0
|
||||
|
||||
f="$(mktemp)"
|
||||
NO_COLOR=1 cmd_proxy default --domain "$dom" --restart >"$f" 2>&1 || rc=$?
|
||||
if [ "$rc" -eq 0 ]; then
|
||||
ui_text "Standard-Server eingerichtet" "$f"
|
||||
else
|
||||
ui_text "Einrichten fehlgeschlagen" "$f"
|
||||
fi
|
||||
rm -f "$f"
|
||||
return 0
|
||||
}
|
||||
|
||||
gui_proxy_add() {
|
||||
if ! npm_require_running 2>/dev/null; then
|
||||
ui_msg "Proxy Manager laeuft nicht" \
|
||||
|
||||
Reference in New Issue
Block a user