1
0
mirror of https://github.com/tommytran732/Pterodactyl-Script synced 2024-10-18 04:35:12 -04:00

Upstream NGINX

Signed-off-by: Tommy <contact@tommytran.io>
This commit is contained in:
Tommy 2022-12-07 11:50:40 -05:00
parent 5234008aec
commit e8b156bf44
No known key found for this signature in database
GPG Key ID: 060B29EB996BD9F2
2 changed files with 119 additions and 129 deletions

View File

@ -14,39 +14,31 @@ Visit my Matrix group: https://matrix.to/#/#tommy:arcticfoxes.net
- Panel upgrade - Panel upgrade
- Daemon installation - Daemon installation
- Daemon upgrade - Daemon upgrade
- phpMyAdmin installation (on nodes with the panel only - optional)
- Automatic LetsEncrypt certificate generation
- HSTS enabled
- MariaDB SSL
- Fail2ban sshd & phpMyAdmin-syslog jails
- Basic firewall configuration - Basic firewall configuration
- Automatic LetsEncrypt certificate generation
- MariaDB SSL
- HSTS enabled
- Additional security headers (CSP, Permission Policy, CORP, COOP)
- Database password reset - Database password reset
# Dependency updates # Dependency Updates
Currently, Pterodactyl's dependencies (PHP, MariaDB) will only recieve minor version updates (e.g. PHP 8.0.1 -> PHP 8.0.x). Dependency upgrade scripts for major version changes (e.g. PHP 8.0.x -> PHP 8.1.0) are planned, but they are not yet available. For now, changing between major versions of Pterodactyl's depdencies are the user's own responsibility. <br />
I expect that a script for Fedora-based distributions to be relatively clean and simple, thanks to dnf's modular repositories. The same cannot be said for Debian-based distributions however, as we have to remove all of the old versions of the dependencies with apt, install the new ones, then apply reconfigurations. Please take this into account when choosing your distribution. Currently, PHP, Composer, and Redis are installed from Remi's modular repository. As such, they will only get minor version updates with `dnf upgrade` (PHP 8.1.0 -> PHP 8.1.x for example). For updates between major versions of these dependencies, use `dnf module` to change the appstream for these dependencies.<br />
```bash
dnf module reset php:remi-8.0
dnf module install php:remi-8.1
dnf distro-sync
```
NGINX, MariaDB, and Docker-CE uses upstream repositories and will get the latest version available on there automatically.
# Script updates/Reproducibility # Script updates/Reproducibility
Unfortunately, there is currently not an option to automatically apply new features / fixes I make to the script to an existing installation. The user has to look at the changelog and the code to apply it on their own. Theoratically, I could write a script to automate this process, but I currently don't have enough bandwidth for this and I want to spend my time developing new features. If anyone could help me with this, I would highly appreciate it. <br /> Unfortunately, there is currently not an option to automatically apply new features / fixes I make to the script to an existing installation. The user has to look at the changelog and the code to apply them on their own. Theoratically, I could write a script to automate this process, but I currently don't have enough bandwidth for this and I want to spend my time developing new features. If anyone could help me with this, I would highly appreciate it. <br />
Ideally, we would want everything to be reproducible from the OS to the Pterodactyl installation. I am currently looking at using Fedora CoreOS and Docker-Compose to accomplish this. If you are interested in such setup, please let me know. Ideally, we would want everything to be reproducible from the OS to the Pterodactyl installation. I am currently looking at using Fedora CoreOS and Docker-Compose to accomplish this. If you are interested in such setup, please let me know.
# Supported Distributions # Supported Distributions
Fedora, CentOS Stream, RHEL, Rocky Linux, AlmaLinux, Ubuntu, and Debian are currently supported distributions. <br /> Only RHEL 9 and its derivatives (CentOS Stream 9, Rocky Linux 9 , AlmaLinux 9) are supported at the moment. Fedora may get supported in the future if there are interest in it.
As it currently stands, RHEL is the best distribution for a production system. RHEL and its derivatives have much longer life cycle support (10 years) than Ubuntu LTS (5 years) and Debian (roughly 3 years - not counting Debian LTS), a much better Mandatory Access Control system, and a superior package manager. CentOS Stream is slightly (~1 minor version) ahead of RHEL, so you could expect it to be ever so slightly less stable. Rocky and AlmaLinux are RHEL rebuilds, so they are likely to get security patches after RHEL, just like how the old CentOS was. Red Hat now offers 16 licenses for free for production use, which also comes with Red Hat Insights, and I highly recommend that you choose RHEL over other distributions if possible. I am using RHEL on my personal Pterodactyl instance as well.<br /> Ubuntu, Debian, and openSUSE are unlikely to get supported, due to them not supporting modular repositories which makes dependency updates cumbersome.
If you live on the edge and don't mind doing a major OS upgrade every 6 months, then Fedora may be a perfect choice. However, I am not recommending it at the moment as it is probably not what people are looking for and I do not have enough energy to help with issues that may arise from doing in-place OS upgrades. <br />
As for Ubuntu, it is simply supported because it is a popular distribution and a lot of people might feel comfortable with it. That being said, I am not quite sure what the best practices are with Ubuntu at the moment - they seem to be pushing snaps very heavily, to the point where even Certbot and Docker are shipped and recommended as snaps. For simplicity, the script currently uses .deb packages just like it does with Debian, but this might change in the future if thoose .debs packages are neglected in favor of snaps. I personally would not use Ubuntu unless I have no other choices.
| Operating System | Version | Supported | Recommended | Notes |
| ----------------- | -------- | -------------------- | ------------------ | ------------------------------------ |
| Fedora | 35 | :heavy_check_mark: | 🔴 | |
| CentOS | Stream 8 | :heavy_check_mark: | ✔️ | |
| RHEL | 8 | :heavy_check_mark: | ✔️ | |
| Rocky Linux | 8 | :heavy_check_mark: | ✔️ | |
| Alma Linux | 8 | :heavy_check_mark: | ✔️ | |
| Ubuntu | 20.04 | :heavy_check_mark: | 🔴 | |
| Debian | 11 | :heavy_check_mark: | 🔴 | |

View File

@ -69,9 +69,8 @@ install_options(){
output "[4] Upgrade panel to ${PANEL}." output "[4] Upgrade panel to ${PANEL}."
output "[5] Upgrade wings to ${WINGS}." output "[5] Upgrade wings to ${WINGS}."
output "[6] Upgrade panel to ${PANEL} and daemon to ${WINGS}." output "[6] Upgrade panel to ${PANEL} and daemon to ${WINGS}."
output "[7] Install phpMyAdmin (only use this after you have installed the panel)." output "[7] Emergency MariaDB root password reset."
output "[8] Emergency MariaDB root password reset." output "[8] Emergency database host information reset."
output "[9] Emergency database host information reset."
read -r choice read -r choice
case $choice in case $choice in
1 ) installoption=1 1 ) installoption=1
@ -92,13 +91,10 @@ install_options(){
6 ) installoption=6 6 ) installoption=6
output "You have selected to upgrade panel to ${PANEL} and daemon to ${DAEMON}." output "You have selected to upgrade panel to ${PANEL} and daemon to ${DAEMON}."
;; ;;
7 ) installoption=7 7 ) installoption=8
output "You have selected to install phpMyAdmin."
;;
8 ) installoption=8
output "You have selected MariaDB root password reset." output "You have selected MariaDB root password reset."
;; ;;
9 ) installoption=9 8 ) installoption=9
output "You have selected Database Host information reset." output "You have selected Database Host information reset."
;; ;;
* ) output "You did not enter a valid selection." * ) output "You did not enter a valid selection."
@ -136,9 +132,6 @@ required_infos() {
install_dependencies(){ install_dependencies(){
output "Installing dependencies..." output "Installing dependencies..."
#Adding upstream repo because RHEL's version is extremely oudated.
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash
if [ "$lsb_dist" != "rhel" ]; then if [ "$lsb_dist" != "rhel" ]; then
subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
rpm --import https://raw.githubusercontent.com/tommytran732/Pterodactyl-Script/master/epel9.asc rpm --import https://raw.githubusercontent.com/tommytran732/Pterodactyl-Script/master/epel9.asc
@ -155,15 +148,44 @@ install_dependencies(){
rpm --import https://raw.githubusercontent.com/tommytran732/Pterodactyl-Script/master/remi9.asc rpm --import https://raw.githubusercontent.com/tommytran732/Pterodactyl-Script/master/remi9.asc
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
dnf install -y nginx redis mariadb-server composer tuned dnf module install -y php:remi-8.1/common
systemctl enable --now nginx
systemctl enable --now redis
systemctl enable --now mariadb
tune-adm profile latency-performance
dnf module install php:remi-8.1/common
dnf install -y php-bcmath php-gd php-mysqlnd php-pdo php-sodium dnf install -y php-bcmath php-gd php-mysqlnd php-pdo php-sodium
systemctl enable --now php-fpm systemctl enable --now php-fpm
dnf module install -y composer:2/common
dnf module install -y redis:remi-7.0/common
systemctl enable --now redis
#Adding upstream repo because RHEL's version is extremely oudated.
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash
dnf install -y nginx mariadb-server
systemctl enable --now mariadb
cat > /etc/yum.repos.d/nginx.repo <<- 'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
dnf config-manager --enable nginx-mainline
dnf install -y nginx
systemctl enable --now nginx
dnf install -y tuned
tune-adm profile latency-performance
} }
install_pterodactyl() { install_pterodactyl() {
@ -175,7 +197,7 @@ install_pterodactyl() {
Q1="CREATE DATABASE IF NOT EXISTS panel;" Q1="CREATE DATABASE IF NOT EXISTS panel;"
Q2="SET old_passwords=0;" Q2="SET old_passwords=0;"
Q3="GRANT ALL ON panel.* TO 'pterodactyl'@'127.0.0.1' IDENTIFIED BY '$password';" Q3="GRANT ALL ON panel.* TO 'pterodactyl'@'127.0.0.1' IDENTIFIED BY '$password';"
Q4="GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP, CREATE ROUTINE, ALTER ROUTINE, EXECUTE, PROCESS, RELOAD, LOCK TABLES, CREATE USER ON *.* TO 'admin'@'$SERVER_IP' IDENTIFIED BY '$adminpassword' WITH GRANT OPTION;" Q4="GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, REFERENCES, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES, CREATE VIEW, EVENT, TRIGGER, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EXECUTE ON *.* TO 'admin'@'$SERVER_IP' IDENTIFIED BY '$adminpassword' WITH GRANT OPTION;"
Q5="SET PASSWORD FOR 'root'@'localhost' = PASSWORD('$rootpassword');" Q5="SET PASSWORD FOR 'root'@'localhost' = PASSWORD('$rootpassword');"
Q6="DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');" Q6="DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');"
Q7="DELETE FROM mysql.user WHERE User='';" Q7="DELETE FROM mysql.user WHERE User='';"
@ -309,17 +331,19 @@ EOF
output "Configuring Nginx web server..." output "Configuring Nginx web server..."
echo ' rm -f /etc/nginx/conf.d/default.conf
cat > /etc/nginx/conf.d/pterodactyl.conf <<- 'EOF'
server { server {
listen 80 default_server; listen 80 default_server;
listen [::]:80 default_server; listen [::]:80 default_server;
server_name '"$FQDN"'; server_name FQDN;
return 301 https://$server_name$request_uri; return 301 https://$server_name$request_uri;
} }
server { server {
listen 443 ssl http2 default_server; listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server; listen [::]:443 ssl http2 default_server;
server_name '"$FQDN"'; server_name FQDN;
root /var/www/pterodactyl/public; root /var/www/pterodactyl/public;
index index.php; index index.php;
@ -331,8 +355,8 @@ server {
client_body_timeout 120s; client_body_timeout 120s;
sendfile off; sendfile off;
ssl_certificate /etc/letsencrypt/live/'"$FQDN"'/fullchain.pem; ssl_certificate /etc/letsencrypt/live/FQDN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/'"$FQDN"'/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/FQDN/privkey.pem;
ssl_session_cache shared:SSL:10m; ssl_session_cache shared:SSL:10m;
ssl_protocols TLSv1.2 TLSv1.3; ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256"; ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256";
@ -374,7 +398,10 @@ server {
location ~ /\.ht { location ~ /\.ht {
deny all; deny all;
} }
}' | tee /etc/nginx/conf.d/pterodactyl.conf >/dev/null 2>&1 }
EOF
sed -i "s/FQDN/${FQDN}/g" /etc/nginx/conf.d/pterodactyl.conf
service nginx restart service nginx restart
restorecon -R /var/www/pterodactyl restorecon -R /var/www/pterodactyl
@ -440,80 +467,6 @@ upgrade_wings(){
output "Your wings have been updated to version ${WINGS}." output "Your wings have been updated to version ${WINGS}."
} }
install_phpmyadmin(){
output "Installing phpMyAdmin..."
dnf -y install phpmyadmin
ln -s /usr/share/phpMyAdmin /var/www/pterodactyl/public/phpmyadmin
cd /var/www/pterodactyl/public/phpmyadmin || exit
SERVER_IP=$(dig +short myip.opendns.com @resolver1.opendns.com -4)
BOWFISH=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 34 | head -n 1`
bash -c 'cat > /etc/phpMyAdmin/config.inc.php' <<EOF
<?php
/* Servers configuration */
\$i = 0;
/* Server: MariaDB [1] */
\$i++;
\$cfg['Servers'][\$i]['verbose'] = 'MariaDB';
\$cfg['Servers'][\$i]['host'] = '${SERVER_IP}';
\$cfg['Servers'][\$i]['port'] = '3306';
\$cfg['Servers'][\$i]['socket'] = '';
\$cfg['Servers'][\$i]['auth_type'] = 'cookie';
\$cfg['Servers'][\$i]['user'] = 'root';
\$cfg['Servers'][\$i]['password'] = '';
\$cfg['Servers'][$i]['ssl'] = true;
\$cfg['ForceSSL'] = true;
/* End of servers configuration */
\$cfg['blowfish_secret'] = '${BOWFISH}';
\$cfg['DefaultLang'] = 'en';
\$cfg['ServerDefault'] = 1;
\$cfg['UploadDir'] = '/var/lib/phpMyAdmin/upload';
\$cfg['SaveDir'] = '/var/lib/phpMyAdmin/save';
\$cfg['CaptchaLoginPublicKey'] = '6LcJcjwUAAAAAO_Xqjrtj9wWufUpYRnK6BW8lnfn';
\$cfg['CaptchaLoginPrivateKey'] = '6LcJcjwUAAAAALOcDJqAEYKTDhwELCkzUkNDQ0J5';
\$cfg['AuthLog'] = syslog
?>
EOF
chmod 755 /etc/phpMyAdmin
chmod 644 /etc/phpMyAdmin/config.inc.php
chown -R nginx:nginx /var/www/pterodactyl
chown -R nginx:nginx /var/lib/phpMyAdmin/temp
bash -c 'cat > /etc/fail2ban/jail.local' <<-'EOF'
[DEFAULT]
# Ban hosts for one hours:
bantime = 3600
# Override /etc/fail2ban/jail.d/00-firewalld.conf:
banaction = iptables-multiport
[sshd]
enabled = true
[phpmyadmin-syslog]
enabled = true
maxentry = 15
EOF
service fail2ban restart
}
ssl_certs(){
output "Installing Let's Encrypt and creating an SSL certificate..."
dnf -y install certbot
if [ "$installoption" = "1" ] || [ "$installoption" = "3" ]; then
dnf -y install python3-certbot-nginx
certbot --nginx --redirect --no-eff-email --email "$email" --agree-tos -d "$FQDN"
setfacl -Rdm u:mysql:rx /etc/letsencrypt
setfacl -Rm u:mysql:rx /etc/letsencrypt
sed -i '/\[mysqld\]/a ssl-key=/etc/letsencrypt/live/'"${FQDN}"'/privkey.pem' /etc/my.cnf.d/server.cnf
sed -i '/\[mysqld\]/a ssl-ca=/etc/letsencrypt/live/'"${FQDN}"'/chain.pem' /etc/my.cnf.d/server.cnf
sed -i '/\[mysqld\]/a ssl-cert=/etc/letsencrypt/live/'"${FQDN}"'/cert.pem' /etc/my.cnf.d/server.cnf
systemctl restart mariadb
fi
if [ "$installoption" = "2" ]; then
certbot certonly --standalone --no-eff-email --email "$email" --agree-tos -d "$FQDN" --non-interactive
fi
systemctl enable --now certbot-renew.timer
}
firewall(){ firewall(){
if [ "$installoption" = "2" ]; then if [ "$installoption" = "2" ]; then
if [ "$lsb_dist" != "rhel" ]; then if [ "$lsb_dist" != "rhel" ]; then
@ -565,6 +518,50 @@ EOF
firewall-cmd --reload firewall-cmd --reload
} }
ssl_certs(){
output "Installing Let's Encrypt and creating an SSL certificate..."
dnf -y install certbot
if [ "$installoption" = "1" ] || [ "$installoption" = "3" ]; then
dnf -y install python3-certbot-nginx
certbot --nginx --redirect --no-eff-email --email "$email" --agree-tos -d "$FQDN"
setfacl -Rdm u:mysql:rx /etc/letsencrypt
setfacl -Rm u:mysql:rx /etc/letsencrypt
sed -i '/\[mysqld\]/a ssl-key=/etc/letsencrypt/live/'"${FQDN}"'/privkey.pem' /etc/my.cnf.d/server.cnf
sed -i '/\[mysqld\]/a ssl-ca=/etc/letsencrypt/live/'"${FQDN}"'/chain.pem' /etc/my.cnf.d/server.cnf
sed -i '/\[mysqld\]/a ssl-cert=/etc/letsencrypt/live/'"${FQDN}"'/cert.pem' /etc/my.cnf.d/server.cnf
systemctl restart mariadb
fi
if [ "$installoption" = "2" ]; then
certbot certonly --standalone --no-eff-email --email "$email" --agree-tos -d "$FQDN" --non-interactive
fi
systemctl enable --now certbot-renew.timer
}
linux_hardening(){
curl https://raw.githubusercontent.com/Kicksecure/security-misc/master/etc/modprobe.d/30_security-misc.conf -o /etc/modprobe.d/30_security-misc.conf
curl https://raw.githubusercontent.com/Kicksecure/security-misc/master/etc/sysctl.d/30_security-misc.conf -o /etc/sysctl.d/30_security-misc.conf
sed -i 's/kernel.yama.ptrace_scope=2/kernel.yama.ptrace_scope=3/g' /etc/sysctl.d/30_security-misc.conf
curl https://raw.githubusercontent.com/Kicksecure/security-misc/master/etc/sysctl.d/30_silent-kernel-printk.conf -o /etc/sysctl.d/30_silent-kernel-printk.conf
sysctl -p
curl https://raw.githubusercontent.com/GrapheneOS/infrastructure/main/chrony.conf -o /etc/chrony.conf
systemctl restart chronyd
mkdir -p /etc/systemd/system/NetworkManager.service.d
curl https://gitlab.com/divested/brace/-/raw/master/brace/usr/lib/systemd/system/NetworkManager.service.d/99-brace.conf -o /etc/systemd/system/NetworkManager.service.d/99-brace.conf
systemctl restart NetworkManager
mkdir -p /etc/systemd/system/irqbalance.service.d
curl https://gitlab.com/divested/brace/-/raw/master/brace/usr/lib/systemd/system/irqbalance.service.d/99-brace.conf -o /etc/systemd/system/irqbalance.service.d/99-brace.conf
systemctl restart irqbalance
mkdir -p /etc/systemd/system/sshd.service.d
curl https://raw.githubusercontent.com/GrapheneOS/infrastructure/main/systemd/system/sshd.service.d/limits.conf -o /etc/systemd/system/sshd.service.d/limits.conf
systemctl restart sshd
}
database_host_reset(){ database_host_reset(){
adminpassword=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1` adminpassword=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1`
Q0="SET old_passwords=0;" Q0="SET old_passwords=0;"
@ -610,6 +607,7 @@ preflight
install_options install_options
case $installoption in case $installoption in
1) required_infos 1) required_infos
linux_hardening
install_dependencies install_dependencies
install_pterodactyl install_pterodactyl
firewall firewall
@ -619,6 +617,7 @@ case $installoption in
print_info_database print_info_database
;; ;;
2) required_infos 2) required_infos
linux_hardening
firewall firewall
ssl_certs ssl_certs
install_wings install_wings
@ -626,6 +625,7 @@ case $installoption in
print_info_database print_info_database
;; ;;
3) required_infos 3) required_infos
linux_hardening
install_dependencies install_dependencies
install_pterodactyl install_pterodactyl
firewall firewall
@ -641,10 +641,8 @@ case $installoption in
6) upgrade_pterodactyl 6) upgrade_pterodactyl
upgrade_wings upgrade_wings
;; ;;
7) install_phpmyadmin 7) curl -sSL https://raw.githubusercontent.com/tommytran732/MariaDB-Root-Password-Reset/master/mariadb-104.sh | sudo bash
;; ;;
8) curl -sSL https://raw.githubusercontent.com/tommytran732/MariaDB-Root-Password-Reset/master/mariadb-104.sh | sudo bash 8) database_host_reset
;;
9) database_host_reset
;; ;;
esac esac