反向代理背后的OpenStack Horizo​​n(首选nginx)

现在的情况:

我有一个Triple-O OpenStack安装(Liberty),甚至连“公共”networking都在私有环境(10.24.7.0/24networking)中。 访问该networking的唯一方法是通过网关主机。 我希望使用反向代理从互联网访问Horizo​​n。 由于安全问题,所有外部通信应通过HTTPS进行encryption。 反向代理应该用作SSL终止主机,并且所有内部通信应该是未encryption的。

OpenStack部署未configuration为使用SSL / TLS,并不知道“公共”networking并非真正公开。

我目前正在尝试使用Nginx作为反向代理,但如果他们提供了解决我的问题的方法,也可以使用其他反向代理软件。

网关主机正在运行RHEL 7.2,Nginx从官方的Nginx仓库安装在版本1.11.1(主线)上。

gateway.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'; ),另一个replaceOpenStack端点IP( sub_filter 'http://10.24.7.9' 'https://$host';
  • Horizo​​n的consolefunction允许用户通过embedded在Horizo​​n中的NoVNC连接到实例的串行控制台。 NoVNC使用websocket在浏览器和运行实例的物理主机之间build立一个双向的TCP连接。 为了支持这一点,我不得不configurationNginx来允许HTTP连接升级,并听取端口6080。
  • iptables允许端口80,443和6080的stream量。

问题:

  • 在Horizo​​n页面上显示实例的详细信息,而不是显示选项卡的主体(概述,日志,控制台,操作日志),选项卡行将重复,只显示概览选项卡的内容。 重复标签
  • 与实例的控制台的连接失败,错误1006.(获取控制台在其自己的浏览器选项卡中显示的所需URL使用nova get-vnc-console <ID> novnc并用FQDNreplace端点IP)。怀疑这个错误是由于从HTTP1.1升级到websocket标准的连接包含关于不能直接从浏览器访问的“公共”接口或NoVNC软件拒绝连接的信息到configuration的服务器地址/主机名(“公共”)与请求中的地址(代理名称/ IP)之间不匹配。 这些都是猜测。 NoVNC错误

Nginx的configuration文件

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

有没有人有这种设置的工作configuration? 我想坚持使用Nginx,但可以对Apache或任何其他可以提供解决scheme的软件进行更改。

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

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

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

这是一个可行的解决scheme:

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

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

这是迄今为止的工作解决scheme:

 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;博士

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

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

当我也为此苦苦挣扎时,我偶然发现了这一点。 这真的帮了我。 然而,nginx并不喜欢`http:// $主机周围的引号等。当你删除它的工作。 这对我来说是一个工作configuration,例如:

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

我张贴这个,因为也许有人正在寻找一个更新的答案。