ldurans / izing.open.io

Chats Whatsapp multisessões
500 stars 278 forks source link

Problema Websocket através de Proxy Reverso #217

Closed cdaher78 closed 1 week ago

cdaher78 commented 1 month ago

Cenário

Meu cenário de instalação está numa VM local (frontend e backend) com banco de dados e redis em Container e uma outra VM com NGINX numa DMZ atuando como proxy reverso para publicação em domínio externo. Não tenho intensão de colocar o sistema numa VPS pois tenho uma infraestrutura para atender esta demanda.

Utilizado para deploy o método de instalação local sugerido: https://github.com/cleitonme/izing.local

Alguns pontos:

Inspecionando o site, acessado por fora, me aparece a seguinte mensagem no console:

Mixed Content: The page at '<URL>' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws:<URL>/socket.io/?EIO=4&transport=websocket'. This request has been blocked; this endpoint must be available over WSS.

Configuração do proxy reverso (nginx):

upstream websocket {
    server vsrv-izing:3000; # Replace with your WebSocket server's IP and port
}

server {
    listen 80;
    server_name meudominio.com.br;
    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 80;
    server_name api.meudominio.com.br;
    # Redirect HTTP to HTTPS
    return 301 https://$host$request_uri;  
}

server {
    listen 443 ssl;
    server_name meudominio.com.br;

    root /home/deploy/izing.io/frontend/dist/pwa; # caminho da pasta dist/pwa

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    underscores_in_headers on;

    index index.html;
    charset utf-8;

    # Configuration for HTTP requests
    location / {
        proxy_pass http://vsrv-izing:4000;

        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        proxy_pass_request_headers on;

    }

    # SSL settings
    ssl_certificate /etc/letsencrypt/live/meudominio.com.br/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/meudominio.com.br/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    listen 443 ssl;
     server_name api.meudominio.com.br;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";
    underscores_in_headers on;

    index index.html;
    charset utf-8;

    #Configuration for HTTP requests
    location / {
        proxy_pass http://websocket;

        # WebSocket support
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass_request_headers on;
        proxy_cache_bypass $http_upgrade;
    }

    #SSL settings
    ssl_certificate /etc/letsencrypt/live/api.meudominio.com.br/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/api.meudominio.com.br/privkey.pem; # managed by Certbot

Caso precise usar um certificado local para criar o nível de segurança exigido, como posso agregar um certificado e chave privada no backend para que a conexão Websocket seja segura (wss)?

Alguém com o mesmo tipo de problema poderia elucidar o que necessita ser feito?

Desde já agradeço.

LuizMarroni commented 1 month ago

Passei pelo mesmo problema e o que resolveu foi configurar o npm da seguinte forma:

Configuração NPM

Além disso, a configuração do meu Nginx no backend para realizar o proxy_pass está assim:

server {
    listen 80;
    server_name izing.com.br;
    return 301 https://$server_name$request_uri; # Redireciona HTTP para HTTPS
}

server {
    listen 443 ssl;
    server_name izing.com.br;

    ssl_certificate /etc/ssl/certs/izing.com.br.crt;
    ssl_certificate_key /etc/ssl/private/izing.com.br.key;

    client_max_body_size 500M;

    location / {
        proxy_pass http://localhost:8081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

No arquivo .env do backend, as configurações são:

# Porta utilizada para proxy com o serviço do backend
PROXY_PORT=443

# Porta que o serviço do backend deverá ouvir
PORT=8081

Eu tive uma má experiência com o certbot, então acabei utilizando apenas o openssl. Para facilitar a configuração, ainda uso o npm. Configurei backend e frontend em um único domínio, diferenciando os dois pelo path /api (ex.: dominio.com.br/api). Também configurei o */socket.io/.

Configuração do Rewrite

Para isso, apliquei um rewrite no /api, mas não no socket.io. Isso me poupou de criar outro DNS. Além disso, configurei estas opções adicionais:

Configurações Adicionais


Espero que ajude!

cdaher78 commented 1 month ago

Boa @LuizMarroni, vou tentar colocar em prática.

Muito obrigado por compartilhar sua experiencia e solução.

Forte abraço!

cdaher78 commented 3 weeks ago

@LuizMarroni, refiz toda minha instalação conforme sugestão e ainda continuo com o mesmo problema Mixed Content: The page at '<URL>' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws:<URL>/socket.io/?EIO=4&transport=websocket'. This request has been blocked; this endpoint must be available over WSS.

Config do .env do Backend:

NODE_ENV=dev
BACKEND_URL=http://vsrv-izing
FRONTEND_URL=http://vsrv-izing:4000

PROXY_PORT=443
PORT=3000

Config do .env do Frontend:

VUE_URL_API=http://vsrv-izing:443
VUE_FACEBOOK_APP_ID='23156312477653241'

Config no NPM:

image

image

image

image

LuizMarroni commented 3 weeks ago

Opa, tudo certinho? Verifiquei a sua configuração, vi que você colocou o caminho dentro do servidor ubuntu no location, o correto seria colocar a mesma coisa que está configurado dentro do .env do frontend, aqui no caso:

VUE_URL_API=http://vsrv-izing:443

E outra coisa também, ao que parece você está utilizando um dns, dentro do VUE URL API você precisa colocar o dns da api, e nao o nome da maquina, já que quem vai realizar as requisições não está na mesma rede que o backend, então vamos supor que o seu dns é teste.com.br

a configuração deveria estar assim:

VUE_URL_API=https://teste.com.br/api

e o env do backend assim:

`NODE_ENV=dev BACKEND_URL=https://teste.com.br/api FRONTEND_URL=https://teste.com.br

PROXY_PORT=443 PORT=3000`

e dentro da configuração do npm que você enviou:

image

o location para a porta 3000 do seu servidor deveria ser /api o mesmo que está dentro do .env do backend e do frontend, e o erro que está apontando ali dentro do seu console é por que o endpoint é em http e o frontend é em https, os dois devem estar em https, por isso que você aponta o /api, para ficar no mesmo dns, assim facilitando a manutenção

cdaher78 commented 3 weeks ago

@LuizMarroni tu é fera demais man!! Deu certo aqui!

Mais uma vez muito obrigado pela força!

LuizMarroni commented 3 weeks ago

Tranquilo cara! Que bom que deu certo, qualquer coisa só chamar!