现在的情况:

现在的情况:

现在的情况:

我有一个 Triple-O OpenStack 安装 (Liberty),其中甚至“公共”网络也位于私有环境 (10.24.7.0/24 网络) 中。访问该网络的唯一方法是通过网关主机。我想使用反向代理使 Horizo​​n 可从互联网访问。出于安全考虑,所有外部通信都应通过 HTTPS 加密。反向代理应用作 SSL 终止主机,所有内部流量都应未加密。

OpenStack 部署未配置为使用 SSL/TLS,并且不知道“公共”网络实际上并不是公共的。

我目前正在尝试使用 Nginx 作为反向代理,但如果其他反向代理软件能够解决我的问题,那么也可以使用它们。

网关主机运行的是 RHEL 7.2,Nginx 从官方 Nginx repo 安装,版本号 1.11.1(主线)。

网关.example.com是示例中使用的 FQDN,
1.2.3.4是示例中使用的网关主机的外部 IP 地址
10.24.7.9是 Triple-O 安装的“公共”端点

迄今的工作:

  • http://gateway.example.com加载 index.html,可以从中下载用于签署服务器证书的 CA 的证书。
  • 由于 OpenStack 安装不知道它位于 SSL 终端点后面,因此我必须重写内容中的链接。这是通过两个 sub_filter 指令完成的,一个是通用的 ( sub_filter 'http://$host' 'https://$host';),另一个是替换 OpenStack 端点 IP ( sub_filter 'http://10.24.7.9' 'https://$host';)
  • Horizo​​n 的功能console允许用户通过 Horizo​​n 中嵌入的 NoVNC 连接到实例的串行控制台。NoVNC 使用 websockets 在浏览器和实例运行的物理主机之间建立双向 TCP 连接。为了支持此功能,我必须配置 Nginx 以允许 HTTP 连接升级并监听端口 6080。
  • iptables允许端口 80、443 和 6080 上的流量。

问题:

  • 在显示实例详细信息的 Horizo​​n 页面上,不会显示选项卡的主体(概览、日志、控制台、操作日志),而是重复选项卡行,并且仅显示概览选项卡的内容。重复标签
  • 实例控制台连接失败,错误代码为 1006。(检索到使控制台显示在其自己的浏览器选项卡中所需的 URL,并将nova get-vnc-console <ID> novnc端点 IP 替换为 FQDN。)我怀疑此错误是由于从 HTTP1.1 升级到 websocket 标准的连接包含有关“公共”接口的信息,该接口无法直接从浏览器访问,或者由于配置的服务器地址/主机名(“公共”)与请求中的地址(代理名称/IP)不匹配,NoVNC 软件拒绝了连接。这两种情况都是推测。NoVNC 错误

Nginx 配置文件

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

有人有这种设置的工作配置吗?我想坚持使用 Nginx,但可以更改为 Apache 或任何其他可以提供解决方案的软件。

编辑:澄清 CA 的使用,增加了有关 NoVNC 连接失败的怀疑

答案1

我也解决了第一个问题。这种奇怪行为的原因是反向代理丢弃了请求的查询部分(? 后面的所有内容)。这又是由于错误配置的 proxy_pass 行造成的。

解决方案是/$uri从配置文件中的两个 proxy_pass 行中删除(详细信息请参阅http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass)。

这是一个可行的解决方案:

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

答案2

通过更改一些配置选项,我能够解决第二个问题(错误 1006)。由于另一个问题仍然存在,我无法确认 NoVNC 控制台是否在 Horizo​​n UI 中工作,但当我直接调用 NoVNC URL 时,我获得了连接并可以与实例交互。

这是迄今为止可行的解决方案:

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

总结

更改:
在端口 443 和 6080 的两个服务器块中我都添加了proxy_set_header Origin http://$host;。不知道这到底是做什么的,但它解决了我的问题。

这仍然留给我第一个问题。

答案3

我在为此苦苦挣扎了一段时间后偶然发现了这一点。这真的帮了我大忙。但是 nginx 不喜欢 http://$host 等周围的 ` 引号。当你删除它们时,它就可以正常工作了。例如,这对我来说是一个有效的配置:

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

我发布此信息是因为也许有人正在寻找更新的答案。

相关内容