From a1b048f2adca256549fee670d01bc23b3a7f47e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Diego=20Nogu=C3=AAs?= Date: Thu, 12 Feb 2026 18:43:35 +0100 Subject: [PATCH] feat: adding traefik + nb reverse proxy --- infrastructure_files/getting-started.sh | 459 +++++++++++++++++++++++- 1 file changed, 452 insertions(+), 7 deletions(-) diff --git a/infrastructure_files/getting-started.sh b/infrastructure_files/getting-started.sh index 25599997c..51ff27933 100755 --- a/infrastructure_files/getting-started.sh +++ b/infrastructure_files/getting-started.sh @@ -91,16 +91,17 @@ read_reverse_proxy_type() { echo " [3] Nginx Proxy Manager (generates config + instructions)" > /dev/stderr echo " [4] External Caddy (generates Caddyfile snippet)" > /dev/stderr echo " [5] Other/Manual (displays setup documentation)" > /dev/stderr + echo " [6] Traefik TCP Proxy (single port 443 + STUN)" > /dev/stderr echo "" > /dev/stderr - echo -n "Enter choice [0-5] (default: 0): " > /dev/stderr + echo -n "Enter choice [0-6] (default: 0): " > /dev/stderr read -r CHOICE < /dev/tty if [[ -z "$CHOICE" ]]; then CHOICE="0" fi - if [[ ! "$CHOICE" =~ ^[0-5]$ ]]; then - echo "Invalid choice. Please enter a number between 0 and 5." > /dev/stderr + if [[ ! "$CHOICE" =~ ^[0-6]$ ]]; then + echo "Invalid choice. Please enter a number between 0 and 6." > /dev/stderr read_reverse_proxy_type return fi @@ -140,6 +141,35 @@ read_traefik_certresolver() { return 0 } +read_traefik_tcp_acme_email() { + echo "" > /dev/stderr + echo "Enter your email for Let's Encrypt certificate notifications." > /dev/stderr + echo -n "Email address: " > /dev/stderr + read -r EMAIL < /dev/tty + if [[ -z "$EMAIL" ]]; then + echo "Email is required for Let's Encrypt." > /dev/stderr + read_traefik_tcp_acme_email + return + fi + echo "$EMAIL" + return 0 +} + +read_enable_proxy() { + echo "" > /dev/stderr + echo "Do you want to enable the NetBird Proxy service?" > /dev/stderr + echo "The proxy exposes internal NetBird network resources to the internet." > /dev/stderr + echo -n "Enable proxy? [y/N]: " > /dev/stderr + read -r CHOICE < /dev/tty + + if [[ "$CHOICE" =~ ^[Yy]$ ]]; then + echo "true" + else + echo "false" + fi + return 0 +} + read_port_binding_preference() { echo "" > /dev/stderr echo "Should container ports be bound to localhost only (127.0.0.1)?" > /dev/stderr @@ -206,6 +236,30 @@ wait_management() { return 0 } +wait_management_traefik() { + set +e + echo -n "Waiting for Management server to become ready" + counter=1 + while true; do + # Check the embedded IdP endpoint through Traefik + if curl -sk -f -o /dev/null "$NETBIRD_HTTP_PROTOCOL://$NETBIRD_DOMAIN/oauth2/.well-known/openid-configuration" 2>/dev/null; then + break + fi + if [[ $counter -eq 60 ]]; then + echo "" + echo "Taking too long. Checking logs..." + $DOCKER_COMPOSE_COMMAND logs --tail=20 traefik + $DOCKER_COMPOSE_COMMAND logs --tail=20 management + fi + echo -n " ." + sleep 2 + counter=$((counter + 1)) + done + echo " done" + set -e + return 0 +} + wait_management_direct() { set +e local upstream_host=$(get_upstream_host) @@ -246,10 +300,12 @@ initialize_default_values() { # Docker images CADDY_IMAGE="caddy" - DASHBOARD_IMAGE="netbirdio/dashboard:latest" + #DASHBOARD_IMAGE="netbirdio/dashboard:latest" + DASHBOARD_IMAGE="netbirdio/dashboard:pr-552" SIGNAL_IMAGE="netbirdio/signal:latest" RELAY_IMAGE="netbirdio/relay:latest" - MANAGEMENT_IMAGE="netbirdio/management:latest" + MANAGEMENT_IMAGE="netbirdio/management:latest" + PROXY_IMAGE="" # Reverse proxy configuration REVERSE_PROXY_TYPE="0" @@ -263,6 +319,14 @@ initialize_default_values() { RELAY_HOST_PORT="8084" BIND_LOCALHOST_ONLY="true" EXTERNAL_PROXY_NETWORK="" + + # Traefik TCP proxy configuration + TRAEFIK_IMAGE="traefik:v3.6" + TRAEFIK_TCP_ACME_EMAIL="" + + # NetBird Proxy configuration + ENABLE_PROXY="false" + PROXY_TOKEN="" return 0 } @@ -293,8 +357,17 @@ configure_reverse_proxy() { TRAEFIK_CERTRESOLVER=$(read_traefik_certresolver) fi + # Handle Traefik TCP proxy prompts + if [[ "$REVERSE_PROXY_TYPE" == "6" ]]; then + TRAEFIK_TCP_ACME_EMAIL=$(read_traefik_tcp_acme_email) + + # Prompt for NetBird Proxy configuration + ENABLE_PROXY=$(read_enable_proxy) + # Note: PROXY_TOKEN will be auto-generated after Management starts + fi + # Handle port binding for external proxy options (2-5) - if [[ "$REVERSE_PROXY_TYPE" -ge 2 ]]; then + if [[ "$REVERSE_PROXY_TYPE" -ge 2 && "$REVERSE_PROXY_TYPE" -le 5 ]]; then BIND_LOCALHOST_ONLY=$(read_port_binding_preference) fi @@ -313,7 +386,7 @@ check_existing_installation() { echo "Generated files already exist, if you want to reinitialize the environment, please remove them first." echo "You can use the following commands:" echo " $DOCKER_COMPOSE_COMMAND down --volumes # to remove all containers and volumes" - echo " rm -f docker-compose.yml Caddyfile dashboard.env management.json relay.env nginx-netbird.conf caddyfile-netbird.txt npm-advanced-config.txt" + echo " rm -f docker-compose.yml Caddyfile dashboard.env management.json relay.env nginx-netbird.conf caddyfile-netbird.txt npm-advanced-config.txt proxy.env" echo "Be aware that this will remove all data from the database, and you will have to reconfigure the dashboard." exit 1 fi @@ -347,6 +420,15 @@ generate_configuration_files() { 5) render_docker_compose_exposed_ports > docker-compose.yml ;; + 6) + render_docker_compose_traefik_tcp > docker-compose.yml + if [[ "$ENABLE_PROXY" == "true" ]]; then + # Create placeholder proxy.env so docker-compose can validate + # This will be overwritten with the actual token after Management starts + echo "# Placeholder - will be updated with token after Management starts" > proxy.env + echo "NB_PROXY_TOKEN=placeholder" >> proxy.env + fi + ;; *) echo "Invalid reverse proxy type: $REVERSE_PROXY_TYPE" > /dev/stderr exit 1 @@ -402,6 +484,50 @@ start_services_and_show_instructions() { echo "" echo "NetBird containers are running. Configure NPM as shown above, then access:" echo " $NETBIRD_HTTP_PROTOCOL://$NETBIRD_DOMAIN" + elif [[ "$REVERSE_PROXY_TYPE" == "6" ]]; then + # Traefik TCP Proxy - two-phase startup if proxy is enabled + echo -e "$MSG_STARTING_SERVICES" + + if [[ "$ENABLE_PROXY" == "true" ]]; then + # Phase 1: Start core services (without proxy) + echo "Starting core services..." + $DOCKER_COMPOSE_COMMAND up -d traefik dashboard signal relay management + + sleep 3 + wait_management_traefik + + # Phase 2: Create proxy token and start proxy + echo "" + echo "Creating proxy access token..." + # Use docker exec with bash to run the token command directly + # (bypassing the entrypoint which adds 'management' as first arg) + PROXY_TOKEN=$($DOCKER_COMPOSE_COMMAND exec -T management \ + bash -c '/go/bin/netbird-mgmt token create --name "default-proxy" --config /etc/netbird/management.json' 2>/dev/null | grep "^Token:" | awk '{print $2}') + + if [[ -z "$PROXY_TOKEN" ]]; then + echo "ERROR: Failed to create proxy token. Check management logs." > /dev/stderr + $DOCKER_COMPOSE_COMMAND logs --tail=20 management + exit 1 + fi + + echo "Proxy token created successfully." + + # Generate proxy.env with the token + render_proxy_env > proxy.env + + # Start proxy service + echo "Starting proxy service..." + $DOCKER_COMPOSE_COMMAND up -d proxy + else + # No proxy - start all services at once + $DOCKER_COMPOSE_COMMAND up -d + + sleep 3 + wait_management_traefik + fi + + echo -e "$MSG_DONE" + print_post_setup_instructions else # External proxies (nginx, external Caddy, other) - need manual config first print_post_setup_instructions @@ -547,6 +673,29 @@ EOF return 0 } +render_proxy_env() { + cat < /dev/stderr ;;