Nginx: проходить через HTTPS к различным целям в зависимости от местоположения - PullRequest
0 голосов
/ 22 мая 2019

Я полный обратный прокси noob to nginx, так что простите, если этот вопрос глуп.Моя ситуация заключается в том, что я запускаю несколько док-контейнеров, которые сами управляют HTTPS-сертификатами, и мне нужен обратный прокси-сервер для доступа к ним из браузера.Проблема в том, что сертификатами нужно управлять из этих контейнеров, а не из обратного прокси-сервера nginx.

Я гуглил и перепробовал много вещей, и единственное, что, похоже, работает, - это пропускать поток напрямую на локальный адрес контейнера..

events { }

stream {
  server {
    listen 443;
    listen [::]:443;

    proxy_pass 10.0.0.1:443;  
  }
}

Когда я работаю с потоком (то есть - насколько я знаю - необходим для этого прохода), я не знаю, как дифференцировать пункты назначения, которые я пытаюсьдостичь.

Мне нужна конфигурация, которая позволила бы мне сделать что-то вроде этого:

https://mail.example.com --> proxy_pass 10.0.0.1
https://mail.example.com --> proxy_pass 10.0.0.1
https://www.example.com --> proxy_pass 10.0.0.2 
https://foo.example.com --> proxy_pass 10.0.0.2

Есть ли способ сделать это?

1 Ответ

1 голос
/ 22 мая 2019

То, что вы ищете, это как настроить сквозной прокси-сервер SSL (переадресация TCP) и использовать информацию SNI для маршрутизации. Я не уверен, что вы можете сделать это с помощью nginx, потому что в nginx нет способа передать соединение, используя информацию SNI (насколько я знаю).

Я попытался создать для этого конфигурацию HAproxy с помощью docker-compose, и кажется, что она работает так, как вы хотите. Я использовал docker-compose для запуска всех приложений в одной сети, чтобы вы могли получить доступ к другим службам на основе их имени в docker-compose.

. / Докер-compose.yml

version: '3'

services:

  proxy:
    image: haproxy:1.9.8
    ports:
      - "443:443"
    volumes:
      - "./haproxy:/usr/local/etc/haproxy"

  mail:
    image: mail    # replace it with your app image, it must have port 443 open
    ports:
      - "445:443"  # this port mapping is for debug purposes only, remove it after

  foo:
    image: foo
    ports:
      - "446:443"

. / HAProxy / haproxy.cfg

defaults
  maxconn 1000
  mode http
  log global
  option dontlognull # bind *:443 ssl crt .
  timeout http-request 5s
  timeout connect 5000
  timeout client 2000000 # ddos protection
  timeout server 2000000 # stick-table type ip size 100k expire 30s store conn_cur

frontend https
  bind *:443
  mode tcp
  option tcplog
  tcp-request inspect-delay 5s
  tcp-request content accept if { req_ssl_hello_type 1 }
  use_backend foo-servers if { req.ssl_sni -i foo.example.com }
  use_backend mail-servers if { req.ssl_sni -i mail.example.com }

backend foo-servers
  mode tcp
  balance roundrobin
  option ssl-hello-chk
  server server1 foo:443       # You can use service name from docker-compose here

backend mail-servers
  mode tcp
  balance roundrobin
  option ssl-hello-chk
  server server1 mail:443

Тогда вы можете просто запустить его:

$ docker-compose up

После этого убедитесь, что ваше приложение работает:

$ curl -k https://localhost:445
mail service
$ curl -k https://localhost:446
foo service

И, наконец, мы можем проверить наш прокси:

$ curl -k https://mail.example.com
mail service
$ curl -k https://foo.example.com
foo service

Примечание: чтобы это работало, я добавил mail.example.com и foo.example.com в / etc / hosts

127.0.0.1   mail.example.com
127.0.0.1   foo.example.com

PS. Вот Dockerfile для приложения "foo" (тот же конфиг для почты):

. / Dockerfile

FROM nginx:latest
COPY ssl.conf                   /etc/nginx/conf.d/ssl.conf
COPY mail.html                  /usr/share/nginx/html/index.html
COPY certs/mail.example.com.crt /etc/nginx/certs/
COPY certs/mail.example.com.key /etc/nginx/certs/
COPY certs/dhparam.pem          /etc/nginx/certs/

. / Ssl.conf

server {
    listen 443 http2 ssl;

    ssl_certificate       /etc/nginx/certs/mail.example.com.crt;
    ssl_certificate_key   /etc/nginx/certs/mail.example.com.key;
    ssl_dhparam           /etc/nginx/certs/dhparam.pem;

    root /usr/share/nginx/html;

    location / {
    }
}

Создать самозаверяющий сертификат:

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout certs/foo.example.com.key -out certs/foo.example.com.crt
$ openssl dhparam -out certs/dhparam.pem 2048

Изображение сборки:

$ docker build -t foo .
...