В продолжение своего вопроса разрабатываю разные версии, как отделять «клиентов» друг от друга, но при этом держать их на одной машине. В конце концов, обезопасить свой же локалхост от взлома. Для этого запустил nginx в chroot'е и написал скрипт, автоматизириющий сий процесс. Представьте, взламывают ваш сервер, хацкер получает «root», смотрит содержимое сервера и обнаруживает, что кроме собственно веб-сервера ничего не установлено. :)
nginx
Собирать nginx + openssl + pcre + zlib будем из исходников, в переменных необходимо только указать свежие версии программ, а также директорию, куда будет произведена установка файлов.
Никаких защит от дурака, никаких проверок — скрипт лишь автоматизирует рутинные действия. Запускать с правами обычного пользователя.
user@linux:~$ cat << EOF >> ~/chroot-nginx.sh
main() {
local pkg_nginx="nginx-1.3.13"
local pkg_openssl="openssl-1.0.1e"
local pkg_pcre="pcre-8.32"
local pkg_zlib="zlib-1.2.7"
local build="$@"
/usr/bin/curl --remote-name "http://nginx.org/download/${pkg_nginx}.tar.gz"
/usr/bin/curl --remote-name "https://www.openssl.org/source/${pkg_openssl}.tar.gz"
/usr/bin/curl --remote-name "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/${pkg_pcre}.tar.bz2"
/usr/bin/curl --remote-name "http://zlib.net/${pkg_zlib}.tar.gz"
/bin/tar --extract --file "${pkg_nginx}.tar.gz"
/bin/tar --extract --file "${pkg_openssl}.tar.gz"
/bin/tar --extract --file "${pkg_pcre}.tar.bz2"
/bin/tar --extract --file "${pkg_zlib}.tar.gz"
cd "${pkg_nginx}"
./configure
--user="http" --group="http"
--with-file-aio
--with-ipv6
--with-openssl="../${pkg_openssl}" --with-http_ssl_module
--with-pcre="../${pkg_pcre}" --with-pcre-jit
--with-zlib="../${pkg_zlib}" --with-http_gzip_static_module
make
mkdir --parents "${build}"
make DESTDIR="${build}" install
}
EOF
chroot
Для сборки chroot-окружения требуются привелегии root, так как будут созданы файлы устройств, изменены права на директории и возможность запускать nginx для прослушивания 0-1024 портов без прав root.
user@linux:~$ cat << EOF >> ~/chroot-nginx.sh
as_root() {
local build="$@"
cd "${build}" || return 0
mkdir "./dev"
mknod -m 0666 "./dev/null" c 1 3
mknod -m 0666 "./dev/random" c 1 8
mknod -m 0444 "./dev/urandom" c 1 9
mkdir "./etc"
touch "./etc/shells"
echo "http:x:33:" >> "./etc/group"
echo "nobody:x:99:" >> "./etc/group"
echo "http:x:33:33:http:/:/bin/false" >> "./etc/passwd"
echo "nobody:x:99:99:nobody:/:/bin/false" >> "./etc/passwd"
echo "http:x:14871::::::" >> "./etc/shadow"
echo "nobody:x:14871::::::" >> "./etc/shadow"
echo "http:::" >> "./etc/gshadow"
echo "nobody:::" >> "./etc/gshadow"
mkdir "./usr/lib"
cp "/usr/lib/libnss_"* "./usr/lib"
ln -s "usr/lib" "./lib"
local lib=""
for lib in $(ldd "./usr/local/nginx/sbin/nginx" | grep -o "[^ ]*/lib[^ ]*"); do
cp "${lib}" ".${lib}"
done
mkdir "./usr/local/nginx/client_body_temp"
mkdir "./usr/local/nginx/proxy_temp"
mkdir "./usr/local/nginx/scgi_temp"
mkdir "./usr/local/nginx/uwsgi_temp"
mkdir "./usr/local/nginx/fastcgi_temp"
mkdir "./tmp"
chown -R "root:root" "."
chown -R "http:http" "./usr/local/nginx/html"
chown -R "http:http" "./usr/local/nginx/logs"
chown "http:http" "./usr/local/nginx/client_body_temp"
chown "http:http" "./usr/local/nginx/proxy_temp"
chown "http:http" "./usr/local/nginx/scgi_temp"
chown "http:http" "./usr/local/nginx/uwsgi_temp"
chown "http:http" "./usr/local/nginx/fastcgi_temp"
setcap "cap_net_bind_service=+ep" "./usr/local/nginx/sbin/nginx"
}
EOF
Сборка
Теперь соберем все это вместе, в один исполняемый файл. Добавив…
user@linux:~$ cat << EOF >> ~/chroot-nginx.sh
case "${UID}" in
"0")
as_root "$@"
;;
*)
main "$@"
;;
esac
EOF
Скопипастив поочередно куски кода в файл, делаем его исполняемым.
user@linux:~$ chmod +x ~/chroot-nginx.sh
С правами своего пользователя выполним сборку nginx в директорию http.
user@linux:~$ ~/chroot-nginx.sh /home/user/http
Зайдем под рутом и выполним доустановку chroot-окружения.
user@linux:~$ su --login
root@linux:~# /home/user/chroot-nginx.sh /home/user/http
Теперь все должно работать, я надеюсь :) можно запускать nginx, без root!
root@linux:~# /usr/bin/chroot --userspec=http:http /home/user/http /usr/local/nginx/sbin/nginx -g "daemon on; master_process on;"