Назад | Перейти на главную страницу

OpenStack Horizon за обратным прокси (предпочтительно nginx)

Текущая ситуация:

У меня есть установка Triple-O OpenStack (Liberty), где даже «общедоступная» сеть находится в частной среде (сеть 10.24.7.0/24). Единственный способ получить доступ к этой сети - через хост-шлюз. Я хочу сделать Horizon доступным из Интернета с помощью обратного прокси. Из соображений безопасности все внешние коммуникации должны быть зашифрованы через HTTPS. Обратный прокси-сервер должен использоваться в качестве хоста завершения SSL, а весь внутренний трафик должен быть незашифрованным.

Развертывание OpenStack не было настроено для использования SSL / TLS и не знает, что «общедоступная» сеть на самом деле не является общедоступной.

В настоящее время я пытаюсь использовать Nginx в качестве обратного прокси, но также возможно использование другого программного обеспечения обратного прокси, если они предоставляют решение моей проблемы.

Узел шлюза работает под управлением RHEL 7.2, Nginx устанавливается из официального репозитория Nginx в версии 1.11.1 (основная линия).

gateway.example.com полное доменное имя, используемое в примерах,
1.2.3.4 внешний IP-адрес шлюза, используемый в примерах.
10.24.7.9 "общедоступная" конечная точка установки Triple-O

Работы пока:

Проблемы:

Конфигурационный файл 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 или любое другое программное обеспечение, которое может предоставить решение.

Изменить: уточнено использование ЦС, добавлены подозрения относительно сбоя подключения NoVNC

Я наткнулся на это, когда тоже боролся с этим некоторое время. И это мне очень помогло. Однако 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;
  }
}

Я публикую это, потому что, возможно, кто-то ищет обновленный ответ.

Мне удалось решить вторую проблему (ошибка 1006), изменив некоторые параметры конфигурации. Поскольку другая проблема все еще сохраняется, я не могу подтвердить, что консоль NoVNC работает из пользовательского интерфейса Horizon, но когда я вызываю URL-адрес NoVNC напрямую, я получаю соединение и могу взаимодействовать с экземпляром.

Это рабочее решение до сих пор:

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

Изменения:
В обоих серверных блоках для портов 443 и 6080 я добавил proxy_set_header Origin http://$host;. Не знаю точно, что это делает, но это решило мою проблему.

Это все еще оставляет мне первую проблему.

Мне удалось решить и первую проблему. Причина такого странного поведения была вызвана тем, что обратный прокси-сервер отбросил часть запроса (все, что стоит за?). Это снова было вызвано неверно настроенными строками 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;  
  }  
}