No description
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
100mountains ca1e86f8c7 Fix SSH password auth not being disabled on Ubuntu 22/24
cloud-init writes sshd_config.d/50-cloud-init.conf with
PasswordAuthentication yes, which overrides sshd_config.
Patch that file too.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:35:21 +00:00
configs Initial commit: general server setup stripped of WordPress 2026-06-09 21:56:03 +00:00
.env.example Add one-command install, .env.example, executable scripts 2026-06-09 21:59:12 +00:00
.gitignore Initial commit: general server setup stripped of WordPress 2026-06-09 21:56:03 +00:00
harden.sh Fix SSH password auth not being disabled on Ubuntu 22/24 2026-06-09 22:35:21 +00:00
install.sh Fix SSH key check to use invoking user's home, not /root 2026-06-09 22:24:50 +00:00
README.md Add one-command install, .env.example, executable scripts 2026-06-09 21:59:12 +00:00
setup-base.sh Add one-command install, .env.example, executable scripts 2026-06-09 21:59:12 +00:00

server-install

General-purpose Ubuntu server setup for a public-facing site. Installs nginx + MariaDB with security hardening. No PHP, no WordPress.

Tuned for ~12GB VPS with high concurrency (audio chat, WebSockets, etc.).

Quick install

git clone https://github.com/100mountains/server-install.git && \
cd server-install && \
sudo ./install.sh

The script will prompt for your domain and email if not set.

Or pre-configure first:

git clone https://github.com/100mountains/server-install.git
cd server-install
cp .env.example .env
# edit .env with your domain and email
sudo ./install.sh

Prerequisites

  • Fresh Ubuntu 22.04 or 24.04 server
  • Your SSH public key in ~/.ssh/authorized_keys — password auth will be disabled
  • Root or sudo access
  • Domain pointing to the server IP

What gets installed

Component Notes
nginx Tuned for many concurrent WebSocket connections
MariaDB Optimised for ~12GB mixed-workload server
certbot Let's Encrypt TLS, auto-configured via nginx plugin
fail2ban SSH + nginx jails (see table below)
chkrootkit / rkhunter Rootkit detection
UFW Firewall: SSH / 80 / 443 only

Scripts

server-install/
├── install.sh        # Orchestrator — run this
├── setup-base.sh     # nginx + MariaDB + certbot
├── harden.sh         # SSH / UFW / fail2ban / log rotation
└── configs/
    ├── nginx/        # nginx.conf template
    ├── mariadb/      # MariaDB tuning
    ├── fail2ban/     # jail.local + filters
    ├── logrotate/    # Log rotation config
    └── systemd/      # Service dependency overrides

Tuning

MariaDB (configs/mariadb/conf.d/60-optimizations.cnf)

Default innodb_buffer_pool_size = 3G suits a mixed 12GB server (nginx + Node.js + DB).

Server RAM Workload Suggested buffer pool
12GB Mixed (web + DB) 3G
12GB DB-heavy 56G
8GB Mixed 2G

nginx (configs/nginx/nginx.conf.template)

worker_connections 4096 and client_max_body_size 1G suit a public audio site with long-lived WebSocket connections. Lower client_max_body_size if you don't need large file uploads.

fail2ban jails

Jail Threshold Ban
sshd 3 attempts 24h
nginx-http-auth 3 attempts 1h
nginx-bad-request 10 attempts 1h
nginx-botsearch 1 probe 24h
nginx-limit-req 10 hits 10m
recidive 3 bans 7 days

Troubleshooting

Locked out of SSH:

sudo cp /root/security_backups_*/sshd_config.backup /etc/ssh/sshd_config
sudo systemctl restart ssh

Service logs:

journalctl -u nginx -n 50
journalctl -u mariadb -n 50
sudo tail -f /var/log/fail2ban.log

Unban an IP:

sudo fail2ban-client unban <ip>

Licence

There is no licence. GO!