ssl (https) nginx + apache для сайтов на CMS Drupal

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

Получив такую задачу, я столкнулся с тем, что большая часть статей в интернете не заточены на особенности работы сайтов под CMS Drupal. Дело в том, что если сделать защищенное соединение только на nginx'е, то у Вас "слетит оформление", потому что drupal генерирует абсолютные ссылки на, например, файлы css. А так как он "видит" только окружение apache'а, то пути получаются не правильными. Сделать https только на apache - тоже не вариант, ведь тогда nginx не будет понимать, что соединение защищённое.

В общем, решение довольно простое - поднимаем https и там и там.

1. Первым делом необходимо создать приватный ключ;

  • 1.1. Лучше бы создать папочку, где будут лежать наши ключики/сертификаты. Не принципиально абсолютно, главное, чтобы Вы потом не искали куда же его засунули. Я создам папку в /etc/nginx:

    mkdir /etc/nginx/ssl
    cd /etc/nginx/ssl
  • 1.2. Теперь сгенерируем сам ключ. Для этого нам потребуется соответствующий пакет, который должен быть установлен. Если его нет - устанавливаем:
    yum install openssl
    При создании ключа, система попросит ввести пароль, позже мы его удалим:
    openssl genrsa -aes256 -out mysite.ru.key 2048
    Spoiler: Highlight to view

    Generating RSA private key, 2048 bit long modulus
    ...................+++
    .................................................+++
    e is 65537 (0x10001)
    Enter pass phrase for mysite.ru.key:
    Verifying - Enter pass phrase for mysite.ru.key:


    Что конкретно мы тут делаем? Генерируем rsa ключ, размером 2048 бит, используя алгоритм шифрования AES и выводим результат в файл;

2. После того, как сгенерирован ключ, можно создавать самозаверенный сертификат:
openssl req -new -key mysite.ru.key -out mysite.ru.csr

Spoiler: Highlight to view

Enter pass phrase for mysite.ru.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [GB]:RU
State or Province Name (full name) [Berkshire]:Moscow
Locality Name (eg, city) [Newbury]:Moscow
Organization Name (eg, company) [My Company Ltd]:mysite.ru
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:mysite.ru
Email Address []:
 
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:       
An optional company name []:


Здесь мы создаём сертификат стандарта x.509 и записываем новый файл, соответственно;
3. Неприятной особенностью ключа с паролем является то, что Apache или nginx будет регулярно спрашивать пароль при старте. Очевидно, что это не очень удобно (если только кто-то не находится постоянно рядом на случай перезагрузки или аварийной остановки). Для удаления ключа из пароля необходимо выполнить следующее:

cp mysite.ru.key mysite.ru.key.orig
openssl rsa -in mysite.ru.key.orig -out mysite.ru.key

4. Далее, создаем сам SSL сертификат:
openssl x509 -req -days 365 -in mysite.ru.csr -signkey mysite.ru.key -out mysite.ru.crt

Spoiler: Highlight to view

Signature ok
subject=/C=RU/ST=Russia/L=Moscow/O=mysite.ru/CN=mysite.ru
Getting Private key


5. Теперь всё готово, для настройки веб-серверов. Начнём с nginx'а. Вот пример конфигурации виртуального хоста /etc/nginx/conf.d/mysite.ru.conf:
Spoiler: Highlight to view
server {
listen ip.ad.dr.es:80;
server_name mysite.ru;

error_log /var/log/nginx/error/mysite.ru;
access_log /var/log/nginx/access/mysite.ru;

location ~* \.(jpg|jpeg|gif|png|bmp|svg|swf|htm|js|ico|css|mp3|ogg|mpe?g|gz|tar|avi|zip|gz|bz2|rar)$ {
try_files $uri $uri/ @drupal;
root /var/www/mysite.ru/www/;
}

location ~ /\.ht {
deny all;
}

location / {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}

location @drupal {
proxy_pass http://127.0.0.1:8081;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}

server {
listen ip.ad.dr.es:443;
server_name mysite.ru;

ssl on;
ssl_certificate /etc/nginx/ssl/mysite.ru.crt;
ssl_certificate_key /etc/nginx/ssl/mysite.ru.key;
ssl_prefer_server_ciphers on;

location ~* \.(jpg|jpeg|gif|png|bmp|svg|swf|htm|js|ico|css|mp3|ogg|mpe?g|gz|tar|avi|zip|gz|bz2|rar)$ {
try_files $uri $uri/ @drupal;
root /var/www/mysite.ru/www/;
}

location ~ /\.ht {
deny all;
}

location / {
proxy_pass https://127.0.0.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}

location @drupal {
proxy_pass https://127.0.0.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}

Как видно, здесь прописано как-будто бы два разных виртуальных хоста: один для работы по http и второй для работы по https.

Хочу обратить внимание, что НЕ ОБЯЗАТЕЛЬНО перенимать все настройки. Это просто пример.

Не забываем проверить правильность конфига и перезапустить сервер:

nginx -t
/etc/init.d/nginx reload

6. Теперь настройка apache. По умолчанию модуля для ssl может и не быть. Поэтому сначала установим его:
yum install mod_ssl
Далее нужно сделать так, чтобы apache слушал 443 порт на локалхосте. Сделать это можно или в настройках всего веб-сервера (/etc/httpd/cong/httpd.conf), или прямо в настройках виртуального хоста. Вот пример:

Spoiler: Highlight to view

Listen 127.0.0.1:443
NameVirtualHost *:443
<VirtualHost *:8081>
  ServerAdmin admin@mysite.ru
  ServerName mysite.ru
  ServerAlias www.mysite.ru
  DocumentRoot /var/www/mysite.ru/www/
  <Directory /var/www/mysite.ru/www/>
    Options FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from All
  </Directory>
</VirtualHost>
 
<VirtualHost *:443>
  SSLEngine on
  SSLCertificateFile /etc/nginx/ssl/mysite.ru.crt
  SSLCertificateKeyFile /etc/nginx/ssl/mysite.ru.key
  ServerAdmin admin@mysite.ru
  ServerName mysite.ru
  ServerAlias www.mysite.ru
  DocumentRoot /var/www/mysite.ru/www/
  <Directory /var/www/mysite.ru/www/>
    Options FollowSymLinks
    AllowOverride All
    Order allow,deny
    Allow from All
  </Directory>
</VirtualHost>


Тут такой же вариант - два виртуальных хоста. Отдельно для http и отдельно для https. Нужно понимать, что данная конфигурация сделана только ради того, чтобы сайт УМЕЛ работать по https. Т.е. здесь нет, например, настроек, чтобы протокол менялся, когда пользователь вводит логин и пароль.

Проверяем конфиг и перезапускаем сервер:

/etc/init.d/httpd configtest
/etc/init.d/httpd graceful

Конечно, чтобы написать приложение для facebook, нужно чтобы сертификат не просто был, т.е. не "самозаверенный", а был зарегистрированный в каком-либо CA.

Добавить комментарий

CAPTCHA
Этот вопрос задается для того, чтобы выяснить, являетесь ли Вы человеком или представляете из себя автоматическую спам-рассылку.
Target Image