Nginx connect() ist beim Verbinden mit Upstream fehlgeschlagen (111: Verbindung abgelehnt), Client: 192.168.128.1, Server: hello-1.local

Nginx connect() ist beim Verbinden mit Upstream fehlgeschlagen (111: Verbindung abgelehnt), Client: 192.168.128.1, Server: hello-1.local

Ich versuche, SSL in meiner Django-, Docker- und Nginx-Umgebung einzurichten. Allerdings ist mir dieser Fehler begegnet:

*19 connect() ist fehlgeschlagen (111: Verbindung abgelehnt) beim Verbinden mit Upstream, Client: 192.168.128.1, Server: hello-1.local, Anfrage: „GET / HTTP/1.1“, Upstream: „https://192.168.128.4:443/“, Host: „hello-1.local“

Meine Nginx-Konfiguration:

client_max_body_size 10M;

upstream web {  
  ip_hash;
  server web:443;
}

server {
    listen 80;
    server_name hello-1.local;
    return 301 https://$host$request_uri;
}

server {    
    
    location /static/ {    
        autoindex on;    
        alias /src/static/; 
    }

    location /media/ {
        autoindex on;
        alias /src/media/;
    }

``

    location / {
        proxy_pass https://web/;
    }
    
    listen 443 ssl;
    server_name hello-1.local;
    ssl_certificate /etc/certs/hello-1.local.crt;
    ssl_certificate_key /etc/certs/hello-1.local.key;
    
} 

docker-compose.yml:

version: "3"

volumes:
  local_postgres_data: {}
  local_postgres_data_backups: {}

services:
  nginx:
    image: nginx:alpine
    container_name: nz01
    ports:
      - 443:443
      - 80:80
    volumes:
      - ./src:/src
      - ./config/nginx:/etc/nginx/conf.d
      - ./config/certs:/etc/certs
    depends_on:
      - web
    networks:
      - djangonetwork
  web:
    build:
      context: .
      dockerfile: compose/django/Dockerfile
    container_name: dz01
    depends_on:
      - db
    volumes:
      - ./src:/src
    expose:
      - 8000
    links:
      - redis
    env_file:
      - ./.envs/.django
    networks:
      - djangonetwork
  db:
    build:
      context: .
      dockerfile: compose/postgres/Dockerfile
    container_name: pz01
    env_file:
      - ./.envs/.postgres
    volumes:
      - local_postgres_data:/var/lib/postgresql/data
      - local_postgres_data_backups:/backups
    networks:
      - djangonetwork
  redis:
    image: redis:alpine
    container_name: rz01
    ports:
      - "6379:6379"
    networks:
      - djangonetwork

networks:
  djangonetwork:
    driver: bridge

Im Browser erhalte ich die Fehlermeldung „502 Bad Gateway“ und ohne SSL läuft die Website einwandfrei. Was könnte das Problem sein?

Antwort1

Was ist also der Upstream?

Der Upstream wird hier definiert:

upstream web {  
  ip_hash;
  server web:443;
}

Mein erster Eindruck davon ist, dass Nginx keine ordnungsgemäße Verbindung zum Upstream-Server mit dem Namen herstellen kann web.

Dies kann mehrere Gründe haben:

  • Ihr Nginx kann nicht lösenweb
  • Der Webserver, auf dem ausgeführt wird, webstellt kein HTTPS/Port 443 bereit
  • Der Webserver verwendet webkein gültiges und vertrauenswürdiges Zertifikat für den Hostnamenweb

Werfen Sie einen Blick auf Ihre docker-compose.yml:

  • Die Anwendung webist auf Port 8000 verfügbar, Sie möchten aber eine Verbindung zu Port 443 in Nginx herstellen und verwenden dabei (vermutlich) auch das falsche Protokoll.

Die Lösung wäre also, Ihre Upstream-Konfiguration in nginx.conf wie folgt zu ändern:

upstream web {  
  ip_hash;
  server web:8000;
}

und der Standortblock wie folgt (https --> http):

location / {
    proxy_pass http://web/;
}

Bezüglich SSL/TLS mit Proxys/Upstreams: Bitte werfen Sie einen Blick in die Nginx-Dokumente dazu:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify

Antwort2

Ich habe ein ähnliches Setup in meiner Webanwendung, wo Nginx ein Reverse-Proxy für Dockerized Django und React ist. Ich verwende auch ein selbstsigniertes Zertifikat für SSL in der lokalen Entwicklung.

Ich hatte Schwierigkeiten, weil React (Next.js) Daten von Djangos REST-API abruft – aber einige Anfragen kommen vom Server, während andere vom Client kommen. Serverbasierte Anfragen konnten http://backend:8000(den Docker-Dienstnamen und den freigegebenen Port) verwenden, aber clientbasierte Anfragen mussten durch https://example.local.

Wenn jemand hier nicht weiterkommt und Swagger UI (z. B. drf-yasg) verwendet, war dies meine Achillesferse – Sie MÜSSEN die OpenAPI „DEFAULT_API_URL“ konfigurieren. Wenn Sie ein selbstsigniertes SSL-Zertifikat mit haben example.local, sollten Sie dies als Ihre Swagger-URL einrichten https://example.local. Mit drf-yasgist hier meine settings.py:

# Swagger
ENDPOINT_DOMAIN = "https://example.com"
if DEBUG:
    ENDPOINT_DOMAIN = "https://example.local"
SWAGGER_SETTINGS = {
    'SECURITY_DEFINITIONS': {
        'basic': {
            'type': 'basic'
        }
    },
    'DEFAULT_API_URL': ENDPOINT_DOMAIN,
}

Zusätzlich musste ich dies in meiner Next.js-Konfiguration anpassen ( next.config.js):

const nextConfig = {
  ...
  assetPrefix: 'https://example.local',
  ...
}

Schließlich sieht meine Nginx-Konfiguration folgendermaßen aus:

server {
  listen 80;
  listen [::]:80;

  server_name example.local;
  return 302 https://example.local$request_uri;
}

# Main server directive
server {
  http2               on;

  listen 443          default ssl;
  listen [::]:443     default ssl;

  ssl_certificate     /etc/nginx/certs/example.test.crt;
  ssl_certificate_key /etc/nginx/certs/example.test.key;

  root                /app;
  server_name         example.local;

  charset utf-8;

  gzip on;
  gzip_disable "msie6";
  gzip_comp_level 6;
  gzip_min_length 1100;
  gzip_buffers 16 8k;
  gzip_proxied any;
  gzip_types
    text/plain
    text/css
    text/js
    text/xml
    text/javascript
    application/javascript
    application/json
    application/xml
    application/rss+xml
    image/svg+xml;

  # Setup frontend requests to use port 3000
  location @frontend {
    internal;
    root       /app/frontend/;
    proxy_pass http://frontend:3000;

    proxy_redirect off;
    proxy_set_header Host              $host;
    proxy_set_header X-Forwarded-For   $remote_addr;
    proxy_set_header X-Forwarded-Host  $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-NginX-Proxy     true;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Url-Scheme      $scheme;
  }

  # Setup backend requests to use port 8000
  location @backend {
    proxy_pass http://backend:8000;

    proxy_redirect off;
    proxy_ssl_verify off;
    proxy_set_header Host              $host;
    proxy_set_header X-Forwarded-For   $remote_addr;
    proxy_set_header X-Forwarded-Host  $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-NginX-Proxy     true;
    proxy_set_header X-Real-IP         $remote_addr;
    proxy_set_header X-Url-Scheme      $scheme;
  }

  # Frontend =============================================
  location / {
    try_files $uri @frontend;
  }

  location ~ ^/assets/(.*)$ {
    root      /app/frontend/public/;
    try_files $uri @frontend;
  }

  location ~ ^/favicon(.*)$ {
    root      /app/frontend/public/assets/favicon/;
    try_files $uri @frontend;
  }

  location ~ ^/_next/(.*)$ {
    root      /app/frontend/;
    try_files $uri @frontend;
  }

  location /_next/webpack-hmr {
    root      /app/frontend/;
    try_files $uri @frontend;

    # Websockets
    proxy_http_version 1.1;
    proxy_set_header   Connection "upgrade";
    proxy_set_header   Upgrade $http_upgrade;
  }

  location /404 {
    try_files $uri @frontend;
  }


  # Backend ===============================================
  location ~ ^/swagger(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/redoc(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/admin(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/api(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/webmention(.*)$ {
    try_files $uri @backend;
  }

  location ~ ^/rss(.*)$ {
    try_files $uri @backend;
  }

  location /sitemap.xml {
    try_files $uri @backend;
  }

  location ~ ^/static/(.*)$ {
    root      /app/backend/;
    try_files $uri @backend;

    autoindex on;
  }

  location ~ ^/uploads/(.*)$ {
    root      /app/backend/;
    try_files $uri @backend;
  }

  location /(500|502|503|504) {
    try_files $uri @backend;
  }

  # Error handling
  error_page 404 /404;
  error_page 500 502 503 504 /500;
}

verwandte Informationen