A bash-only, read-only auditor that validates a server’s readiness to host UserSpice 5. It checks PHP version/extensions and php.ini thresholds, web-server rewrite/HTTPS readiness, system resources, application directory permissions, optional RDS TCP reachability, and enumerates Apache/Nginx vhosts. Outputs human-readable results and (optionally) JSON.
- PHP: CLI presence, version (warn on ≥8.4), required/recommended extensions,
php.ini(memory_limit,post_max_size,upload_max_filesize,date.timezone), session path. - Web server: Apache
mod_rewrite, Nginxtry_fileshint. - System resources: CPU cores, RAM, disk space, inode headroom,
ulimit -n. - App path (optional): Presence of
.htaccess/index.php; writability ofusers,usersc,images,uploads,cache. - RDS reachability (optional): TCP probe to
host:portusingncor/dev/tcp. - VHosts: Apache/Nginx docroots discovered from live configs.
- HTTPS/SSL: Apache
mod_ssl, :443 listener, firewall (ufw/firewalld) status, per-vhost cert/key paths, Let’s Encrypt presence/expiry, live HTTP/HTTPS probes, Cloudflare proxy hints, redirect guidance.
scripts/audit.sh \
[--app-path /var/www/html] \
[--rds mydb.x.rds.amazonaws.com:3306] \
[--json]PHP_BIN=php, minimum PHP 8.1, warn on 8.4+- Size floors:
MIN_PHP_MEMORY_MB=128,MIN_PHP_POST_MB=8,MIN_PHP_UPLOAD_MB=8 - System floors:
MIN_RAM_MB=1024,MIN_DISK_MB=1024,MIN_INODES_PCT_FREE=5,MIN_ULIMIT_NOFILE=1024 - Web user guess:
WEB_USER_GUESS=www-data
- Prints PASS/WARN/FAIL with suggested remediation commands (apt/yum/systemctl/Certbot).
--jsonadds a machine-readable array of findings.- Exit 0 if no FAILs; Exit 1 if any FAIL is recorded.
- Linux shell with standard tools; best results when
php,openssl,curl,apache2ctl/httpd,nginx,ss/netstat, andncare available (the script falls back where possible). - Sufficient permissions to read web-server configs for full vhost discovery.
- Validates an input FQDN and derives a sanitized Linux username from it (dots → underscores, lowercase).
- Creates a system user/group and home at
/home/<username>, with web root at/home/<username>/public_html. - Drops a simple
index.htmlif none exists. - Generates
/etc/apache2/sites-available/<domain>.confwith :80 and :443 vhosts (snakeoil certs). - Enables mod_rewrite and mod_ssl, enables the site, runs
apache2ctl configtest, and reloads Apache. - Saves a randomly generated password to
/root/<username>-password.txt(mode600).
- Run as root on Debian/Ubuntu-style Apache layout (
apache2ctl,a2enmod,a2ensiteavailable). - Packages:
apache2,openssl(for password generation). - DNS should already point the domain to this server (needed later for real TLS).
sudo ./vhost-one.sh example.yourdomain.com
# or run without arg and follow the prompt- User & home:
/home/<sanitized-username>/ - Web root:
/home/<sanitized-username>/public_html/ - VHost:
/etc/apache2/sites-available/<domain>.conf - Password (if user newly created):
/root/<sanitized-username>-password.txt
-
The :443 vhost uses snakeoil certs for bootstrapping. Replace with Let’s Encrypt:
sudo certbot --apache -d <domain>
-
If
a2enmod/a2ensiteare missing, enable modules/sites manually and reload Apache. -
Re-running is idempotent for user, dirs, modules, and site enablement; it won’t clobber existing files.
Provision a clean UserSpice 5 codebase into /home/<USER>/public_html from your fork, and apply canonical file/dir permissions suitable for production.
-
Enumerates
/home/*and prompts you to select a target account. -
Ensures
public_htmlexists; if non-empty, interactively offers to wipe all contents. -
Clones
https://github.com/tocsindata/UserSpice5.gitinto the target directory. -
Sets ownership to
<USER>:www-data. -
Applies secure defaults: dirs 755, files 644.
-
Grants required writability:
users/init.php→ 664 (installer needs write)usersc/plugins/,usersc/widgets/→ 2775 (setgid, collaborative writes)
- Linux with
bashandgit. - Run with sufficient privileges to chown/chmod under
/home/<USER>. - Existing user home at
/home/<USER>.
sudo ./git-pull-userspice.sh
# follow the prompt to select the target account- Install path:
/home/<USER>/public_html - Repo:
tocsindata/UserSpice5
After completing the UserSpice web installer, you may tighten:
chmod 644 /home/<USER>/public_html/users/init.php- Destructive when confirmed: will delete all contents of
public_htmlif you agree. - Script is idempotent regarding directory creation and permission application.
Safely dismantle an Apache vhost for a given domain and, if desired, remove the associated sanitized system user and home directory created by your setup workflow.
- Validates the FQDN, derives the sanitized username (lowercase; dots → underscores).
- Disables the Apache site (
a2dissite), backs up the vhost file to/root/vhost-backups/<domain>.conf.<timestamp>, then removes it. - Runs
apache2ctl configtestand reloads Apache. - Optionally deletes the system user (via
userdel -r) and the/home/<user>/public_htmltree. - Optionally removes the saved password file and domain-specific Apache logs.
-
Multiple interactive prompts guard destructive steps:
- Remove vhost?
- Delete system user and home?
- Delete stored password file?
- Delete Apache logs?
-
Extra sanity checks prevent accidental deletion (e.g., refuses to act on
root).
- Run as root on Debian/Ubuntu Apache layout (requires
apache2ctl,a2dissite,systemctl). - The domain’s vhost file path:
/etc/apache2/sites-available/<domain>.conf.
sudo ./domain-remove.sh <domain.example.com>
# or run without an argument and follow the prompts- VHost:
/etc/apache2/sites-available/<domain>.conf(backed up, then removed) - Site link:
/etc/apache2/sites-enabled/<domain>.conf(disabled) - User home:
/home/<sanitized-username>/(optional removal) - Password file:
/root/<sanitized-username>-password.txt(optional removal) - Logs:
/var/log/apache2/<domain>_*.log(optional removal)
- This script mirrors the inverse of your
setup.sh/vhost-creation workflow. - After vhost removal, ensure DNS/CDN (e.g., Cloudflare) is updated if the domain is being decommissioned.
Automate installation or upgrade of PHP to a specified or auto-detected stable version, including common extensions, across Debian/Ubuntu (APT) and RHEL/Alma/Rocky/Amazon Linux (DNF). Supports mod_php (Ubuntu/Debian) and php-fpm modes.
- Version selection:
--version X.Yor--version X.Y.Z; otherwise auto-detects latest stable from php.net (skips X.Y.0 by default). - Repo setup: Adds Ondřej PPA (Ubuntu) or Sury (Debian); enables Remi or AL2023 module streams on DNF-based systems.
- Extensions: Installs a practical set (
curl mbstring intl xml zip gd mysql ldap opcache bcmath readline). - Web integration: Optionally switches libapache2-mod-php on Debian/Ubuntu or enables php-fpm with Apache.
- Safety & logging: Strict mode (
set -euo pipefail), clear logs, distro detection, and graceful fallbacks.
- Run as root.
- Internet access to package repos and php.net JSON.
- Package managers: apt or dnf available.
# Auto-detect latest stable (skips .0 minors)
sudo ./update-php.sh
# Pin a branch or exact patch
sudo ./update-php.sh --version 8.3
sudo ./update-php.sh --version 8.3.12
# Allow .0 minors
sudo ./update-php.sh --allow-dot-zero
# Choose integration mode
sudo ./update-php.sh --fpm
sudo ./update-php.sh --mod-php # Debian/Ubuntu only
# Specify Apache service name when needed
sudo ./update-php.sh --apache-service httpd # RHEL/Alma/Rocky/AMZ- Detect OS and package manager; set appropriate Apache service.
- Determine target PHP version (CLI
--versionor fetch from php.net). - Configure package repositories (Ondřej/Sury on apt; Remi/AL modules on dnf).
- Install PHP for the requested series and the listed extensions.
- If requested, switch mod_php (a2dismod/a2enmod) or enable php-fpm and restart Apache.
- Print summary (
php -v) and ensure services are enabled/restarted.
- By default,
SKIP_DOT_ZERO=1avoids.0minor releases (can be overridden with--allow-dot-zero). - On Amazon Linux 2023, you must provide
--versionto pick the stream (e.g.,8.3). - For RHEL-family, Apache integration is via php-fpm + proxy_fcgi (mod_php is uncommon).
Automate Let’s Encrypt certificate issuance and renewal for Apache (webroot http-01) non-interactively. Detects and fixes snakeoil/staging/mis-chained certs, discovers vhosts, validates webroots, and patches Apache configs to use the issued LE certs.
- Vhost discovery & parsing: Reads Apache configs (
apache2ctl/httpd) to findServerName/ServerAlias, :80/:443 blocks, and document roots. - Webroot preflight: Writes a temporary token under
.well-known/acme-challenge/and verifies it via HTTP before requesting a cert. - Issuance/Renewal logic: Renews when
< RENEW_DAYSremain, when SANs change, or when served issuer is not production Let’s Encrypt. - Auto-patching: Inserts or normalizes :443 blocks, replaces
SSLCertificateFile/KeyFilewith LE paths, removes deprecatedChainFile, and can disabledefault-sslsnakeoil. - Operational checks: Verifies local 443 listener, external reachability, Cloudflare proxy presence (with optional wait), IPv6 hints.
- Safety: Single-instance lock; configtest + reloads (and restart fallback) after changes.
CERT_EMAIL="[email protected]"RENEW_DAYS=30STAGING=0(production ACME by default)APACHE_RELOAD_CMD="systemctl reload apache2"FORCE_DISABLE_DEFAULT_SSL=1PREF_CHALLENGE="http-01"
- Run as root.
- Packages:
certbot,apache2ctlorhttpd,openssl,curl(andncfor reachability checks recommended). - Apache vhosts present and resolvable via DNS; port 80 reachable for
http-01.
- Sanity checks (443 listener, external reachability, tools present).
- Collect and parse vhost configs → build domain groups (primary + aliases) and webroots.
- Preflight each domain’s webroot via HTTP token fetch.
- Run
certbot certonly(production unlessSTAGING=1) with per-domain-wroots. - Patch vhosts to LE
fullchain.pem/privkey.pem, reload Apache, verify served fingerprint. - Handle Cloudflare (optional wait/probe). Summarize outcome.
sudo ./cert.sh
# Non-interactive; discovers all Apache vhosts and (re)issues as needed.- If behind Cloudflare, temporarily gray-cloud DNS or switch to DNS-01; the script warns and performs a post-issue probe with a short wait.
- The script does not manage cron; schedule it yourself (e.g., daily) to keep certificates current.