Added suspend hidden service feature + disabled php7.0 for new accounts
This commit is contained in:
@ -4,7 +4,7 @@ const DBUSER='hosting'; // Database user
|
|||||||
const DBPASS='MY_PASSWORD'; // Database password
|
const DBPASS='MY_PASSWORD'; // Database password
|
||||||
const DBNAME='hosting'; // Database
|
const DBNAME='hosting'; // Database
|
||||||
const PERSISTENT=true; // Use persistent database conection true/false
|
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 CAPTCHA=0; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme)
|
||||||
const ADDRESS='dhosting4okcs22v.onion'; // our own address
|
const ADDRESS='dhosting4okcs22v.onion'; // our own address
|
||||||
const SERVERS=[ //servers and ports we are running on
|
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 REQUIRE_APPROVAL=false; //require admin approval of new sites? true/false
|
||||||
const ADMIN_PASSWORD='MY_PASSWORD'; //password for admin interface
|
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 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
|
const PHP_CONFIG='memory_limit = 256M
|
||||||
error_reporting = E_ALL
|
error_reporting = E_ALL
|
||||||
post_max_size = 10G
|
post_max_size = 10G
|
||||||
@ -40,7 +41,51 @@ opcache.revalidate_freq=2
|
|||||||
opcache.revalidate_path=1
|
opcache.revalidate_path=1
|
||||||
opcache.save_comments=1
|
opcache.save_comments=1
|
||||||
opcache.optimization_level=0xffffffff
|
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 \'<html><head><title>Suspended</title></head><body>This domain has been suspended due to violation of <a href="http://' . ADDRESS . '">hosting rules</a>.</body></html>\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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){
|
function get_onion($pkey){
|
||||||
$keyData = openssl_pkey_get_details($pkey);
|
$keyData = openssl_pkey_get_details($pkey);
|
||||||
@ -233,15 +278,20 @@ NumEntryGuards 6
|
|||||||
NumDirectoryGuards 6
|
NumDirectoryGuards 6
|
||||||
NumPrimaryGuards 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%"]);
|
$stmt->execute(["$key%"]);
|
||||||
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
|
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/
|
$torrc.="HiddenServiceDir /var/lib/tor-instances/$key/hidden_service_$tmp[0].onion/
|
||||||
HiddenServiceNumIntroductionPoints $tmp[2]
|
HiddenServiceNumIntroductionPoints $tmp[2]
|
||||||
HiddenServiceVersion $tmp[4]
|
HiddenServiceVersion $tmp[4]
|
||||||
HiddenServiceMaxStreamsCloseCircuit 1
|
HiddenServiceMaxStreamsCloseCircuit 1
|
||||||
HiddenServiceMaxStreams $tmp[5]
|
HiddenServiceMaxStreams $tmp[5]
|
||||||
HiddenServicePort 80 unix:/var/run/nginx/$tmp[1]
|
HiddenServicePort 80 unix:/var/run/nginx/$socket
|
||||||
";
|
";
|
||||||
if($tmp[3]){
|
if($tmp[3]){
|
||||||
$torrc.="HiddenServicePort 25\n";
|
$torrc.="HiddenServicePort 25\n";
|
||||||
|
164
var/www/cron.php
164
var/www/cron.php
@ -16,21 +16,15 @@ $db->query('UPDATE service_instances SET reload=0 WHERE reload=1;');
|
|||||||
|
|
||||||
//add new accounts
|
//add new accounts
|
||||||
$del=$db->prepare("DELETE FROM new_account WHERE user_id=?;");
|
$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': '';
|
$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)){
|
while($id=$stmt->fetch(PDO::FETCH_NUM)){
|
||||||
$onion=$id[7];
|
$onion=$id[6];
|
||||||
$system_account=$id[0];
|
$system_account=$id[0];
|
||||||
$firstchar=substr($system_account, 0, 1);
|
$firstchar=substr($system_account, 0, 1);
|
||||||
$reload[$firstchar]=true;
|
$reload[$firstchar]=true;
|
||||||
//php openssl implementation has some issues, re-export using native openssl
|
$enable_onion->execute([$id[6]]);
|
||||||
$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]]);
|
|
||||||
//add and manage rights of system user
|
//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));
|
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');
|
chown("/home/$system_account", 'root');
|
||||||
@ -49,7 +43,7 @@ while($id=$stmt->fetch(PDO::FETCH_NUM)){
|
|||||||
|
|
||||||
//configuration for services
|
//configuration for services
|
||||||
|
|
||||||
if($id[4]>0){
|
if($id[3]>0){
|
||||||
$php_location="
|
$php_location="
|
||||||
location ~ [^/]\.php(/|\$) {
|
location ~ [^/]\.php(/|\$) {
|
||||||
include snippets/fastcgi-php.conf;
|
include snippets/fastcgi-php.conf;
|
||||||
@ -59,7 +53,7 @@ $php_location="
|
|||||||
}else{
|
}else{
|
||||||
$php_location='';
|
$php_location='';
|
||||||
}
|
}
|
||||||
if($id[5]){
|
if($id[4]){
|
||||||
$autoindex='on';
|
$autoindex='on';
|
||||||
}else{
|
}else{
|
||||||
$autoindex='off';
|
$autoindex='off';
|
||||||
@ -104,62 +98,98 @@ php_admin_value[session.save_path] = /home/$system_account/tmp
|
|||||||
//save configuration files
|
//save configuration files
|
||||||
file_put_contents("/etc/nginx/sites-enabled/$system_account", $nginx);
|
file_put_contents("/etc/nginx/sites-enabled/$system_account", $nginx);
|
||||||
foreach(PHP_VERSIONS as $key=>$version){
|
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);
|
file_put_contents("/etc/php/$version/fpm/pool.d/$firstchar/$system_account.conf", $php);
|
||||||
break;
|
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
|
//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
|
//delete old accounts
|
||||||
$del=$db->prepare("DELETE FROM users WHERE id=?;");
|
$del=$db->prepare("DELETE FROM users WHERE id=?;");
|
||||||
$stmt=$db->query("SELECT system_account, id, mysql_user FROM users WHERE todelete=1 LIMIT 100;");
|
$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);
|
$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){
|
foreach($onions as $onion){
|
||||||
$firstchar=substr($onion[0], 0, 1);
|
$firstchar=substr($onion[0], 0, 1);
|
||||||
$reload[$firstchar]=true;
|
$reload[$firstchar]=true;
|
||||||
//delete config files
|
if(file_exists("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/")){
|
||||||
foreach(PHP_VERSIONS as $v){
|
foreach(glob("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/*") as $file){
|
||||||
// new naming schema
|
unlink($file);
|
||||||
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
|
rmdir("/var/lib/tor-instances/$firstchar/hidden_service_$onion[0].onion/");
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
}
|
$del_onions->execute([$onion[0]]);
|
||||||
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]]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//reload services
|
//reload services
|
||||||
if(!empty($reload)){
|
if(!empty($reload)){
|
||||||
exec('service nginx reload');
|
exec('service nginx reload');
|
||||||
@ -173,39 +203,39 @@ foreach($reload as $key => $val){
|
|||||||
|
|
||||||
//continue deleting old accounts
|
//continue deleting old accounts
|
||||||
$stmt=$db->prepare('SELECT mysql_database FROM mysql_databases WHERE user_id=?;');
|
$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
|
//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
|
//delete user and group
|
||||||
exec('userdel -rf ' . escapeshellarg($onion[0]));
|
exec('userdel -rf ' . escapeshellarg($account[0]));
|
||||||
//delete all log files
|
//delete all log files
|
||||||
if(file_exists("/var/log/nginx/access_$onion[0].log")){
|
if(file_exists("/var/log/nginx/access_$account[0].log")){
|
||||||
unlink("/var/log/nginx/access_$onion[0].log");
|
unlink("/var/log/nginx/access_$account[0].log");
|
||||||
}
|
}
|
||||||
if(file_exists("/var/log/nginx/access_$onion[0].log.1")){
|
if(file_exists("/var/log/nginx/access_$account[0].log.1")){
|
||||||
unlink("/var/log/nginx/access_$onion[0].log.1");
|
unlink("/var/log/nginx/access_$account[0].log.1");
|
||||||
}
|
}
|
||||||
if(file_exists("/var/log/nginx/error_$onion[0].log")){
|
if(file_exists("/var/log/nginx/error_$account[0].log")){
|
||||||
unlink("/var/log/nginx/error_$onion[0].log");
|
unlink("/var/log/nginx/error_$account[0].log");
|
||||||
}
|
}
|
||||||
if(file_exists("/var/log/nginx/error_$onion[0].log.1")){
|
if(file_exists("/var/log/nginx/error_$account[0].log.1")){
|
||||||
unlink("/var/log/nginx/error_$onion[0].log.1");
|
unlink("/var/log/nginx/error_$account[0].log.1");
|
||||||
}
|
}
|
||||||
//delete user from database
|
//delete user from database
|
||||||
$db->exec("DROP USER '$onion[2]'@'%';");
|
$db->exec("DROP USER '$account[2]'@'%';");
|
||||||
$stmt->execute([$onion[1]]);
|
$stmt->execute([$account[1]]);
|
||||||
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
|
while($tmp=$stmt->fetch(PDO::FETCH_NUM)){
|
||||||
$db->exec("DROP DATABASE IF EXISTS `$tmp[0]`;");
|
$db->exec("DROP DATABASE IF EXISTS `$tmp[0]`;");
|
||||||
}
|
}
|
||||||
$db->exec('FLUSH PRIVILEGES;');
|
$db->exec('FLUSH PRIVILEGES;');
|
||||||
//delete user from user database
|
//delete user from user database
|
||||||
$del->execute([$onion[1]]);
|
$del->execute([$account[1]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update passwords
|
// 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;");
|
$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=?;");
|
$del=$db->prepare("DELETE FROM pass_change WHERE user_id=?;");
|
||||||
while($onion=$stmt->fetch(PDO::FETCH_NUM)){
|
while($account=$stmt->fetch(PDO::FETCH_NUM)){
|
||||||
exec('usermod -p '. escapeshellarg($onion[1]) . ' ' . escapeshellarg($onion[0]));
|
exec('usermod -p '. escapeshellarg($account[1]) . ' ' . escapeshellarg($account[0]));
|
||||||
$del->execute([$onion[2]]);
|
$del->execute([$account[2]]);
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ if(empty($_SESSION['logged_in'])){
|
|||||||
$cnt=$stmt->fetch(PDO::FETCH_NUM)[0];
|
$cnt=$stmt->fetch(PDO::FETCH_NUM)[0];
|
||||||
echo "<a href=\"$_SERVER[SCRIPT_NAME]?action=approve\">Approve pending sites ($cnt)</a> | ";
|
echo "<a href=\"$_SERVER[SCRIPT_NAME]?action=approve\">Approve pending sites ($cnt)</a> | ";
|
||||||
}
|
}
|
||||||
echo "<a href=\"$_SERVER[SCRIPT_NAME]?action=list\">List of accounts</a> | <a href=\"$_SERVER[SCRIPT_NAME]?action=delete\">Delete accounts</a> | <a href=\"$_SERVER[SCRIPT_NAME]?action=edit\">Edit hidden services</a> | <a href=\"$_SERVER[SCRIPT_NAME]?action=logout\">Logout</a></p>";
|
echo "<a href=\"$_SERVER[SCRIPT_NAME]?action=list\">List of accounts</a> | <a href=\"$_SERVER[SCRIPT_NAME]?action=delete\">Delete accounts</a> | <a href=\"$_SERVER[SCRIPT_NAME]?action=suspend\">Suspend hidden services</a> | <a href=\"$_SERVER[SCRIPT_NAME]?action=edit\">Edit hidden services</a> | <a href=\"$_SERVER[SCRIPT_NAME]?action=logout\">Logout</a></p>";
|
||||||
if(empty($_REQUEST['action']) || $_REQUEST['action']==='login'){
|
if(empty($_REQUEST['action']) || $_REQUEST['action']==='login'){
|
||||||
echo '<p>Welcome to the admin panel!</p>';
|
echo '<p>Welcome to the admin panel!</p>';
|
||||||
}elseif($_REQUEST['action']==='logout'){
|
}elseif($_REQUEST['action']==='logout'){
|
||||||
@ -94,6 +94,32 @@ if(empty($_SESSION['logged_in'])){
|
|||||||
echo "<p style=\"color:red;\">Invalid onion address!</p>";
|
echo "<p style=\"color:red;\">Invalid onion address!</p>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}elseif($_REQUEST['action']==='suspend'){
|
||||||
|
echo '<p>Suspend hidden service:</p>';
|
||||||
|
echo "<form action=\"$_SERVER[SCRIPT_NAME]\" method=\"POST\">";
|
||||||
|
echo '<p>Onion address: <input type="text" name="onion" size="30" value="';
|
||||||
|
if(isSet($_POST['onion'])){
|
||||||
|
echo htmlspecialchars($_POST['onion']);
|
||||||
|
}
|
||||||
|
echo '" required autofocus></p>';
|
||||||
|
echo '<input type="submit" name="action" value="suspend"></form><br>';
|
||||||
|
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 "<p style=\"color:green;\">Successfully queued for suspension!</p>";
|
||||||
|
$stmt=$db->prepare('UPDATE service_instances SET reload = 1 WHERE id=?');
|
||||||
|
$stmt->execute([substr($match[1], 0, 1)]);
|
||||||
|
}else{
|
||||||
|
echo "<p style=\"color:red;\">Onion address not hosted by us!</p>";
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
echo "<p style=\"color:red;\">Invalid onion address!</p>";
|
||||||
|
}
|
||||||
|
}
|
||||||
}elseif(in_array($_REQUEST['action'], ['edit', 'edit_2'], true)){
|
}elseif(in_array($_REQUEST['action'], ['edit', 'edit_2'], true)){
|
||||||
echo '<p>Edit hidden service:</p>';
|
echo '<p>Edit hidden service:</p>';
|
||||||
echo "<form action=\"$_SERVER[SCRIPT_NAME]\" method=\"POST\">";
|
echo "<form action=\"$_SERVER[SCRIPT_NAME]\" method=\"POST\">";
|
||||||
|
@ -8,7 +8,7 @@ try{
|
|||||||
session_start();
|
session_start();
|
||||||
$user=check_login();
|
$user=check_login();
|
||||||
if(isset($_REQUEST['action']) && isset($_REQUEST['onion']) && $_REQUEST['action']==='edit'){
|
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']]);
|
$stmt->execute([$_REQUEST['onion'], $user['id']]);
|
||||||
if($onion=$stmt->fetch(PDO::FETCH_NUM)){
|
if($onion=$stmt->fetch(PDO::FETCH_NUM)){
|
||||||
$stmt=$db->prepare('UPDATE onions SET enabled = ?, enable_smtp = ?, num_intros = ?, max_streams = ? WHERE onion=?;');
|
$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</label></td>';
|
echo '>Enabled</label></td>';
|
||||||
echo '<td><input type="number" name="num_intros" min="3" max="20" value="'.$onion['num_intros'].'"></td>';
|
echo '<td><input type="number" name="num_intros" min="3" max="20" value="'.$onion['num_intros'].'"></td>';
|
||||||
echo '<td><input type="number" name="max_streams" min="0" max="65535" value="'.$onion['max_streams'].'"></td>';
|
echo '<td><input type="number" name="max_streams" min="0" max="65535" value="'.$onion['max_streams'].'"></td>';
|
||||||
echo '<td><button type="submit" name="action" value="edit">Save</button></td></tr>';
|
if(in_array($onion['enabled'], [0, 1])){
|
||||||
|
echo '<td><button type="submit" name="action" value="edit">Save</button></td>';
|
||||||
|
}else{
|
||||||
|
echo '<td>Unavailable</td>';
|
||||||
|
}
|
||||||
|
echo '</tr>';
|
||||||
}
|
}
|
||||||
echo '</table>';
|
echo '</table>';
|
||||||
echo '<h3>MySQL Database</h3>';
|
echo '<h3>MySQL Database</h3>';
|
||||||
|
@ -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 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 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 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;");
|
$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 (?);');
|
$stmt=$db->prepare('INSERT INTO service_instances (id) VALUES (?);');
|
||||||
foreach(SERVICE_INSTANCES as $key){
|
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/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";
|
echo "Database and files have successfully been set up\n";
|
||||||
}else{
|
}else{
|
||||||
$version=$version->fetch(PDO::FETCH_NUM)[0];
|
$version=$version->fetch(PDO::FETCH_NUM)[0];
|
||||||
@ -212,6 +213,20 @@ pm.max_children = 8
|
|||||||
}
|
}
|
||||||
$db->exec('UPDATE service_instances SET reload=1;');
|
$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 \'<html><head><title>Suspended</title></head><body>This domain has been suspended due to violation of <a href="http://' . ADDRESS . '">hosting rules</a>.</body></html>\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
';
|
||||||
|
file_put_contents('/etc/nginx/sites-enabled/default', $nginx_default, FILE_APPEND);
|
||||||
|
}
|
||||||
$stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';");
|
$stmt=$db->prepare("UPDATE settings SET value=? WHERE setting='version';");
|
||||||
$stmt->execute([DBVERSION]);
|
$stmt->execute([DBVERSION]);
|
||||||
if(DBVERSION!=$version){
|
if(DBVERSION!=$version){
|
||||||
|
Reference in New Issue
Block a user