업스트림에 연결하는 동안 Nginx connect()가 실패했습니다(111: 연결이 거부됨), 클라이언트: 192.168.128.1, 서버: hello-1.local

업스트림에 연결하는 동안 Nginx connect()가 실패했습니다(111: 연결이 거부됨), 클라이언트: 192.168.128.1, 서버: hello-1.local

django + docker + nginx 환경에서 SSL을 설정하려고 합니다. 그러나 다음 오류가 발생했습니다.

*19 업스트림에 연결하는 동안 connect()가 실패했습니다(111: 연결이 거부됨), 클라이언트: 192.168.128.1, 서버: hello-1.local, 요청: "GET / HTTP/1.1", 업스트림: "https://192.168. 128.4:443/", 호스트: "hello-1.local"

내 Nginx 구성:

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;
    
} 

도커-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

브라우저에서 502 Bad Gateway 오류가 발생하고 SSL이 없어도 웹사이트는 잘 실행됩니다. 무엇이 문제일까요?

답변1

그렇다면 업스트림은 무엇입니까?

업스트림은 다음과 같이 정의됩니다.

upstream web {  
  ip_hash;
  server web:443;
}

내가 처음 읽은 내용은 Nginx가 이름이 지정된 업스트림 서버에 제대로 연결할 수 없다는 것입니다 web.

여기에는 여러 가지 이유가 있을 수 있습니다.

  • Nginx를 해결할 수 없습니다web
  • 실행 중인 웹 서버가 webhttps/포트 443을 제공하지 않습니다.
  • 실행 중인 웹 서버가 web호스트 이름에 대해 유효하고 신뢰할 수 있는 인증서를 사용하지 않습니다.web

docker-compose.yml을 살펴보세요.

  • 응용 프로그램은 web포트 8000에 노출되어 있지만 잘못된 프로토콜을 사용하여 Nginx의 포트 443에 연결하려고 합니다.

따라서 해결책은 nginx.conf에서 upstream-config를 다음과 같이 변경하는 것입니다.

upstream web {  
  ip_hash;
  server web:8000;
}

다음과 같은 위치 블록(https --> http):

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

프록시/업스트림이 포함된 SSL/TLS 관련: 이에 대한 Nginx-docs를 살펴보십시오.http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify

답변2

Nginx가 Dockerized Django 및 React의 역방향 프록시인 웹 애플리케이션에도 비슷한 설정이 있습니다. 또한 로컬 개발에서는 SSL용 자체 서명 인증서를 사용하고 있습니다.

React(Next.js)가 Django의 REST API에서 데이터를 가져오기 때문에 어려움을 겪고 있었습니다. 하지만 일부 요청은 서버에서 오고 다른 요청은 클라이언트에서 옵니다. 서버 기반 요청은 (Docker 서비스 이름 및 노출된 포트)를 사용할 수 있었지만 http://backend:8000클라이언트 기반 요청은 https://example.local.

누군가 이것에 갇혀 있고 Swagger UI(예: drf-yasg)를 사용하고 있다면 이것이 나의 아킬레스건이었습니다. OpenAPI "DEFAULT_API_URL"을 구성해야 합니다. 을(를) 사용하여 자체 서명된 SSL 인증서가 있는 경우 Swagger URL로 example.local설정해야 합니다 . 을 https://example.local사용하면 drf-yasg다음과 같습니다 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,
}

또한 Next.js 구성( )에서 이를 일치시켜야 했습니다 next.config.js.

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

마지막으로 내 Nginx 구성은 다음과 같습니다.

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;
}

관련 정보