Fix NPM forward host: use real host IP instead of Docker gateway
- npm_service._get_forward_host() now detects the actual host IP via UDP socket (works inside Docker containers) instead of using 172.17.0.1 Docker gateway which NPM can't reach - install.sh uses hostname -I for NPM forward host - Removed npm_api_url parameter from _get_forward_host() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -224,7 +224,7 @@ async def deploy_customer(db: Session, customer_id: int) -> dict[str, Any]:
|
|||||||
npm_proxy_id = None
|
npm_proxy_id = None
|
||||||
npm_stream_id = None
|
npm_stream_id = None
|
||||||
if not local_mode:
|
if not local_mode:
|
||||||
forward_host = npm_service._get_forward_host(config.npm_api_url)
|
forward_host = npm_service._get_forward_host()
|
||||||
npm_result = await npm_service.create_proxy_host(
|
npm_result = await npm_service.create_proxy_host(
|
||||||
api_url=config.npm_api_url,
|
api_url=config.npm_api_url,
|
||||||
npm_email=config.npm_api_email,
|
npm_email=config.npm_api_email,
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ Also manages NPM streams for STUN/TURN relay UDP ports.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import socket
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from urllib.parse import urlparse
|
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
||||||
@@ -24,34 +24,29 @@ logger = logging.getLogger(__name__)
|
|||||||
NPM_TIMEOUT = 30
|
NPM_TIMEOUT = 30
|
||||||
|
|
||||||
|
|
||||||
def _get_forward_host(npm_api_url: str) -> str:
|
def _get_forward_host() -> str:
|
||||||
"""Determine the IP/hostname to forward traffic to.
|
"""Detect the host machine's real IP address.
|
||||||
|
|
||||||
The NPM proxy host must forward to the MSP appliance's host IP,
|
NPM proxy hosts must forward to the actual host IP where Docker
|
||||||
NOT to a Docker container name, because the customer's Caddy
|
port mappings are exposed — NOT a container name or Docker gateway.
|
||||||
container exposes its port on the host via Docker port mapping.
|
|
||||||
|
|
||||||
We extract the host from the NPM API URL — if the admin configured
|
Uses a UDP socket to determine the primary outbound IP address
|
||||||
``http://10.0.0.5:81/api``, we forward to ``10.0.0.5``.
|
of the host (works inside Docker containers).
|
||||||
If the admin configured ``http://npm:81/api`` (container name),
|
|
||||||
we fall back to the Docker gateway IP ``172.17.0.1``.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
npm_api_url: The NPM API base URL from system config.
|
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
IP address or hostname to forward to.
|
The host's primary IP address (e.g. ``192.168.26.191``).
|
||||||
"""
|
"""
|
||||||
parsed = urlparse(npm_api_url)
|
try:
|
||||||
host = parsed.hostname or "172.17.0.1"
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
s.connect(("8.8.8.8", 80))
|
||||||
# If the host looks like a container name (no dots, not an IP), use Docker gateway
|
host_ip = s.getsockname()[0]
|
||||||
if not any(c == "." for c in host) and not host.startswith("172.") and host != "localhost":
|
s.close()
|
||||||
logger.info("NPM URL host '%s' looks like a container name, using Docker gateway 172.17.0.1", host)
|
logger.info("Detected host IP: %s", host_ip)
|
||||||
|
return host_ip
|
||||||
|
except Exception:
|
||||||
|
logger.warning("Could not detect host IP, falling back to 172.17.0.1")
|
||||||
return "172.17.0.1"
|
return "172.17.0.1"
|
||||||
|
|
||||||
return host
|
|
||||||
|
|
||||||
|
|
||||||
async def _npm_login(client: httpx.AsyncClient, api_url: str, email: str, password: str) -> str:
|
async def _npm_login(client: httpx.AsyncClient, api_url: str, email: str, password: str) -> str:
|
||||||
"""Authenticate with NPM and return a JWT token.
|
"""Authenticate with NPM and return a JWT token.
|
||||||
|
|||||||
11
install.sh
11
install.sh
@@ -442,15 +442,8 @@ if [ -n "$MSP_DOMAIN" ]; then
|
|||||||
echo ""
|
echo ""
|
||||||
echo -e "${CYAN}Creating NPM proxy host for MSP Appliance (${MSP_DOMAIN})...${NC}"
|
echo -e "${CYAN}Creating NPM proxy host for MSP Appliance (${MSP_DOMAIN})...${NC}"
|
||||||
|
|
||||||
# Determine forward host from NPM API URL
|
# Use the actual host IP for NPM forwarding (not Docker gateway!)
|
||||||
NPM_HOST=$(echo "$NPM_API_URL" | sed -E 's|https?://([^:/]+).*|\1|')
|
FORWARD_HOST=$(hostname -I | awk '{print $1}')
|
||||||
|
|
||||||
# If host looks like a container name (no dots), use Docker gateway
|
|
||||||
if ! echo "$NPM_HOST" | grep -q '\.'; then
|
|
||||||
FORWARD_HOST="172.17.0.1"
|
|
||||||
else
|
|
||||||
FORWARD_HOST="$NPM_HOST"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Step 1: Login to NPM
|
# Step 1: Login to NPM
|
||||||
NPM_TOKEN=$(curl -s -X POST "${NPM_API_URL}/tokens" \
|
NPM_TOKEN=$(curl -s -X POST "${NPM_API_URL}/tokens" \
|
||||||
|
|||||||
Reference in New Issue
Block a user