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

Использование Nginx для обслуживания мультитенантного приложения с HTTPS

У нас есть мультитенантное приложение (ядро dotnet + Angular), основной URL-адрес веб-сайта для https://example.com, URL-адреса клиентов: (http://cust1.example.com, http: //cust2.example.com, ......)

Если клиенту нужно использовать свой собственный домен, ему просто нужно перенаправить свой домен на наш сервер, например: У клиента 1 есть свой собственный домен: customer1.com, поэтому он перейдет к настройке домена и изменит настройку DNS, чтобы ссылаться в запись IP нашего сервера @ = XXXX (IP-адрес нашего сервера) CNAME www = cust1.example.com Затем он может открыть свое приложение, используя свой домен (http://customer1.com) Вместо того, чтобы использовать (http://cust1.example.com)

Нет, мы переходим к следующему шагу и используем HTTPS, я создал подстановочный сертификат с LetsEncrypt, используя certbot: sudo certbot --server https://acme-v02.api.letsencrypt.org/directory -d * .example.com --manual --preferred-calls dns-01 Certonly

Теперь приложение работает как HTTPS, если вы заходите в него с (https://cust1.example.com) и работает нормально,

Но проблема в том, как обслуживать HTTPS с разными доменными именами, допустим, что я хочу посетить https://customer1.com, очевидно, что он не может работать, потому что на сервере с этим доменным именем нет сертификата.

Нам нужен автоматический способ создания сертификатов для новых доменов без создания нового блока в конфигурационном файле nginx, потому что, возможно, будет 100000 клиентов, поэтому это невозможно сделать вручную.

Вот мой файл конфигурации Nginx.

server {
    listen 80 default_server;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl default_server;
    server_name example.com *.example.com;

     access_log /var/log/nginx/example.com.access.log;
     error_log /var/log/nginx/example.com.error.log;
     ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
     ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
 proxy_pass http://localhost:5000;
 proxy_http_version 1.1;
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection keep-alive;
 proxy_set_header Host $host;
 proxy_cache_bypass $http_upgrade;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Forwarded-Proto $scheme;
    }

}

Я пытался использовать Lua с nginx, но не нашел способа сделать это,

Кто-нибудь может предложить решение этой проблемы?

Я бы порекомендовал Ansible в качестве инструмента настройки для этой задачи, поскольку он позволяет использовать шаблоны и переменные для настройки сайтов системы SaaS ваших клиентов. В вашем случае это может показаться излишним и повторением, но это принесет огромные преимущества, если вы начнете реализовывать другие задачи инфраструктуры в том же списке сайтов. Обычно я ожидал таких вещей, как:

  • Продление SSL / Letsencrypt
  • специальные сценарии резервного копирования
  • любые другие массовые изменения

Минимальная настройка с ролями, не проверенная на синтаксис или что-то еще, будет выглядеть так:

groups_vars / все:

sites:
 - { name: customer1.yoursaas.com, user: www_customer1, memory_limit: "256M", max_children: 2, port: 5000 }
 - { name: yoursaas.customerdomain.com, user: www_customer2, memory_limit: "256M", max_children: 2, port: 5001  }

роли / nginx / tasks / main.yml:

---

- name: copy host files
  template: src=nginx-host.j2 dest=/etc/nginx/sites-available/{{item.name}} owner=root group=root mode=0644
  with_items:
   - "{{sites}}"
  notify:
     - reload nginx
  tags:
   - nginx

роли / nginx / шаблоны / nginx-host.j2:

server {
    listen 80 default_server;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl default_server;
    server_name {{item.name}};

    access_log /var/log/nginx/{{item.name}}.access.log;
    error_log /var/log/nginx/{{item.name}}.error.log;
    ssl_certificate /etc/letsencrypt/live/{{item.name}}/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/{{item.name}}/privkey.pem;

    location / {
        proxy_pass http://localhost:{{item.port}};
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection keep-alive;
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
     }

}

webserver.yml:

---
- hosts: tag_group_web_servers
  vars_files:
    - group_vars/all
    - group_vars/vault

  roles:
    - nginx

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

Еще одно преимущество заключается в том, что с помощью инструмента конфигурации вы можете иметь очень подробные (повторяющиеся) файлы конфигурации без дополнительной работы и риска ошибок из-за повторения. Это позволяет другим людям легче понять, как что-то настроено.

Я надеюсь, что вы сможете найти решение с помощью указанного ниже файла vhost.

server {
    server_name *.myapp.io;
}

server {
    server_name ~^(?<account>.+)\.myapp\.io$;

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_param ACCOUNT $account; # $_SERVER['ACCOUNT']
    }
}

server {
    server_name ~^(?<account>.+)\.myapp\.io$;

    root /var/www/$account;

    access_log /var/log/nginx/$account-access.log;
    error_log  /var/log/nginx/$account-error.log;
}