Linux Guide

Aerostat’s Guide To Linux

(Ubuntu Edition)

Web View · GitHub View · Standalone Markdown

A Simpler Guide To Linux.

An Aerostat & Co. pub.

Version 1.1


Introduction

This is a practical guide to setting up and hardening a Linux server, focused on Ubuntu 22.04 LTS. It covers everything from initial provisioning through advanced security controls, with curated links to authoritative external resources throughout.

This guide is published on GitHub so that Aerostat and the broader community can contribute. You can submit links, corrections, or new sections via pull request — all contributions are welcome.

Feel free to use this guide and fork it freely. If it helps you learn Linux security a little bit faster, this whole project is worth it.


Table of Contents

  1. Initial Server Setup
  2. Locking Down the OS
  3. Kernel Hardening with sysctl
  4. User Account Hardening
  5. Sudo Configuration
  6. SSH Hardening
  7. Two-Factor Authentication (2FA)
  8. Firewall Configuration
  9. Automatic Updates
  10. Encrypt Data Communication
  11. TLS/SSL Best Practices
  12. Filesystem Security
  13. Intrusion Detection with AIDE
  14. Log Management
  15. Monitoring and Auditing
  16. When to Move from Vercel / PaaS to a Self-Managed Server
  17. Container Security (Docker)
  18. Useful Commands
  19. Resources

Initial Server Setup

After first booting your Ubuntu server, update all packages immediately:

sudo apt update && sudo apt upgrade -y
sudo apt autoremove -y

Set your hostname:

sudo hostnamectl set-hostname your-server-name

Set your timezone:

sudo timedatectl set-timezone America/New_York
# List available timezones: timedatectl list-timezones

Synchronize time with NTP (essential for log accuracy and certificate validation):

sudo systemctl enable systemd-timesyncd
sudo systemctl start systemd-timesyncd
timedatectl status

Remove unnecessary packages to reduce the attack surface:

sudo apt purge telnet ftp rsh-client rsh-redone-client -y
sudo apt autoremove -y

📖 Reference: Ubuntu Server Initial Setup – DigitalOcean


Locking Down the OS

Lock the Boot Directory

The /boot directory contains important files related to the Linux kernel. Lock it to read-only by adding the following line to /etc/fstab:

LABEL=/boot   /boot   ext2   defaults,ro   1 2

Note: Remember to set it back to read-write (rw) temporarily when upgrading the kernel: sudo mount -o remount,rw /boot

Disable Unused Filesystems

Prevent loading of uncommon filesystem types by creating a blacklist file:

sudo nano /etc/modprobe.d/uncommon-fs.conf

Add the following:

install cramfs /bin/true
install freevxfs /bin/true
install jffs2 /bin/true
install hfs /bin/true
install hfsplus /bin/true
install squashfs /bin/true
install udf /bin/true
install vfat /bin/true

Disable Core Dumps

Core dumps can expose sensitive data. Disable them in /etc/security/limits.conf:

* hard core 0
* soft core 0

And in /etc/sysctl.conf:

fs.suid_dumpable = 0

Disable USB Storage (optional, for high-security environments)

echo "install usb-storage /bin/true" | sudo tee /etc/modprobe.d/disable-usb-storage.conf

📖 Reference: CIS Ubuntu Linux Benchmark (PDF)


Kernel Hardening with sysctl

The Linux kernel exposes a range of tunable parameters via sysctl. Applying secure defaults protects against network attacks, privilege escalation, and information leakage.

Create or edit /etc/sysctl.d/99-hardening.conf:

# --- IP Spoofing Protection ---
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# --- Ignore ICMP Broadcast Requests ---
net.ipv4.icmp_echo_ignore_broadcasts = 1

# --- Ignore Bogus ICMP Error Responses ---
net.ipv4.icmp_ignore_bogus_error_responses = 1

# --- SYN Flood Protection ---
net.ipv4.tcp_syncookies = 1

# --- Disable IP Source Routing ---
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv6.conf.all.accept_source_route = 0

# --- Disable ICMP Redirects ---
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0

# --- Log Suspicious Packets ---
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1

# --- Disable IPv6 if not needed ---
# net.ipv6.conf.all.disable_ipv6 = 1

# --- Protect against SUID/SGID privilege escalation ---
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2

# --- Prevent ptrace attacks ---
kernel.yama.ptrace_scope = 1

# --- Disable Magic SysRq Key ---
kernel.sysrq = 0

# --- Randomize virtual address space (ASLR) ---
kernel.randomize_va_space = 2

Apply immediately:

sudo sysctl -p /etc/sysctl.d/99-hardening.conf

📖 Reference: Kernel Self-Protection Project 📖 Reference: sysctl Hardening – Arch Wiki


User Account Hardening

Create a Non-Root Admin User

Never use root for daily tasks. Create a dedicated admin user:

adduser adminuser
usermod -aG sudo adminuser

Disable the Root Account

sudo passwd -l root

Or set its shell to /usr/sbin/nologin in /etc/passwd:

root:x:0:0:root:/root:/usr/sbin/nologin

Set Strong Password Policies

Install libpam-pwquality and configure password strength:

sudo apt install libpam-pwquality -y

Edit /etc/security/pwquality.conf:

minlen = 14
minclass = 4
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
maxrepeat = 3

Set password aging in /etc/login.defs:

PASS_MAX_DAYS   90
PASS_MIN_DAYS   7
PASS_WARN_AGE   14

Apply aging to an existing user:

sudo chage -M 90 -m 7 -W 14 username

Lock Inactive Accounts

Automatically disable accounts that have not been used in 30 days:

sudo useradd -D -f 30

Restrict su to the Wheel Group

Edit /etc/pam.d/su and uncomment or add:

auth required pam_wheel.so use_uid

📖 Reference: Linux User Account Security – SANS Institute


Sudo Configuration

Edit the sudoers file safely with visudo:

sudo visudo

Recommended settings:

# Require password for sudo every time (no caching)
Defaults timestamp_timeout=0

# Log all sudo commands
Defaults logfile="/var/log/sudo.log"

# Restrict sudo to a specific group
%sudo ALL=(ALL:ALL) ALL

# Limit specific users to specific commands
deployuser ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx

Audit who has sudo access:

grep -Po '^sudo.+:\K.*$' /etc/group

📖 Reference: sudoers Manual (sudo.ws)


SSH Hardening

Edit /etc/ssh/sshd_config to apply the following settings:

# Change the default port to reduce noise from automated scanners
Port 2222

# Disable root login
PermitRootLogin no

# Require key-based authentication only
PasswordAuthentication no
ChallengeResponseAuthentication no

# Disable unused features
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PermitTunnel no

# Restrict authentication attempts
MaxAuthTries 3
MaxSessions 2

# Only allow specific users
AllowUsers your_username

# Set a login grace period
LoginGraceTime 30

# Use modern key exchange and ciphers only
KexAlgorithms curve25519-sha256,diffie-hellman-group16-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

# Disconnect idle sessions
ClientAliveInterval 300
ClientAliveCountMax 2

Restart SSH after making changes (keep your current session open until you verify):

sudo sshd -t          # Test configuration for syntax errors
sudo systemctl restart sshd

Generate Strong SSH Keys

Use Ed25519 (preferred) or RSA-4096:

# Ed25519 (recommended)
ssh-keygen -t ed25519 -C "your_email@example.com"

# RSA 4096-bit (legacy compatibility)
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# Copy public key to server
ssh-copy-id -p 2222 user@remote_host

📖 Reference: Mozilla OpenSSH Guidelines 📖 Reference: SSH Audit Tool (ssh-audit.com)


Two-Factor Authentication (2FA)

Adding TOTP-based 2FA to SSH provides an extra layer of protection even if a private key is compromised.

Install Google Authenticator PAM module:

sudo apt install libpam-google-authenticator -y

Run the setup as your user:

google-authenticator

Follow the prompts to configure TOTP. Then edit /etc/pam.d/sshd:

# Add at the top:
auth required pam_google_authenticator.so

In /etc/ssh/sshd_config, enable challenge-response:

ChallengeResponseAuthentication yes
AuthenticationMethods publickey,keyboard-interactive

Restart SSH:

sudo systemctl restart sshd

📖 Reference: How To Set Up Multi-Factor Authentication for SSH – DigitalOcean


Firewall Configuration

UFW (Uncomplicated Firewall)

UFW is the recommended frontend for iptables on Ubuntu:

sudo apt install ufw -y

# Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow essential services (use your actual SSH port)
sudo ufw allow 2222/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'

# Rate-limit SSH to prevent brute force
sudo ufw limit 2222/tcp

sudo ufw enable
sudo ufw status verbose

Fail2Ban

Fail2Ban monitors log files and bans IPs that show malicious behavior:

sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

Create a local jail config at /etc/fail2ban/jail.local (this overrides defaults and survives upgrades):

[DEFAULT]
bantime  = 3600
findtime = 600
maxretry = 3
destemail = admin@yourdomain.com
action = %(action_mwl)s

[sshd]
enabled  = true
port     = 2222
logpath  = %(sshd_log)s
maxretry = 3
bantime  = 86400

[nginx-http-auth]
enabled  = true

Check banned IPs:

sudo fail2ban-client status sshd

📖 Reference: Fail2Ban Documentation 📖 Reference: UFW Essentials – DigitalOcean


Automatic Updates

Enable unattended security upgrades to ensure critical patches are applied automatically:

sudo apt install unattended-upgrades apt-listchanges -y
sudo dpkg-reconfigure --priority=low unattended-upgrades

Edit /etc/apt/apt.conf.d/50unattended-upgrades to enable automatic reboots (optional):

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "02:00";
Unattended-Upgrade::Mail "admin@yourdomain.com";

Verify it runs:

sudo unattended-upgrade --dry-run --debug

📖 Reference: Automatic Updates – Ubuntu Documentation


Encrypt Data Communication

Use scp, ssh, rsync, or sftp for all file transfers — never FTP or Telnet in plaintext.

Secure Remote File Transfers

# Copy a file to remote server
scp -P 2222 file.txt user@remote:/path/

# Sync a directory (efficient, only transfers diffs)
rsync -avz -e "ssh -p 2222" ./local/ user@remote:/remote/

# Mount remote filesystem locally
sudo apt install sshfs -y
sshfs -p 2222 user@remote_host:/remote/path /local/mountpoint

Verify Remote Host Fingerprints

Always verify a server’s host key on first connection:

ssh-keyscan -p 2222 remote_host | ssh-keygen -lf -

Use GPG for File Encryption at Rest

sudo apt install gnupg -y

# Encrypt a file
gpg --symmetric --cipher-algo AES256 sensitive_file.txt

# Decrypt
gpg sensitive_file.txt.gpg

📖 Reference: Rsync + SSH – man page 📖 Reference: GnuPG Documentation


TLS/SSL Best Practices

Obtain Free TLS Certificates with Let’s Encrypt

sudo apt install certbot -y

# For Nginx
sudo apt install python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Auto-renewal is handled by a systemd timer — verify:
sudo systemctl status certbot.timer

Test Your TLS Configuration

After configuring HTTPS, test your server’s TLS grade:

Recommended Nginx TLS settings (/etc/nginx/snippets/ssl-params.conf):

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy "no-referrer-when-downgrade";

📖 Reference: Mozilla SSL Configuration Generator 📖 Reference: Let’s Encrypt Documentation


Filesystem Security

Set Correct Permissions on Key Files

chmod 700 /root
chmod 600 /etc/ssh/sshd_config
chmod 644 /etc/passwd
chmod 640 /etc/shadow
chmod 440 /etc/sudoers
chmod 600 /boot/grub/grub.cfg

Secure /tmp and /var/tmp

Mount /tmp with noexec, nosuid, and nodev to prevent execution of malicious scripts:

tmpfs   /tmp       tmpfs   defaults,noexec,nosuid,nodev   0 0
tmpfs   /var/tmp   tmpfs   defaults,noexec,nosuid,nodev   0 0

Enable Auditing with auditd

sudo apt install auditd audispd-plugins -y
sudo systemctl enable auditd
sudo systemctl start auditd

Add rules to /etc/audit/rules.d/audit.rules:

# Watch authentication files
-w /etc/passwd -p wa -k passwd_changes
-w /etc/shadow -p wa -k shadow_changes
-w /etc/group -p wa -k group_changes
-w /etc/sudoers -p wa -k sudoers_changes

# Monitor SSH configuration
-w /etc/ssh/sshd_config -p wa -k sshd_config

# Detect privilege escalation
-a always,exit -F arch=b64 -S setuid -k priv_esc
-a always,exit -F arch=b64 -S setgid -k priv_esc

# Track all commands run as root
-a exit,always -F arch=b64 -F euid=0 -S execve -k root_commands

Apply rules without reboot:

sudo auditctl -R /etc/audit/rules.d/audit.rules

Search audit logs:

sudo ausearch -k passwd_changes
sudo aureport --auth

📖 Reference: Linux Audit Documentation (linux-audit.com)


Intrusion Detection with AIDE

AIDE (Advanced Intrusion Detection Environment) monitors filesystem integrity by creating a baseline database and alerting you to unexpected changes.

sudo apt install aide aide-common -y

# Initialize the baseline database (run after setting up the server)
sudo aideinit
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# Run a check (compare current state to baseline)
sudo aide --check

Automate daily checks with cron:

sudo crontab -e

Add:

0 3 * * * /usr/bin/aide --check | mail -s "AIDE Report: $(hostname)" admin@yourdomain.com

📖 Reference: AIDE Manual


Log Management

Centralized Logging with rsyslog

Ubuntu uses rsyslog by default. To forward logs to a central log server:

Edit /etc/rsyslog.conf:

*.* @logserver.yourdomain.com:514   # UDP
*.* @@logserver.yourdomain.com:514  # TCP (more reliable)

Log Rotation with logrotate

Check configuration at /etc/logrotate.conf and /etc/logrotate.d/. Example for a custom app:

/var/log/myapp/*.log {
    daily
    missingok
    rotate 14
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
}

Systemd Journal

# View all logs since last boot
journalctl -b

# Follow logs in real time
journalctl -f

# Filter by service
journalctl -u nginx.service

# View authentication logs
journalctl _COMM=sshd

Persist journal logs across reboots (edit /etc/systemd/journald.conf):

Storage=persistent

📖 Reference: Linux Logging – Loggly Guide 📖 Reference: journalctl – man page


Monitoring and Auditing

Check Listening Ports

ss -tulpn
# or
sudo netstat -tulpn

Check Logged-in Users

who          # Currently logged in
w            # Logged in with activity
last         # Login history
lastfail     # Failed login attempts

Check Running Services

sudo systemctl list-units --type=service --state=running

Disable services you don’t need:

sudo systemctl disable --now cups bluetooth avahi-daemon

System Security Audit with Lynis

Lynis is a comprehensive security auditing tool for Linux:

sudo apt install lynis -y
sudo lynis audit system

It produces a scored report with actionable hardening suggestions.

Rootkit Detection

sudo apt install rkhunter chkrootkit -y

# rkhunter
sudo rkhunter --update
sudo rkhunter --propupd     # Baseline file properties
sudo rkhunter --check

# chkrootkit
sudo chkrootkit

Vulnerability Scanning with OpenVAS / Greenbone

For periodic vulnerability scanning, consider running Greenbone Community Edition or using an external service such as Tenable Nessus Essentials (free for up to 16 IPs).

📖 Reference: Lynis Documentation (cisofy.com) 📖 Reference: NIST National Vulnerability Database


When to Move from Vercel / PaaS to a Self-Managed Server

Services like Vercel, Netlify, Railway, Render, Fly.io, and Heroku are excellent for getting projects live quickly — zero infrastructure knowledge required. But there comes a point where they hold you back technically, financially, or legally. This section helps you recognize that inflection point.

Signs You’ve Outgrown a PaaS

💸 Cost is scaling faster than your product

Managed platforms charge a premium for compute, bandwidth, and execution time. A single Next.js app with moderate traffic can cost $100–$500/month on Vercel Pro, while a Hetzner VPS or AWS EC2 instance with equivalent resources costs $5–$40/month. If your monthly PaaS bill has grown into the hundreds, a self-managed server will almost certainly be cheaper.

A Hetzner CX22 (2 vCPU, 4 GB RAM) is ~€4/month. A comparable Vercel plan with similar function invocations can run $20–$100+/month.

🔒 You need full control over your security posture

PaaS providers manage the underlying infrastructure, which means you cannot:

  • Apply custom kernel hardening (sysctl parameters, seccomp profiles)
  • Install and configure auditd, AIDE, or rkhunter for compliance
  • Enforce specific firewall rules at the network interface level
  • Meet compliance standards (HIPAA, PCI-DSS, SOC 2, ISO 27001) that require evidence of OS-level controls

If your application handles sensitive data — health records, financial data, PII — you almost certainly need a managed server where you control the full stack.

⚙️ Your workloads don’t fit the serverless model

PaaS platforms are optimized for stateless, short-lived request/response cycles. You’ll hit walls when you need:

  • Long-running processes — video transcoding, ML inference, batch jobs, websocket servers
  • Background workers — queue consumers (Celery, Sidekiq, BullMQ) that run continuously
  • Persistent connections — databases, message brokers (Redis, RabbitMQ, Kafka) that you want to co-locate with your app
  • Cron jobs — reliable, sub-minute scheduling without paying per-invocation fees
  • Custom runtimes — specific compiler versions, system libraries, binary dependencies not available in the platform’s build environment

📦 You’re running a database or stateful service

Managed database addons on PaaS platforms (Postgres, Redis, etc.) are convenient but expensive and limited. At scale you’ll want:

  • Control over postgresql.conf tuning parameters
  • Custom backup and replication strategies
  • Ability to co-locate the database on the same private network as your app to eliminate latency

🌐 You need custom networking

PaaS platforms abstract away networking. A self-managed server lets you:

  • Assign static IPs and configure reverse DNS (PTR records) — required for reliable email sending
  • Set up private VPCs and subnet isolation between services
  • Run an Nginx or Caddy reverse proxy with fine-grained routing, rate-limiting, and caching rules
  • Use WireGuard or OpenVPN to link servers in a private mesh

🏛️ Vendor lock-in is a concern

Vercel’s Edge Functions, Netlify’s primitives, and similar platform-specific features are not portable. If you ever need to migrate, you’ll need to rewrite infrastructure code. A standard Linux server with Docker Compose or Kubernetes is deployable anywhere.


Choosing a Cloud / VPS Provider

Provider Best For Notes
Hetzner Cost-conscious teams, EU data residency Cheapest dedicated and VPS options; excellent network; data centers in Germany, Finland, US
AWS EC2 Enterprise, compliance, global reach Widest ecosystem (S3, RDS, IAM, VPC); steep learning curve; pay-per-use
Google Cloud (GCE) ML workloads, global load balancing Strong networking; per-second billing; generous free tier
Microsoft Azure Microsoft/.NET shops, enterprise AD integration Best for Windows workloads; HIPAA/FedRAMP BAAs available
DigitalOcean Developer-friendly, simple pricing Great docs; Droplets are easy to provision; less powerful than AWS at scale
Linode / Akamai Budget alternative to AWS Straightforward pricing; good for small-to-mid workloads
OVHcloud EU compliance, dedicated servers Very affordable dedicated hardware; good for GDPR-sensitive workloads

Migration Checklist: PaaS → Self-Managed Server

When you’re ready to make the move, work through this checklist:

  • Provision the server — choose a provider above, pick a region close to your users
  • Follow this guide — apply all hardening steps (SSH keys, UFW, Fail2Ban, unattended-upgrades)
  • Set up a reverse proxy — Nginx or Caddy (Caddy auto-manages TLS via Let’s Encrypt)
  • Containerize your app — Docker + Docker Compose makes the app portable and repeatable
  • Configure a process managersystemd or pm2 to keep your app running after crashes/reboots
  • Set up automated backups — snapshot the VPS, back up databases to S3/Backblaze B2
  • Configure monitoring — set up Uptime Kuma (self-hosted) or Grafana Cloud free tier for alerts
  • Point your domain — update DNS A records, verify TLS certificate is issued
  • Test your deployment pipeline — GitHub Actions or GitLab CI pushing to the server over SSH
  • Run a Lynis audit — verify the security posture before going live

Quick Cost Comparison (2024 approximate)

Workload Vercel/Render/Railway Hetzner VPS AWS EC2
Simple Next.js site Free – $20/mo €4/mo (CX22) ~$8/mo (t3.micro)
API + PostgreSQL $50–$150/mo €8–€15/mo $30–$80/mo
High-traffic app (10M req/mo) $200–$500+/mo €15–€30/mo $80–$200/mo
Video/ML processing Not practical €20–€80/mo (dedicated) $100–$500/mo (GPU)

Rule of thumb: Once your PaaS bill consistently exceeds $50–$100/month, it’s worth evaluating a self-managed server. The operational overhead is real, but this guide exists to make it manageable.

📖 Reference: Hetzner vs AWS vs DigitalOcean Comparison – Geekflare 📖 Reference: Caddy Server Documentation 📖 Reference: Self-Hosting vs PaaS – a practical guide (Hacker News discussion)


Container Security (Docker)

If you run Docker on your server, apply these additional hardening measures.

Run as Non-Root

Never run application containers as root. In your Dockerfile:

RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser

Use Read-Only Filesystems

docker run --read-only --tmpfs /tmp myimage

Limit Container Capabilities

docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myimage

Scan Images for Vulnerabilities

# Using Docker Scout (built into Docker Desktop / CLI)
docker scout cves myimage:latest

# Using Trivy (open source)
sudo apt install trivy -y
trivy image myimage:latest

Secure the Docker Daemon

Edit /etc/docker/daemon.json:

{
  "icc": false,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  },
  "no-new-privileges": true,
  "userns-remap": "default"
}

📖 Reference: Docker Security Best Practices 📖 Reference: CIS Docker Benchmark 📖 Reference: Trivy – Open Source Vulnerability Scanner


Useful Commands

Command Description
uname -a Show kernel version and system info
lsb_release -a Show Ubuntu version
df -h Show disk usage
du -sh /var/log/* Show size of log directories
free -h Show memory usage
top / htop Display running processes
iotop Monitor disk I/O by process
journalctl -xe View recent system log errors
journalctl -f Follow live system log
ss -tulpn Show open network ports
lsof -i List open network connections
ps aux --sort=-%cpu List processes by CPU usage
chmod, chown Change file permissions/ownership
sudo visudo Safely edit sudoers file
sudo lynis audit system Full security audit
sudo aide --check Check filesystem integrity
sudo rkhunter --check Check for rootkits
sudo ufw status verbose Show firewall rules
sudo fail2ban-client status Show Fail2Ban jail status
sudo auditctl -l List active audit rules
sudo ausearch -k key Search audit logs by key
openssl s_client -connect host:443 Test TLS certificate

Resources

Official Documentation & Standards

Source Link
Ubuntu Security Notices ubuntu.com/security/notices
Ubuntu Server Guide ubuntu.com/server/docs
CIS Ubuntu Linux Benchmark cisecurity.org/benchmark/ubuntu_linux
NIST SP 800-123 – Server Security nvlpubs.nist.gov
NSA/CISA Linux Hardening Guide media.defense.gov

Hardening Guides & Checklists

Source Link
Book of Zeus – Harden Ubuntu bookofzeus.com/harden-ubuntu
Pluralsight – Server Hardening Checklist pluralsight.com
DigitalOcean Security Tutorials digitalocean.com/community/tags/security
Arch Linux Security Wiki wiki.archlinux.org/title/Security
Linux Hardening Guide (trimstray) github.com/trimstray/the-practical-linux-hardening-guide

SSH & Encryption

Source Link
Mozilla OpenSSH Guidelines infosec.mozilla.org/guidelines/openssh
SSH Audit Tool ssh-audit.com
Mozilla SSL Configuration Generator ssl-config.mozilla.org
SSL Labs Server Test ssllabs.com/ssltest
Let’s Encrypt letsencrypt.org

Tools

Tool Description Link
Lynis Security auditing & compliance cisofy.com/lynis
AIDE Filesystem integrity monitoring aide.github.io
Fail2Ban Brute-force IP banning fail2ban.org
rkhunter Rootkit detection rkhunter.sourceforge.net
Trivy Container vulnerability scanner aquasecurity.github.io/trivy
testssl.sh Command-line TLS scanner testssl.sh
OpenSCAP SCAP compliance scanner open-scap.org

Learning & Community

Source Link
SANS Reading Room (Linux) sans.org/reading-room
Linux Audit Blog linux-audit.com
Kernel Self-Protection Project kernsec.org
CVE Details (Ubuntu) cvedetails.com/vendor/51/Ubuntu.html
NIST NVD nvd.nist.gov

How to Contribute

This guide is open source. If you’d like to contribute:

  • Fork this repository on GitHub
  • Create a branch for your changes
  • Submit a pull request with your additions or corrections

All contributions are welcome and appreciated.

A portable summary lives in LINUX_GUIDE.md. The previous mixed homepage draft is archived in index-backup-1.md.


Published by Aerostat & Co. — Use freely, fork widely.

Aerostat's Guide To Linux

A practical Ubuntu LTS setup and hardening guide from Aerostat & Co.

Powered by Bootstrap 4 Github Pages

GitHub Repo stars