Compare commits
2 Commits
f741605c78
...
aca4e19980
Author | SHA1 | Date | |
---|---|---|---|
aca4e19980
|
|||
3c30c5b370
|
@ -98,12 +98,12 @@ To harden the system and hide pids from non-root users, also add the following:
|
|||||||
proc /proc proc defaults,hidepid=2 0 0
|
proc /proc proc defaults,hidepid=2 0 0
|
||||||
```
|
```
|
||||||
|
|
||||||
And add the `noatime,usrjquota=aquota.user,jqfmt=vfsv1` options to the `/home` mountpoint (if not a separate partition, the `/` mointpoint and `noatime`to `/`. Then initialize quota (replace `/home` with `/`, if you do not have a separate partition):
|
And add the `noatime,usrjquota=aquota.user,jqfmt=vfsv1` options to the `/home` mountpoint, then initialize quota. Replace `/home` with `/`, if you do not have a separate partition:
|
||||||
```
|
```
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
mount -o remount /home
|
mount -o remount $(findmnt -n -o TARGET --target /home)
|
||||||
quotacheck -cMu /home
|
quotacheck -cMu $(findmnt -n -o TARGET --target /home)
|
||||||
quotaon /home
|
quotaon $(findmnt -n -o TARGET --target /home)
|
||||||
```
|
```
|
||||||
|
|
||||||
In some cases, you might get an error, that quota is not supported. This is usually the case in virtual environments. Make sure you have the full kernel installed, not one with a `-virtual` package. They usually are `linux-image-amd64`, `linux-image-arm64` or `linux-image-generic`, depending on your distribution. Also make sure, you are running a real virtual machine (e.g. KVM). Some providers sell containerized VPSes (e.g. OpenVZ), which means you don't run your own kernel...
|
In some cases, you might get an error, that quota is not supported. This is usually the case in virtual environments. Make sure you have the full kernel installed, not one with a `-virtual` package. They usually are `linux-image-amd64`, `linux-image-arm64` or `linux-image-generic`, depending on your distribution. Also make sure, you are running a real virtual machine (e.g. KVM). Some providers sell containerized VPSes (e.g. OpenVZ), which means you don't run your own kernel...
|
||||||
|
@ -6,7 +6,7 @@ export LANG=C.UTF-8
|
|||||||
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"
|
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin"
|
||||||
# install all required packages
|
# install all required packages
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get update
|
DEBIAN_FRONTEND=noninteractive apt-get update
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -y apt-transport-tor bash-completion bind9 brotli bzip2 ca-certificates clamav-daemon clamav-freshclam curl dovecot-imapd dovecot-lmtpd dovecot-pop3d git hardlink haveged iptables libio-socket-ip-perl libsasl2-modules locales locales-all logrotate lsb-release mariadb-server nano postfix postfix-mysql quota quotatool redis rsync ssh subversion tor unzip vim wget xz-utils zip zopfli
|
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -y apt-transport-tor bash-completion bind9 brotli bzip2 ca-certificates clamav-daemon clamav-freshclam curl dovecot-imapd dovecot-lmtpd dovecot-pop3d git hardlink haveged iptables libio-socket-ip-perl libsasl2-modules locales locales-all logrotate lsb-release mariadb-server nano postfix postfix-mysql quota quotatool redis rsync ssh subversion tor unzip util-linux vim wget xz-utils zip zopfli
|
||||||
# build dependencies
|
# build dependencies
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -y autoconf automake bison cmake g++ gcc ghostscript gnupg libaom-dev `apt-cache search --names-only 'libargon2(-0)?-dev' | awk '{print $1;}' | head -n1` libbrotli-dev libbz2-dev libc-client2007e-dev libcurl4-openssl-dev libde265-dev libdjvulibre-dev libedit-dev `apt-cache search --names-only 'libenchant(-2)?-dev' | awk '{print $1;}' | head -n1` libffi-dev `apt-cache search --names-only libfreetype6?-dev | awk '{print $1;}' | head -n1` libfftw3-dev libfribidi-dev libgd-dev libgmp-dev libgpg-error-dev libgpgme-dev libharfbuzz-dev libheif-dev libkrb5-dev libldap2-dev liblmdb-dev liblqr-1-0-dev libmariadb-dev libonig-dev libopenexr-dev libopenjp2-7-dev libpango1.0-dev libpcre3-dev libpng-dev libpspell-dev libqdbm-dev libraqm-dev libraw-dev libreadline-dev librsvg2-dev libsasl2-dev libsodium-dev libssh2-1-dev libssl-dev libsqlite3-dev libsystemd-dev libtidy-dev libtool libwebp-dev libwmf-dev libx265-dev libxml2-dev libxpm-dev libxslt1-dev libzip-dev libzstd-dev make poppler-utils ragel re2c yasm zlib1g-dev
|
DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends install -y autoconf automake bison cmake g++ gcc ghostscript gnupg libaom-dev `apt-cache search --names-only 'libargon2(-0)?-dev' | awk '{print $1;}' | head -n1` libbrotli-dev libbz2-dev libc-client2007e-dev libcurl4-openssl-dev libde265-dev libdjvulibre-dev libedit-dev `apt-cache search --names-only 'libenchant(-2)?-dev' | awk '{print $1;}' | head -n1` libffi-dev `apt-cache search --names-only libfreetype6?-dev | awk '{print $1;}' | head -n1` libfftw3-dev libfribidi-dev libgd-dev libgmp-dev libgpg-error-dev libgpgme-dev libharfbuzz-dev libheif-dev libkrb5-dev libldap2-dev liblmdb-dev liblqr-1-0-dev libmariadb-dev libonig-dev libopenexr-dev libopenjp2-7-dev libpango1.0-dev libpcre3-dev libpng-dev libpspell-dev libqdbm-dev libraqm-dev libraw-dev libreadline-dev librsvg2-dev libsasl2-dev libsodium-dev libssh2-1-dev libssl-dev libsqlite3-dev libsystemd-dev libtidy-dev libtool libwebp-dev libwmf-dev libx265-dev libxml2-dev libxpm-dev libxslt1-dev libzip-dev libzstd-dev make poppler-utils ragel re2c yasm zlib1g-dev
|
||||||
|
|
||||||
|
@ -5,7 +5,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=20; //database layout version
|
const DBVERSION=21; //database layout version
|
||||||
const CAPTCHA=1; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme)
|
const CAPTCHA=1; // Captcha difficulty (0=off, 1=simple, 2=moderate, 3=extreme)
|
||||||
const ADDRESS='dhosting4xxoydyaivckq7tsmtgi4wfs3flpeyitekkmqwu4v4r46syd.onion'; // our own address
|
const ADDRESS='dhosting4xxoydyaivckq7tsmtgi4wfs3flpeyitekkmqwu4v4r46syd.onion'; // our own address
|
||||||
const CANONICAL_URL='https://hosting.danwin1210.me'; // our preferred domain for search engines
|
const CANONICAL_URL='https://hosting.danwin1210.me'; // our preferred domain for search engines
|
||||||
@ -139,14 +139,6 @@ bindtextdomain('hosting', __DIR__.'/locale');
|
|||||||
bind_textdomain_codeset('hosting', 'UTF-8');
|
bind_textdomain_codeset('hosting', 'UTF-8');
|
||||||
textdomain('hosting');
|
textdomain('hosting');
|
||||||
|
|
||||||
function get_onion_v2($pkey) : string {
|
|
||||||
$keyData = openssl_pkey_get_details($pkey);
|
|
||||||
$pk = base64_decode(substr($keyData['key'], 27, -26));
|
|
||||||
$skipped_first_22 = substr($pk, 22);
|
|
||||||
$first_80_bits_of_sha1 = hex2bin(substr(sha1($skipped_first_22), 0, 20));
|
|
||||||
return base32_encode($first_80_bits_of_sha1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function get_onion_v3(string $sk) : string {
|
function get_onion_v3(string $sk) : string {
|
||||||
if(PHP_INT_SIZE === 4){
|
if(PHP_INT_SIZE === 4){
|
||||||
$pk = ParagonIE_Sodium_Core32_Ed25519::sk_to_pk($sk);
|
$pk = ParagonIE_Sodium_Core32_Ed25519::sk_to_pk($sk);
|
||||||
@ -420,47 +412,7 @@ function private_key_to_onion(string $priv_key) : array {
|
|||||||
$onion = '';
|
$onion = '';
|
||||||
$priv_key = trim($priv_key);
|
$priv_key = trim($priv_key);
|
||||||
$version = 0;
|
$version = 0;
|
||||||
if(($pkey = openssl_pkey_get_private($priv_key)) !== false){
|
if(($priv = base64_decode($priv_key, true)) !== false){
|
||||||
$version = 2;
|
|
||||||
$details = openssl_pkey_get_details($pkey);
|
|
||||||
if($details['type'] === OPENSSL_KEYTYPE_RSA){
|
|
||||||
$p = gmp_init(bin2hex($details['rsa']['p']), 16);
|
|
||||||
$q = gmp_init(bin2hex($details['rsa']['q']), 16);
|
|
||||||
$n = gmp_init(bin2hex($details['rsa']['n']), 16);
|
|
||||||
$d = gmp_init(bin2hex($details['rsa']['d']), 16);
|
|
||||||
$dmp1 = gmp_init(bin2hex($details['rsa']['dmp1']), 16);
|
|
||||||
$dmq1 = gmp_init(bin2hex($details['rsa']['dmq1']), 16);
|
|
||||||
$iqmp = gmp_init(bin2hex($details['rsa']['iqmp']), 16);
|
|
||||||
}
|
|
||||||
if($details['type'] !== OPENSSL_KEYTYPE_RSA){
|
|
||||||
$message = 'Error: private key is not an RSA key.';
|
|
||||||
$ok = false;
|
|
||||||
}elseif($details['bits'] !== 1024){
|
|
||||||
$message = 'Error: private key not of bitsize 1024.';
|
|
||||||
$ok = false;
|
|
||||||
}elseif(gmp_prob_prime($p) === 0){
|
|
||||||
$message = 'Error: p is not a prime';
|
|
||||||
$ok = false;
|
|
||||||
}elseif(gmp_prob_prime($q) === 0){
|
|
||||||
$message = 'Error: q is not a prime';
|
|
||||||
$ok = false;
|
|
||||||
}elseif(gmp_cmp($n, gmp_mul($p, $q) ) !== 0){
|
|
||||||
$message = 'Error: n does not equal p q';
|
|
||||||
$ok = false;
|
|
||||||
}elseif(gmp_cmp($dmp1, gmp_mod($d, gmp_sub($p, 1) ) ) !==0 ){
|
|
||||||
$message = 'Error: dmp1 invalid';
|
|
||||||
$ok = false;
|
|
||||||
}elseif(gmp_cmp($dmq1, gmp_mod($d, gmp_sub($q, 1) ) ) !== 0){
|
|
||||||
$message = 'Error: dmq1 invalid';
|
|
||||||
$ok = false;
|
|
||||||
}elseif(gmp_cmp($iqmp, gmp_invert($q, $p) ) !==0 ){
|
|
||||||
$message = 'Error: iqmp not inverse of q';
|
|
||||||
$ok = false;
|
|
||||||
}else{
|
|
||||||
$onion = get_onion_v2($pkey);
|
|
||||||
}
|
|
||||||
return ['ok' => $ok, 'message' => $message, 'onion' => $onion, 'version' => $version];
|
|
||||||
} elseif(($priv = base64_decode($priv_key, true)) !== false){
|
|
||||||
$version = 3;
|
$version = 3;
|
||||||
if( ! str_starts_with( $priv, '== ed25519v1-secret: type0 ==' . hex2bin( '000000' ) ) || strlen($priv) !== 96){
|
if( ! str_starts_with( $priv, '== ed25519v1-secret: type0 ==' . hex2bin( '000000' ) ) || strlen($priv) !== 96){
|
||||||
$message = 'Error: v3 secret key invalid.';
|
$message = 'Error: v3 secret key invalid.';
|
||||||
@ -478,11 +430,7 @@ function private_key_to_onion(string $priv_key) : array {
|
|||||||
function generate_new_onion(int $version = 3) : array {
|
function generate_new_onion(int $version = 3) : array {
|
||||||
$priv_key = '';
|
$priv_key = '';
|
||||||
$onion = '';
|
$onion = '';
|
||||||
if($version === 2){
|
if($version === 3){
|
||||||
$pkey = openssl_pkey_new(['private_key_bits' => 1024, 'private_key_type' => OPENSSL_KEYTYPE_RSA]);
|
|
||||||
openssl_pkey_export($pkey, $priv_key);
|
|
||||||
$onion = get_onion_v2($pkey);
|
|
||||||
} else {
|
|
||||||
$seed = random_bytes(32);
|
$seed = random_bytes(32);
|
||||||
$sk = ed25519_seckey_expand($seed);
|
$sk = ed25519_seckey_expand($seed);
|
||||||
$priv_key = base64_encode('== ed25519v1-secret: type0 ==' . hex2bin('000000') . $sk);
|
$priv_key = base64_encode('== ed25519v1-secret: type0 ==' . hex2bin('000000') . $sk);
|
||||||
|
@ -68,7 +68,7 @@ if(isset($_POST['action']) && $_POST['action']==='add_onion'){
|
|||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
$onion_version = 3;
|
$onion_version = 3;
|
||||||
if(isset($_REQUEST['onion_type']) && in_array($_REQUEST['onion_type'], [2, 3])){
|
if(isset($_REQUEST['onion_type']) && in_array($_REQUEST['onion_type'], [3])){
|
||||||
$onion_version = $_REQUEST['onion_type'];
|
$onion_version = $_REQUEST['onion_type'];
|
||||||
}
|
}
|
||||||
$check=$db->prepare('SELECT null FROM onions WHERE onion=?;');
|
$check=$db->prepare('SELECT null FROM onions WHERE onion=?;');
|
||||||
@ -210,9 +210,6 @@ if($count_onions<MAX_NUM_USER_ONIONS){
|
|||||||
echo '<label><input type="radio" name="onion_type" value="3"';
|
echo '<label><input type="radio" name="onion_type" value="3"';
|
||||||
echo (!isset($_POST['onion_type']) || $_POST['onion_type']==3) ? ' checked' : '';
|
echo (!isset($_POST['onion_type']) || $_POST['onion_type']==3) ? ' checked' : '';
|
||||||
echo '>'._('Random v3 Address').'</label>';
|
echo '>'._('Random v3 Address').'</label>';
|
||||||
echo '<label><input type="radio" name="onion_type" value="2"';
|
|
||||||
echo isset($_POST['onion_type']) && $_POST['onion_type']==2 ? ' checked' : '';
|
|
||||||
echo '>'._('Random v2 Address').'</label>';
|
|
||||||
echo '<label><input id="custom_onion" type="radio" name="onion_type" value="custom"';
|
echo '<label><input id="custom_onion" type="radio" name="onion_type" value="custom"';
|
||||||
echo isset($_POST['onion_type']) && $_POST['onion_type']==='custom' ? ' checked' : '';
|
echo isset($_POST['onion_type']) && $_POST['onion_type']==='custom' ? ' checked' : '';
|
||||||
echo '>'._('Custom private key');
|
echo '>'._('Custom private key');
|
||||||
|
@ -74,7 +74,7 @@ if($_SERVER['REQUEST_METHOD']==='POST'){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
if(isset($_REQUEST['onion_type']) && in_array($_REQUEST['onion_type'], [2, 3])){
|
if(isset($_REQUEST['onion_type']) && in_array($_REQUEST['onion_type'], [3])){
|
||||||
$onion_version = $_REQUEST['onion_type'];
|
$onion_version = $_REQUEST['onion_type'];
|
||||||
}
|
}
|
||||||
$check=$db->prepare('SELECT null FROM onions WHERE onion=?;');
|
$check=$db->prepare('SELECT null FROM onions WHERE onion=?;');
|
||||||
@ -148,7 +148,6 @@ foreach(PHP_VERSIONS as $key => $version){
|
|||||||
<tr><td colspan=2><label><input type="checkbox" name="autoindex" value="1"<?php echo $autoindex; ?>><?php echo _('Enable autoindex (listing of files)'); ?></label></td></tr>
|
<tr><td colspan=2><label><input type="checkbox" name="autoindex" value="1"<?php echo $autoindex; ?>><?php echo _('Enable autoindex (listing of files)'); ?></label></td></tr>
|
||||||
<tr><td colspan=2><?php echo _('Type of hidden service:'); ?><br>
|
<tr><td colspan=2><?php echo _('Type of hidden service:'); ?><br>
|
||||||
<label><input type="radio" name="onion_type" value="3"<?php echo (!isset($_POST['onion_type']) || $_POST['onion_type']==3) ? ' checked' : ''; ?>><?php echo _('Random v3 Address'); ?></label>
|
<label><input type="radio" name="onion_type" value="3"<?php echo (!isset($_POST['onion_type']) || $_POST['onion_type']==3) ? ' checked' : ''; ?>><?php echo _('Random v3 Address'); ?></label>
|
||||||
<label><input type="radio" name="onion_type" value="2"<?php echo isset($_POST['onion_type']) && $_POST['onion_type']==2 ? ' checked' : ''; ?>><?php echo _('Random v2 Address'); ?></label>
|
|
||||||
<label><input id="custom_onion" type="radio" name="onion_type" value="custom"<?php echo isset($_POST['onion_type']) && $_POST['onion_type']==='custom' ? ' checked' : ''; ?>><?php echo _('Custom private key'); ?>
|
<label><input id="custom_onion" type="radio" name="onion_type" value="custom"<?php echo isset($_POST['onion_type']) && $_POST['onion_type']==='custom' ? ' checked' : ''; ?>><?php echo _('Custom private key'); ?>
|
||||||
<textarea id="private_key" name="private_key" rows="5" cols="28">
|
<textarea id="private_key" name="private_key" rows="5" cols="28">
|
||||||
<?php echo isset($_REQUEST['private_key']) ? htmlspecialchars($_REQUEST['private_key']) : ''; ?>
|
<?php echo isset($_REQUEST['private_key']) ? htmlspecialchars($_REQUEST['private_key']) : ''; ?>
|
||||||
|
@ -156,6 +156,9 @@ if(!$version){
|
|||||||
if($version<20){
|
if($version<20){
|
||||||
$db->exec("ALTER TABLE onions CHANGE max_streams max_streams tinyint(3) unsigned NOT NULL DEFAULT '6';");
|
$db->exec("ALTER TABLE onions CHANGE max_streams max_streams tinyint(3) unsigned NOT NULL DEFAULT '6';");
|
||||||
}
|
}
|
||||||
|
if($version<21){
|
||||||
|
$db->exec('UPDATE onions SET enabled=-1 WHERE version = 2;');
|
||||||
|
}
|
||||||
$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]);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user