OpenStack Horizon por trás do proxy reverso (nginx preferido)

2

Situação atual:

Eu tenho uma instalação do Triple-O OpenStack (Liberty) onde até mesmo a rede "pública" está em um ambiente privado (rede 10.24.7.0/24). A única maneira de obter acesso a essa rede é através de um host de gateway. Eu gostaria de tornar o Horizon acessível a partir da internet usando um proxy reverso. Devido a preocupações de segurança, toda a comunicação externa deve ser criptografada via HTTPS. O proxy reverso deve ser usado como host de terminação SSL e todo o tráfego interno deve ser descriptografado.

A implantação do OpenStack não foi configurada para usar SSL / TLS e não sabe que a rede "pública" não é realmente pública.

Atualmente, estou tentando usar o Nginx como proxy reverso, mas o uso de outro software de proxy reverso também é possível se eles fornecerem uma solução para o meu problema.

O host do gateway está executando o RHEL 7.2, o Nginx é instalado a partir do repositório oficial do Nginx na versão 1.11.1 (mainline).

gateway.example.com é o FQDN usado nos exemplos,
1.2.3.4 é o endereço IP externo do host do gateway usado nos exemplos < br> 10.24.7.9 é o ponto final "público" da instalação Triple-O

Trabalhe até agora:

  • http://gateway.example.com carrega o index.html onde o certificado da CA usado para assinar o certificado do servidor pode ser baixado.
  • Devido ao fato de que a instalação do OpenStack não sabe que está por trás de um ponto de terminação SSL, tenho que reescrever links no conteúdo. Isso é feito com duas diretivas de sub_filter, uma genérica ( sub_filter 'http://$host' 'https://$host'; ) e outra que substitui o IP de ponto de extremidade do OpenStack ( sub_filter 'http://10.24.7.9' 'https://$host'; )
  • O recurso console do Horizon permite que um usuário se conecte ao console serial de uma instância por meio do NoVNC incorporado no Horizon. O NoVNC usa websockets para estabelecer uma conexão TCP bidirecional entre o navegador e o host phyical no qual a instância é executada. Para suportar isso, tive que configurar o Nginx para permitir atualizações de conexão HTTP e para ouvir a porta 6080.
  • iptables permite o tráfego nas portas 80, 443 e 6080.

Problemas:

  • Na página Horizon mostrando detalhes para uma instância em vez de mostrar o corpo de uma guia (visão geral, log, console, log de ações), a linha da guia é repetida e apenas o conteúdo da guia de visão geral é exibido.
  • Conexõescomoconsoledeumainstânciafalhamcomoerro1006.(AURLnecessáriaparaobteroconsoleexibidoemsuaprópriaguiadonavegadorfoirecuperadacomnovaget-vnc-console<ID>novncesubstituindooIPdoterminalpeloFQDN.)SuspeitoqueesseerroécausadodevidoaofatodequeaconexãoquefoiatualizadadoHTTP1.1paraopadrãowebsocketcontéminformaçõessobreainterface"pública" que não pode ser acessada diretamente do navegador OU que a conexão é recusada pelo software NoVNC devido a uma incompatibilidade entre o endereço do servidor configurado / hostname ("public") e o endereço na solicitação (nome do proxy / IP). Ambas são uma especulação.

ArquivodeconfiguraçãoNginx

ssl_certificate/etc/nginx/certs/gateway.example.com.crt;ssl_certificate_key/etc/nginx/certs/gateway.example.com.key;ssl_dhparam/etc/nginx/certs/dh.pem;ssl_protocolsTLSv1.2TLSv1.1;ssl_ciphersAES256+EECDH:AES128+EECDH:!aNULL:!eNULL:!ECDSA:!SHA:!DSS;ssl_prefer_server_cipherson;ssl_session_cacheshared:SSL:10m;ssl_session_timeout10m;server{#httpserver_namegateway.example.comlocalhost1.2.3.4;listen*:80;root/usr/share/nginx/html;location/{indexindex.html;}location~^/dashboard{return302'https://$host$request_uri';}location~^/console{return302'https://$host:6080$request_uri';}location~^/websockify{return302'https://$host:6080$request_uri';}}server{#httpsserver_namegateway.example.comlocalhost1.2.3.4;listen*:443;sslon;location/{sub_filter''http://10.24.7.9''''https://$host'';sub_filter''http://$host''''https://$host'';sub_filter_last_modifiedon;sub_filter_onceoff;sub_filter_types*;proxy_pass'http://10.24.7.9/$uri';proxy_request_bufferingoff;proxy_http_version1.1;proxy_set_headerUpgrade$http_upgrade;proxy_set_headerConnection"upgrade";  
    proxy_set_header         Host                              $host;  
    proxy_set_header         Accept-Encoding                   "";  
    proxy_set_header         X-Real-IP                         $remote_addr;  
    proxy_set_header         X-Forwarded-Host                  $host;  
    proxy_set_header         X-Forwarded-Server                $host;  
    proxy_set_header         X-Forwarded-Proto                 $scheme;  
    proxy_set_header         X-Forwarded-For                   $proxy_add_x_forwarded_for;  
    proxy_connect_timeout    90;  
    proxy_send_timeout       90;  
    proxy_read_timeout       90;  
  }  
}  

server { # https on port 6080 for novnc  
  server_name                gateway.example.com localhost 1.2.3.4;  
  listen                     *:6080;  
  ssl                        on;  

  location / {  
    proxy_pass               'http://10.24.7.9:6080/$uri';  
    proxy_request_buffering  off;  
    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-Host   $host;  
    proxy_set_header         X-Forwarded-Server $host;  
    proxy_set_header         X-Forwarded-Proto  $scheme;  
    proxy_set_header         X-Forwarded-For    $proxy_add_x_forwarded_for;  
 #    proxy_connect_timeout    90;  
 #    proxy_send_timeout       90;  
 #    proxy_read_timeout       90;  
  }  
}  

Alguém tem uma configuração funcional para esse tipo de configuração? Eu gostaria de ficar com o Nginx, mas posso fazer a mudança para o Apache ou qualquer outro software que possa fornecer uma solução.

Editar: esclareceu o uso da CA, adicionou suspeitas sobre falha na conexão NoVNC

    
por Gerald Schneider 29.06.2016 / 17:45

3 respostas

0

Eu também consegui resolver o primeiro problema. A razão para esse comportamento estranho foi causada porque o proxy reverso caiu a parte de consulta da solicitação (tudo por trás do?). Isso novamente foi causado por linhas proxy_pass configuradas incorretamente.

A solução para isso foi remover /$uri das duas linhas proxy_pass no arquivo de configuração (veja detalhes link ).

Esta é uma solução funcional:

ssl_certificate /etc/nginx/certs/gateway.example.com.crt;  
ssl_certificate_key /etc/nginx/certs/gateway.example.com.key;  
ssl_dhparam /etc/nginx/certs/dh.pem;  
ssl_protocols TLSv1.2 TLSv1.1;  
ssl_ciphers AES256+EECDH:AES128+EECDH:!aNULL:!eNULL:!ECDSA:!SHA:!DSS;  
ssl_prefer_server_ciphers on;  
ssl_session_cache shared:SSL:10m;  
ssl_session_timeout 10m;  

server { # http  
  server_name gateway.example.com localhost 1.2.3.4;  
  listen *:80;  
  root /usr/share/nginx/html;  

  location / {  
    index index.html;  
  }  

  location ~ ^/dashboard {  
    return 302 'https://$host$request_uri';  
  }  

  location ~ ^/console {  
    return 302 'https://$host:6080$request_uri';  
  }  

  location ~ ^/websockify {  
    return 302 'https://$host:6080$request_uri';  
  }  
}  

server { # https  
  server_name gateway.example.com localhost 1.2.3.4;  
  listen *:443;  
  ssl on;  

  location / {  
    sub_filter ''http://10.24.7.9'' ''https://$host'';  
    sub_filter ''http://$host'' ''https://$host'';  
    sub_filter_last_modified on;  
    sub_filter_once off;  
    sub_filter_types *;  
    proxy_pass 'http://10.24.7.9';  
    proxy_request_buffering off;  
    proxy_http_version 1.1;  
    proxy_set_header Upgrade $http_upgrade;  
    proxy_set_header Connection "upgrade";  
    proxy_set_header Host $host;  
    proxy_set_header Origin 'http://$host';  
    proxy_set_header Accept-Encoding "";  
    proxy_set_header X-Real-IP $remote_addr;  
    proxy_set_header X-Forwarded-Host $host;  
    proxy_set_header X-Forwarded-Server $host;  
    proxy_set_header X-Forwarded-Proto $scheme;  
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
    proxy_connect_timeout 90;  
    proxy_send_timeout 90;  
    proxy_read_timeout 90;  
  }  
}  

server { # https on port 6080 for novnc  
  server_name gateway.example.com localhost 1.2.3.4;  
  listen *:6080;  
  ssl on;  

  location / {  
  proxy_pass 'http://10.24.7.9:6080';  
  proxy_request_buffering off;  
  proxy_http_version 1.1;  
  proxy_set_header Upgrade $http_upgrade;  
  proxy_set_header Connection "upgrade";  
  proxy_set_header Host $host;  
  proxy_set_header Origin 'http://$host';  
  proxy_set_header X-Real-IP $remote_addr;  
  proxy_set_header X-Forwarded-Host $host;  
  proxy_set_header X-Forwarded-Server $host;  
  proxy_set_header X-Forwarded-Proto $scheme;  
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
  # proxy_connect_timeout 90;  
  # proxy_send_timeout 90;  
  # proxy_read_timeout 90;  
  }  
}  
    
por 02.07.2016 / 15:39
0

Consegui resolver o segundo dos problemas (erro 1006) alterando algumas das opções de configuração. Como o outro problema ainda persiste, não posso confirmar que o console NoVNC funciona dentro da interface do Horizon, mas quando eu chamo a URL do NoVNC diretamente, obtenho uma conexão e posso interagir com a instância.

Esta é a solução de trabalho até agora:

ssl_certificate /etc/nginx/certs/gateway.example.com.crt;  
ssl_certificate_key /etc/nginx/certs/gateway.example.com.key;   
ssl_dhparam                /etc/nginx/certs/dh.pem;  
ssl_protocols              TLSv1.2 TLSv1.1;  
ssl_ciphers                AES256+EECDH:AES128+EECDH:!aNULL:!eNULL:!ECDSA:!SHA:!DSS;  
ssl_prefer_server_ciphers  on;  
ssl_session_cache          shared:SSL:10m;  
ssl_session_timeout        10m;  

server { # http  
  server_name                 gateway.example.com localhost 1.2.3.4;  
  listen                      *:80;  
  root                        /usr/share/nginx/html;  

  location / {  
    index                     index.html;  
  }  

  location ~ ^/dashboard {  
    return                    302     'https://$host$request_uri';  
  }  

  location ~ ^/console {  
    return                    302     'https://$host:6080$request_uri';  
  }  

  location ~ ^/websockify {  
    return                    302     'https://$host:6080$request_uri';  
  }  
}  

server { # https  
  server_name                gateway.example.com localhost 1.2.3.4;  
  listen                     *:443;  
  ssl                        on;  

  location / {  
    sub_filter               ''http://10.24.7.9''    ''https://$host'';  
    sub_filter               ''http://$host''        ''https://$host'';  
    sub_filter_last_modified on;  
    sub_filter_once          off;  
    sub_filter_types         *;  
    proxy_pass               'http://10.24.7.9/$uri';  
    proxy_request_buffering  off;  
    proxy_http_version       1.1;  
    proxy_set_header         Upgrade                           $http_upgrade;  
    proxy_set_header         Connection                        "upgrade";  
    proxy_set_header         Host                              $host;  
    proxy_set_header         Origin                            'http://$host';  
    proxy_set_header         Accept-Encoding                   "";  
    proxy_set_header         X-Real-IP                         $remote_addr;  
    proxy_set_header         X-Forwarded-Host                  $host;  
    proxy_set_header         X-Forwarded-Server                $host;  
    proxy_set_header         X-Forwarded-Proto                 $scheme;  
    proxy_set_header         X-Forwarded-For                   $proxy_add_x_forwarded_for;  
    proxy_connect_timeout    90;  
    proxy_send_timeout       90;  
    proxy_read_timeout       90;  
  }  
}  

server { # https on port 6080 for novnc  
  server_name                gateway.example.com localhost 1.2.3.4;  
  listen                     *:6080;  
  ssl                        on;  

  location / {  
    proxy_pass               'http://10.24.7.9:6080/$uri';  
    proxy_request_buffering  off;  
    proxy_http_version       1.1;  
    proxy_set_header         Upgrade            $http_upgrade;  
    proxy_set_header         Connection         "upgrade";  
    proxy_set_header         Host               $host;  
    proxy_set_header         Origin             'http://$host';  
    proxy_set_header         X-Real-IP          $remote_addr;  
    proxy_set_header         X-Forwarded-Host   $host;  
    proxy_set_header         X-Forwarded-Server $host;  
    proxy_set_header         X-Forwarded-Proto  $scheme;  
    proxy_set_header         X-Forwarded-For    $proxy_add_x_forwarded_for;  
 #    proxy_connect_timeout    90;  
 #    proxy_send_timeout       90;  
 #    proxy_read_timeout       90;  
  }  
}  

tl; dr

Alterações:
Nos dois blocos de servidor para as portas 443 e 6080, adicionei proxy_set_header Origin http://$host; . Não sei exatamente o que isso está fazendo, mas resolveu meu problema.

Isso ainda me deixa com o primeiro problema.

    
por 30.06.2016 / 15:13
0

Eu tropecei nisso enquanto eu estava lutando com isso por um tempo também. E isso realmente me ajudou. No entanto nginx não gosta das 'citações em torno do host http: // $ etc. Quando você remove as que funciona. Esta é uma configuração de trabalho para mim, por exemplo:

ssl_certificate /etc/ssl/cert.pem;
ssl_certificate_key /etc/ssl/cert.key;
ssl_ciphers HIGH:!RC4:!MD5:!aNULL:!eNULL:!EXP:!LOW:!MEDIUM;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;

server { # http
  server_name openstack.example.com;
  listen *:80;

  location / {
    return 302 https://$host$request_uri;
  }

  location ~ ^/console {
    return 302 https://$host:6080$request_uri;
  }

  location ~ ^/websockify {
    return 302 https://$host:6080$request_uri;
  }
}

server { # https
  server_name openstack.example.com;
  listen *:443;
  ssl on;

  location / {
    sub_filter 'http://192.168.0.200:6080' 'https://$host:6080';
    sub_filter 'http://$host:6080' 'https://$host:6080';
    sub_filter_last_modified on;
    sub_filter_once off;
    sub_filter_types *;
    proxy_pass http://192.168.0.200;
    proxy_request_buffering off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header Origin http://$host;
    proxy_set_header Accept-Encoding "";
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_read_timeout 90;
  }
}

server { # https on port 6080 for novnc
  server_name openstack.example.com;
  listen *:6080;
  ssl on;

  location / {
    proxy_pass http://192.168.0.200:6080;
    proxy_request_buffering off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_set_header Origin http://$host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_read_timeout 90;
  }
}

Estou postando isso porque talvez alguém esteja procurando uma resposta atualizada.

    
por 03.11.2017 / 17:14