No description
- Shell 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
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> |
||
| configs | ||
| .env.example | ||
| .gitignore | ||
| harden.sh | ||
| install.sh | ||
| README.md | ||
| setup-base.sh | ||
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 | 5–6G |
| 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!