%20fall%C3%B3%20(111%3A%20Conexi%C3%B3n%20rechazada)%20al%20conectarse%20al%20flujo%20ascendente%2C%20cliente%3A%20192.168.128.1%2C%20servidor%3A%20hello-1.local.png)
Estoy intentando configurar SSL en mi entorno Django + Docker + nginx. Sin embargo encontré este error:
*19 Error en la conexión () (111: Conexión rechazada) al conectarse al flujo ascendente, cliente: 192.168.128.1, servidor: hello-1.local, solicitud: "GET / HTTP/1.1", flujo ascendente: "https://192.168. 128.4:443/", anfitrión: "hola-1.local"
Mi configuración de 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;
}
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
En el navegador, aparece el error 502 Bad Gateway y sin SSL, el sitio web funciona bien. ¿Cual podría ser el problema?
Respuesta1
¿Cuál es entonces el upstream?
El upstream se define aquí:
upstream web {
ip_hash;
server web:443;
}
Mi primera lectura de esto es que Nginx no puede conectarse correctamente al servidor ascendente llamado web
.
Esto puede tener varias razones:
- tu Nginx no puede resolver
web
- el servidor web que se ejecuta
web
no sirve https/puerto 443 - el servidor web que se ejecuta
web
no utiliza un certificado válido y confiable para el nombre de hostweb
Echando un vistazo a tu docker-compose.yml:
- la aplicación
web
está expuesta al puerto 8000, pero desea conectarse al puerto 443 en Nginx, y también utiliza el protocolo incorrecto (supongo)
Entonces, la solución sería cambiar su configuración ascendente en nginx.conf de esta manera:
upstream web {
ip_hash;
server web:8000;
}
y el bloque de ubicación así (https --> http):
location / {
proxy_pass http://web/;
}
Con respecto a SSL/TLS con proxies/upstreams: eche un vistazo a los documentos de Nginx sobre esto:http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify
Respuesta2
Tengo una configuración similar en mi aplicación web donde Nginx es un proxy inverso para Dockerized Django y React. También estoy usando un certificado autofirmado para SSL en desarrollo local.
Estaba pasando por un momento difícil porque React (Next.js) está obteniendo datos de la API REST de Django, pero algunas solicitudes provienen del servidor mientras que otras provienen del cliente. Las solicitudes basadas en el servidor podían utilizar http://backend:8000
(el nombre del servicio Docker y el puerto expuesto), pero las solicitudes basadas en el cliente debían pasar por https://example.local
.
Si alguien está atascado en esto y usa Swagger UI (es decir, drf-yasg), este fue mi talón de Aquiles: NECESITA configurar OpenAPI "DEFAULT_API_URL". Si tiene un certificado SSL autofirmado con example.local
, debe configurarlo https://example.local
como su URL Swagger. Con drf-yasg
, aquí está mi 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,
}
Además, tuve que hacer coincidir esto en mi configuración de Next.js ( next.config.js
):
const nextConfig = {
...
assetPrefix: 'https://example.local',
...
}
Finalmente, mi configuración de Nginx se ve así:
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;
}