====== Сажаем apache в тюрьму, а шифровки ему туда будет носить nginx ====== ---- ====== Введение ====== В далеком 2007-м году автор столкнулся с проблемой когда один из сайтов был взломан, и злоумышленник получил доступ к консоле сервера. Присутствие постороннего было обнаружено, только через два часа и за это время он успел дотянуться до других серверов, которые находились в dmz. С тех пор я предпочитаю рассаживать сайты по разным jail-ам и максимально изолировать их друг от друга и от базового сервера, для того чтоб максимально усложнить жизнь очередному хакеру. 8-) ====== Настройка ====== Начнем с создания пустой клетки, из которой потом по необходимости будет клонировать рабочие. В принципе можно каждый раз клетку создавать с нуля. ===== Создание базовой jail ===== Создаем файловую систему для клеток, и внутри нее еще одну ФС для клетки с лимитом в 5Gb: zfs create -o mountpoint=/jails zroot/jails zfs create -o quota=5G zroot/jails/empty Скачиваем архив с базовой системой и разворачиваем его: cd /jails/empty fetch http://ftp.ru.freebsd.org/pub/FreeBSD/releases/amd64/12.2-RELEASE/base.txz tar xvJf ./base.txz rm -f ./base.txz Обновляем систему внутри будущей клетки: freebsd-update -b /jails/empty/ fetch install Теперь базовая пустая клетка готова. При необходимости новую jail можно создать на ее основе при помощи команды zfs clone: zfs snapshot zroot/jails/empty@12.1 && zfs list -t snapshot zfs clone zroot/jails/empty@12.1 zroot/jails/www ===== Настройка системы ===== Поскольку мы хотим максимально изолировать клетку от внешнего мира и от базового сервера, то работать с интернетом они будут через сетевой мост. ==== rc.conf ==== Создадим два интерфейса для двух разных клеток. В /rtc/rc.conf прописываем: cloned_interfaces="bridge0 epair0 epair1" ifconfig_bridge0="inet 10.0.0.1/24 addm epair0b addm epair1b up" ifconfig_epair0b="up" ifconfig_epair1b="up" Поднимаем интерфейсы: service netif cloneup ==== Firewall ==== По умолчанию у клеток не будет доступа в интернет, но он потребуется для установки и обновления ПО. Поэтому в /etc/pf.conf прописываем: nat on $ext_if from 10.0.0.0/24 to any -> ($ext_if) table persist pass inet proto tcp from to any port { http, https } flags S/SA keep state применяем новые правила: service pf reload Теперь для того, чтоб предоставить клетке доступ в интернет для обновления ПО достаточно просто добавить в таблицу jails необходимые ip адреса. ==== Настройка jail ==== Создаем /etc/jail.conf: exec.start = "/bin/sh /etc/rc"; exec.stop = "/bin/sh /etc/rc.shutdown"; exec.clean; mount.devfs; path = "/jails/$name"; exec.consolelog = "/var/log/jail_${name}_console.log"; www { $vif = "epair0a"; host.hostname = "www.local"; vnet; vnet.interface = $vif; # workaround # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=238326 exec.prestop += "ifconfig $vif -vnet $name"; allow.chflags; devfs_ruleset = 10; } Так же перед запуском надо настроить сеть внутри самой клетки. Для этого создаем файлы rc.conf: echo 'defaultrouter="10.0.0.1" \ ifconfig_epair0a="10.0.0.2/24"' >> /jails/www/etc/rc.conf и файл resolv.conf: echo 'nameserver 10.0.0.1' >> /jails/www/etc/resolv.conf ===== Настройка jail ===== ==== Запуск ==== Даем клетке временный доступ в интернет: pfctl -t jails -Ta 10.0.0.2 Включаем и запускаем сервис: service jail enable service jail start Посмотреть список запушенных клеток: jls Обновляем pkg внутри клетки и устанавливаем zsh: pkg -j www upgrade pkg -j www install zsh Заходим в консоль клетки: jexec www ==== Установка и настройка apache ==== Устанавливаем apache с поддержкой php и mysql: pkg install apache24 pkg install php74 mod_php74 php74-extensions php74-mysqli Для поддержки php добавляем в httpd.conf: [...] AddType application/x-httpd-php .php .php3 .phtml AddType application/x-httpd-php-source .phps Запускаем: service apache24 enable service apache24 start ====== NGINX ====== Осталось только установить и настроить nginx, чтоб он работал как прокси для apache. pkg install nginx Пример конфигурационного файла: worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; server_tokens off; sendfile on; keepalive_timeout 65; server { listen 80 default_server; listen 443 default_server; server_name _; access_log off; log_not_found off; # Optional return 444; ssl_certificate /usr/local/etc/nginx/ssl/bhole.crt; ssl_certificate_key /usr/local/etc/nginx/ssl/bhole.key; } server { listen 80; server_name www.nzgw.ru nzgw.ru; return 301 https://www.nzgw.ru$request_uri; } server { listen 443 ssl; server_name www.nzgw.ru nzgw.ru; ssl_certificate /usr/local/etc/letsencrypt/live/nzgw.ru/fullchain.pem; ssl_certificate_key /usr/local/etc/letsencrypt/live/nzgw.ru/privkey.pem; ssl_trusted_certificate /usr/local/etc/letsencrypt/live/nzgw.ru/chain.pem; ssl_prefer_server_ciphers on; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits ssl_dhparam /usr/local/etc/ssl/dh2048.pem; location / { proxy_pass http://10.0.0.2; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; } } } Запуск: service nginx enable service nginx start