From 55bc8cd75710d5dcc6f134954118ccc7a941d1a6 Mon Sep 17 00:00:00 2001 From: Daniel Winzen Date: Tue, 1 Jan 2019 13:47:30 +0100 Subject: [PATCH] Introduce mysqld socket stream forwarding with nginx for chroot jails --- README.md | 2 +- etc/nginx/fastcgi.conf | 3 ++ etc/nginx/nginx.conf | 4 +++ .../system/nginx.service.d/custom.conf | 1 + var/www/common.php | 27 ++++++++++++------ var/www/cron.php | 2 +- var/www/html/home.php | 2 +- var/www/setup.php | 28 +++++++++++-------- var/www/setup_chroot.sh | 1 + 9 files changed, 48 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index f1e0177..66f5de1 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ To get the latest mariadb version, you should follow these instructions to add t The following command will install all required packages: ``` -apt-get --no-install-recommends install apt-transport-tor aspell clamav-daemon clamav-freshclam clamav-milter composer curl dovecot-imapd dovecot-pop3d git dnsmasq haveged hunspell iptables locales-all logrotate mariadb-server nano nginx-light postfix postfix-mysql \ +apt-get --no-install-recommends install apt-transport-tor aspell clamav-daemon clamav-freshclam clamav-milter composer curl dovecot-imapd dovecot-pop3d git dnsmasq haveged hunspell iptables locales-all logrotate mariadb-server nano nginx-full postfix postfix-mysql \ php7.3-bcmath php7.3-bz2 php7.3-cli php7.3-curl php7.3-dba php7.3-enchant php7.3-fpm php7.3-gd php7.3-gmp php7.3-imap php7.3-intl php7.3-json php7.3-mbstring php7.3-mysql php7.3-opcache php7.3-pspell php7.3-readline php7.3-recode php7.3-soap php7.3-sqlite3 php7.3-tidy php7.3-xml php7.3-xmlrpc php7.3-xsl php7.3-zip \ phpmyadmin php-apcu php-gnupg php-imagick quota quotatool rsync sasl2-bin ssh subversion tor unzip vim vsftpd wget zip && apt-get --no-install-recommends install adminer ``` diff --git a/etc/nginx/fastcgi.conf b/etc/nginx/fastcgi.conf index 2efe4cb..2517237 100644 --- a/etc/nginx/fastcgi.conf +++ b/etc/nginx/fastcgi.conf @@ -26,3 +26,6 @@ fastcgi_param SERVER_NAME $server_name; fastcgi_param REDIRECT_STATUS 200; # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ fastcgi_param HTTP_PROXY ""; + +#running in chroots +fastcgi_param SCRIPT_FILENAME /www/$fastcgi_script_name; diff --git a/etc/nginx/nginx.conf b/etc/nginx/nginx.conf index 6fca841..107568c 100644 --- a/etc/nginx/nginx.conf +++ b/etc/nginx/nginx.conf @@ -100,3 +100,7 @@ http { include /etc/nginx/sites-enabled/*; } + +stream { + include /etc/nginx/streams-enabled/*; +} diff --git a/etc/systemd/system/nginx.service.d/custom.conf b/etc/systemd/system/nginx.service.d/custom.conf index 722eec4..3a4d423 100644 --- a/etc/systemd/system/nginx.service.d/custom.conf +++ b/etc/systemd/system/nginx.service.d/custom.conf @@ -18,5 +18,6 @@ SystemCallArchitectures=native BindPaths=/var/log/nginx/ BindPaths=/var/lib/nginx/ BindPaths=/var/run/ +BindPaths=/var/www/var/run/ BindPaths=/run/ InaccessiblePaths=/root/ diff --git a/var/www/common.php b/var/www/common.php index a4d59d0..d9050ad 100644 --- a/var/www/common.php +++ b/var/www/common.php @@ -1,6 +1,6 @@ query("SELECT users.system_account, users.php, users.autoindex, onions.onion FROM users INNER JOIN onions ON (onions.user_id=users.id) WHERE onions.enabled IN (1, -2) AND users.id NOT IN (SELECT user_id FROM new_account) AND users.todelete!=1;"); + while($tmp=$stmt->fetch(PDO::FETCH_ASSOC)){ + $nginx.="server { + listen unix:/home/$tmp[system_account]/var/run/mysqld/mysqld.sock; + proxy_pass unix:/var/run/mysqld/mysqld.sock; +} +"; + } + file_put_contents("/etc/nginx/streams-enabled/hosted_sites", $nginx); + exec("service nginx reload"); } function rewrite_php_config(PDO $db, string $key){ diff --git a/var/www/cron.php b/var/www/cron.php index 09c9739..7c48437 100644 --- a/var/www/cron.php +++ b/var/www/cron.php @@ -140,7 +140,7 @@ foreach($accounts as $account){ $drop_user->execute([$account[2]]); $stmt->execute([$account[1]]); while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ - $db->exec("DROP DATABASE IF EXISTS `$tmp[0]`;"); + $db->exec('DROP DATABASE IF EXISTS `'.preg_replace('/[^a-z0-9]/i', '', $tmp[0]).'`;'); } $db->exec('FLUSH PRIVILEGES;'); //delete user from user database diff --git a/var/www/html/home.php b/var/www/html/home.php index faad6f7..dcb38c1 100644 --- a/var/www/html/home.php +++ b/var/www/html/home.php @@ -77,7 +77,7 @@ echo 'DatabaseHostUser'; $stmt=$db->prepare('SELECT mysql_database FROM mysql_databases WHERE user_id=?;'); $stmt->execute([$user['id']]); while($mysql=$stmt->fetch(PDO::FETCH_ASSOC)){ - echo "$mysql[mysql_database]127.0.0.1$user[mysql_user]"; + echo "$mysql[mysql_database]localhost$user[mysql_user]"; } echo ''; echo '

Change MySQL password

'; diff --git a/var/www/setup.php b/var/www/setup.php index f62b846..8c2e0ee 100644 --- a/var/www/setup.php +++ b/var/www/setup.php @@ -35,7 +35,6 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';")) $db->exec('CREATE TABLE settings (setting varchar(50) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL PRIMARY KEY, value text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;'); $stmt=$db->prepare("INSERT INTO settings (setting, value) VALUES ('version', ?);"); $stmt->execute([DBVERSION]); - exec('/var/www/setup_chroot.sh /var/www'); echo "Database and files have successfully been set up\n"; }else{ $version=$version->fetch(PDO::FETCH_NUM)[0]; @@ -122,8 +121,6 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';")) // some software may break when absolute installation path changes, add symlinks to prevent that symlink('.', '/home/'.$tmp['system_account'].'/home'); symlink('.', '/home/'.$tmp['system_account'].'/'.$tmp['system_account']); - exec('/var/www/setup_chroot.sh ' . escapeshellarg('/home/'.$tmp['system_account'])); - exec('grep ' . escapeshellarg($tmp['system_account']) . ' /etc/passwd >> ' . escapeshellarg("/home/$tmp[system_account]/etc/passwd")); $firstchar=substr($tmp['system_account'], 0, 1); //delete config files foreach(array_replace(PHP_VERSIONS, DISABLED_PHP_VERSIONS) as $v){ @@ -139,9 +136,7 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';")) if(file_exists("/etc/nginx/sites-enabled/$tmp[system_account]")){ unlink("/etc/nginx/sites-enabled/$tmp[system_account]"); } - exec('/var/www/setup_chroot.sh /var/www'); } - $db->exec('UPDATE service_instances SET reload=1;'); } $stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';"); $stmt->execute([DBVERSION]); @@ -235,11 +230,22 @@ php_admin_value[open_basedir] = /usr/share/adminer:/tmp file_put_contents("/etc/php/$version/fpm/pool.d/www.conf", $pool_config); exec("service php$version-fpm@default reload"); } - file_put_contents('/etc/nginx/sites-enabled/default', NGINX_DEFAULT); - exec("service nginx reload"); - if(DBVERSION!=$version){ - echo "Database and files have successfully been updated to the latest version\n"; - }else{ - echo "Database and files already up-to-date\n"; + echo "Updating chroots, this might take a while…\n"; + exec('/var/www/setup_chroot.sh /var/www'); + $stmt=$db->query('SELECT system_account FROM users;'); + while($tmp=$stmt->fetch(PDO::FETCH_ASSOC)){ + exec('/var/www/setup_chroot.sh ' . escapeshellarg('/home/'.$tmp['system_account'])); + exec('grep ' . escapeshellarg($tmp['system_account']) . ' /etc/passwd >> ' . escapeshellarg("/home/$tmp[system_account]/etc/passwd")); } + file_put_contents('/etc/nginx/sites-enabled/default', NGINX_DEFAULT); + if(!file_exists("/etc/nginx/streams-enabled/")){ + mkdir("/etc/nginx/streams-enabled/", 0755, true); + } + file_put_contents('/etc/nginx/streams-enabled/default', "server { + listen unix:/var/www/var/run/mysqld/mysqld.sock; + proxy_pass unix:/var/run/mysqld/mysqld.sock; +}"); + exec("service nginx reload"); + $db->exec('UPDATE service_instances SET reload=1;'); + echo "Done - Database and files have been updated to the latest version :)\n"; } diff --git a/var/www/setup_chroot.sh b/var/www/setup_chroot.sh index 4f2de58..15fd802 100755 --- a/var/www/setup_chroot.sh +++ b/var/www/setup_chroot.sh @@ -61,6 +61,7 @@ CHROOT_DIRECTORY_STRUCTURE=( '/usr/sbin' '/var' '/var/run' + '/var/run/mysqld' ) BINARIES_GENERAL=( '/usr/lib/openssh/sftp-server'