diff --git a/README.md b/README.md index 6546d97..1289ddd 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Installing Pterodactyl in just a few minutes!
Please note this script is meant to be used on fresh installations only. You must run it as root.

`curl -Ls https://api.github.com/repos/TommyTran732/Pterodactyl-Script/releases/latest | grep -wo "https.*install.sh" | wget -qi -`
-
+
`bash install.sh`

Visit my Matrix group: https://matrix.to/#/#tommy:arcticfoxes.net @@ -14,39 +14,31 @@ Visit my Matrix group: https://matrix.to/#/#tommy:arcticfoxes.net - Panel upgrade - Daemon installation - 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 +- Automatic LetsEncrypt certificate generation +- MariaDB SSL +- HSTS enabled +- Additional security headers (CSP, Permission Policy, CORP, COOP) - Database password reset -# 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.
+# Dependency Updates -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.
+ +```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 -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.
+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.
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 -Fedora, CentOS Stream, RHEL, Rocky Linux, AlmaLinux, Ubuntu, and Debian are currently supported distributions.
+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.
- -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.
- -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: | 🔴 | | +Ubuntu, Debian, and openSUSE are unlikely to get supported, due to them not supporting modular repositories which makes dependency updates cumbersome. \ No newline at end of file diff --git a/install.sh b/install.sh index 95e4e9e..afefaec 100644 --- a/install.sh +++ b/install.sh @@ -69,9 +69,8 @@ install_options(){ output "[4] Upgrade panel to ${PANEL}." output "[5] Upgrade wings 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 "[8] Emergency MariaDB root password reset." - output "[9] Emergency database host information reset." + output "[7] Emergency MariaDB root password reset." + output "[8] Emergency database host information reset." read -r choice case $choice in 1 ) installoption=1 @@ -92,13 +91,10 @@ install_options(){ 6 ) installoption=6 output "You have selected to upgrade panel to ${PANEL} and daemon to ${DAEMON}." ;; - 7 ) installoption=7 - output "You have selected to install phpMyAdmin." - ;; - 8 ) installoption=8 + 7 ) installoption=8 output "You have selected MariaDB root password reset." ;; - 9 ) installoption=9 + 8 ) installoption=9 output "You have selected Database Host information reset." ;; * ) output "You did not enter a valid selection." @@ -136,9 +132,6 @@ required_infos() { install_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 subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms 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 dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm - dnf install -y nginx redis mariadb-server composer tuned - 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 module install -y php:remi-8.1/common dnf install -y php-bcmath php-gd php-mysqlnd php-pdo php-sodium 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() { @@ -175,7 +197,7 @@ install_pterodactyl() { Q1="CREATE DATABASE IF NOT EXISTS panel;" Q2="SET old_passwords=0;" 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');" 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='';" @@ -309,17 +331,19 @@ EOF output "Configuring Nginx web server..." -echo ' + rm -f /etc/nginx/conf.d/default.conf + + cat > /etc/nginx/conf.d/pterodactyl.conf <<- 'EOF' server { listen 80 default_server; listen [::]:80 default_server; - server_name '"$FQDN"'; + server_name FQDN; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; - server_name '"$FQDN"'; + server_name FQDN; root /var/www/pterodactyl/public; index index.php; @@ -331,8 +355,8 @@ server { client_body_timeout 120s; sendfile off; - ssl_certificate /etc/letsencrypt/live/'"$FQDN"'/fullchain.pem; - ssl_certificate_key /etc/letsencrypt/live/'"$FQDN"'/privkey.pem; + ssl_certificate /etc/letsencrypt/live/FQDN/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/FQDN/privkey.pem; ssl_session_cache shared:SSL:10m; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256"; @@ -374,7 +398,10 @@ server { location ~ /\.ht { 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 restorecon -R /var/www/pterodactyl @@ -440,80 +467,6 @@ upgrade_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 - 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(){ if [ "$installoption" = "2" ]; then if [ "$lsb_dist" != "rhel" ]; then @@ -565,6 +518,50 @@ EOF 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(){ adminpassword=`cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1` Q0="SET old_passwords=0;" @@ -610,6 +607,7 @@ preflight install_options case $installoption in 1) required_infos + linux_hardening install_dependencies install_pterodactyl firewall @@ -619,6 +617,7 @@ case $installoption in print_info_database ;; 2) required_infos + linux_hardening firewall ssl_certs install_wings @@ -626,6 +625,7 @@ case $installoption in print_info_database ;; 3) required_infos + linux_hardening install_dependencies install_pterodactyl firewall @@ -641,10 +641,8 @@ case $installoption in 6) upgrade_pterodactyl 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 - ;; - 9) database_host_reset + 8) database_host_reset ;; esac