Compare commits
44 Commits
f741605c78
...
master
Author | SHA1 | Date | |
---|---|---|---|
d320b3319d
|
|||
9c22642a4b
|
|||
708e0a798b
|
|||
f66f8faba4
|
|||
85fc40ac85
|
|||
6c20f5fb3a
|
|||
9039e5b282
|
|||
c8ff688804 | |||
08de8bfbca | |||
0c673483c8
|
|||
2dac5be589
|
|||
9201440a23
|
|||
9952f570a2
|
|||
40294a5f16
|
|||
d3dea7493e
|
|||
00e88c28cb
|
|||
a537c1951c
|
|||
6b3131ba72
|
|||
7ce9c8b2df
|
|||
26d7641476
|
|||
da164f0214
|
|||
04ac6b3f64
|
|||
b95e94520d
|
|||
d9854af2fc
|
|||
5a0aefffc1
|
|||
13a7cb8a46
|
|||
212cb17038
|
|||
2a38afe72d
|
|||
1a574acc92
|
|||
996db7f3fe
|
|||
613fb66bc3
|
|||
bec7028304
|
|||
5db791499a | |||
efa31d7ffa | |||
31249c6c97 | |||
47011b6f1c | |||
a6e25edaf8
|
|||
649137e5f4
|
|||
dd89208bdd
|
|||
7a3b4963c8
|
|||
1a82182187
|
|||
d3d1cc5d4f
|
|||
aca4e19980
|
|||
3c30c5b370
|
38
README.md
38
README.md
@ -2,6 +2,7 @@ General Information:
|
|||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
This is a setup for a Tor based shared hosting server. It is provided as is and before putting it into production you should make changes according to your needs. This is a work in progress and you should carefully check the commit history for changes before updating.
|
This is a setup for a Tor based shared hosting server. It is provided as is and before putting it into production you should make changes according to your needs. This is a work in progress and you should carefully check the commit history for changes before updating.
|
||||||
|
For a production server, at least 1TB of SSD disk space, 32GB RAM and 8 CPU cores is recommended. For a small testing/personal server, 4GB RAM and 1 CPU core is enough.
|
||||||
|
|
||||||
Translation:
|
Translation:
|
||||||
--------------------------
|
--------------------------
|
||||||
@ -14,11 +15,13 @@ Once you are done, you can open a pull request, or [email me](mailto:daniel@danw
|
|||||||
Installation Instructions:
|
Installation Instructions:
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
The configuration was tested with a standard Debian bullseye and Ubuntu 20.04 LTS installation. It's recommended you install Debian bullseye (or newer) on your server, but with a little tweaking you may also get this working on other distributions and/or versions. If you want to build it on a raspberry pi, please do not use the raspbian images as several things will break. Download an image for your pi model from [https://raspi.debian.net/daily-images/](https://raspi.debian.net/daily-images/) instead.
|
The configuration was tested with a standard Debian bookworm and Ubuntu 24.04 LTS installation. It's recommended you install Debian bookworm (or newer) on your server, but with a little tweaking you may also get this working on other distributions and/or versions. If you want to build it on a raspberry pi, please do not use the raspbian images as several things will break. Download an image for your pi model from [https://raspi.debian.net/daily-images/](https://raspi.debian.net/daily-images/) instead.
|
||||||
|
|
||||||
|
Because I regularly get asked to make a video tutorial on how to set this up, I decided to create a tutorial which you can [watch on YouTube](https://www.youtube.com/watch?v=f2-SOlnIYmg). It is basically just copy-pasting commands, but maybe it helps someone.
|
||||||
|
|
||||||
Uninstall packages that may interfere with this setup:
|
Uninstall packages that may interfere with this setup:
|
||||||
```
|
```
|
||||||
DEBIAN_FRONTEND=noninteractive apt-get purge -y apache2* dnsmasq* eatmydata exim4* imagemagick-6-common mysql-client* mysql-server* nginx* libnginx-mod* php7* resolvconf && systemctl disable systemd-resolved.service && systemctl stop systemd-resolved.service
|
DEBIAN_FRONTEND=noninteractive apt purge -y apache2* dnsmasq* eatmydata exim4* imagemagick-6-common mysql-client* mysql-server* nginx* libnginx-mod* php7* resolvconf && systemctl disable systemd-resolved.service && systemctl stop systemd-resolved.service
|
||||||
```
|
```
|
||||||
|
|
||||||
If you have problems resolving hostnames after this step, temporarily switch to a public nameserver like 1.1.1.1 (from CloudFlare) or 8.8.8.8 (from Google)
|
If you have problems resolving hostnames after this step, temporarily switch to a public nameserver like 1.1.1.1 (from CloudFlare) or 8.8.8.8 (from Google)
|
||||||
@ -27,10 +30,20 @@ If you have problems resolving hostnames after this step, temporarily switch to
|
|||||||
rm /etc/resolv.conf && echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
rm /etc/resolv.conf && echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Add additional repositories:
|
||||||
|
```
|
||||||
|
apt update && apt install git apt-transport-tor curl
|
||||||
|
curl -sSL https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc > /etc/apt/trusted.gpg.d/torproject.gpg
|
||||||
|
curl -sSL https://packages.sury.org/nginx/apt.gpg > /etc/apt/trusted.gpg.d/sury.gpg
|
||||||
|
echo "deb tor://apow7mjfryruh65chtdydfmqfpj5btws7nbocgtaovhvezgccyjazpqd.onion/torproject.org/ `lsb_release -cs` main" >> /etc/apt/sources.list
|
||||||
|
echo "deb https://packages.sury.org/nginx/ `lsb_release -cs` main" >> /etc/apt/sources.list
|
||||||
|
apt update && apt upgrade
|
||||||
|
```
|
||||||
|
|
||||||
Install git and clone this repository
|
Install git and clone this repository
|
||||||
|
|
||||||
```
|
```
|
||||||
apt-get update && apt-get install git && git clone https://github.com/DanWin/hosting && cd hosting
|
apt update && apt install git && git clone https://github.com/DanWin/hosting && cd hosting
|
||||||
```
|
```
|
||||||
|
|
||||||
Install custom optimized binaries
|
Install custom optimized binaries
|
||||||
@ -38,21 +51,12 @@ Install custom optimized binaries
|
|||||||
./install_binaries.sh
|
./install_binaries.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
To get the latest mariadb version, you should follow these instructions to add the official repository for your distribution: (https://downloads.mariadb.org/mariadb/repositories/)
|
|
||||||
|
|
||||||
Add torproject to our repositories:
|
|
||||||
```
|
|
||||||
curl --socks5-hostname 127.0.0.1:9050 -sSL http://apow7mjfryruh65chtdydfmqfpj5btws7nbocgtaovhvezgccyjazpqd.onion/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc > /etc/apt/trusted.gpg.d/torproject.gpg
|
|
||||||
echo "deb tor://apow7mjfryruh65chtdydfmqfpj5btws7nbocgtaovhvezgccyjazpqd.onion/torproject.org/ `lsb_release -cs` main" >> /etc/apt/sources.list
|
|
||||||
apt-get update && apt-get upgrade
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that debian also has an onion service package archive, so you may want to edit /etc/apt/sources.list to load from there instead:
|
Note that debian also has an onion service package archive, so you may want to edit /etc/apt/sources.list to load from there instead:
|
||||||
```
|
```
|
||||||
deb tor://2s4yqjx5ul6okpp3f2gaunr2syex5jgbfpfvhxxbbjwnrsvbk5v3qbid.onion/debian `lsb_release -cs` main
|
deb tor://2s4yqjx5ul6okpp3f2gaunr2syex5jgbfpfvhxxbbjwnrsvbk5v3qbid.onion/debian `lsb_release -cs` main
|
||||||
```
|
```
|
||||||
|
|
||||||
Copy (and modify according to your needs) the site files in `var/www` to `/var/www`, `usr/local` to `/usr/local` and the configuration files in `etc` to `/etc` after installation has finished. Then restart some services:
|
Copy (and modify according to your needs) the site files in `var/www` to `/var/www` and the configuration files in `etc` to `/etc` after installation has finished. Then restart some services:
|
||||||
```
|
```
|
||||||
systemctl daemon-reload && systemctl restart bind9.service && systemctl restart tor@default.service
|
systemctl daemon-reload && systemctl restart bind9.service && systemctl restart tor@default.service
|
||||||
```
|
```
|
||||||
@ -98,12 +102,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...
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# Run this script whenever nginx doesn't start up due to stale sockets
|
# Run this script whenever nginx doesn't start up due to stale sockets
|
||||||
rm -f /home/*/var/run/mysqld/mysqld.sock /home/*/var/run/mail.sock /run/nginx.sock /run/nginx/* /var/www/var/run/mysqld/mysqld.sock /var/www/var/run/mail.sock /var/spool/postfix/var/run/mysqld/mysqld.sock
|
rm -f /home/*/run/mysqld/mysqld.sock /home/*/run/mail.sock /run/nginx.sock /run/nginx/* /var/www/run/mysqld/mysqld.sock /var/www/run/mail.sock /var/spool/postfix/var/run/mysqld/mysqld.sock
|
||||||
|
175
etc/jailkit/jk_init.ini
Normal file
175
etc/jailkit/jk_init.ini
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
[uidbasics]
|
||||||
|
# this section probably needs adjustment on 64bit systems
|
||||||
|
# or non-Linux systems
|
||||||
|
comment = common files for all jails that need user/group information
|
||||||
|
paths = /lib/libnsl.so.*, /lib64/libnsl.so.*, /lib/libnss*.so.2, /lib64/libnss*.so.2, /lib/i386-linux-gnu/libnsl.so.*, /lib/i386-linux-gnu/libnss*.so.2, /lib/x86_64-linux-gnu/libnsl.so.*, /lib/x86_64-linux-gnu/libnss*.so.2, /lib/arm-linux-gnueabihf/libnss*.so.2, /lib/arm-linux-gnueabihf/libnsl*.so.*, /etc/nsswitch.conf, /etc/ld.so.conf
|
||||||
|
# Solaris needs
|
||||||
|
# paths = /etc/default/nss, /lib/libnsl.so.1, /usr/lib/nss_*.so.1, /etc/nsswitch.conf
|
||||||
|
|
||||||
|
[netbasics]
|
||||||
|
comment = common files for all jails that need any internet connectivity
|
||||||
|
paths = /lib/libnss_dns.so.2, /lib64/libnss_dns.so.2, /lib/libnss_mdns*.so.2, /etc/resolv.conf, /etc/host.conf, /etc/hosts, /etc/protocols, /etc/services
|
||||||
|
# on Solaris devices /dev/udp and /dev/tcp might be needed too, not sure
|
||||||
|
|
||||||
|
[logbasics]
|
||||||
|
comment = timezone information and log sockets
|
||||||
|
paths = /etc/localtime
|
||||||
|
need_logsocket = 1
|
||||||
|
# Solaris does not need logsocket
|
||||||
|
# but needs
|
||||||
|
# devices = /dev/log, /dev/conslog
|
||||||
|
|
||||||
|
[jk_lsh]
|
||||||
|
comment = Jailkit limited shell
|
||||||
|
paths = /usr/sbin/jk_lsh, /etc/jailkit/jk_lsh.ini
|
||||||
|
users = root
|
||||||
|
groups = root
|
||||||
|
includesections = uidbasics, logbasics
|
||||||
|
|
||||||
|
[limitedshell]
|
||||||
|
comment = alias for jk_lsh
|
||||||
|
includesections = jk_lsh
|
||||||
|
|
||||||
|
[cvs]
|
||||||
|
comment = Concurrent Versions System
|
||||||
|
paths = cvs
|
||||||
|
devices = /dev/null
|
||||||
|
|
||||||
|
[git]
|
||||||
|
comment = Fast Version Control System
|
||||||
|
paths = /usr/bin/git*, /usr/lib/git-core, /usr/share/git-core, /usr/bin/basename, /bin/uname, /usr/bin/pager
|
||||||
|
includesections = editors, perl
|
||||||
|
|
||||||
|
[scp]
|
||||||
|
comment = ssh secure copy
|
||||||
|
paths = scp
|
||||||
|
includesections = netbasics, uidbasics
|
||||||
|
devices = /dev/urandom, /dev/null
|
||||||
|
|
||||||
|
[sftp]
|
||||||
|
comment = ssh secure ftp
|
||||||
|
paths = /usr/lib/sftp-server, /usr/libexec/openssh/sftp-server, /usr/lib/misc/sftp-server, /usr/libexec/sftp-server, /usr/lib/openssh/sftp-server
|
||||||
|
includesections = netbasics, uidbasics
|
||||||
|
devices = /dev/urandom, /dev/null
|
||||||
|
# on solaris
|
||||||
|
#paths = /usr/lib/ssh/sftp-server
|
||||||
|
|
||||||
|
[ssh]
|
||||||
|
comment = ssh secure shell
|
||||||
|
paths = ssh
|
||||||
|
includesections = netbasics, uidbasics
|
||||||
|
devices = /dev/urandom, /dev/tty, /dev/null
|
||||||
|
|
||||||
|
[rsync]
|
||||||
|
paths = rsync
|
||||||
|
includesections = netbasics, uidbasics
|
||||||
|
|
||||||
|
[procmail]
|
||||||
|
comment = procmail mail delivery
|
||||||
|
paths = procmail, /bin/sh
|
||||||
|
devices = /dev/null
|
||||||
|
|
||||||
|
[basicshell]
|
||||||
|
comment = bash based shell with several basic utilities
|
||||||
|
paths = /bin/sh, bash, ls, cat, chmod, mkdir, cp, cpio, date, dd, echo, egrep, false, fgrep, grep, gunzip, gzip, ln, ls, mkdir, mktemp, more, mv, pwd, rm, rmdir, sed, sh, sleep, sync, tar, touch, true, uncompress, zcat, /etc/motd, /etc/issue, /etc/bash.bashrc, /etc/bashrc, /etc/profile, /usr/lib/locale/en_US.utf8
|
||||||
|
users = root
|
||||||
|
groups = root
|
||||||
|
includesections = uidbasics
|
||||||
|
|
||||||
|
[interactiveshell]
|
||||||
|
comment = for ssh access to a full shell
|
||||||
|
includesections = uidbasics, basicshell, terminfo, editors, extendedshell
|
||||||
|
|
||||||
|
[midnightcommander]
|
||||||
|
comment = Midnight Commander
|
||||||
|
paths = mc, mcedit, mcview, /usr/share/mc
|
||||||
|
includesections = basicshell, terminfo
|
||||||
|
|
||||||
|
[extendedshell]
|
||||||
|
comment = bash shell including things like awk, bzip, tail, less
|
||||||
|
paths = awk, bzip2, bunzip2, ldd, less, clear, cut, du, find, head, less, md5sum, nice, sort, tac, tail, tr, sort, wc, watch, whoami
|
||||||
|
includesections = basicshell, midnightcommander, editors
|
||||||
|
|
||||||
|
[terminfo]
|
||||||
|
comment = terminfo databases, required for example for ncurses or vim
|
||||||
|
paths = /etc/terminfo, /usr/share/terminfo, /lib/terminfo
|
||||||
|
|
||||||
|
[editors]
|
||||||
|
comment = vim, joe and nano
|
||||||
|
includesections = terminfo
|
||||||
|
paths = joe, nano, vi, vim, /etc/vimrc, /etc/joe, /usr/share/vim
|
||||||
|
|
||||||
|
[netutils]
|
||||||
|
comment = several internet utilities like wget, ftp, rsync, scp, ssh
|
||||||
|
paths = wget, lynx, ftp, host, rsync, smbclient
|
||||||
|
includesections = netbasics, ssh, sftp, scp
|
||||||
|
|
||||||
|
[apacheutils]
|
||||||
|
comment = htpasswd utility
|
||||||
|
paths = htpasswd
|
||||||
|
|
||||||
|
[extshellplusnet]
|
||||||
|
comment = alias for extendedshell + netutils + apacheutils
|
||||||
|
includesections = extendedshell, netutils, apacheutils
|
||||||
|
|
||||||
|
[openvpn]
|
||||||
|
comment = jail for the openvpn daemon
|
||||||
|
paths = /usr/sbin/openvpn
|
||||||
|
users = root,nobody
|
||||||
|
groups = root,nogroup
|
||||||
|
#includesections = netbasics
|
||||||
|
devices = /dev/urandom, /dev/random, /dev/net/tun
|
||||||
|
includesections = netbasics, uidbasics
|
||||||
|
need_logsocket = 1
|
||||||
|
|
||||||
|
[apache]
|
||||||
|
comment = the apache webserver, very basic setup, probably too limited for you
|
||||||
|
paths = /usr/sbin/apache
|
||||||
|
users = root, www-data
|
||||||
|
groups = root, www-data
|
||||||
|
includesections = netbasics, uidbasics
|
||||||
|
|
||||||
|
[perl]
|
||||||
|
comment = the perl interpreter and libraries
|
||||||
|
paths = perl, /usr/lib/perl, /usr/lib/perl5, /usr/share/perl, /usr/share/perl5
|
||||||
|
|
||||||
|
[xauth]
|
||||||
|
comment = getting X authentication to work
|
||||||
|
paths = /usr/bin/X11/xauth, /usr/X11R6/lib/X11/rgb.txt, /etc/ld.so.conf
|
||||||
|
|
||||||
|
[xclients]
|
||||||
|
comment = minimal files for X clients
|
||||||
|
paths = /usr/X11R6/lib/X11/rgb.txt
|
||||||
|
includesections = xauth
|
||||||
|
|
||||||
|
[vncserver]
|
||||||
|
comment = the VNC server program
|
||||||
|
paths = Xvnc, Xrealvnc, /usr/X11R6/lib/X11/fonts/
|
||||||
|
includesections = xclients
|
||||||
|
|
||||||
|
[ping]
|
||||||
|
comment = Ping program
|
||||||
|
paths_w_setuid = /bin/ping
|
||||||
|
|
||||||
|
#[xterm]
|
||||||
|
#comment = xterm
|
||||||
|
#paths = /usr/bin/X11/xterm, /usr/share/terminfo, /etc/terminfo
|
||||||
|
#devices = /dev/pts/0, /dev/pts/1, /dev/pts/2, /dev/pts/3, /dev/pts/4, /dev/ptyb4, /dev/ptya4, /dev/tty, /dev/tty0, /dev/tty4
|
||||||
|
|
||||||
|
[php]
|
||||||
|
comment = the php interpreter and libraries
|
||||||
|
paths = /usr/bin/php*, composer, /usr/bin/phar*, env, /usr/lib/php, /usr/share/php, /usr/share/php*, /usr/share/zoneinfo, /usr/share/ca-certificates, /etc/ssl/certs, /usr/lib/ssl/certs, /etc/localtime
|
||||||
|
includesections = netbasics
|
||||||
|
|
||||||
|
[locales]
|
||||||
|
comment = all translations
|
||||||
|
paths = /usr/lib/locale, /usr/share/i18n, /etc/default/locale, /etc/locale.alias
|
||||||
|
|
||||||
|
[custom_hosting]
|
||||||
|
comment = custom giftGRÜN configuration
|
||||||
|
includesections = php, git, netutils, interactiveshell, locales
|
||||||
|
devices = /dev/zero, /dev/random
|
||||||
|
paths = base32, base64, basenc, brotli, cksum, comm, csplit, curl, dirname, dir, expand, expr, factor, fmt, fold, gpg, id, install, join, link, mysql, mysqldump, mysqlcheck, nl, nohup, numfmt, od, openssl, paste, pr, printenv, printf, ptx, readlink, realpath, seq, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum, shred, shuf, split, stat, stdbuf, sum, test, tee, timeout, tput, truncate, tsort, unexpand, uniq, unlink, unxz, unzip, vdir, which, xargs, xz, zip, zopfli, nologin, /etc/bash_completion, /etc/bash_completion.d, /usr/share/bash-completion, /etc/profile.d, /etc/ld.so.conf.d, /etc/hostname
|
||||||
|
emptydirs = /run/mysqld, /tmp
|
||||||
|
users = root, www-data
|
||||||
|
groups = root, www-data
|
@ -11,7 +11,6 @@ innodb_buffer_pool_size = 1G
|
|||||||
innodb_log_buffer_size = 16M
|
innodb_log_buffer_size = 16M
|
||||||
innodb_log_file_size = 128M
|
innodb_log_file_size = 128M
|
||||||
innodb_flush_log_at_trx_commit = 2
|
innodb_flush_log_at_trx_commit = 2
|
||||||
#innodb-defragment = 1
|
|
||||||
skip_name_resolve = 1
|
skip_name_resolve = 1
|
||||||
query_cache_size = 128M
|
query_cache_size = 128M
|
||||||
query_cache_limit = 4M
|
query_cache_limit = 4M
|
||||||
|
@ -2,6 +2,7 @@ daemon on;
|
|||||||
user www-data;
|
user www-data;
|
||||||
worker_processes 1;
|
worker_processes 1;
|
||||||
pid /run/nginx.pid;
|
pid /run/nginx.pid;
|
||||||
|
include /etc/nginx/modules-enabled/*.conf;
|
||||||
pcre_jit on;
|
pcre_jit on;
|
||||||
worker_rlimit_nofile 100000;
|
worker_rlimit_nofile 100000;
|
||||||
worker_shutdown_timeout 30m;
|
worker_shutdown_timeout 30m;
|
||||||
|
@ -23,7 +23,7 @@ ip6tables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|||||||
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
||||||
#allow tor traffic
|
#allow tor traffic
|
||||||
for tor in bind debian-tor _tor-a _tor-b _tor-c _tor-d _tor-e _tor-f _tor-g _tor-h _tor-i _tor-j _tor-k _tor-l _tor-m _tor-n _tor-o _tor-p _tor-q _tor-r _tor-s; do(
|
for tor in bind debian-tor _tor-a; do(
|
||||||
iptables -t nat -A OUTPUT -m owner --uid-owner $tor -j RETURN
|
iptables -t nat -A OUTPUT -m owner --uid-owner $tor -j RETURN
|
||||||
ip6tables -t nat -A OUTPUT -m owner --uid-owner $tor -j RETURN
|
ip6tables -t nat -A OUTPUT -m owner --uid-owner $tor -j RETURN
|
||||||
iptables -A OUTPUT -m owner --uid-owner $tor -j ACCEPT
|
iptables -A OUTPUT -m owner --uid-owner $tor -j ACCEPT
|
||||||
|
@ -24,7 +24,7 @@ LockPersonality=true
|
|||||||
SystemCallArchitectures=native
|
SystemCallArchitectures=native
|
||||||
ReadWritePaths=-/var/log/nginx/
|
ReadWritePaths=-/var/log/nginx/
|
||||||
ReadWritePaths=-/var/lib/nginx/
|
ReadWritePaths=-/var/lib/nginx/
|
||||||
ReadWritePaths=-/var/www/var/run/
|
ReadWritePaths=-/var/www/run/
|
||||||
ReadWritePaths=-/var/spool/postfix/
|
ReadWritePaths=-/var/spool/postfix/
|
||||||
ReadWritePaths=-/run/
|
ReadWritePaths=-/run/
|
||||||
InaccessiblePaths=-/root/
|
InaccessiblePaths=-/root/
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=rapid spam filtering system
|
|
||||||
After=nss-lookup.target network-online.target
|
|
||||||
Documentation=https://rspamd.com/doc/
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
LimitNOFILE=1048576
|
|
||||||
NonBlocking=true
|
|
||||||
ExecStart=/usr/local/bin/rspamd -c /usr/local/etc/rspamd/rspamd.conf -f
|
|
||||||
ExecReload=/bin/kill -HUP $MAINPID
|
|
||||||
User=_rspamd
|
|
||||||
RuntimeDirectory=rspamd
|
|
||||||
RuntimeDirectoryMode=0755
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
@ -13,6 +13,7 @@ HiddenServiceEnableIntroDoSRatePerSec 10
|
|||||||
HiddenServiceEnableIntroDoSBurstPerSec 100
|
HiddenServiceEnableIntroDoSBurstPerSec 100
|
||||||
HiddenServiceMaxStreams 10
|
HiddenServiceMaxStreams 10
|
||||||
HiddenServiceMaxStreamsCloseCircuit 1
|
HiddenServiceMaxStreamsCloseCircuit 1
|
||||||
|
HiddenServicePoWDefensesEnabled 1
|
||||||
|
|
||||||
ClientUseIPv6 1
|
ClientUseIPv6 1
|
||||||
ClientUseIPv4 1
|
ClientUseIPv4 1
|
||||||
|
1307
install_binaries.sh
1307
install_binaries.sh
File diff suppressed because it is too large
Load Diff
@ -5,8 +5,8 @@ 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=hard, 4=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
|
||||||
const SERVERS=[ //servers and ports we are running on
|
const SERVERS=[ //servers and ports we are running on
|
||||||
@ -25,7 +25,7 @@ const INDEX_MD5S=[ //MD5 sums of index.hosting.html files that should be conside
|
|||||||
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 ENABLE_SHELL_ACCESS=true; //allows users to login via ssh, when disabled only sftp is allowed - run setup.php to migrate existing accounts
|
const ENABLE_SHELL_ACCESS=true; //allows users to login via ssh, when disabled only sftp is allowed - run setup.php to migrate existing accounts
|
||||||
const ADMIN_PASSWORD='MY_PASSWORD'; //password for admin interface
|
const ADMIN_PASSWORD='MY_PASSWORD'; //password for admin interface
|
||||||
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. If tor starts using 100% cpu and failing circuits every few hours after a restart, add more instances. In my experience this happens around 250 hidden services per instance - run setup.php after change
|
const SERVICE_INSTANCES=['a']; //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. If tor starts using 100% cpu and failing circuits every few hours after a restart, add more instances. In my experience this happens around 250 hidden services per instance - run setup.php after change
|
||||||
const DISABLED_PHP_VERSIONS=[]; //php versions still installed on the system but no longer offered for new accounts
|
const DISABLED_PHP_VERSIONS=[]; //php versions still installed on the system but no longer offered for new accounts
|
||||||
const PHP_VERSIONS=[7 => '8.1', 8 => '8.2']; //currently active php versions
|
const PHP_VERSIONS=[7 => '8.1', 8 => '8.2']; //currently active php versions
|
||||||
const DEFAULT_PHP_VERSION='8.2'; //default php version
|
const DEFAULT_PHP_VERSION='8.2'; //default php version
|
||||||
@ -95,6 +95,8 @@ const CLEARNET_ADDRESS = 'hosting.danwin1210.me'; //Domain under which the servi
|
|||||||
const CLEARNET_SUBDOMAINS = 'danwin1210.me'; //domain of which all subdomains are mapped to this server
|
const CLEARNET_SUBDOMAINS = 'danwin1210.me'; //domain of which all subdomains are mapped to this server
|
||||||
const DEFAULT_LANG = 'en'; //default language
|
const DEFAULT_LANG = 'en'; //default language
|
||||||
const LANGUAGES = [ //available languages
|
const LANGUAGES = [ //available languages
|
||||||
|
'cs' => ['name' => 'Czech', 'locale' => 'cs_CZ', 'dir' => 'ltr'],
|
||||||
|
'de' => ['name' => 'Deutsch', 'locale' => 'de_DE', 'dir' => 'ltr'],
|
||||||
'en' => ['name' => 'English', 'locale' => 'en_GB', 'dir' => 'ltr'],
|
'en' => ['name' => 'English', 'locale' => 'en_GB', 'dir' => 'ltr'],
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -139,14 +141,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);
|
||||||
@ -223,6 +217,45 @@ function send_captcha(): void
|
|||||||
imagesetpixel($im, mt_rand(0, 55), mt_rand(0, 24), $dots);
|
imagesetpixel($im, mt_rand(0, 55), mt_rand(0, 24), $dots);
|
||||||
}
|
}
|
||||||
echo '<img width="55" height="24" src="data:image/gif;base64,';
|
echo '<img width="55" height="24" src="data:image/gif;base64,';
|
||||||
|
}elseif(CAPTCHA === 3){
|
||||||
|
$im = imagecreatetruecolor(55, 24);
|
||||||
|
$bg = imagecolorallocatealpha($im, 0, 0, 0, 127);
|
||||||
|
$fg = imagecolorallocate($im, 255, 255, 255);
|
||||||
|
$cc = imagecolorallocate($im, 200, 200, 200);
|
||||||
|
$cb = imagecolorallocatealpha($im, 0, 0, 0, 127);
|
||||||
|
imagefill($im, 0, 0, $bg);
|
||||||
|
$line = imagecolorallocate($im, 255, 255, 255);
|
||||||
|
$deg = (mt_rand(0,1)*2-1)*mt_rand(10, 20);
|
||||||
|
|
||||||
|
$background = imagecreatetruecolor(120, 80);
|
||||||
|
imagefill($background, 0, 0, $cb);
|
||||||
|
|
||||||
|
for ($i=0; $i<20; ++$i) {
|
||||||
|
$char=imagecreatetruecolor(12, 16);
|
||||||
|
imagestring($char, 5, 2, 2, $captchachars[mt_rand(0, $length)], $cc);
|
||||||
|
$char = imagerotate($char, (mt_rand(0,1)*2-1)*mt_rand(10, 20), $cb);
|
||||||
|
$char = imagescale($char, 24, 32);
|
||||||
|
imagefilter($char, IMG_FILTER_SMOOTH, 0.6);
|
||||||
|
imagecopy($background, $char, rand(0, 100), rand(0, 60), 0, 0, 24, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
imagestring($im, 5, 5, 5, $code, $fg);
|
||||||
|
$im = imagescale($im, 110, 48);
|
||||||
|
imagefilter($im, IMG_FILTER_SMOOTH, 0.5);
|
||||||
|
imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR);
|
||||||
|
$im = imagerotate($im, $deg, $bg);
|
||||||
|
$im = imagecrop($im, array('x'=>0, 'y'=>0, 'width'=>120, 'height'=>80));
|
||||||
|
imagecopy($background, $im, 0, 0, 0, 0, 110, 80);
|
||||||
|
imagedestroy($im);
|
||||||
|
$im = $background;
|
||||||
|
|
||||||
|
for($i=0;$i<1000;++$i){
|
||||||
|
$c = mt_rand(100,230);
|
||||||
|
$dots=imagecolorallocate($im, $c, $c, $c);
|
||||||
|
imagesetpixel($im, mt_rand(0, 120), mt_rand(0, 80), $dots);
|
||||||
|
}
|
||||||
|
imagedestroy($char);
|
||||||
|
echo '<img width="120" height="80" src="data:image/png;base64,';
|
||||||
}else{
|
}else{
|
||||||
$im = imagecreatetruecolor(150, 200);
|
$im = imagecreatetruecolor(150, 200);
|
||||||
$bg = imagecolorallocate($im, 0, 0, 0);
|
$bg = imagecolorallocate($im, 0, 0, 0);
|
||||||
@ -403,6 +436,7 @@ HiddenServiceExportCircuitID haproxy
|
|||||||
HiddenServiceEnableIntroDoSDefense 1
|
HiddenServiceEnableIntroDoSDefense 1
|
||||||
HiddenServiceEnableIntroDoSRatePerSec 10
|
HiddenServiceEnableIntroDoSRatePerSec 10
|
||||||
HiddenServiceEnableIntroDoSBurstPerSec 100
|
HiddenServiceEnableIntroDoSBurstPerSec 100
|
||||||
|
HiddenServicePoWDefensesEnabled 1
|
||||||
";
|
";
|
||||||
$torrc.="HiddenServicePort 80 unix:/var/run/nginx/$socket\n";
|
$torrc.="HiddenServicePort 80 unix:/var/run/nginx/$socket\n";
|
||||||
if($tmp['enable_smtp']){
|
if($tmp['enable_smtp']){
|
||||||
@ -420,47 +454,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 +472,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);
|
||||||
@ -610,12 +600,12 @@ function rewrite_nginx_config(): void
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$nginx_mysql.="server {
|
$nginx_mysql.="server {
|
||||||
listen unix:/home/$tmp[system_account]/var/run/mysqld/mysqld.sock;
|
listen unix:/home/$tmp[system_account]/run/mysqld/mysqld.sock;
|
||||||
proxy_pass unix:/var/run/mysqld/mysqld.sock;
|
proxy_pass unix:/var/run/mysqld/mysqld.sock;
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
$nginx_mail.="server {
|
$nginx_mail.="server {
|
||||||
listen unix:/home/$tmp[system_account]/var/run/mail.sock;
|
listen unix:/home/$tmp[system_account]/run/mail.sock;
|
||||||
root /var/www/mail;
|
root /var/www/mail;
|
||||||
location / {
|
location / {
|
||||||
include snippets/fastcgi-php.conf;
|
include snippets/fastcgi-php.conf;
|
||||||
|
@ -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']) : ''; ?>
|
||||||
|
BIN
var/www/locale/uk/LC_MESSAGES/hosting.mo
Normal file
BIN
var/www/locale/uk/LC_MESSAGES/hosting.mo
Normal file
Binary file not shown.
1202
var/www/locale/uk/LC_MESSAGES/hosting.po
Normal file
1202
var/www/locale/uk/LC_MESSAGES/hosting.po
Normal file
File diff suppressed because it is too large
Load Diff
@ -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]);
|
||||||
}
|
}
|
||||||
@ -361,7 +364,7 @@ if(!file_exists("/etc/nginx/streams-enabled/")){
|
|||||||
mkdir("/etc/nginx/streams-enabled/", 0755, true);
|
mkdir("/etc/nginx/streams-enabled/", 0755, true);
|
||||||
}
|
}
|
||||||
file_put_contents('/etc/nginx/streams-enabled/default', "server {
|
file_put_contents('/etc/nginx/streams-enabled/default', "server {
|
||||||
listen unix:/var/www/var/run/mysqld/mysqld.sock;
|
listen unix:/var/www/run/mysqld/mysqld.sock;
|
||||||
proxy_pass unix:/var/run/mysqld/mysqld.sock;
|
proxy_pass unix:/var/run/mysqld/mysqld.sock;
|
||||||
}");
|
}");
|
||||||
exec('systemctl enable nginx');
|
exec('systemctl enable nginx');
|
||||||
|
@ -1,334 +1,33 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
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"
|
||||||
|
|
||||||
test "$1" != "" || { echo "Need path to chroot directory"; exit 1; }
|
test "$1" != "" || { echo "Need path to chroot directory"; exit 1; }
|
||||||
|
|
||||||
ALL_LIB_DIRECTORIES=()
|
|
||||||
ALL_LIB_FILES=()
|
|
||||||
|
|
||||||
### functions
|
|
||||||
function CHROOT_BINARY() {
|
|
||||||
BINARY="$(which $1)"
|
|
||||||
if [ "$BINARY" == "" ]; then
|
|
||||||
return;
|
|
||||||
fi
|
|
||||||
if [ "$(echo $BINARY | grep -E '.*:.*')" != "" ]; then
|
|
||||||
BINARY="$(echo $BINARY | cut -d':' -f2)"
|
|
||||||
fi
|
|
||||||
LIB_FILES="$(ldd $BINARY 2>&1 | grep -v 'not a dynamic executable' | awk '{ print $3 }' | grep -E '^/(.*)' || echo)"
|
|
||||||
LDD_FILES="$(ldd $BINARY 2>&1 | grep -v 'not a dynamic executable' | grep 'ld-linux' | awk '{ print $1; }' || echo)"
|
|
||||||
if [ "$LIB_FILES" != "" ]; then
|
|
||||||
for LIB_FILE in $LIB_FILES; do
|
|
||||||
ADD_LIB $LIB_FILE
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
if [ "$LDD_FILES" != "" ]; then
|
|
||||||
for LDD_FILE in $LDD_FILES; do
|
|
||||||
ADD_LIB $LDD_FILE
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
BINARY_DIRECTORY="$(dirname $BINARY)"
|
|
||||||
mkdir -pm 0555 $CHROOT_DIRECTORY$BINARY_DIRECTORY
|
|
||||||
cp $BINARY $CHROOT_DIRECTORY$BINARY
|
|
||||||
chmod 0555 $CHROOT_DIRECTORY$BINARY
|
|
||||||
}
|
|
||||||
|
|
||||||
function ADD_LIB() {
|
|
||||||
LIB_DIRECTORY="$(dirname $1)"
|
|
||||||
if [[ ! "${ALL_LIB_DIRECTORIES[@]}" =~ "$LIB_DIRECTORY" ]]; then
|
|
||||||
ALL_LIB_DIRECTORIES=(${ALL_LIB_DIRECTORIES[@]} "$LIB_DIRECTORY")
|
|
||||||
fi
|
|
||||||
if [[ ! "${ALL_LIB_FILES[@]}" =~ "$1" ]]; then
|
|
||||||
ALL_LIB_FILES=(${ALL_LIB_FILES[@]} "$1")
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function CHROOT_LIBRARIES() {
|
|
||||||
for DIRECTORY in ${ALL_LIB_DIRECTORIES[@]}; do
|
|
||||||
mkdir -pm 0555 $CHROOT_DIRECTORY$DIRECTORY
|
|
||||||
done
|
|
||||||
for FILE in ${ALL_LIB_FILES[@]}; do
|
|
||||||
cp $FILE $CHROOT_DIRECTORY$FILE
|
|
||||||
chmod 0555 $CHROOT_DIRECTORY$FILE
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
### variables
|
### variables
|
||||||
CHROOT_DIRECTORY=$1
|
CHROOT_DIRECTORY=$1
|
||||||
CHROOT_DIRECTORY_STRUCTURE=(
|
|
||||||
'/etc'
|
|
||||||
'/etc/default'
|
|
||||||
'/dev'
|
|
||||||
'/tmp'
|
|
||||||
'/usr'
|
|
||||||
'/usr/share'
|
|
||||||
'/usr/share/bash-completion'
|
|
||||||
'/usr/share/bash-completion/completions'
|
|
||||||
'/usr/bin'
|
|
||||||
'/usr/lib'
|
|
||||||
'/usr/lib/openssh'
|
|
||||||
'/usr/sbin'
|
|
||||||
'/var'
|
|
||||||
'/var/run'
|
|
||||||
'/var/run/mysqld'
|
|
||||||
)
|
|
||||||
CHROOT_DIRECTORY_TO_CLEAN=(
|
|
||||||
'/bin'
|
|
||||||
'/lib'
|
|
||||||
'/usr/bin'
|
|
||||||
'/usr/lib'
|
|
||||||
'/usr/sbin'
|
|
||||||
)
|
|
||||||
BINARIES_GENERAL=(
|
|
||||||
'['
|
|
||||||
'awk'
|
|
||||||
'base32'
|
|
||||||
'base64'
|
|
||||||
'basename'
|
|
||||||
'basenc'
|
|
||||||
'bash'
|
|
||||||
'brotli'
|
|
||||||
'bzip2'
|
|
||||||
'cat'
|
|
||||||
'chmod'
|
|
||||||
'cksum'
|
|
||||||
'clear'
|
|
||||||
'comm'
|
|
||||||
'composer'
|
|
||||||
'cp'
|
|
||||||
'csplit'
|
|
||||||
'curl'
|
|
||||||
'cut'
|
|
||||||
'date'
|
|
||||||
'dd'
|
|
||||||
'dirname'
|
|
||||||
'dir'
|
|
||||||
'du'
|
|
||||||
'echo'
|
|
||||||
'egrep'
|
|
||||||
'env'
|
|
||||||
'expand'
|
|
||||||
'expr'
|
|
||||||
'factor'
|
|
||||||
'false'
|
|
||||||
'fgrep'
|
|
||||||
'find'
|
|
||||||
'fmt'
|
|
||||||
'fold'
|
|
||||||
'git'
|
|
||||||
'git-receive-pack'
|
|
||||||
'git-shell'
|
|
||||||
'git-upload-archive'
|
|
||||||
'git-upload-pack'
|
|
||||||
'gpg'
|
|
||||||
'grep'
|
|
||||||
'gunzip'
|
|
||||||
'gzip'
|
|
||||||
'head'
|
|
||||||
'id'
|
|
||||||
'install'
|
|
||||||
'join'
|
|
||||||
'less'
|
|
||||||
'link'
|
|
||||||
'ln'
|
|
||||||
'ls'
|
|
||||||
'md5sum'
|
|
||||||
'mkdir'
|
|
||||||
'mktemp'
|
|
||||||
'mv'
|
|
||||||
'mysql'
|
|
||||||
'mysqldump'
|
|
||||||
'mysqlcheck'
|
|
||||||
'nano'
|
|
||||||
'nl'
|
|
||||||
'nohup'
|
|
||||||
'numfmt'
|
|
||||||
'od'
|
|
||||||
'openssl'
|
|
||||||
'paste'
|
|
||||||
'php8.1'
|
|
||||||
'php8.2'
|
|
||||||
'pr'
|
|
||||||
'printenv'
|
|
||||||
'printf'
|
|
||||||
'ptx'
|
|
||||||
'pwd'
|
|
||||||
'readlink'
|
|
||||||
'realpath'
|
|
||||||
'rm'
|
|
||||||
'rmdir'
|
|
||||||
'rsync'
|
|
||||||
'scp'
|
|
||||||
'sed'
|
|
||||||
'seq'
|
|
||||||
'sftp'
|
|
||||||
'sh'
|
|
||||||
'sha1sum'
|
|
||||||
'sha224sum'
|
|
||||||
'sha256sum'
|
|
||||||
'sha384sum'
|
|
||||||
'sha512sum'
|
|
||||||
'shred'
|
|
||||||
'shuf'
|
|
||||||
'sleep'
|
|
||||||
'sort'
|
|
||||||
'split'
|
|
||||||
'ssh'
|
|
||||||
'stat'
|
|
||||||
'stdbuf'
|
|
||||||
'sum'
|
|
||||||
'tac'
|
|
||||||
'tail'
|
|
||||||
'tar'
|
|
||||||
'test'
|
|
||||||
'tee'
|
|
||||||
'timeout'
|
|
||||||
'touch'
|
|
||||||
'tput'
|
|
||||||
'tr'
|
|
||||||
'true'
|
|
||||||
'truncate'
|
|
||||||
'tsort'
|
|
||||||
'uname'
|
|
||||||
'unexpand'
|
|
||||||
'uniq'
|
|
||||||
'unlink'
|
|
||||||
'unxz'
|
|
||||||
'unzip'
|
|
||||||
'vdir'
|
|
||||||
'vi'
|
|
||||||
'vim'
|
|
||||||
'wc'
|
|
||||||
'wget'
|
|
||||||
'which'
|
|
||||||
'xargs'
|
|
||||||
'xz'
|
|
||||||
'zip'
|
|
||||||
'zopfli'
|
|
||||||
'nologin'
|
|
||||||
)
|
|
||||||
FILES_GENERAL=(
|
|
||||||
'/etc/hosts'
|
|
||||||
'/etc/hostname'
|
|
||||||
'/etc/resolv.conf'
|
|
||||||
'/etc/nsswitch.conf'
|
|
||||||
'/etc/services'
|
|
||||||
'/etc/protocols'
|
|
||||||
'/etc/locale.alias'
|
|
||||||
'/etc/default/locale'
|
|
||||||
'/etc/localtime'
|
|
||||||
'/etc/profile'
|
|
||||||
'/etc/bash_completion'
|
|
||||||
'/etc/bash.bashrc'
|
|
||||||
'/usr/share/bash-completion/bash_completion'
|
|
||||||
'/usr/share/bash-completion/completions/alias'
|
|
||||||
'/usr/share/bash-completion/completions/bind'
|
|
||||||
'/usr/share/bash-completion/completions/bzip2'
|
|
||||||
'/usr/share/bash-completion/completions/compgen'
|
|
||||||
'/usr/share/bash-completion/completions/complete'
|
|
||||||
'/usr/share/bash-completion/completions/curl'
|
|
||||||
'/usr/share/bash-completion/completions/declare'
|
|
||||||
'/usr/share/bash-completion/completions/export'
|
|
||||||
'/usr/share/bash-completion/completions/find'
|
|
||||||
'/usr/share/bash-completion/completions/function'
|
|
||||||
'/usr/share/bash-completion/completions/git'
|
|
||||||
'/usr/share/bash-completion/completions/gzip'
|
|
||||||
'/usr/share/bash-completion/completions/id'
|
|
||||||
'/usr/share/bash-completion/completions/kill'
|
|
||||||
'/usr/share/bash-completion/completions/mysql'
|
|
||||||
'/usr/share/bash-completion/completions/openssl'
|
|
||||||
'/usr/share/bash-completion/completions/pwd'
|
|
||||||
'/usr/share/bash-completion/completions/rsync'
|
|
||||||
'/usr/share/bash-completion/completions/scp'
|
|
||||||
'/usr/share/bash-completion/completions/sh'
|
|
||||||
'/usr/share/bash-completion/completions/sftp'
|
|
||||||
'/usr/share/bash-completion/completions/tar'
|
|
||||||
'/usr/share/bash-completion/completions/typeset'
|
|
||||||
'/usr/share/bash-completion/completions/wget'
|
|
||||||
'/etc/ld.so.conf'
|
|
||||||
)
|
|
||||||
DIRECTORIES_GENERAL=(
|
|
||||||
'/usr/lib/git-core'
|
|
||||||
'/usr/share/git-core'
|
|
||||||
'/usr/lib/locale'
|
|
||||||
'/usr/share/i18n'
|
|
||||||
'/etc/ssl'
|
|
||||||
'/usr/lib/ssl'
|
|
||||||
'/usr/share/ca-certificates'
|
|
||||||
'/etc/bash_completion.d'
|
|
||||||
'/usr/share/zoneinfo'
|
|
||||||
'/lib/terminfo'
|
|
||||||
'/usr/share/terminfo'
|
|
||||||
'/usr/lib/php'
|
|
||||||
'/etc/profile.d'
|
|
||||||
'/etc/ld.so.conf.d'
|
|
||||||
)
|
|
||||||
### test variables/parameters
|
### test variables/parameters
|
||||||
test "$CHROOT_DIRECTORY" != ""
|
test "$CHROOT_DIRECTORY" != ""
|
||||||
|
|
||||||
if [ "$2" != "" ]; then
|
if [ "$2" != "" ]; then
|
||||||
CHROOT_BINARY $2
|
jk_cp -j "$CHROOT_DIRECTORY" -k "$2"
|
||||||
CHROOT_LIBRARIES
|
|
||||||
ldconfig -r $CHROOT_DIRECTORY
|
|
||||||
echo "copied extra binary $2";
|
echo "copied extra binary $2";
|
||||||
exit 0;
|
exit 0;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
### init chroot directory
|
### init chroot directory
|
||||||
mkdir -p $CHROOT_DIRECTORY
|
if [[ -d "$CHROOT_DIRECTORY/bin" ]]; then
|
||||||
chown root:www-data $CHROOT_DIRECTORY
|
chown root:root "$CHROOT_DIRECTORY"
|
||||||
chmod 550 $CHROOT_DIRECTORY
|
chmod 555 "$CHROOT_DIRECTORY"
|
||||||
for DIRECTORY in ${CHROOT_DIRECTORY_TO_CLEAN[@]}; do
|
jk_update -j "$CHROOT_DIRECTORY" -k /bin /lib /usr
|
||||||
rm -rf $CHROOT_DIRECTORY$DIRECTORY
|
else
|
||||||
done
|
mkdir -p "$CHROOT_DIRECTORY"
|
||||||
ln -s usr/bin $CHROOT_DIRECTORY/bin
|
chown root:root "$CHROOT_DIRECTORY"
|
||||||
ln -s usr/lib $CHROOT_DIRECTORY/lib
|
chmod 555 "$CHROOT_DIRECTORY"
|
||||||
for DIRECTORY in ${CHROOT_DIRECTORY_STRUCTURE[@]}; do
|
jk_init -j "$CHROOT_DIRECTORY" -k custom_hosting
|
||||||
mkdir -pm 0555 $CHROOT_DIRECTORY$DIRECTORY
|
chmod 777 "$CHROOT_DIRECTORY/tmp"
|
||||||
done
|
echo "export HOME=/" > "$CHROOT_DIRECTORY/etc/profile.d/hosting.sh"
|
||||||
chmod 777 $CHROOT_DIRECTORY/tmp
|
echo "export HISTFILE=/.bash_history" >> "$CHROOT_DIRECTORY/etc/profile.d/hosting.sh"
|
||||||
# users and groups
|
echo 'export PATH="$PATH:/.composer/vendor/bin"' >> "$CHROOT_DIRECTORY/etc/profile.d/hosting.sh"
|
||||||
echo "root:x:0:0:root:/root:/bin/bash" > $CHROOT_DIRECTORY/etc/passwd
|
fi
|
||||||
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
|
|
||||||
|
|
||||||
# /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
|
|
||||||
test -e $CHROOT_DIRECTORY/dev/tty || mknod -m 666 $CHROOT_DIRECTORY/dev/tty c 5 0
|
|
||||||
test -e $CHROOT_DIRECTORY/dev/random || mknod -m 644 $CHROOT_DIRECTORY/dev/random c 1 8
|
|
||||||
test -e $CHROOT_DIRECTORY/dev/urandom || mknod -m 644 $CHROOT_DIRECTORY/dev/urandom c 1 9
|
|
||||||
# copy general directories
|
|
||||||
for DIRECTORY in ${DIRECTORIES_GENERAL[@]}; do
|
|
||||||
rm -rf $CHROOT_DIRECTORY$DIRECTORY
|
|
||||||
cp -Rp $DIRECTORY $CHROOT_DIRECTORY$DIRECTORY
|
|
||||||
done
|
|
||||||
echo "export HOME=/" > $CHROOT_DIRECTORY/etc/profile.d/hosting.sh
|
|
||||||
echo "export HISTFILE=/.bash_history" >> $CHROOT_DIRECTORY/etc/profile.d/hosting.sh
|
|
||||||
echo 'export PATH="$PATH:/.composer/vendor/bin"' >> $CHROOT_DIRECTORY/etc/profile.d/hosting.sh
|
|
||||||
# copy general files
|
|
||||||
for FILE in ${FILES_GENERAL[@]}; do
|
|
||||||
cp $FILE $CHROOT_DIRECTORY$FILE
|
|
||||||
done
|
|
||||||
### copy shared libraries and binaries
|
|
||||||
# general
|
|
||||||
for BINARY in ${BINARIES_GENERAL[@]}; do
|
|
||||||
CHROOT_BINARY $BINARY
|
|
||||||
done
|
|
||||||
# git
|
|
||||||
for BINARY in `find /usr/lib/git-core -type f`; do
|
|
||||||
CHROOT_BINARY $BINARY
|
|
||||||
done
|
|
||||||
# networking
|
|
||||||
for LIB in /lib/*/libnss_*; do
|
|
||||||
ADD_LIB $LIB
|
|
||||||
done
|
|
||||||
# php
|
|
||||||
for LIB in /usr/lib/php/*/*.so; do
|
|
||||||
ADD_LIB $LIB
|
|
||||||
done
|
|
||||||
CHROOT_LIBRARIES
|
|
||||||
ldconfig -r $CHROOT_DIRECTORY
|
|
||||||
ln -f $CHROOT_DIRECTORY/usr/bin/php8.2 $CHROOT_DIRECTORY/usr/bin/php
|
|
||||||
|
Reference in New Issue
Block a user