Private
Public Access
1
0

Automate server hardening in install.sh, update guide accordingly

Move firewall (UFW), fail2ban, auto-updates, and Docker log rotation
from manual guide steps into install.sh automation. Update guide.md
to describe the automated process instead of manual commands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
constantprojects
2026-02-23 16:32:47 -07:00
parent d63701abfb
commit b7dc25fbf2
2 changed files with 134 additions and 174 deletions

227
guide.md
View File

@@ -149,176 +149,6 @@ When typing a password in the terminal, **nothing appears on screen** — no dot
If you get "Connection refused" or "Connection timed out," wait a minute — your server might still be starting up. Try again after 60 seconds. If it still doesn't work, double-check the IP address.
[/callout]
[step: Secure Your Server]
Before installing anything else, let's lock down your server with a **firewall**, **brute-force protection**, **automatic security updates**, and **Docker log management**. This takes about 3 minutes and prevents the vast majority of problems before they start.
Think of it this way: your server is now on the public internet, and automated bots are already scanning it looking for easy targets. These steps stop them cold and keep your server healthy long-term.
**First, update your server's software:**
This makes sure you have the latest security patches. It's the equivalent of running Windows Update or updating your phone.
[code:bash]
apt update && apt upgrade -y
[/code]
This may take a minute. If you see a pink/purple screen asking about restarting services, just press **Enter** to accept the defaults.
**Install the firewall, fail2ban, and automatic updates:**
[code:bash]
apt install -y ufw fail2ban unattended-upgrades
[/code]
This installs three tools:
- [UFW](https://wiki.ubuntu.com/UncomplicatedFirewall) (Uncomplicated Firewall) — blocks all network traffic except what you explicitly allow
- [Fail2ban](https://www.fail2ban.org/) — watches for repeated failed login attempts and automatically bans those IP addresses
- [Unattended Upgrades](https://wiki.debian.org/UnattendedUpgrades) — automatically installs security patches so you don't have to remember to do it manually
**Configure the firewall:**
You need to tell the firewall which types of traffic to allow. Your server needs exactly three things open:
[code:bash]
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
[/code]
Here's what each line does:
- `ufw allow OpenSSH` — allows SSH connections (port 22), so you can keep connecting to your server remotely. **This line is critical** — without it, you'd be locked out of your own server.
- `ufw allow 80/tcp` — allows HTTP web traffic (needed for SSL certificate setup)
- `ufw allow 443/tcp` — allows HTTPS web traffic (your actual website)
Everything else (thousands of other ports) is blocked by default. That's exactly what you want.
**Turn on the firewall:**
[code:bash]
ufw enable
[/code]
You'll see a warning that says "Command may disrupt existing SSH connections." Type `y` and press Enter. Your current connection will stay active — the warning is just being cautious.
[callout:danger]
**Make sure you ran `ufw allow OpenSSH` before this step.** If you enable the firewall without allowing SSH first, you will be locked out of your server and will need to use your VPS provider's emergency web console to fix it.
[/callout]
**Verify the firewall is working:**
[code:bash]
ufw status
[/code]
You should see output like this:
[terminal]
$ ufw status
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443/tcp (v6) ALLOW Anywhere (v6)
[/terminal]
If you see `Status: active` with those three rules listed, your firewall is properly configured.
**Configure fail2ban:**
Fail2ban works out of the box for SSH protection with sensible defaults, but let's make sure it's running:
[code:bash]
systemctl enable fail2ban
systemctl start fail2ban
[/code]
The first command tells fail2ban to start automatically whenever your server reboots. The second starts it right now.
You can verify it's running with:
[code:bash]
fail2ban-client status sshd
[/code]
[terminal]
$ fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
[/terminal]
This shows fail2ban is monitoring SSH login attempts. After a few hours online, you'll likely see banned IPs here — that's fail2ban doing its job, blocking automated bots that try to guess passwords.
[callout:info]
**What does fail2ban actually do?** By default, if someone (or a bot) fails to log in via SSH 5 times within 10 minutes, fail2ban bans their IP address for 10 minutes. This makes brute-force password guessing effectively impossible — a bot that can try thousands of passwords per second gets cut off after just 5 attempts.
[/callout]
**Enable automatic security updates:**
Your server should install security patches on its own — you don't want to rely on remembering to SSH in and run updates. Enable it with:
[code:bash]
dpkg-reconfigure -plow unattended-upgrades
[/code]
When asked "Automatically download and install stable updates?", select **Yes** and press Enter.
That's all it takes. From now on, your server will check for and install security updates daily in the background. It won't restart your server or touch your website — it only patches the underlying operating system.
[callout:info]
**Will auto-updates break anything?** No. Unattended upgrades only installs security patches for your operating system (Ubuntu/Debian), not major version upgrades. It won't touch Docker, WordPress, or anything in your website. It's the same type of automatic update your phone does overnight.
[/callout]
**Set up Docker log rotation:**
Docker containers generate log files that grow over time. Without a size limit, these logs can eventually fill up your server's disk. Let's set a sensible limit now so this never becomes a problem.
Create the Docker configuration file:
[code:bash]
mkdir -p /etc/docker
cat > /etc/docker/daemon.json << 'EOF'
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF
[/code]
This tells Docker to:
- Keep each log file to a maximum of **10 megabytes**
- Keep at most **3** rotated log files per container
- That's a maximum of 30 MB of logs per container — plenty for troubleshooting, but no risk of filling your disk
[callout:info]
You're running this **before** the WebsiteBox installer, so Docker may or may not be installed yet. That's fine — if Docker isn't installed yet, the file will be waiting for it. If Docker is already installed, restart it to apply the setting: `systemctl restart docker`
[/callout]
Now restart Docker if it's already running (if it's not installed yet, this will harmlessly fail):
[code:bash]
systemctl restart docker 2>/dev/null || true
[/code]
[callout:tip]
**That's it for server setup.** You now have a firewall blocking all unnecessary ports, fail2ban stopping brute-force attacks, automatic security updates keeping your OS patched, and Docker log rotation preventing disk bloat. Combined with the security features WebsiteBox sets up later (Wordfence, rate-limited logins, encrypted HTTPS), your server will be well-protected and low-maintenance. For further hardening down the road, see the "Going Further" step at the end of this guide.
[/callout]
[step: Run the Installer]
Now for the easy part. Copy and paste this single command into your terminal and press Enter:
@@ -333,11 +163,60 @@ curl -fsSL https://raw.githubusercontent.com/websitebox/websitebox/main/install.
This one command does everything needed to prepare your server:
1. **Installs Docker** — the software that packages and runs your website (think of it as a container system that keeps everything organized and isolated)
2. **Downloads WebsiteBox** — the project files that define your website setup
3. **Starts the setup wizard** — an interactive questionnaire to configure your site (covered in the next step)
1. **Updates your system** — installs the latest security patches
2. **Secures your server** — sets up a firewall ([UFW](https://wiki.ubuntu.com/UncomplicatedFirewall)), brute-force protection ([Fail2ban](https://www.fail2ban.org/)), and automatic security updates ([Unattended Upgrades](https://wiki.debian.org/UnattendedUpgrades))
3. **Installs Docker** — the software that packages and runs your website (think of it as a container system that keeps everything organized and isolated)
4. **Configures log rotation** — prevents Docker logs from filling up your disk over time
5. **Downloads WebsiteBox** — the project files that define your website setup
6. **Starts the setup wizard** — an interactive questionnaire to configure your site (covered in the next step)
You'll see text scrolling by as things install. This is normal — let it run. It typically takes 1-2 minutes depending on your server's speed.
You'll see output scrolling by as each step completes. Here's roughly what to expect:
[terminal]
═══════════════════════════════════════════════════════════
WebsiteBox Installer
═══════════════════════════════════════════════════════════
Detected: ubuntu 22.04
───────────────────────────────────────────────────────────
Securing your server...
───────────────────────────────────────────────────────────
Updating system packages...
System packages updated.
Installing firewall, fail2ban, and automatic updates...
Configuring firewall...
Firewall enabled: SSH, HTTP, and HTTPS allowed. All other ports blocked.
Fail2ban enabled: brute-force SSH protection active.
Automatic security updates enabled.
Docker log rotation configured (10MB max per log, 3 files per container).
Server secured:
Firewall: active (SSH, HTTP, HTTPS only)
Fail2ban: active (SSH brute-force protection)
Auto-updates: enabled (daily security patches)
Docker log limits: configured (30MB max per container)
Installing Docker...
Docker installation complete.
Cloning WebsiteBox...
═══════════════════════════════════════════════════════════
WebsiteBox Setup Wizard
═══════════════════════════════════════════════════════════
[/terminal]
The entire process takes 2-3 minutes. If you see a pink/purple screen asking about restarting services during the update, just press **Enter** to accept the defaults.
When the "WebsiteBox Setup Wizard" header appears, the installer is done and the setup wizard has started — that's covered in the next step.
[callout:info]
**What just got secured?** The installer automatically set up four layers of protection:
- **[UFW firewall](https://wiki.ubuntu.com/UncomplicatedFirewall)** — blocks all network traffic except SSH (so you can connect), HTTP (port 80), and HTTPS (port 443). Everything else is locked down.
- **[Fail2ban](https://www.fail2ban.org/)** — if someone (or a bot) fails to log in via SSH 5 times in 10 minutes, their IP address is automatically banned. This stops brute-force password guessing.
- **[Unattended Upgrades](https://wiki.debian.org/UnattendedUpgrades)** — your server will automatically install security patches daily. It only patches the operating system — it won't touch Docker, WordPress, or your website.
- **Docker log rotation** — container logs are capped at 30 MB each so they can't fill up your disk over months of running.
[/callout]
[callout:warning]
**If you get a "permission denied" error**, your server may need administrator privileges. Try this version instead: