Проксі-сервер Nginx для бек-енд-аутентифікації із сертифікацією SSL-клієнта


14

У мене два сервери, на обох є nginx. Сервер A прослуховує 443 і налаштований для автентифікації за допомогою клієнтського SSL-сертифіката.

Сервер B має внутрішній процес, який потребує зв'язку з сервером A через nginx.

Я хотів би налаштувати Nginx на сервері B, який прослуховуватиме 8080 (без шифрування, оскільки це все місцеве спілкування) та проксі-пропуск до ServerA: 443.

Питання полягає в тому, як мені ввести сертифікат клієнта? Я не знайшов жодної функції proxy_xxxx, яка б це зробила.

Я знаю, як зробити еквівалент тому, що використовується socat, але моя вимога - використовувати nginx.


2
З огляду на директиви в проксі-модулі nginx, схоже, неможливо змусити сервер nginx використовувати cert для автентифікації: nginx.org/en/docs/http/ngx_http_proxy_module.html Хоча Apache підтримує цю функцію.
NuTTyX

Ось чого я боявся ... будь-яка ідея, якщо є спеціальний модуль чи щось, що може змусити цю роботу? Така особливість повинна існувати!
Bastien974

Я знайшов утиліту для переміщення конфігураційних файлів з apache до nginx ( github.com/nhnc-nginx/apache2nginx ), тому я завантажив її, створив фіктивну apache.conf і передаю її через інструмент, але отримав цей результат :### Section 2: Unconverted directives ### # Flag Description # [S] Unsupported directives. # In conf file: dummy.conf # Line 32: SSLProxyMachineCertificateFile /path/to/cert (mod_ssl.c) # [S] SSLProxyMachineCertificateFile: No relevant directive in Nginx.
NuTTyX

Відповіді:


21

Чи достатньо пройти дані про сертифікат клієнта?

Ви можете додати

proxy_set_header X-SSL-CERT $ssl_client_escaped_cert;

у вашу конфігурацію, і тоді інформація про сертифікат доступна для сервера B через заголовок X-SSL-Cert.


1
Як зазначається тут , майте на увазі, чи ваш бекенд може замінити \tз \nцього заголовка раз прочитане.
lucasvc

3
Відповідно до документації nginx , $ssl_client_certзмінна застаріла; $ssl_client_escaped_certзмінна повинна використовуватися замість цього.
дубек

1
@dubek гарний улов, я б оновлював відповідь безпосередньо у таких випадках.
Кріс Стричинський

Я намагався це рішення, але, здається, він пропускає сертифікат лише у випадку, якщо перевірка сертифікату встановлена. Я не хочу вмикати його, чи є спосіб змусити його працювати, не встановлюючи перевірку?
juhako

5

Мабуть, це те, що ви шукаєте: http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate Доступно з версії 1.7.8.

location / {
    ...
    proxy_pass     the_other_nginx;
    proxy_ssl_certificate  the_certificate.pem;
    ...
}

1
Це неправильно. Це призначає сервер клієнта проксі-серверу, який буде використовуватися для запитів до бекенда. Але запитуваний сказав, що цей зв’язок незашифрований лише для локальних мереж, тому перевірки сертифікату клієнта немає. Відповідь jwilkins працює добре.
Kenyakorn Ketsombut

@KenyakornKetsombut Я вважаю, що ви неправильно прочитали питання. Сервер B не має шифрування (прослуховування на 8080), але повинен спілкуватися з сервером A (прослуховування на 443, із шифруванням). Отже, B потрібно надіслати клієнтський сертифікат до A для автентифікації. Ви можете використовувати proxy_ssl_certificate для цього. jwilkins відповість, буде пересилати до А, що надається B. Обоє можуть працювати залежно від того, що вам потрібно.
Nicolas Malbran

Привіт Ніколя. Я намагався сказати: якщо сервер B не використовує шифрування (на порту 8080), він не використовує нічого, як HTTPS / SSL або як би ви його не називали. Клієнтські сертифікати є частиною SSL, тому ця частина не може бути виконана сервером B. B не може надсилати та отримувати жоден клієнтський сертифікат.
Kenyakorn Ketsombut

1
Я отримую nginx: [emerg] для сертифіката "certs / Roro_Client.pem" nginx: файл конфігурації /etc/nginx/nginx.conf не визначено "proxy_ssl_certificate_key" не вдалося, коли я спробував це з 1.8.0
Wolfgang Fahl

4

Здається, проблема значною мірою залежить від версії. У Ubuntu 14.04 LTS типовим nginx є застарілий 1,4. Спочатку потрібно встановити версію на основі PPA

https://leftshift.io/upgrading-nginx-to-the-latest-version-on-ubuntu-servers

показує, як це зробити за допомогою:

sudo add-apt-repository ppa:nginx/stable
sudo aptitude safe-upgrade

Ви повинні закінчити:

nginx -v
nginx version: nginx/1.8.0

Конфігурація з @ xatr0z відповідь https://serverfault.com/a/636455/162693, що вказує на http://www.senginx.org/en/index.php/Proxy_HTTPS_Client_Certificate не працює:

неробоча пропозиція

backend {
    server some-ip:443;
}

server {
    listen 80;


    location / {
        proxy_ssl_certificate        certs/client.crt;
        proxy_ssl_certificate_key    certs/client.key;


        proxy_pass https://backend;
    }
}

не працює з коробки з 1.8.0. Це, мабуть, означає лише підказку і не використовуватиметься як файл конфігурації як такий або залежить від іншої версії.

Я тестую на сервері Akend2 на основі apache2 з включеними SSL та сертифікатами клієнта з власним підписом SSLOptions конфігурації Apache встановлені на:

SSLOptions +ExportCertData +FakeBasicAuth + StdEnvVars

Це полегшує налагодження ситуації, оскільки в скрипті phpinfo () на задній панелі відображатиметься інформація про сервер та клієнтську сторону.

Щоб перевірити це, я використав:

https: // бекенд / тест / phpinfo

із сертифікатом SSL, встановленим у браузері, і я отримую такі розділи, як: SSL_SERVER_S_DN_CN для сертифіката сервера та SSL_CLIENT_S_DN_CN для сертифіката клієнта.

В якості першого запуску я використовував (заповнюючи частини в дужках) для налаштування nginx на сервері Frontend B:

server {
  listen 8080;
  server_name <frontend>;

  location / {
    proxy_buffering off;
    proxy_pass https://<backend>;
    #proxy_ssl_certificate      certs/<SSL Client Certificate>.crt;
    #proxy_ssl_certificate_key  certs/<SSL Client Certificate>.key;
  }
}

видалення конкретної частини сертифіката клієнта SSL лише для того, щоб перевірити, чи працює сам зворотний проксі.

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
service nginx restart
nginx stop/waiting
nginx start/running, process 8931

Тепер http: // frontend: 8080 / test / phpinfo.php працює The

SSL_SERVER_S_DN_CN для серверного сертифіката відображається, а SSL_CLIENT_S_DN_CN для клієнтського сертифіката ще не відображається

Тепер після коментарів:

server {
  listen 8080;
  server_name <frontend>;

  location / {
    proxy_buffering off;
    proxy_pass https://<backend>;
    proxy_ssl_certificate      certs/<SSL Client Certificate>.crt;
    proxy_ssl_certificate_key  certs/<SSL Client Certificate>.key;
  }
}

і перевірка / перезапуск

nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
service nginx restart
nginx stop/waiting
nginx start/running, process 8931

http: // frontend: 8080 / test / phpinfo.php працює і

SSL_SERVER_S_DN_CN для сертифіката сервера відображається і SSL_CLIENT_S_DN_CN для сертифіката клієнта відображається

тому зараз у нас працює так, як просили.

Зверніть увагу на помилку https://trac.nginx.org/nginx/ticket/872#ticket


Ви можете поспостерігати за проблемою, що повторюється, ruby-forum.com/topic/6875137, яка може зіпсувати шоу
Вольфганг Фаль

1

Є досить акуратна стаття про nginx та SSL-клієнтські сертифікати; він використовує PHP з FastCGI як приклад, але я думаю, ви можете це адаптувати до налаштування зворотного проксі:

server {
    listen        443;
    ssl on;
    server_name example.com;

    ssl_certificate      /etc/nginx/certs/server.crt;
    ssl_certificate_key  /etc/nginx/certs/server.key;
    ssl_client_certificate /etc/nginx/certs/ca.crt;
    ssl_verify_client optional;

    location / {
        root           /var/www/example.com/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param  SCRIPT_FILENAME /var/www/example.com/lib/Request.class.php;
        fastcgi_param  VERIFIED $ssl_client_verify;
        fastcgi_param  DN $ssl_client_s_dn;
        include        fastcgi_params;
    }
}

Джерело http://nategood.com/client-side-certificate-authentication-in-ngi


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.