From 58b5efb96c0397c9714347080c09313862955f77 Mon Sep 17 00:00:00 2001 From: Daniel Winzen Date: Sun, 28 Oct 2018 08:48:30 +0100 Subject: [PATCH] Added suspend hidden service feature + disabled php7.0 for new accounts --- var/www/common.php | 60 +++++++++++++-- var/www/cron.php | 164 ++++++++++++++++++++++++----------------- var/www/html/admin.php | 28 ++++++- var/www/html/home.php | 9 ++- var/www/setup.php | 17 ++++- 5 files changed, 202 insertions(+), 76 deletions(-) diff --git a/var/www/common.php b/var/www/common.php index c47a696..36c9e1a 100644 --- a/var/www/common.php +++ b/var/www/common.php @@ -4,7 +4,7 @@ const DBUSER='hosting'; // Database user const DBPASS='MY_PASSWORD'; // Database password const DBNAME='hosting'; // Database const PERSISTENT=true; // Use persistent database conection true/false -const DBVERSION=9; //database layout version +const DBVERSION=10; //database layout version const CAPTCHA=0; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme) const ADDRESS='dhosting4okcs22v.onion'; // our own address const SERVERS=[ //servers and ports we are running on @@ -19,7 +19,8 @@ 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 ADMIN_PASSWORD='MY_PASSWORD'; //password for admin interface const SERVICE_INSTANCES=['2', '3', '4', '5', '6', '7', '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']; -const PHP_VERSIONS=[1 => '7.0', 2 => '7.1', 3 => '7.2', 4 => '7.3']; +const DISABLED_PHP_VERSIONS=[1 => '7.0']; +const PHP_VERSIONS=[2 => '7.1', 3 => '7.2', 4 => '7.3']; const PHP_CONFIG='memory_limit = 256M error_reporting = E_ALL post_max_size = 10G @@ -40,7 +41,51 @@ opcache.revalidate_freq=2 opcache.revalidate_path=1 opcache.save_comments=1 opcache.optimization_level=0xffffffff -opcache.validate_permission=1'; +opcache.validate_permission=1 +'; +const NGINX_DEFAULT = 'server { + listen unix:/var/run/nginx/suspended backlog=2048; + add_header Content-Type text/html; + location / { + return 200 \'SuspendedThis domain has been suspended due to violation of hosting rules.\'; + } +} +server { + listen [::]:80 ipv6only=off fastopen=100 backlog=2048 default_server; + listen unix:/var/run/nginx.sock backlog=2048 default_server; + root /var/www/html; + index index.php; + server_name ' . ADDRESS . ' *.' . ADDRESS . '; + location / { + try_files $uri $uri/ =404; + location ~ \.php$ { + include snippets/fastcgi-php.conf; + fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; + } + } + location /phpmyadmin { + root /usr/share; + location ~ \.php$ { + include snippets/fastcgi-php.conf; + fastcgi_pass unix:/run/php/php7.2-fpm.sock; + } + } + location /adminer { + root /usr/share/adminer; + location ~ \.php$ { + include snippets/fastcgi-php.conf; + fastcgi_pass unix:/run/php/php7.2-fpm.sock; + } + } + location /externals/jush/ { + root /usr/share/adminer; + } + location /nginx/ { + root /var/log/; + internal; + } +} +'; function get_onion($pkey){ $keyData = openssl_pkey_get_details($pkey); @@ -233,15 +278,20 @@ NumEntryGuards 6 NumDirectoryGuards 6 NumPrimaryGuards 6 "; - $stmt=$db->prepare('SELECT onions.onion, users.system_account, onions.num_intros, onions.enable_smtp, onions.version, onions.max_streams FROM onions INNER JOIN users ON (users.id=onions.user_id) WHERE onions.onion LIKE ? AND onions.enabled=1;'); + $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.onion LIKE ? AND onions.enabled IN (1, -2) AND users.id NOT IN (SELECT user_id FROM new_account);'); $stmt->execute(["$key%"]); while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ +if($tmp[6]==1){ + $socket=$tmp[1]; +}else{ + $socket='suspended'; +} $torrc.="HiddenServiceDir /var/lib/tor-instances/$key/hidden_service_$tmp[0].onion/ HiddenServiceNumIntroductionPoints $tmp[2] HiddenServiceVersion $tmp[4] HiddenServiceMaxStreamsCloseCircuit 1 HiddenServiceMaxStreams $tmp[5] -HiddenServicePort 80 unix:/var/run/nginx/$tmp[1] +HiddenServicePort 80 unix:/var/run/nginx/$socket "; if($tmp[3]){ $torrc.="HiddenServicePort 25\n"; diff --git a/var/www/cron.php b/var/www/cron.php index ac09ffb..42a011d 100644 --- a/var/www/cron.php +++ b/var/www/cron.php @@ -16,21 +16,15 @@ $db->query('UPDATE service_instances SET reload=0 WHERE reload=1;'); //add new accounts $del=$db->prepare("DELETE FROM new_account WHERE user_id=?;"); -$update_priv=$db->prepare("UPDATE onions SET private_key=? 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, onions.private_key, users.php, users.autoindex, users.id, onions.onion 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;"); +$stmt=$db->query("SELECT users.system_account, users.username, new_account.password, users.php, users.autoindex, users.id, onions.onion 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)){ - $onion=$id[7]; + $onion=$id[6]; $system_account=$id[0]; $firstchar=substr($system_account, 0, 1); $reload[$firstchar]=true; - //php openssl implementation has some issues, re-export using native openssl - $pkey=openssl_pkey_get_private($id[3]); - openssl_pkey_export_to_file($pkey, 'key.tmp'); - openssl_pkey_free($pkey); - $priv_key=shell_exec('openssl rsa < key.tmp'); - unlink('key.tmp'); - $update_priv->execute([$priv_key, $id[6]]); + $enable_onion->execute([$id[6]]); //add and manage rights of system user exec('useradd -l -p ' . escapeshellarg($id[2]) . ' -g www-data -k /var/www/skel -m -s /usr/sbin/nologin ' . escapeshellarg($system_account)); chown("/home/$system_account", 'root'); @@ -49,7 +43,7 @@ while($id=$stmt->fetch(PDO::FETCH_NUM)){ //configuration for services -if($id[4]>0){ +if($id[3]>0){ $php_location=" location ~ [^/]\.php(/|\$) { include snippets/fastcgi-php.conf; @@ -59,7 +53,7 @@ $php_location=" }else{ $php_location=''; } -if($id[5]){ +if($id[4]){ $autoindex='on'; }else{ $autoindex='off'; @@ -104,62 +98,98 @@ php_admin_value[session.save_path] = /home/$system_account/tmp //save configuration files file_put_contents("/etc/nginx/sites-enabled/$system_account", $nginx); foreach(PHP_VERSIONS as $key=>$version){ - if($id[4]==$key){ + if($id[3]==$key){ file_put_contents("/etc/php/$version/fpm/pool.d/$firstchar/$system_account.conf", $php); break; } } - //save hidden service - mkdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion", 0700); - file_put_contents("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/hostname", "$onion.onion\n"); - file_put_contents("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/private_key", $priv_key); - chmod("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/hostname", 0600); - chmod("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/private_key", 0600); - chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/", "_tor-$firstchar"); - chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/hostname", "_tor-$firstchar"); - chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/private_key", "_tor-$firstchar"); - chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/", "_tor-$firstchar"); - chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/hostname", "_tor-$firstchar"); - chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion.onion/private_key", "_tor-$firstchar"); //remove from to-add queue - $del->execute([$id[6]]); + $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 FROM onions WHERE enabled=2;'); +$onions=$stmt->fetchAll(PDO::FETCH_NUM); +foreach($onions as $onion){ + $firstchar=substr($onion[0], 0, 1); + $reload[$firstchar]=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_to_file($pkey, 'key.tmp'); + openssl_pkey_free($pkey); + $priv_key=shell_exec('openssl rsa < key.tmp'); + unlink('key.tmp'); + //save hidden service + mkdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion", 0700); + file_put_contents("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hostname", "$onion[0].onion\n"); + file_put_contents("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key", $priv_key); + chmod("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hostname", 0600); + chmod("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key", 0600); + chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/", "_tor-$firstchar"); + chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hostname", "_tor-$firstchar"); + chown("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key", "_tor-$firstchar"); + chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/", "_tor-$firstchar"); + chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/hostname", "_tor-$firstchar"); + chgrp("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/private_key", "_tor-$firstchar"); + $update_onion->execute([$priv_key, $onion[0]]); + } } //delete old accounts $del=$db->prepare("DELETE FROM users WHERE id=?;"); $stmt=$db->query("SELECT system_account, id, mysql_user FROM users WHERE todelete=1 LIMIT 100;"); +$accounts=$stmt->fetchAll(PDO::FETCH_NUM); +$mark_onions=$db->prepare('UPDATE onions SET enabled=-1 WHERE user_id=? AND enabled!=-2;'); +foreach($accounts as $account){ + $firstchar=substr($account[0], 0, 1); + $reload[$firstchar]=true; + //delete config files + foreach(DISABLED_PHP_VERSIONS as $v){ + // new naming schema + if(file_exists("/etc/php/$v/fpm/pool.d/$firstchar/$account[0].conf")){ + unlink("/etc/php/$v/fpm/pool.d/$firstchar/$account[0].conf"); + } + // old naming schema + if(file_exists("/etc/php/$v/fpm/pool.d/$firstchar/".substr($account[0], 0, 16).".conf")){ + unlink("/etc/php/$v/fpm/pool.d/$firstchar/".substr($account[0], 0, 16).".conf"); + } + } + foreach(PHP_VERSIONS as $v){ + // new naming schema + if(file_exists("/etc/php/$v/fpm/pool.d/$firstchar/$account[0].conf")){ + unlink("/etc/php/$v/fpm/pool.d/$firstchar/$account[0].conf"); + } + // old naming schema + if(file_exists("/etc/php/$v/fpm/pool.d/$firstchar/".substr($account[0], 0, 16).".conf")){ + unlink("/etc/php/$v/fpm/pool.d/$firstchar/".substr($account[0], 0, 16).".conf"); + } + } + if(file_exists("/etc/nginx/sites-enabled/$account[0]")){ + unlink("/etc/nginx/sites-enabled/$account[0]"); + } + $mark_onions->execute([$account[1]]); +} + +//delete hidden services from tor +$del_onions=$db->prepare('DELETE FROM onions WHERE onion=?;'); +$stmt=$db->query('SELECT onion FROM onions WHERE enabled=-1;'); $onions=$stmt->fetchAll(PDO::FETCH_NUM); -$stmt=$db->prepare('SELECT onion FROM onions WHERE user_id=?;'); -$del_onions=$db->prepare('DELETE FROM onions WHERE user_id=?;'); foreach($onions as $onion){ $firstchar=substr($onion[0], 0, 1); $reload[$firstchar]=true; - //delete config files - foreach(PHP_VERSIONS as $v){ - // new naming schema - if(file_exists("/etc/php/$v/fpm/pool.d/$firstchar/$onion[0].conf")){ - unlink("/etc/php/$v/fpm/pool.d/$firstchar/$onion[0].conf"); - } - // old naming schema - if(file_exists("/etc/php/$v/fpm/pool.d/$firstchar/".substr($onion[0], 0, 16).".conf")){ - unlink("/etc/php/$v/fpm/pool.d/$firstchar/".substr($onion[0], 0, 16).".conf"); + if(file_exists("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/")){ + foreach(glob("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/*") as $file){ + unlink($file); } + rmdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/"); } - if(file_exists("/etc/nginx/sites-enabled/$onion[0]")){ - unlink("/etc/nginx/sites-enabled/$onion[0]"); - } - $stmt->execute([$onion[1]]); - while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ - //delete hidden service from tor - if(file_exists("/var/lib/tor-instances/$firstchar/hidden_service_$tmp[0].onion/")){ - unlink("/var/lib/tor-instances/$firstchar/hidden_service_$tmp[0].onion/hostname"); - unlink("/var/lib/tor-instances/$firstchar/hidden_service_$tmp[0].onion/private_key"); - rmdir("/var/lib/tor-instances/$firstchar/hidden_service_$tmp[0].onion/"); - } - } - $del_onions->execute([$onion[1]]); + $del_onions->execute([$onion[0]]); } + + //reload services if(!empty($reload)){ exec('service nginx reload'); @@ -173,39 +203,39 @@ foreach($reload as $key => $val){ //continue deleting old accounts $stmt=$db->prepare('SELECT mysql_database FROM mysql_databases WHERE user_id=?;'); -foreach($onions as $onion){ +foreach($accounts as $account){ //kill processes of the user to allow deleting system users - exec('skill -u ' . escapeshellarg($onion[0])); + exec('skill -u ' . escapeshellarg($account[0])); //delete user and group - exec('userdel -rf ' . escapeshellarg($onion[0])); + exec('userdel -rf ' . escapeshellarg($account[0])); //delete all log files - if(file_exists("/var/log/nginx/access_$onion[0].log")){ - unlink("/var/log/nginx/access_$onion[0].log"); + if(file_exists("/var/log/nginx/access_$account[0].log")){ + unlink("/var/log/nginx/access_$account[0].log"); } - if(file_exists("/var/log/nginx/access_$onion[0].log.1")){ - unlink("/var/log/nginx/access_$onion[0].log.1"); + if(file_exists("/var/log/nginx/access_$account[0].log.1")){ + unlink("/var/log/nginx/access_$account[0].log.1"); } - if(file_exists("/var/log/nginx/error_$onion[0].log")){ - unlink("/var/log/nginx/error_$onion[0].log"); + if(file_exists("/var/log/nginx/error_$account[0].log")){ + unlink("/var/log/nginx/error_$account[0].log"); } - if(file_exists("/var/log/nginx/error_$onion[0].log.1")){ - unlink("/var/log/nginx/error_$onion[0].log.1"); + if(file_exists("/var/log/nginx/error_$account[0].log.1")){ + unlink("/var/log/nginx/error_$account[0].log.1"); } //delete user from database - $db->exec("DROP USER '$onion[2]'@'%';"); - $stmt->execute([$onion[1]]); + $db->exec("DROP USER '$account[2]'@'%';"); + $stmt->execute([$account[1]]); while($tmp=$stmt->fetch(PDO::FETCH_NUM)){ $db->exec("DROP DATABASE IF EXISTS `$tmp[0]`;"); } $db->exec('FLUSH PRIVILEGES;'); //delete user from user database - $del->execute([$onion[1]]); + $del->execute([$account[1]]); } // update passwords $stmt=$db->query("SELECT users.system_account, pass_change.password, users.id FROM pass_change INNER JOIN users ON (users.id=pass_change.user_id) LIMIT 100;"); $del=$db->prepare("DELETE FROM pass_change WHERE user_id=?;"); -while($onion=$stmt->fetch(PDO::FETCH_NUM)){ - exec('usermod -p '. escapeshellarg($onion[1]) . ' ' . escapeshellarg($onion[0])); - $del->execute([$onion[2]]); +while($account=$stmt->fetch(PDO::FETCH_NUM)){ + exec('usermod -p '. escapeshellarg($account[1]) . ' ' . escapeshellarg($account[0])); + $del->execute([$account[2]]); } diff --git a/var/www/html/admin.php b/var/www/html/admin.php index 5e8c989..ac1fcb4 100644 --- a/var/www/html/admin.php +++ b/var/www/html/admin.php @@ -42,7 +42,7 @@ if(empty($_SESSION['logged_in'])){ $cnt=$stmt->fetch(PDO::FETCH_NUM)[0]; echo "Approve pending sites ($cnt) | "; } - echo "List of accounts | Delete accounts | Edit hidden services | Logout

"; + echo "List of accounts | Delete accounts | Suspend hidden services | Edit hidden services | Logout

"; if(empty($_REQUEST['action']) || $_REQUEST['action']==='login'){ echo '

Welcome to the admin panel!

'; }elseif($_REQUEST['action']==='logout'){ @@ -94,6 +94,32 @@ if(empty($_SESSION['logged_in'])){ echo "

Invalid onion address!

"; } } + }elseif($_REQUEST['action']==='suspend'){ + echo '

Suspend hidden service:

'; + echo "
"; + echo '

Onion address:

'; + echo '

'; + if(!empty($_POST['onion'])){ + if(preg_match('~^([a-z2-7]{16}|[a-z2-7]{56})(\.onion)?$~', $_POST['onion'], $match)){ + $stmt=$db->prepare('SELECT null FROM onions WHERE onion=?;'); + $stmt->execute([$match[1]]); + if($stmt->fetch(PDO::FETCH_NUM)){ + $stmt=$db->prepare('UPDATE onions SET enabled=-2 WHERE onion=?;'); + $stmt->execute([$match[1]]); + echo "

Successfully queued for suspension!

"; + $stmt=$db->prepare('UPDATE service_instances SET reload = 1 WHERE id=?'); + $stmt->execute([substr($match[1], 0, 1)]); + }else{ + echo "

Onion address not hosted by us!

"; + } + }else{ + echo "

Invalid onion address!

"; + } + } }elseif(in_array($_REQUEST['action'], ['edit', 'edit_2'], true)){ echo '

Edit hidden service:

'; echo "
"; diff --git a/var/www/html/home.php b/var/www/html/home.php index 9ecba6f..dcb38c1 100644 --- a/var/www/html/home.php +++ b/var/www/html/home.php @@ -8,7 +8,7 @@ try{ session_start(); $user=check_login(); if(isset($_REQUEST['action']) && isset($_REQUEST['onion']) && $_REQUEST['action']==='edit'){ - $stmt=$db->prepare('SELECT onions.version FROM onions INNER JOIN users ON (users.id=onions.user_id) WHERE onions.onion=? AND users.id=?;'); + $stmt=$db->prepare('SELECT onions.version FROM onions INNER JOIN users ON (users.id=onions.user_id) WHERE onions.onion=? AND users.id=? AND onions.enabled IN (0, 1);'); $stmt->execute([$_REQUEST['onion'], $user['id']]); if($onion=$stmt->fetch(PDO::FETCH_NUM)){ $stmt=$db->prepare('UPDATE onions SET enabled = ?, enable_smtp = ?, num_intros = ?, max_streams = ? WHERE onion=?;'); @@ -63,7 +63,12 @@ while($onion=$stmt->fetch(PDO::FETCH_ASSOC)){ echo '>Enabled'; echo ''; echo ''; - echo ''; + if(in_array($onion['enabled'], [0, 1])){ + echo ''; + }else{ + echo 'Unavailable'; + } + echo ''; } echo ''; echo '

MySQL Database

'; diff --git a/var/www/setup.php b/var/www/setup.php index 8d24c80..9c73bcb 100644 --- a/var/www/setup.php +++ b/var/www/setup.php @@ -26,7 +26,7 @@ if(!@$version=$db->query("SELECT value FROM settings WHERE setting='version';")) $db->exec('CREATE TABLE new_account (user_id int(11) NOT NULL PRIMARY KEY, password varchar(255) COLLATE latin1_bin NOT NULL, approved tinyint(1) UNSIGNED NOT NULL, CONSTRAINT new_account_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 pass_change (user_id int(11) NOT NULL PRIMARY KEY, password varchar(255) COLLATE latin1_bin NOT NULL, CONSTRAINT pass_change_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 mysql_databases (user_id int(11) NOT NULL, mysql_database varchar(64) COLLATE latin1_bin NOT NULL, KEY user_id, CONSTRAINT mysql_database_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 onions (user_id int(11) NOT 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', KEY user_id (user_id), KEY enabled (enabled), CONSTRAINT onions_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 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', KEY user_id (user_id), KEY enabled (enabled), CONSTRAINT onions_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE SET NULL ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); $db->exec("CREATE TABLE service_instances (id char(1) NOT NULL PRIMARY KEY, reload tinyint(1) UNSIGNED NOT NULL DEFAULT '0', KEY reload (reload)) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_bin;"); $stmt=$db->prepare('INSERT INTO service_instances (id) VALUES (?);'); foreach(SERVICE_INSTANCES as $key){ @@ -91,6 +91,7 @@ pm.max_children = 8 file_put_contents("/etc/php/$version/fpm/pool.d/$instance/www.conf", $pool_config); } } + file_put_contents('/etc/nginx/sites-enabled/default', NGINX_DEFAULT); echo "Database and files have successfully been set up\n"; }else{ $version=$version->fetch(PDO::FETCH_NUM)[0]; @@ -212,6 +213,20 @@ pm.max_children = 8 } $db->exec('UPDATE service_instances SET reload=1;'); } + if($version<10){ + $db->exec('ALTER TABLE onions CHANGE user_id user_id int(11) NULL;'); + $db->exec('ALTER TABLE onions DROP FOREIGN KEY onions_ibfk_1;'); + $db->exec('ALTER TABLE onions ADD CONSTRAINT onions_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE SET NULL ON UPDATE CASCADE;'); + $nginx_default = 'server { + listen unix:/var/run/nginx/suspended backlog=2048; + add_header Content-Type text/html; + location / { + return 200 \'SuspendedThis domain has been suspended due to violation of hosting rules.\'; + } +} +'; + file_put_contents('/etc/nginx/sites-enabled/default', $nginx_default, FILE_APPEND); + } $stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';"); $stmt->execute([DBVERSION]); if(DBVERSION!=$version){