Хостинг php-сайтов на proxmox
Вступление
Задача следующая: Необходимо обеспечить хостинг LAMP+WordPress сайтов. Сайты должны быть изолированы друг от друга, при этом необходимо обеспечить доступ заказчикам к файлам сайта через ssh, ftp, и sftp.
В данной статье будет рассмотрен вариант реализации при помощи среды виртуализации Proxmox 4. На виртуальных машинах будем использовать ubuntu-14-04 из официальных шаблонов proxmox.
Схема
Как это работает
Для каждого wordpress создается отдельная виртуальная машина (контейнер LXC). Для доступа к контейнерам в качестве фронт-энд создается одна виртуальная машина GW с белым IP. На ней настраиваем Nginx-reverse-proxy для выставления наружу сайтов, ssh-сервер и ftp-сервер. Кроме того, на GW настраиваем NAT для выхода виртуальных машин в интернет (по необходимости).
Доступ клиентам к виртуальной машине по SSH:
На GW для каждого клиента делается аккаунт, при подключении клиента по ssh (авторизация по ключу) вместо /bin/bash автоматически запускается ssh, который соединяется с виртуальной машиной клиента (авторизация по ключу).
Доступ клиентам к файлам на виртуальной машине по sftp:
На GW настраивается отдельный sshd на порту 2222. При подключении к нему, делается chroot в домашнюю директорию пользователя + автоматически происходит переключение на протокол sftp.
В домашнем каталоге организуем папку в которую будет смонтирована (automount+sshfs) файловая система с виртуальной машины клиента.
Доступ клиентам к файлам на виртуальной машине по ftp:
Аналогично предыдущему пункту, настраивается ftpd, который делает chroot в домашнюю директорию пользователя.
Доступ разработчикам к файлам на виртуальной машине по sftp:
Для разработчиков создается отдельный аккаунт, в домашнем каталоге которого смонтированы файловые системы всех виртуальных машин (automount+sshfs). Подключение осуществляется так же к порту 2222.
Настраиваем
Все действия будем производить в консоли на Proxmox-хосте.
Разворачивание виртуальных машин, настройка nginx и wordpress
Сперва развернем виртуальную машину для GW
pct create 100 /var/lib/vz/template/cache/ubuntu-14.04-standard_14.04-1_amd64.tar.gz -hostname GW -storage local -password wigsikjis -net0 name=eth0,bridge=vmbr0,ip=192.168.77.74/24,gw=192.168.77.254 -net1 name=eth1,bridge=vmbr1,ip=10.100.100.1/24 -cpulimit 1 -onboot 1 # Отключаем apparmor в контейнере. Иначе не будет работать autofs echo "lxc.aa_profile: unconfined" >> /etc/pve/lxc/100.conf # прописываем монтирование /dev/fuse в контейнере (для sshfs) echo "lxc.mount.entry = /dev/fuse dev/fuse none bind,create=file 0 0" >> /etc/pve/lxc/100.conf # Стартуем контейнер, заходим pct start 100 pct enter 100 apt-get -y update; apt-get -y upgrade # настраиваем русскую локаль locale-gen en_US en_US.UTF-8 ru_RU ru_RU.UTF-8 dpkg-reconfigure locales # устанавливаем ништяки apt-get -y install aptitude aptitude -y install mc curl # syslog error workaround rm /var/log/syslog; service rsyslog restart # add user for developers adduser pmadmin
включаем NAT и маршрутизацию:
aptitude install iptables-persistent sed -i '/:POSTROUTING ACCEPT/a -A POSTROUTING -s 10.100.100.0/24 -o eth0 -j MASQUERADE' /etc/iptables/rules.v4 service iptables-persistent restart echo "net.ipv4.conf.all.forwarding = 1" > /etc/sysctl.d/60-ip-forwarding.conf sysctl -p /etc/sysctl.d/60-ip-forwarding.conf
Настраиваем nginx reverse-proxy
aptitude -y install nginx echo 'server { listen 80; server_name test1.example.com; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; location / { proxy_pass http://10.100.100.104/; } }' > /etc/nginx/sites-available/test1.example.com ln -s /etc/nginx/sites-available/test1.example.com /etc/nginx/sites-enabled/ service nginx restart
Развернем виртуальную машину для wordpress-сайта
pct create 100104 /var/lib/vz/template/cache/ubuntu-14.04-standard_14.04-1_amd64.tar.gz -hostname vm100104 -storage local -password wigsikjis -net0 name=eth0,bridge=vmbr1,ip=10.100.100.104/24,gw=10.100.100.1 -cpulimit 1 -onboot 1 pct start 100104 pct enter 100104 apt-get -y update; apt-get -y upgrade locale-gen en_US en_US.UTF-8 ru_RU ru_RU.UTF-8 dpkg-reconfigure locales apt-get -y install aptitude aptitude -y install mc sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config service ssh restart
Устанавливаем LAMP + Wordpress
aptitude -y install php5 mysql-server php5-mysql rm /var/www/html/index.html wget -O - https://wordpress.org/latest.tar.gz | tar -C /var/www/html --strip-components=1 -xz chown -R www-data:www-data /var/www/html echo "CREATE DATABASE wordpress character set utf8;" | mysql
Добавляем у себя в hosts ip нашего севера и устанавливаем wordpress
sudo echo "192.168.77.74 test1.example.com" >> /etc/hosts firefox test1.example.com
Настройка доступа по ssh к виртуальной машине
На GW заводим пользователя vm100104, генерируем ssh ключ, затем кладем этот ключ на виртуальную машину.
adduser vm100104 su - vm100104 ssh-keygen ssh-copy-id root@10.100.100.104 exit
Открываем доступ пользователю на GW - кладем его публичный ключ пользователя (из putty) в authorized_keys + привязываем к этому ключу команду
su - vm100104 echo 'command="ssh root@10.100.100.104",no-X11-forwarding,no-agent-forwarding,no-port-forwarding ssh-rsa AAAAB3Nza.....' >> /home/vm100104/.ssh/authorized_keys exit
Проверяем со своего компа (видим приглашение root@vm100104 - значит мы на виртуалке vm100104):
vps@vps:~$ ssh vm100104@192.168.77.74 X11 forwarding request failed on channel 0 Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 4.2.3-2-pve x86_64) * Documentation: https://help.ubuntu.com/ Last login: Tue Dec 22 08:39:44 2015 from 10.100.100.3 root@vm100104:~#
Настройка autofs и sshfs на GW
Autofs работает от пользователя root
, по этому нужно для root-a сделать ssh-ключ на GW
и положить его на ноду:
все действия делаем на GW
# Генерируем ключ ssh-keygen # Создаем на ноде в домашней директории пользователя www-data (apache) папку .ssh и копируем туда публичный ключ root с GW ssh -i /home/vm100104/.ssh/id_rsa root@10.100.100.104 "mkdir /var/www/.ssh" scp -i /home/vm100104/.ssh/id_rsa /root/.ssh/id_rsa.pub root@10.100.100.104:/var/www/.ssh/authorized_keys ssh -i /home/vm100104/.ssh/id_rsa root@10.100.100.104 "chown -R www-data:www-data /var/www/.ssh" ssh -i /home/vm100104/.ssh/id_rsa root@10.100.100.104 "chmod 600 /var/www/.ssh/authorized_keys" # Настраиваем на ноде sshd таким образом, что бы для пользователя www-data (apache) автоматически запускался sftp ssh -i /home/vm100104/.ssh/id_rsa root@10.100.100.104 "echo 'Match user www-data' >> /etc/ssh/sshd_config" ssh -i /home/vm100104/.ssh/id_rsa root@10.100.100.104 "echo 'ForceCommand internal-sftp' >> /etc/ssh/sshd_config" ssh -i /home/vm100104/.ssh/id_rsa root@10.100.100.104 "service ssh restart"
Устанавливаем и настраиваем autofs
aptitude -y install sshfs autofs mkdir /etc/auto.master.d # Настраиваем autofs в папке /00_sites (это доступ к файлам виртуалок для разработчиков) mkdir /00_sites echo "/00_sites /etc/auto.master.d/00_sites.ssh uid=`id -u pmadmin`,gid=`id -g pmadmin`,--timeout=5,--ghost" > /etc/auto.master.d/00_sites.autofs echo 'vm100104 -fstype=fuse,rw,nodev,nonempty,noatime,allow_other,reconnect,StrictHostKeyChecking=no,Compression=no :sshfs\#www-data@10.100.100.104\:/var/www/html' >> /etc/auto.master.d/00_sites.ssh service autofs restart # autofs в папку /home/vm100104/site (это доступ к файлам сайта для клиента) mkdir /home/vm100104/site echo "/home/vm100104/site /etc/auto.master.d/vm100104.ssh uid=`id -u vm100104`,gid=`id -g vm100104`,--timeout=5,--ghost" > /etc/auto.master.d/vm100104.autofs echo 'vm100104 -fstype=fuse,rw,nodev,nonempty,noatime,allow_other,reconnect,StrictHostKeyChecking=no,Compression=no :sshfs\#www-data@10.100.100.104\:/var/www/html' >> /etc/auto.master.d/vm100104.ssh service autofs restart
проверяем
root@GW:~# ls /00_sites/ vm100104 root@GW:~# ls /00_sites/vm100104 latest.tar.gz wp-activate.php wp-config.php wp-includes wp-mail.php xmlrpc.php license.txt wp-admin wp-config-sample.php wp-links-opml.php wp-settings.php phpinfo.php wp-blog-header.php wp-content wp-load.php wp-signup.php index.php readme.html wp-comments-post.php wp-cron.php wp-login.php wp-trackback.php root@GW:~# ls /home/vm100104/site/ vm100104 root@GW:~# ls /home/vm100104/site/vm100104 latest.tar.gz wp-activate.php wp-config.php wp-includes wp-mail.php xmlrpc.php license.txt wp-admin wp-config-sample.php wp-links-opml.php wp-settings.php phpinfo.php wp-blog-header.php wp-content wp-load.php wp-signup.php index.php readme.html wp-comments-post.php wp-cron.php wp-login.php wp-trackback.php
Настраиваем sftpd на GW
На GW уже запущен sshd на стандартном порту - через него осуществляется доступ пользователям по ssh к виртуальным машинам.
Нам нужно сделать так, что бы при подключении по sftp происходил chroot в папку ~/sites
(в которой через autofs смонтирована файловая система с виртуальной машины пользователя).
Для этого придется поднять отдельный sshd на другом порту и с отдельным конфигом. Назовем этот сервис sshfsd и выделим для него порт 2222.
# Создаем конфиг для sftpd cp /etc/ssh/sshd_config /etc/ssh/sftpd_config sed -i 's/Port 22/Port 2222/' /etc/ssh/sftpd_config # Добавляем в конфиг правила для выполнения chroot для всех пользователей echo "ChrootDirectory %h/site" >> /etc/ssh/sftpd_config echo "ForceCommand internal-sftp" >> /etc/ssh/sftpd_config # Добавляем индивидуальное правило для выполнения chroot для пользователя pmadmin echo "" >> /etc/ssh/sftpd_config echo "Match user pmadmin" >> /etc/ssh/sftpd_config echo "ChrootDirectory /00_sites" >> /etc/ssh/sftpd_config echo "ForceCommand internal-sftp" >> /etc/ssh/sftpd_config # Добавляем sftpd в upstart cp /etc/init/ssh.conf /etc/init/sftpd.conf sed -i 's#OpenSSH server#OpenSFTP server#;s#exec /usr/sbin/sshd -D#exec /usr/sbin/sshd -D -f /etc/ssh/sftpd_config#' /etc/init/sftpd.conf # Устанавливаем права на домашнюю директорию для того, что бы chroot сработал chown root:root /home/vm100104; chmod 755 /home/vm100104 service sftpd start
Проверяем
vps@vps:~$ sftp -P 2222 vm100104@192.168.77.74 Connected to 192.168.77.74. sftp> ls vm100104 vps@vps:~$ sftp -P 2222 pmadmin@192.168.77.74 Connected to 192.168.77.74. sftp> ls mv100104
Настраиваем доступ по ftp
aptitude -y install vsftpd # Включаем chroot для всех пользователей sed -i 's/#chroot_local_user=YES/chroot_local_user=YES/' /etc/vsftpd.conf # Исправление ошибки "425 Security BAD IP connecting problem" при подключении через nat echo 'pasv_promiscuous=YES' >> /etc/vsftpd.conf # Подключаем индивидуальный конфиг пользователя pmadmin, в котором указан /00_sites в качестве домашнего каталога echo 'user_config_dir=/etc/vsftpd/users/' >> /etc/vsftpd.conf mkdir /etc/vsftpd /etc/vsftpd/users echo 'local_root=/00_sites' >> /etc/vsftpd/users/pmadmin service vsftpd restart
проверяем
vps@vps:~$ lftp vm100104@192.168.77.74 Пароль: lftp vm100104@192.168.77.74:~> ls drwxr-xr-x 3 0 0 0 Dec 24 08:40 site vps@vps:~$ lftp pmadmin@192.168.77.74 Пароль: lftp pmadmin@192.168.77.74:~> ls dr-xr-xr-x 2 0 0 0 Dec 24 08:40 100104 dr-xr-xr-x 2 0 0 0 Dec 24 08:40 100105
Доступ по smb (только для staging-сервера, который находится в интранет)
aptitude -y install samba echo "[phpstuff]" >> /etc/samba/smb.conf echo "path = /00_sites" >> /etc/samba/smb.conf echo "guest ok = yes" >> /etc/samba/smb.conf echo "browseable = yes" >> /etc/samba/smb.conf echo "public = yes" >> /etc/samba/smb.conf echo "writeable = yes" >> /etc/samba/smb.conf echo "force user = pmadmin" >> /etc/samba/smb.conf echo "force group = pmadmin" >> /etc/samba/smb.conf echo "create mask = 0664" >> /etc/samba/smb.conf echo "directory mask = 0775" >> /etc/samba/smb.conf service smbd restart
Готово.