Виртуальная лаба в домашних условиях. Часть 2: apache и немного ansible
Продолжаем поднимать домашнюю лабу с преферансом и курсистками. В прошлой серии мы поговорили про сеть (с которой всё начинается), теперь же мы поговорим про вещи более практичные – доступ к виртуалкам извне с помощью reverse proxy, организацию ssl-подключения при помощи бесплатных сертификатов от Let’s Encrypt и немного посмотрим на плейбуки ansible, с помощью которых удобно раскатывать новые машины и готовить их к работе.
0. Disclaimer
Для начала о том, чего тут НЕ будет.
– Здесь не будет описываться установка VMWare или Debian
– Здесь не будет описываться настройка Mikrotik “с нуля”
– Здесь не будет описываться установка пакетов через apt (будь то ansible, zabbix или apache)
Я предполагаю, что компетенция моих читателей достаточна для того, чтобы не только прочитать всё то, что написано ниже, но и применять на практике с умом и пониманием, что вообще делается и для чего.
1. Настройка Reverse-proxy
Зачем нужен reverse proxy? Например, когда вам нужно отделить фронт-энд и бэкэнд. В качестве бэкэнда может выступать Tomcat, или вообще самописное приложение, которое выпускать в интернет “как есть” просто опасно. Или, к примеру, вам нужно выставить несколько веб-приложений за одним ip-адресом. Если все лежит на одной машине, проблем нет – VirtualHost спасёт отца русской демократии. А если нет? Если каждое приложение – это отдельная ВМ или docker-контейнер? Вот тут нам и пригодится reverse-proxy.
“Правильные пацаны” считают, что поднимать прокси на apache не нужно – “дорого” по ресурсам, меньше гибкости и т.д. Но для меня Apache подошёл как нельзя кстати – во-первых, я с ним банально больше работал, а во-вторых, у меня уже были нужные конфиги, и не хотелось переделывать их под nginx.
Для включения режима прокси надо установить следующие пакеты:
apt-get install apache2 libapache2-mod-proxy-html libxml2-dev
А затем включить модули apache:
a2enmod proxy && a2enmod ssl && a2enmod cache && a2enmod proxy_connect && a2enmod proxy_html && a2enmod rewrite && a2enmod cache && a2enmod disk_cache
Не забудьте перезапустить apache.
Возможно, для вашего приложения потребуются еще какие-то модули. Это можно узнать в документации или эмпирически 😉
Теперь делаем конфиг для нашего приложения:
ServerName jira.nixman.info
ProxyPreserveHost On
Order deny,allow
Allow from all
ProxyPass / http://192.168.88.186:8080/
ProxyPassReverse / http://192.168.88.186:8080/
Order allow,deny
Allow from all
ErrorLog ${APACHE_LOG_DIR}/jira-error.log
CustomLog ${APACHE_LOG_DIR}/jira-access.log combined
Из конфига понятно, что мы перекидываем запросы, пришедшие на адрес jira.nixman.info:80 внутрь локалки, на порт 8080.
Никакой фильтрации или особо заковыристых опций я не добавлял, так что случай можно считать простейшим (хотя и рабочим).
1.1 Зачем нужен SSL-offload
Делать сайты без https-версии в последнее время становится моветоном. Особенно, когда появился Let’s Encrypt, c его абсолютно бесплатными сертификатами, которые, к тому же, действуют всего три месяца, что побуждает к автоматизации процесса их продления.
Собственно SSL-offload – это механизм, при котором данные шифруются только между клиентом и прокси-сервером, на котором SSL-сертификат снимается, и дальше трафик до сервера идёт уже нешифрованный.
Пример конфига с ssl-offload ниже:
ServerAdmin webmaster@nixman.info
ServerName jira.nixman.info
ServerAlias *jira.nixman.info
DocumentRoot /var/www
SSLOptions +StrictRequire
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/jira.nixman.info/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/jira.nixman.info/privkey.pem
BrowserMatch "MSIE [2-6]" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [17-9]" \
ssl-unclean-shutdown
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
SSLHonorCipherOrder on
ErrorLog ${APACHE_LOG_DIR}/jira-ssl-error.log
CustomLog ${APACHE_LOG_DIR}/jira-ssl-access.log combined
ProxyPass / http://192.168.88.186:8080/
ProxyPassReverse / http://192.168.88.186:8080/
Как вы видите, конфиг, по сути, объединяет в себе предыдущий вариант (с http без ssl) и ssl-секцию обычного VirtualHost, как он обычно настраивается в Apache. При этом на хосте, куда проксируется трафик, может висеть вообще что угодно (у меня это Tomcat с Jira).
Инструкцию по получению сертификатов тут приводить не буду – во-первых, у каждого свой, удобный ему метод (а кто-то вообще до сих пор пользует годичные startssl и wosign), а во-вторых многочисленные how-to на эту тему (включая официальные) весьма просты и гуглятся буквально за несколько секунд.
2. Бонус: полезные плейбуки ansible
Я только в начале пути освоения ansible, но кое-какие из плейбуков уже пригодились.
Например, вот так можно подготовить машину “с нуля” до какого-то нужного уровня:
- hosts: all
user: snake
become: true
become_method: sudo
tasks:
- name: Add user
action: user name=ansible password=VeRy$eCrEtP@$sw0rD groups=sudo
- name: Allow 'sudo' group to have passwordless sudo
lineinfile:
dest: /etc/sudoers
state: present
regexp: '^%sudo'
line: '%sudo ALL=(ALL) NOPASSWD: ALL'
- authorized_key:
user: ansible
state: present
key: "{{ lookup('file', '/home/ansible/.ssh/id_rsa.pub') }}"
- name: Software install
apt: name={{item}} state=latest
with_items:
- htop
- mc
- nano
- ntpdate
- ntp
- tcpdump
- traceroute
- telnet
- curl
- name: NTP daemon enable
service: name=ntp enabled=yes
- name: PermitRootLoginSSH
lineinfile: dest=/etc/ssh/sshd_config regexp="^MaxSessions 10" insertafter="^#MaxSessions 10" line="PermitRootLogin no"
В этом плейбуке мы добавляем пользователя ansible (обратите внимание, он добавляется в группу sudo, а группе даётся право запускать sudo без дополнительного ввода пароля. Не делайте такое в продакшене!), копируем ему наш открытый ключ, чтобы в будущем ходить на машину без ввода пароля, потом ставим начальный набор софта, а заодно запрещаем ходить по ssh руту.
Т.к. подразумевается, что у машина у нас “с нуля”, то нужно задать пользователя, от которого будет выполняться плейбук в системе, а так же указать, что пароли (обычный и sudo) нужно запросить:
ansible@master:~$ ansible-playbook -latlassian.snake.local new.yml -u snake -k -K
А вот таким плейбуком можно обновить пакеты разом на всех хостах. В продакшене так делать нельзя, но в лабе – почему бы и нет?
- hosts: debian
user: ansible
become: true
become_method: sudo
tasks:
- name: Update apt cache
apt: update_cache=yes
- name: Update packets
apt: upgrade=full
Углубляться дальше не буду, но думаю, что если перед вами стоит какая-то более-менее типовая задача, то “про неё тоже есть плейбук”.
На этом всё. Думаю, в процессе добавления новых фишечек будут появляться новые серии (навскидку – хочется поднять внутри локальной сети ipv6), ну а пока – до новых встреч в эфире!