Виртуальная лаба в домашних условиях. Часть 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), ну а пока – до новых встреч в эфире!

Leave a Reply