Tag: proxmox

  • Configuração do nginx como proxy reverso para WordPress, Nextcloud e Proxmox

    Nenhuma das publicações sobre instalação de WordPress ou Nextcloud aborda acesso via HTTPS ou certificados SSL, apenas HTTP.

    Acontece que isso é centralizado em uma instalação do nginx, atuando como proxy reverso. O servidor que hospeda o nginx e o servidor de OpenVPN são a mesma máquina: um VPS com 512mb de RAM e 1vCPU.

    O nginx recebe as requisições em HTTPS e as encaminha em HTTP* de forma segura para os outros servidores – clientes da VPN: WordPress, Nextcloud e Proxmox – 3 máquinas diferentes.

    * Proxmox usa HTTPS por padrão mas com um certificado verificado por uma CA interna

    Vantagens:

    • só é necessário gerenciar os certificados em um servidor, independente de quantos sites são.
    • as 3 máquinas diferentes poderiam estar em qualquer rede, qualquer lugar – isso é, se não fossem virtualizadas dentro do Proxmox, podendo até ser uma rede residencial que bloqueia tráfego de entrada (muito obrigado, Claro), basta se conectar na VPN.

    Desvantagem:

    • existe um pouco de latência devido à distância entre as máquinas (Rio de Janeiro) e o VPS (São Paulo).

    Ainda que fosse possível abrir as portas na rede e o OpenVPN não fosse necessário, usar o nginx como um proxy reverso na mesma LAN ainda poderia ser vantajoso pelo o gerenciamento centralizado dos certificados SSL, logs de acesso e uso de múltiplos nomes de domínio em diferentes servidores pro mesmo IP na mesma porta.

    Os arquivos de configuração do nginx para cada site devem ficar localizados em /etc/nginx/sites-available e para habilitá-los basta criar um symlink em /etc/nginx/sites-enabled com:

    # ln -s /etc/nginx/sites-available/sua_config /etc/nginx/sites-enabled/

    A primeira configuração recomendada é para receber a solicitação HTTP na porta 80 e redirecionar o cliente para fazer uma solicitação HTTPS na porta padrão 443.

    server {
        listen 80 default_server;
        server_name _;
        return 301 https://$host$request_uri;
    }

    Em todos os exemplos de configuração abaixo, substitua o nome do servidor (FQDN), o caminho para o certificado e chave SSL e o IP privado para onde deve ser encaminhada a solicitação.

    Como mencionado, é possível usar a mesma porta para todos os servidores, como a porta padrão HTTPS, desde que cada um tenha o parâmetro server_name diferente, cada um com um nome de domínio (FQDN).

    Configuração para o Proxmox:

    upstream proxmox {
        server "seuproxmox.dominio.com";
    }
    
    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        server_name seuproxmox.dominio.com;
        ssl_certificate /etc/letsencrypt/live/seu.dominio.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/seu.dominio.com/privkey.pem;
        proxy_redirect off;
        location / {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_pass https://10.8.0.2:8006;
            proxy_buffering off;
            client_max_body_size 0;
            proxy_connect_timeout  3600s;
            proxy_read_timeout  3600s;
            proxy_send_timeout  3600s;
            send_timeout  3600s;
        }
    }

    Para o Nextcloud:

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        ssl_certificate /etc/letsencrypt/live/seu.dominio.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/seu.dominio.com/privkey.pem;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        add_header X-Content-Type-Options "nosniff";
        server_name seunextcloud.dominio.com;
        location / {
            proxy_pass http://10.8.0.3;
            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_redirect off;
        }
        send_timeout 1800;
    }

    Configurações adicionais são recomendadas no lado do servidor Nextcloud, no arquivo /var/www/nextcloud/config/config.php

      'trusted_proxies' =>
      array (
        0 => '10.8.0.1',
      ),
      'overwritehost' => 'seunextcloud.dominio.com',
      'overwriteprotocol' => 'https',
      'overwritecondaddr' => '^10\\.8\\.0\\.1$',
      'overwritewebroot' => '/',
      'overwrite.cli.url' => 'https://seunextcloud.dominio.com',

    Para o WordPress:

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        ssl_certificate /etc/letsencrypt/live/seu.dominio.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/seu.dominio.com/privkey.pem;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        add_header X-Content-Type-Options "nosniff";
        server_name seuwordpress.dominio.com;
        location / {
            proxy_pass http://10.8.0.4;
            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_redirect off;
        }
        send_timeout 1800;
    }

    Configurações adicionais são requeridas no lado do servidor do WordPress, no arquivo /var/www/html/wp-config.php

    define('WP_HOME', 'https://seuwordpress.dominio.com');
    define('WP_SITEURL', 'https://seuwordpress.dominio.com');
    
    if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
        $_SERVER['HTTPS'] = 'on';
    }
    
    if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
        $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
    }

    Sugestão de configuração adicional para o WordPress – o WordPress não tem um mecanismo de proteção contra tentativas de acesso por força bruta. Para mitigar isso, além de usar boas senhas, você pode limitar o acesso por IP às localizações /wp-admin e /wp-login.php na configuração do proxy reverso adicionando essa configuração:

    server {
        location ~* ^/(wp-admin|wp-login.php) {
            allow 186.205.1.165;    # seu IP de casa
            allow 191.252.110.50;    # seu IP do trabalho
            deny all;
            proxy_pass http://10.8.0.4;
            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;
        }
    }

    Por conveniência, você também pode fazer o nginx escutar pra solicitações a HTTP na porta 80 e redirecionar todos os clientes para uma solicitação HTTPS:

    server {
        listen 80 default_server;
        server_name _;
        return 301 https://$host$request_uri;
    }

    Após configurado, inicie o serviço.

    # systemctl enable --now nginx

    Caso ainda não tenha certificados SSL válidos, eles podem ser obtidos gratuitamente com a Let’s Encrypt, uma organização sem fins lucrativos, com o comando certbot. Primeiro, pare o serviço nginx, já que o certbot vai criar um processo que também vai escutar na porta 80. Então, use o comando nesse formato:

    # certbot certonly --standalone -d seu.dominio.com -d seunextcloud.dominio.com -d seuproxmox.dominio.com -d seuwordpress.dominio.com

    Siga os prompts do programa e, ao terminar, inicie o nginx.service novamente.

    Caso esteja usando o proxy reverso para servidores dentro de uma VPN, você pode querer ver isso aqui.