Allow changing instances + add nginx_rewrites table + optimizations
This commit is contained in:
@ -6,7 +6,7 @@ This is a setup for a TOR based shared hosting server. It is provided as is and
|
||||
Installation Instructions:
|
||||
--------------------------
|
||||
|
||||
The configuration was tested with a standard Debian sid and Ubuntu 16.04 LTS installation. It's recommended you install Debian sid on your server, but with a little tweaking you may also get this working on other distributions and/or versions.
|
||||
The configuration was tested with a standard Debian buster and Ubuntu 18.04 LTS installation. It's recommended you install Debian buster (or newer) on your server, but with a little tweaking you may also get this working on other distributions and/or versions.
|
||||
|
||||
Uninstall packages that may interfere with this setup:
|
||||
```
|
||||
|
@ -23,7 +23,7 @@ const INDEX_MD5S=[ //MD5 sums of index.hosting.html files that should be considd
|
||||
const REQUIRE_APPROVAL=false; //require admin approval of new sites? true/false
|
||||
const ENABLE_SHELL_ACCESS=true; //allows users to login via ssh, when disabled only (s)ftp is allowed - run setup.php to migrate existing accounts
|
||||
const ADMIN_PASSWORD='MY_PASSWORD'; //password for admin interface
|
||||
const SERVICE_INSTANCES=['1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; //one character per instance - run multiple tor+php-fpm instances for load balancing, remove all but one instance if you expect less than 100 accounts. Adding new instances is always possible at a later time, just removing one takes some manual cleanup for now - run setup.php after change
|
||||
const SERVICE_INSTANCES=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's']; //one character per instance - run multiple tor+php-fpm instances for load balancing, remove all but one instance if you expect less than 200 accounts. - run setup.php after change
|
||||
const DISABLED_PHP_VERSIONS=[]; //php versions still installed on the system but no longer offered for new accounts
|
||||
const PHP_VERSIONS=[4 => '7.3']; //currently active php versions
|
||||
const DEFAULT_PHP_VERSION='7.3'; //default php version
|
||||
@ -81,7 +81,6 @@ server {
|
||||
}
|
||||
}
|
||||
location /phpmyadmin {
|
||||
root /usr/share;
|
||||
location ~ \.php$ {
|
||||
include snippets/fastcgi-php.conf;
|
||||
fastcgi_param DOCUMENT_ROOT /html;
|
||||
@ -113,6 +112,7 @@ const MAX_NUM_USER_DOMAINS = 3; //maximum number of clearnet domains a user may
|
||||
const SKIP_USER_CHROOT_UPDATE = true; //skips updating user chroots when running setup.php
|
||||
const DEFAULT_QUOTA_SIZE = 10 * 1024 * 1024; //per user disk quota in kb - Defaults to 10 GB
|
||||
const DEFAULT_QUOTA_FILES = 100000; //per user file quota - by default allow no more than 100000 files
|
||||
const NUM_GUARDS = 50; //number of tor guard relays to distribute the load on
|
||||
|
||||
function get_onion_v2($pkey) : string {
|
||||
$keyData = openssl_pkey_get_details($pkey);
|
||||
@ -312,36 +312,65 @@ function check_captcha_error() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function rewrite_torrc(PDO $db, string $key){
|
||||
$torrc="ClientUseIPv6 1
|
||||
function rewrite_torrc(PDO $db, string $instance){
|
||||
$update_onion=$db->prepare('UPDATE onions SET private_key=? WHERE onion=?;');
|
||||
$torrc='ClientUseIPv6 1
|
||||
ClientUseIPv4 1
|
||||
SOCKSPort 0
|
||||
MaxClientCircuitsPending 1024
|
||||
NumEntryGuards 15
|
||||
NumDirectoryGuards 15
|
||||
NumPrimaryGuards 15
|
||||
";
|
||||
$stmt=$db->prepare('SELECT onions.onion, users.system_account, onions.num_intros, onions.enable_smtp, onions.version, onions.max_streams, onions.enabled FROM onions LEFT JOIN users ON (users.id=onions.user_id) WHERE onions.instance = ? AND onions.enabled IN (1, -2) AND users.id NOT IN (SELECT user_id FROM new_account) AND users.todelete!=1;');
|
||||
$stmt->execute([$key]);
|
||||
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
if($tmp[6]==1){
|
||||
$socket=$tmp[1];
|
||||
NumEntryGuards '.NUM_GUARDS.'
|
||||
NumDirectoryGuards '.NUM_GUARDS.'
|
||||
NumPrimaryGuards '.NUM_GUARDS.'
|
||||
';
|
||||
$stmt=$db->prepare('SELECT onions.onion, users.system_account, onions.num_intros, onions.enable_smtp, onions.version, onions.max_streams, onions.enabled, onions.private_key FROM onions LEFT JOIN users ON (users.id=onions.user_id) WHERE onions.instance = ? AND onions.enabled IN (1, -2) AND users.id NOT IN (SELECT user_id FROM new_account) AND users.todelete!=1;');
|
||||
$stmt->execute([$instance]);
|
||||
while($tmp=$stmt->fetch(PDO::FETCH_ASSOC)){
|
||||
if(!file_exists("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion")){
|
||||
if($tmp['version']==2){
|
||||
//php openssl implementation has some issues, re-export using native openssl
|
||||
$pkey=openssl_pkey_get_private($tmp['private_key']);
|
||||
openssl_pkey_export($pkey, $exported);
|
||||
openssl_pkey_free($pkey);
|
||||
$priv_key=shell_exec('echo ' . escapeshellarg($exported) . ' | openssl rsa');
|
||||
//save hidden service
|
||||
mkdir("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion", 0700);
|
||||
file_put_contents("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/private_key", $priv_key);
|
||||
chmod("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/private_key", 0600);
|
||||
chown("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/", "_tor-$instance");
|
||||
chown("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/private_key", "_tor-$instance");
|
||||
chgrp("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/", "_tor-$instance");
|
||||
chgrp("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/private_key", "_tor-$instance");
|
||||
$update_onion->execute([$priv_key, $tmp['onion']]);
|
||||
}elseif($tmp['version']==3){
|
||||
$priv_key=base64_decode($tmp['private_key']);
|
||||
//save hidden service
|
||||
mkdir("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion", 0700);
|
||||
file_put_contents("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/hs_ed25519_secret_key", $priv_key);
|
||||
chmod("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/hs_ed25519_secret_key", 0600);
|
||||
chown("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/", "_tor-$instance");
|
||||
chown("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/hs_ed25519_secret_key", "_tor-$instance");
|
||||
chgrp("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/", "_tor-$instance");
|
||||
chgrp("/var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion/hs_ed25519_secret_key", "_tor-$instance");
|
||||
}
|
||||
}
|
||||
if($tmp['enabled']==1){
|
||||
$socket=$tmp['system_account'];
|
||||
}else{
|
||||
$socket='suspended';
|
||||
}
|
||||
$torrc.="HiddenServiceDir /var/lib/tor-instances/$key/hidden_service_$tmp[0].onion
|
||||
HiddenServiceNumIntroductionPoints $tmp[2]
|
||||
HiddenServiceVersion $tmp[4]
|
||||
$torrc.="HiddenServiceDir /var/lib/tor-instances/$instance/hidden_service_$tmp[onion].onion
|
||||
HiddenServiceNumIntroductionPoints $tmp[num_intros]
|
||||
HiddenServiceVersion $tmp[version]
|
||||
HiddenServiceMaxStreamsCloseCircuit 1
|
||||
HiddenServiceMaxStreams $tmp[5]
|
||||
HiddenServiceMaxStreams $tmp[max_streams]
|
||||
HiddenServicePort 80 unix:/var/run/nginx/$socket
|
||||
";
|
||||
if($tmp[3]){
|
||||
if($tmp['enable_smtp']){
|
||||
$torrc.="HiddenServicePort 25\n";
|
||||
}
|
||||
}
|
||||
file_put_contents("/etc/tor/instances/$key/torrc", $torrc);
|
||||
exec("service tor@$key reload");
|
||||
file_put_contents("/etc/tor/instances/$instance/torrc", $torrc);
|
||||
exec('systemctl reload '.escapeshellarg("tor@$instance"));
|
||||
}
|
||||
|
||||
function private_key_to_onion(string $priv_key) : array {
|
||||
@ -433,8 +462,27 @@ function ed25519_seckey_expand(string $seed) : string {
|
||||
|
||||
function rewrite_nginx_config(PDO $db){
|
||||
$nginx='';
|
||||
$rewrites = [];
|
||||
// rewrite rules
|
||||
$stmt = $db->query('SELECT user_id, regex, replacement, flag, ifnotexists FROM nginx_rewrites;');
|
||||
while($tmp = $stmt->fetch(PDO::FETCH_ASSOC)){
|
||||
if(!isset($rewrites[$tmp['user_id']])){
|
||||
$rewrites[$tmp['user_id']] = '';
|
||||
}
|
||||
if($tmp['ifnotexists']){
|
||||
$rewrites[$tmp['user_id']] .= "if (!-e \$request_filename) {\n\t\t";
|
||||
}
|
||||
$rewrites[$tmp['user_id']] .= "rewrite '$tmp[regex]' '$tmp[replacement]'";
|
||||
if(!empty($tmp['flag'])){
|
||||
$rewrites[$tmp['user_id']] .= " $tmp[flag]";
|
||||
}
|
||||
$rewrites[$tmp['user_id']] .= ";\n\t";
|
||||
if($tmp['ifnotexists']){
|
||||
$rewrites[$tmp['user_id']] .= "}\n\t";
|
||||
}
|
||||
}
|
||||
// onions
|
||||
$stmt=$db->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;");
|
||||
$stmt=$db->query("SELECT users.system_account, users.php, users.autoindex, onions.onion, users.id 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)){
|
||||
if($tmp['php']>0){
|
||||
$php_location="
|
||||
@ -456,7 +504,11 @@ function rewrite_nginx_config(PDO $db){
|
||||
error_log /home/$tmp[system_account]/logs/error.log notice;
|
||||
disable_symlinks on from=/home/$tmp[system_account];
|
||||
autoindex $autoindex;
|
||||
location / {
|
||||
";
|
||||
if(isset($rewrites[$tmp['id']])){
|
||||
$nginx .= $rewrites[$tmp['id']];
|
||||
}
|
||||
$nginx .= "location / {
|
||||
try_files \$uri \$uri/ =404;$php_location
|
||||
}
|
||||
}
|
||||
@ -464,7 +516,7 @@ function rewrite_nginx_config(PDO $db){
|
||||
|
||||
}
|
||||
// clearnet domains
|
||||
$stmt=$db->query("SELECT users.system_account, users.php, users.autoindex, domains.domain FROM users INNER JOIN domains ON (domains.user_id=users.id) WHERE domains.enabled = 1 AND users.id NOT IN (SELECT user_id FROM new_account) AND users.todelete != 1;");
|
||||
$stmt=$db->query("SELECT users.system_account, users.php, users.autoindex, domains.domain, users.id FROM users INNER JOIN domains ON (domains.user_id=users.id) WHERE domains.enabled = 1 AND users.id NOT IN (SELECT user_id FROM new_account) AND users.todelete != 1;");
|
||||
while($tmp=$stmt->fetch(PDO::FETCH_ASSOC)){
|
||||
if($tmp['php']>0){
|
||||
$php_location="
|
||||
@ -486,7 +538,11 @@ function rewrite_nginx_config(PDO $db){
|
||||
error_log /home/$tmp[system_account]/logs/error.log notice;
|
||||
disable_symlinks on from=/home/$tmp[system_account];
|
||||
autoindex $autoindex;
|
||||
location / {
|
||||
";
|
||||
if(isset($rewrites[$tmp['id']])){
|
||||
$nginx .= $rewrites[$tmp['id']];
|
||||
}
|
||||
$nginx .= "location / {
|
||||
try_files \$uri \$uri/ =404;$php_location
|
||||
}
|
||||
}
|
||||
@ -504,7 +560,7 @@ function rewrite_nginx_config(PDO $db){
|
||||
";
|
||||
}
|
||||
file_put_contents("/etc/nginx/streams-enabled/hosted_sites", $nginx);
|
||||
exec("service nginx reload");
|
||||
exec('systemctl reload nginx');
|
||||
}
|
||||
|
||||
function rewrite_php_config(PDO $db, string $key){
|
||||
@ -529,7 +585,7 @@ listen.owner = www-data
|
||||
listen.group = www-data
|
||||
listen.mode = 0660
|
||||
pm = ondemand
|
||||
pm.max_children = 75
|
||||
pm.max_children = 50
|
||||
pm.process_idle_timeout = 10s;
|
||||
chroot = /home/$tmp[system_account]
|
||||
php_admin_value[memory_limit] = 256M
|
||||
@ -540,7 +596,7 @@ php_admin_value[session.save_path] = /tmp
|
||||
";
|
||||
}
|
||||
file_put_contents("/etc/php/$version/fpm/pool.d/$key/www.conf", $php);
|
||||
exec("service php$version-fpm@$key restart");
|
||||
exec('systemctl restart '.escapeshellarg("php$version-fpm@$key"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -602,7 +658,7 @@ function get_new_tor_instance(PDO $db){
|
||||
}
|
||||
|
||||
function add_user_onion(PDO $db, int $user_id, string $onion, string $priv_key, int $onion_version) {
|
||||
$stmt=$db->prepare('INSERT INTO onions (user_id, onion, private_key, version, enabled, instance) VALUES (?, ?, ?, ?, 2, ?);');
|
||||
$stmt=$db->prepare('INSERT INTO onions (user_id, onion, private_key, version, enabled, enable_smtp, instance) VALUES (?, ?, ?, ?, 1, 0, ?);');
|
||||
$stmt->execute([$user_id, $onion, $priv_key, $onion_version, get_new_tor_instance($db)]);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@ $db->query('UPDATE service_instances SET reload=0 WHERE reload=1;');
|
||||
|
||||
//add new accounts
|
||||
$del=$db->prepare("DELETE FROM new_account WHERE user_id=?;");
|
||||
$enable_onion=$db->prepare("UPDATE onions SET enabled=2 WHERE onion=?;");
|
||||
$approval = REQUIRE_APPROVAL ? 'WHERE new_account.approved=1': '';
|
||||
$stmt=$db->query("SELECT users.system_account, users.username, new_account.password, users.php, users.autoindex, users.id, onions.onion, users.instance FROM new_account INNER JOIN users ON (users.id=new_account.user_id) INNER JOIN onions ON (onions.user_id=users.id) $approval LIMIT 100;");
|
||||
while($id=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
@ -24,7 +23,6 @@ while($id=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
$system_account=$id[0];
|
||||
$instance=$id[7];
|
||||
$reload[$instance]=true;
|
||||
$enable_onion->execute([$id[6]]);
|
||||
//add and manage rights of system user
|
||||
$shell = ENABLE_SHELL_ACCESS ? '/bin/bash' : '/usr/sbin/nologin';
|
||||
exec('useradd -l -p ' . escapeshellarg($id[2]) . ' -g www-data -k /var/www/skel -m -s ' . escapeshellarg($shell) . ' ' . escapeshellarg($system_account));
|
||||
@ -44,42 +42,6 @@ while($id=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
$del->execute([$id[5]]);
|
||||
}
|
||||
|
||||
//add hidden services to tor
|
||||
$update_onion=$db->prepare('UPDATE onions SET private_key=?, enabled=1 WHERE onion=?;');
|
||||
$stmt=$db->query('SELECT onion, private_key, version, instance FROM onions WHERE enabled=2;');
|
||||
$onions=$stmt->fetchAll(PDO::FETCH_NUM);
|
||||
foreach($onions as $onion){
|
||||
$instance = $onion[3];
|
||||
$reload[$instance] = true;
|
||||
if($onion[2]==2){
|
||||
//php openssl implementation has some issues, re-export using native openssl
|
||||
$pkey=openssl_pkey_get_private($onion[1]);
|
||||
openssl_pkey_export($pkey, $exported);
|
||||
openssl_pkey_free($pkey);
|
||||
$priv_key=shell_exec('echo ' . escapeshellarg($exported) . ' | openssl rsa');
|
||||
//save hidden service
|
||||
mkdir("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion", 0700);
|
||||
file_put_contents("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/private_key", $priv_key);
|
||||
chmod("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/private_key", 0600);
|
||||
chown("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/", "_tor-$instance");
|
||||
chown("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/private_key", "_tor-$instance");
|
||||
chgrp("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/", "_tor-$instance");
|
||||
chgrp("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/private_key", "_tor-$instance");
|
||||
$update_onion->execute([$priv_key, $onion[0]]);
|
||||
}elseif($onion[2]==3){
|
||||
$priv_key=base64_decode($onion[1]);
|
||||
//save hidden service
|
||||
mkdir("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion", 0700);
|
||||
file_put_contents("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/hs_ed25519_secret_key", $priv_key);
|
||||
chmod("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/hs_ed25519_secret_key", 0600);
|
||||
chown("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/", "_tor-$instance");
|
||||
chown("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/hs_ed25519_secret_key", "_tor-$instance");
|
||||
chgrp("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/", "_tor-$instance");
|
||||
chgrp("/var/lib/tor-instances/$instance/hidden_service_$onion[0].onion/hs_ed25519_secret_key", "_tor-$instance");
|
||||
$update_onion->execute([$onion[1], $onion[0]]);
|
||||
}
|
||||
}
|
||||
|
||||
//delete old accounts
|
||||
$del=$db->prepare("DELETE FROM users WHERE id=?;");
|
||||
$stmt=$db->query("SELECT system_account, id, mysql_user, instance FROM users WHERE todelete=1 LIMIT 100;");
|
||||
|
@ -146,13 +146,13 @@ if(empty($_SESSION['logged_in'])){
|
||||
if($error=check_csrf_error()){
|
||||
echo '<p style="color:red;">'.$error.'</p>';
|
||||
}elseif(preg_match('~^([a-z2-7]{16}|[a-z2-7]{56})(\.onion)?$~', $onion, $match)){
|
||||
$stmt=$db->prepare('SELECT null FROM onions WHERE onion=?;');
|
||||
$stmt=$db->prepare('SELECT instance FROM onions WHERE onion=?;');
|
||||
$stmt->execute([$match[1]]);
|
||||
if($stmt->fetch(PDO::FETCH_NUM)){
|
||||
if($instance=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
$stmt=$db->prepare('UPDATE onions SET enabled=-2 WHERE onion=?;');
|
||||
$stmt->execute([$match[1]]);
|
||||
echo "<p style=\"color:green;\">Successfully queued for suspension!</p>";
|
||||
enqueue_instance_reload($db, substr($match[1], 0, 1));
|
||||
enqueue_instance_reload($db, $instance[0]);
|
||||
}else{
|
||||
echo "<p style=\"color:red;\">Onion address not hosted by us!</p>";
|
||||
}
|
||||
@ -179,7 +179,7 @@ if(empty($_SESSION['logged_in'])){
|
||||
echo '<p style="color:red;">'.$error.'</p>';
|
||||
}elseif(preg_match('~^([a-z2-7]{16}|[a-z2-7]{56})(\.onion)?$~', $onion, $match)){
|
||||
if(isset($_POST['num_intros'])){
|
||||
$stmt=$db->prepare('SELECT version FROM onions WHERE onion=?;');
|
||||
$stmt=$db->prepare('SELECT version, instance FROM onions WHERE onion=?;');
|
||||
$stmt->execute([$match[1]]);
|
||||
if($onion=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
$stmt=$db->prepare('UPDATE onions SET enabled = ?, enable_smtp = ?, num_intros = ?, max_streams = ? WHERE onion=?;');
|
||||
@ -200,7 +200,7 @@ if(empty($_SESSION['logged_in'])){
|
||||
$max_streams = 65535;
|
||||
}
|
||||
$stmt->execute([$enabled, $enable_smtp, $num_intros, $max_streams, $match[1]]);
|
||||
enqueue_instance_reload($db, substr($match[1], 0, 1));
|
||||
enqueue_instance_reload($db, $onion[1]);
|
||||
echo "<p style=\"color:green;\">Changes successfully saved!</p>";
|
||||
}
|
||||
}
|
||||
|
@ -242,6 +242,7 @@ if(!empty($_FILES['files'])){
|
||||
|
||||
$files=$dirs=[];
|
||||
$list=ftp_rawlist($ftp, '.');
|
||||
if(is_array($list)){
|
||||
foreach($list as $file){
|
||||
preg_match('/^([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+([^\s]*)\s+(.*)$/', $file, $match);
|
||||
if($match[0][0]==='d'){
|
||||
@ -250,6 +251,7 @@ foreach($list as $file){
|
||||
$files[$match[9]]=['name'=>$match[9], 'mtime'=>ftp_mdtm($ftp, $match[9]), 'size'=>$match[5]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//sort our files
|
||||
if($sort==='M'){
|
||||
|
@ -30,6 +30,7 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';"))
|
||||
$db->exec("CREATE TABLE onions (user_id int(11) NULL, onion varchar(56) COLLATE latin1_bin NOT NULL PRIMARY KEY, private_key varchar(1000) COLLATE latin1_bin NOT NULL, version tinyint(1) NOT NULL, enabled tinyint(1) NOT NULL DEFAULT '1', num_intros tinyint(3) NOT NULL DEFAULT '3', enable_smtp tinyint(1) NOT NULL DEFAULT '1', max_streams tinyint(3) unsigned NOT NULL DEFAULT '20', instance char(1) NOT NULL DEFAULT '2', KEY user_id (user_id), KEY enabled (enabled), KEY instance(instance), CONSTRAINT onions_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE SET NULL ON UPDATE CASCADE, CONSTRAINT instance_ibfk_1 FOREIGN KEY (instance) REFERENCES service_instances (id) ON DELETE RESTRICT ON UPDATE RESTRICT) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;");
|
||||
$db->exec("CREATE TABLE domains (user_id int(11) NULL, domain varchar(255) COLLATE latin1_bin NOT NULL PRIMARY KEY, enabled tinyint(1) NOT NULL DEFAULT '1', KEY user_id (user_id), KEY enabled (enabled), CONSTRAINT domains_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;");
|
||||
$db->exec('CREATE TABLE disk_quota (user_id int(11) NOT NULL, quota_size int(10) unsigned NOT NULL, quota_files int(10) unsigned NOT NULL, updated tinyint(1) NOT NULL DEFAULT 1, KEY user_id (user_id), KEY updated (updated), CONSTRAINT disk_quota_ibfk_2 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;');
|
||||
$db->exec('CREATE TABLE nginx_rewrites (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, user_id int(11) NOT NULL, `regex` varchar(255) NOT NULL, replacement varchar(255) NOT NULL, `flag` varchar(9) NOT NULL, ifnotexists tinyint(1) NOT NULL, CONSTRAINT nginx_rewrites_ibfk_2 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;');
|
||||
$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]);
|
||||
@ -150,6 +151,10 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';"))
|
||||
$stmt = $db->prepare('INSERT INTO disk_quota (user_id, quota_size, quota_files) SELECT id, ?, ? FROM users;');
|
||||
$stmt->execute([DEFAULT_QUOTA_SIZE, DEFAULT_QUOTA_FILES]);
|
||||
}
|
||||
if($version<16){
|
||||
$db->exec('UPDATE onions SET enabled=1 WHERE enabled=2;');
|
||||
$db->exec('CREATE TABLE nginx_rewrites (id int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, user_id int(11) NOT NULL, `regex` varchar(255) NOT NULL, replacement varchar(255) NOT NULL, `flag` varchar(9) NOT NULL, ifnotexists tinyint(1) NOT NULL, CONSTRAINT nginx_rewrites_ibfk_2 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;');
|
||||
}
|
||||
$stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';");
|
||||
$stmt->execute([DBVERSION]);
|
||||
}
|
||||
@ -253,7 +258,7 @@ php_admin_value[open_basedir] = /html/adminer:/tmp
|
||||
mkdir("/etc/php/$version/fpm/pool.d/", 0755, true);
|
||||
}
|
||||
file_put_contents("/etc/php/$version/fpm/pool.d/www.conf", $pool_config);
|
||||
exec("service php$version-fpm@default reload");
|
||||
exec('systemctl reload '.escapeshellarg("php$version-fpm@default"));
|
||||
}
|
||||
echo "Updating chroots, this might take a while…\n";
|
||||
exec('/var/www/setup_chroot.sh /var/www');
|
||||
@ -275,10 +280,32 @@ 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");
|
||||
exec('systemctl reload nginx');
|
||||
$stmt=$db->prepare('INSERT IGNORE INTO service_instances (id) VALUES (?);');
|
||||
foreach(SERVICE_INSTANCES as $key){
|
||||
$stmt->execute([$key]);
|
||||
}
|
||||
$stmt=$db->query('SELECT id FROM service_instances;');
|
||||
$update_users=$db->prepare('UPDATE users SET instance = (SELECT id FROM service_instances WHERE id !=? ORDER BY RAND() limit 1) WHERE instance=?;');
|
||||
$update_onions=$db->prepare('UPDATE onions SET instance = (SELECT id FROM service_instances WHERE id !=? ORDER BY RAND() limit 1) WHERE instance=?;');
|
||||
$drop_instance=$db->prepare('DELETE FROM service_instances WHERE id=?;');
|
||||
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
|
||||
if(!in_array($tmp[0], SERVICE_INSTANCES)){
|
||||
exec('systemctl stop '.escapeshellarg("tor@$tmp[0]"));
|
||||
exec('systemctl disable '.escapeshellarg("tor@$tmp[0]"));
|
||||
exec('rm -r '.escapeshellarg("/var/lib/tor-instances/$tmp[0]/"));
|
||||
exec('rm -r '.escapeshellarg("/etc/tor/instances/$tmp[0]/"));
|
||||
exec('userdel '.escapeshellarg("_tor-$tmp[0]"));
|
||||
foreach(PHP_VERSIONS as $version){
|
||||
exec('systemctl stop '.escapeshellarg("php$version-fpm@$tmp[0]"));
|
||||
exec('systemctl disable '.escapeshellarg("php$version-fpm@$tmp[0]"));
|
||||
exec('rm -r '.escapeshellarg("/etc/php/$version/fpm/pool.d/$tmp[0]/"));
|
||||
unlink("/etc/php/$version/fpm/php-fpm-".basename($tmp[0]).'.conf');
|
||||
}
|
||||
$update_users->execute([$tmp[0], $tmp[0]]);
|
||||
$update_onions->execute([$tmp[0], $tmp[0]]);
|
||||
$drop_instance->execute($tmp);
|
||||
}
|
||||
}
|
||||
$db->exec('UPDATE service_instances SET reload=1;');
|
||||
echo "Done - Database and files have been updated to the latest version :)\n";
|
||||
|
@ -15,34 +15,32 @@ function CHROOT_BINARY() {
|
||||
if [ "$LIB_FILES" != "" ]; then
|
||||
for LIB_FILE in $LIB_FILES; do
|
||||
LIB_DIRECTORY="$(dirname $LIB_FILE)"
|
||||
test -d $CHROOT_DIRECTORY$LIB_DIRECTORY || mkdir -pm 0555 $CHROOT_DIRECTORY$LIB_DIRECTORY
|
||||
diff $LIB_FILE $CHROOT_DIRECTORY$LIB_FILE > /dev/null 2>&1 || cp $LIB_FILE $CHROOT_DIRECTORY$LIB_FILE
|
||||
mkdir -pm 0555 $CHROOT_DIRECTORY$LIB_DIRECTORY
|
||||
cp $LIB_FILE $CHROOT_DIRECTORY$LIB_FILE
|
||||
chmod 0555 $CHROOT_DIRECTORY$LIB_FILE
|
||||
done
|
||||
fi
|
||||
if [ "$LDD_FILES" != "" ]; then
|
||||
for LDD_FILE in $LDD_FILES; do
|
||||
LDD_DIRECTORY="$(dirname $LDD_FILE)"
|
||||
test -d $CHROOT_DIRECTORY$LDD_DIRECTORY || mkdir -pm 0555 $CHROOT_DIRECTORY${LDD_DIRECTORY}
|
||||
diff $LDD_FILE $CHROOT_DIRECTORY$LDD_FILE > /dev/null 2>&1 || cp $LDD_FILE $CHROOT_DIRECTORY$LDD_FILE
|
||||
mkdir -pm 0555 $CHROOT_DIRECTORY${LDD_DIRECTORY}
|
||||
cp $LDD_FILE $CHROOT_DIRECTORY$LDD_FILE
|
||||
chmod 0555 $CHROOT_DIRECTORY$LDD_FILE
|
||||
done
|
||||
fi
|
||||
diff $BINARY $CHROOT_DIRECTORY/$BINARY > /dev/null 2>&1 || cp $BINARY $CHROOT_DIRECTORY/$BINARY
|
||||
cp $BINARY $CHROOT_DIRECTORY/$BINARY
|
||||
chmod 0555 $CHROOT_DIRECTORY/$BINARY
|
||||
}
|
||||
|
||||
function CHROOT_FILE() {
|
||||
diff $1 $CHROOT_DIRECTORY/$1 > /dev/null 2>&1 || cp $1 $CHROOT_DIRECTORY/$1
|
||||
cp $1 $CHROOT_DIRECTORY/$1
|
||||
}
|
||||
|
||||
function CHROOT_DIRECTORY() {
|
||||
test -d $CHROOT_DIRECTORY/$1 || mkdir -pm 0555 $CHROOT_DIRECTORY/$1
|
||||
diff -r $1 $CHROOT_DIRECTORY/$1 > /dev/null 2>&1 || {
|
||||
test ! -d $CHROOT_DIRECTORY/$1 || rm -rf $CHROOT_DIRECTORY/$1/ > /dev/null 2>&1
|
||||
mkdir -pm 0555 $CHROOT_DIRECTORY/$1
|
||||
rm -rf $CHROOT_DIRECTORY/$1/ > /dev/null 2>&1
|
||||
cp -Rp $1 $CHROOT_DIRECTORY/$1
|
||||
}
|
||||
}
|
||||
|
||||
### variables
|
||||
CHROOT_DIRECTORY=$1
|
||||
@ -204,6 +202,9 @@ echo "root:x:0:0:root:/root:/bin/bash" > $CHROOT_DIRECTORY/etc/passwd
|
||||
echo "www-data:x:33:33::/var/www:/bin/bash" >> $CHROOT_DIRECTORY/etc/passwd
|
||||
echo "root:x:0:" > $CHROOT_DIRECTORY/etc/group
|
||||
echo "www-data:x:33:www-data" >> $CHROOT_DIRECTORY/etc/group
|
||||
echo "export HOME=/" > $CHROOT_DIRECTORY/etc/profile.d/hosting.sh
|
||||
echo "export HISTFILE=/.bash_history" >> $CHROOT_DIRECTORY/etc/profile.d/hosting.sh
|
||||
|
||||
# /dev devices
|
||||
test -e $CHROOT_DIRECTORY/dev/null || mknod -m 666 $CHROOT_DIRECTORY/dev/null c 1 3
|
||||
test -e $CHROOT_DIRECTORY/dev/zero || mknod -m 666 $CHROOT_DIRECTORY/dev/zero c 1 5
|
||||
@ -235,4 +236,4 @@ done
|
||||
for BINARY in /usr/lib/php/*/*.so; do
|
||||
CHROOT_BINARY $BINARY
|
||||
done
|
||||
diff $CHROOT_DIRECTORY/usr/bin/php7.3 $CHROOT_DIRECTORY/usr/bin/php > /dev/null 2>&1 || cp -r $CHROOT_DIRECTORY/usr/bin/php7.3 $CHROOT_DIRECTORY/usr/bin/php
|
||||
cp -l $CHROOT_DIRECTORY/usr/bin/php7.3 $CHROOT_DIRECTORY/usr/bin/php
|
||||
|
Reference in New Issue
Block a user