Repository navigation
Updating and Hardening
sudo deploy/update.shWraps scripts/update_cli.php: pulls application code updates, then runs any pending database
migrations from admin/database_updates.php up to includes/database_version.php's
LATEST_DATABASE_VERSION.
Recommended cadence: monthly, or right after harden.sh's unattended-upgrades has kept the OS
current but a known application-level fix has shipped. Always take a fresh
Backup and Restore run (or confirm the scheduled timer ran recently) before
updating a production instance — a schema migration is exactly the kind of change you want a tested
rollback path for.
Deliberately uses plain --update (a git pull), never --force_update
(git fetch --all && git reset --hard origin/master) — a hard reset in an automated wrapper would
silently discard any local edit made directly on the box, which a git pull instead merges or fails
loudly on.
sudo deploy/harden.sh # box-wide hardening only
sudo deploy/harden.sh --dry-run # preview every action, change nothing
sudo deploy/harden.sh --domain itflow.example.com --app-root /var/www/itflow.example.com \
--ssl-cert /etc/ssl/certs/itflow.example.com.crt \
--ssl-cert-key /etc/ssl/private/itflow.example.com.key
# also (re)render that vhost hardenedA standalone, idempotent, re-runnable hardening pass — the fuller superset of what
Bare Metal Install's install.sh applies inline during a fresh install.
- PHP-FPM hardening — validated with a config test, service reloaded only on success, rolled back automatically otherwise.
- MariaDB hardening — same validate-then-restart-then-rollback pattern.
- A mysql_secure_installation-equivalent cleanup — removes anonymous MySQL users and the
testdatabase (skipped, with a warning, if MariaDB's root account isn't using the defaultunix_socketauth this expects). - fail2ban jails for SSH brute-force and repeated failed/blocked app auth requests.
-
ufw— auto-detects every portsshdactually listens on and allows all of them, plus 80/443 (and 8443 in--proxy-mode), before enabling the firewall. -
unattended-upgrades, restricted to
-securityorigin packages only, with automatic reboot explicitly disabled (a live app rebooting itself unattended is its own outage). - nginx — the shared rate-limit zone and shared locations snippet unconditionally, plus (only if
--domain/--app-root/--ssl-cert/--ssl-cert-keyare given) a re-rendered vhost for that domain.
Every step is check-before-act and safe to run repeatedly — including against a box that already has one or more other ITFlow instances hardened by an earlier run.
install.sh does not invoke harden.sh. It applies its own inline copy of steps 1–2 and 4–5
above during a fresh install, but not the mysql_secure_installation cleanup (3) or
unattended-upgrades (6). Practical recommendation: run harden.sh once, standalone, right after
install.sh completes —
sudo deploy/install.sh --domain=itflow.example.com ...
sudo deploy/harden.sh— it'll find the config install.sh already applied unchanged and skip re-writing it, so you only
actually pick up the two extra steps.
harden.sh is also the right tool, entirely on its own, for a company that already has ITFlow running
from a manual or older setup and just wants to retrofit this hardening onto it. Always preview first
with --dry-run on a box you didn't just build with install.sh.
Selective skips are available for every section (--skip-php, --skip-mariadb,
--skip-mysql-secure, --skip-fail2ban, --skip-ufw, --skip-unattended-upgrades, --skip-nginx) —
see --help for the full list.