This directory contains ubuntu_server_setup.sh, an interactive CLI script to perform initial setup and security hardening on a fresh Ubuntu server.
- Operation modes: Choose between
initial-setup,network-config, orfirewall-config- initial-setup: Security hardening (no firewall changes)
- network-config: Interactive netplan configuration for an interface. Offers Add config (existing flow) or Remove config (delete
/etc/netplan/60-<iface>.yamland apply changes). - firewall-config: Only configure/reset UFW based on selected role (no SSH/netplan changes)
- authorized-key: Add an SSH public key to a user's
~/.ssh/authorized_keys
- Updates system packages:
apt update && apt upgrade - Configures UFW firewall: Only in
firewall-configmode. Resets rules, denies incoming and allows outgoing by default, always allowsssh, then opens extra ports based on your selected role - Hardens SSH: disables password authentication, restricts root login, reduces auth retries, disables X11 forwarding, and more
- Optional Fail2Ban: if chosen, installs and configures Fail2Ban to protect SSH
- Optional Authorized Key: interactively add an SSH public key to a user's
~/.ssh/authorized_keys
- Ubuntu Server with internet access
- Root privileges (run with
sudo) gitinstalled (for repo-based install)
Recommended: clone the repository on the server and run the script from there.
sudo apt update && sudo apt install -y git
git clone https://github.com/yigitahmetsahin/ubuntu-configurator.git
cd ubuntu-configurator/templates
sudo chmod +x ubuntu_server_setup.sh
sudo ./ubuntu_server_setup.shAlternatively, download only the script directly from GitHub and run it:
curl -fsSL -H 'Cache-Control: no-cache' -H 'Pragma: no-cache' \
"https://raw.githubusercontent.com/yigitahmetsahin/ubuntu-configurator/main/ubuntu_server_setup.sh?t=$(date +%s)" \
-o "$HOME/ubuntu_server_setup.sh"
sudo chmod +x "$HOME/ubuntu_server_setup.sh"
sudo "$HOME/ubuntu_server_setup.sh"You will be prompted for:
- Operation mode:
initial-setup,network-config, orfirewall-config- If
initial-setup:- Install Fail2Ban (y/N)?
- If
authorized-key:- Prompts for username and SSH public key, then creates/updates
~/.ssh/authorized_keyswith secure permissions and avoids duplicates.
- Prompts for username and SSH public key, then creates/updates
- If
network-config:- Action: choose
add-configorremove-configremove-config: select an existing interface defined in netplan; the script backs up and removes/etc/netplan/60-<iface>.yaml, validates, and applies.add-config: existing flow described below.
- Select interface: choose from missing (not yet in netplan) or existing interfaces
- DHCP (y/N): use DHCP for IPv4 or configure static
- Network type: choose between public (internet access) or local (CIDR-specific, no default route)
- If local: specify CIDR range that should use this interface (e.g.,
192.168.0.0/16); the script prevents0.0.0.0/0 - Local mode disables default routes and DNS from DHCP, sets route metric to 500, and adds a
scope: linkroute for the specified CIDR
- If local: specify CIDR range that should use this interface (e.g.,
- If static: provide
address (CIDR)and optionalDNS servers - Optional (Y/n): mark interface as optional to skip boot wait
- Action: choose
- If
firewall-config:- Select setup type: same roles as above; script resets UFW and applies role ports only
- For
redisandmariadb, you'll be prompted to optionally enter a source IP/CIDR. If provided, UFW allows only that source to the role's port; if left empty, it allows from anywhere.
- If
The script always allows ssh and then opens additional ports per role:
- redis:
6379/tcp - mariadb:
3306/tcp - api:
80/tcp,80/udp,443/tcp,443/udp - ui-app:
80/tcp,80/udp,443/tcp,443/udp - vpn:
1194/udp(OpenVPN UDP),443/tcp(OpenVPN TCP & web forwarding),943/tcp(Admin/Client Web UI) - deployinator:
80/tcp,3000/tcp,443/tcp
Notes:
- UFW is reset each run. Re-running the script will re-apply base rules and your selected role.
- SSH hardening is applied unconditionally. Ensure you have working SSH key-based access before running.
The script prints a summary at the end and shows:
ufw status(firewall state)systemctl status fail2ban(only if installed)sshd -t(validates SSH config)
When running network-config, it also:
- Writes
/etc/netplan/60-<iface>.yaml(backs up existing file if present) - Validates configuration (
netplan generate) and applies it (netplan apply) - Shows interface status:
ip addr show <iface>andnetworkctl status <iface>
- Public networks: Interface becomes the default route for internet traffic (metric 100)
- DHCP public: IP address and default routing managed automatically by DHCP
- Static public: Manual IP configuration with default route via specified gateway
- Local networks: Interface never advertises a default gateway; only the specified CIDR is routed through this interface with
scope: link- DHCP local: IP obtained via DHCP, default route/DNS disabled, and route metric set to 500
- Static local: Manual IP configuration with a
scope: linkroute for the CIDR
- Check firewall:
sudo ufw status verbose - Validate SSH config:
sudo sshd -t - Check Fail2Ban (if installed):
sudo systemctl status fail2ban --no-pager -l - Netplan preview:
sudo netplan get - Netplan try (safe apply with rollback):
sudo netplan try - Network logs:
journalctl -u systemd-networkd --no-pager -b
- Disable firewall temporarily:
sudo ufw disable - Remove Fail2Ban:
sudo apt remove -y fail2ban - Restore SSH config backup (created by the script):
sudo cp /etc/ssh/sshd_config.backup.YYYYMMDD_HHMMSS /etc/ssh/sshd_config
sudo systemctl restart sshInternal use. Add a license here if required for your project.
- When adding or updating a feature in this folder, update this
README.mdaccordingly. - Document new flags, environment variables, inputs/outputs, and any breaking changes.
- If a new script or tool is introduced, add a short usage example.