Complete SSH hardening and network troubleshooting documentation
- SSH port change to 2222 completed and documented - Dual ethernet interface issue resolved (enp4s0 vs enp3s0f0) - Static IP configuration achieved (192.168.0.100) - Mosh setup: local working, external blocked by ISP UDP filtering - DuckDNS migration from cron script to router-based updates - Added comprehensive security tool explanations (WireGuard, UFW, fail2ban) - Network interface identification and MAC address issue resolution 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,9 @@ ssh-copy-id -i ~/.ssh/homelab_ed25519.pub user@target
|
|||||||
```
|
```
|
||||||
|
|
||||||
### SSH Hardening
|
### SSH Hardening
|
||||||
|
|
||||||
|
**Status:** ✅ **Complete** - Port changed to 2222
|
||||||
|
|
||||||
Edit `/etc/ssh/sshd_config`:
|
Edit `/etc/ssh/sshd_config`:
|
||||||
```
|
```
|
||||||
# Disable root login
|
# Disable root login
|
||||||
@@ -23,7 +26,7 @@ PermitRootLogin no
|
|||||||
PasswordAuthentication no
|
PasswordAuthentication no
|
||||||
PubkeyAuthentication yes
|
PubkeyAuthentication yes
|
||||||
|
|
||||||
# Change default port (optional)
|
# Change default port (CRITICAL - currently still on 22)
|
||||||
Port 2222
|
Port 2222
|
||||||
|
|
||||||
# Restrict users
|
# Restrict users
|
||||||
@@ -39,19 +42,73 @@ MaxAuthTries 3
|
|||||||
MaxStartups 2
|
MaxStartups 2
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Completed:**
|
||||||
|
1. ✅ Changed SSH port from 22 to 2222
|
||||||
|
2. ✅ Updated router port forwarding rules
|
||||||
|
3. ✅ External access via ak-homelab.duckdns.org:2222 working
|
||||||
|
|
||||||
Restart SSH: `sudo systemctl restart sshd`
|
Restart SSH: `sudo systemctl restart sshd`
|
||||||
|
|
||||||
|
### Mosh Alternative (Investigation Needed)
|
||||||
|
|
||||||
|
**Issue:** SSH can be unreliable on WiFi connections with packet loss.
|
||||||
|
|
||||||
|
**Mosh Benefits:**
|
||||||
|
- Maintains connection during network switches (ethernet ↔ WiFi)
|
||||||
|
- Handles poor WiFi connections better
|
||||||
|
- Local echo for responsive typing
|
||||||
|
- Roaming support (IP changes don't break connection)
|
||||||
|
|
||||||
|
**Installation:**
|
||||||
|
```bash
|
||||||
|
# Server side
|
||||||
|
sudo pacman -S mosh
|
||||||
|
|
||||||
|
# Client side
|
||||||
|
mosh user@server
|
||||||
|
```
|
||||||
|
|
||||||
|
**Requirements:**
|
||||||
|
- UDP ports 60000-61000 open on router
|
||||||
|
- SSH still needed for initial authentication
|
||||||
|
|
||||||
|
**Status:** ✅ **Local use working** ❌ **External blocked by ISP**
|
||||||
|
|
||||||
|
**Key Findings:**
|
||||||
|
- **Local mosh**: Works perfectly (`mosh localhost`, `mosh 192.168.0.100`)
|
||||||
|
- **External mosh**: Blocked by ISP UDP port filtering on ports 60000-61000
|
||||||
|
- **SSH still needed**: Mosh uses SSH for initial authentication, then switches to UDP
|
||||||
|
|
||||||
|
**ISP UDP Blocking Issue:**
|
||||||
|
- Most ISPs block UDP ports 60000-61000 for "security"
|
||||||
|
- SSH works fine (TCP port 2222) but mosh fails (UDP 60000-61000)
|
||||||
|
- Router port forwarding is correct, but ISP drops UDP packets
|
||||||
|
|
||||||
|
**Current Recommendation:**
|
||||||
|
- Use mosh for local/internal network connections
|
||||||
|
- Stick with SSH for external connections until VPN is set up
|
||||||
|
- VPN tunnel can bypass ISP UDP blocking
|
||||||
|
|
||||||
### SSH Client Configuration
|
### SSH Client Configuration
|
||||||
Create `~/.ssh/config`:
|
Create `~/.ssh/config`:
|
||||||
```
|
```
|
||||||
Host homelab
|
Host homelab
|
||||||
HostName your-domain.duckdns.org
|
HostName ak-homelab.duckdns.org
|
||||||
User hoborg
|
User hoborg
|
||||||
Port 2222
|
Port 2222
|
||||||
IdentityFile ~/.ssh/homelab_ed25519
|
IdentityFile ~/.ssh/homelab_ed25519
|
||||||
ServerAliveInterval 60
|
ServerAliveInterval 60
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```bash
|
||||||
|
# Connect via SSH
|
||||||
|
ssh homelab
|
||||||
|
|
||||||
|
# Connect via Mosh (uses SSH config automatically)
|
||||||
|
mosh homelab
|
||||||
|
```
|
||||||
|
|
||||||
## Dynamic DNS with DuckDNS
|
## Dynamic DNS with DuckDNS
|
||||||
|
|
||||||
### Account Setup
|
### Account Setup
|
||||||
@@ -68,6 +125,24 @@ Cron job for automatic updates:
|
|||||||
*/5 * * * * /home/hoborg/.local/scripts/duckdns.py >/dev/null 2>&1
|
*/5 * * * * /home/hoborg/.local/scripts/duckdns.py >/dev/null 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Current Setup (Router-based)
|
||||||
|
|
||||||
|
**Status:** ✅ **Migrated from script to router DynDNS**
|
||||||
|
|
||||||
|
**Changes made:**
|
||||||
|
- ✅ Disabled cron job script (`*/5 * * * *` entry removed)
|
||||||
|
- ✅ Enabled router Dynamic DNS for ak-homelab.duckdns.org
|
||||||
|
- ⏳ **Testing pending** - Cannot force public IP change to verify
|
||||||
|
|
||||||
|
**Router DynDNS Benefits:**
|
||||||
|
- Immediate updates on IP change (vs 5-minute delay)
|
||||||
|
- Works when server is down
|
||||||
|
- Lower resource usage
|
||||||
|
|
||||||
|
**Limitations:**
|
||||||
|
- Likely IPv4-only (Sagemcom router limitation)
|
||||||
|
- Less control over update process
|
||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
```bash
|
```bash
|
||||||
# Check current IP
|
# Check current IP
|
||||||
@@ -75,10 +150,40 @@ curl -s https://ipinfo.io/ip
|
|||||||
|
|
||||||
# Verify DNS resolution
|
# Verify DNS resolution
|
||||||
nslookup ak-homelab.duckdns.org
|
nslookup ak-homelab.duckdns.org
|
||||||
|
|
||||||
|
# Check IPv6 (likely not updated by router)
|
||||||
|
nslookup -type=AAAA ak-homelab.duckdns.org
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Testing will occur naturally when ISP changes public IP address.**
|
||||||
|
|
||||||
## VPN Setup with WireGuard
|
## VPN Setup with WireGuard
|
||||||
|
|
||||||
|
### What is WireGuard?
|
||||||
|
WireGuard is a modern, lightweight VPN protocol that creates secure tunnels between devices. It encrypts all network traffic and routes it through a VPN server, making your internet connection private and secure.
|
||||||
|
|
||||||
|
**Key benefits:**
|
||||||
|
- **Privacy**: Hides your IP address and encrypts traffic
|
||||||
|
- **Security**: Protects against man-in-the-middle attacks on public WiFi
|
||||||
|
- **Access**: Bypass geo-restrictions and enables remote homelab access
|
||||||
|
- **Performance**: Much faster than OpenVPN with lower battery drain
|
||||||
|
- **Simplicity**: Easy to configure compared to other VPN protocols
|
||||||
|
|
||||||
|
**When you need VPN:**
|
||||||
|
- Accessing homelab remotely over internet
|
||||||
|
- Working from public WiFi frequently
|
||||||
|
- Need to bypass ISP restrictions
|
||||||
|
- Running public-facing services
|
||||||
|
|
||||||
|
**Costs:** WireGuard itself is free. Self-hosted VPN costs $5-20/month for VPS hosting.
|
||||||
|
|
||||||
|
**Use cases:**
|
||||||
|
- Access homelab services remotely (SSH, web interfaces, file shares)
|
||||||
|
- Secure connection on public WiFi
|
||||||
|
- Bypass ISP restrictions or geo-blocks
|
||||||
|
|
||||||
|
**Performance:** Much faster and lighter than OpenVPN, better battery life on mobile devices.
|
||||||
|
|
||||||
### Server Configuration
|
### Server Configuration
|
||||||
Install WireGuard: `pacman -S wireguard-tools`
|
Install WireGuard: `pacman -S wireguard-tools`
|
||||||
|
|
||||||
@@ -129,6 +234,18 @@ sudo systemctl start wg-quick@wg0
|
|||||||
|
|
||||||
## Firewall Configuration
|
## Firewall Configuration
|
||||||
|
|
||||||
|
### UFW (Uncomplicated Firewall)
|
||||||
|
|
||||||
|
**What it does:** Controls what network traffic is allowed in/out of your server.
|
||||||
|
|
||||||
|
**Key functions:**
|
||||||
|
- **Default deny**: Blocks all incoming connections by default
|
||||||
|
- **Port control**: Open only specific ports you need (SSH, HTTP, etc.)
|
||||||
|
- **Rate limiting**: Prevent brute force attacks
|
||||||
|
- **Application profiles**: Pre-configured rules for common services
|
||||||
|
|
||||||
|
**Why needed:** Without firewall, all services are exposed to network attacks.
|
||||||
|
|
||||||
### UFW Setup
|
### UFW Setup
|
||||||
```bash
|
```bash
|
||||||
# Install and enable UFW
|
# Install and enable UFW
|
||||||
@@ -177,7 +294,77 @@ sudo ufw logging on
|
|||||||
### Monitoring
|
### Monitoring
|
||||||
- **Log analysis**: Monitor `/var/log/auth.log` for SSH attempts
|
- **Log analysis**: Monitor `/var/log/auth.log` for SSH attempts
|
||||||
- **Network monitoring**: Use netstat/ss to check listening ports
|
- **Network monitoring**: Use netstat/ss to check listening ports
|
||||||
- **Intrusion detection**: Consider fail2ban for automated blocking
|
- **Intrusion detection**: Use fail2ban for automated blocking
|
||||||
|
|
||||||
|
## fail2ban - Intrusion Prevention
|
||||||
|
|
||||||
|
### What is fail2ban?
|
||||||
|
|
||||||
|
**What it does:** Automatically blocks IP addresses that show malicious behavior.
|
||||||
|
|
||||||
|
**Key functions:**
|
||||||
|
- **Log monitoring**: Watches system logs for suspicious activity
|
||||||
|
- **Pattern detection**: Identifies failed login attempts, scanning, etc.
|
||||||
|
- **Automatic blocking**: Temporarily bans offending IP addresses
|
||||||
|
- **Customizable rules**: Configure what triggers a ban and for how long
|
||||||
|
|
||||||
|
**Common protections:**
|
||||||
|
- SSH brute force attempts
|
||||||
|
- Web server attacks (404 scanning, etc.)
|
||||||
|
- Email server abuse
|
||||||
|
- Custom application attacks
|
||||||
|
|
||||||
|
**Example:** After 5 failed SSH login attempts in 10 minutes, ban IP for 1 hour.
|
||||||
|
|
||||||
|
**Why important:** Reduces server load and prevents automated attacks from succeeding through persistence.
|
||||||
|
|
||||||
|
### fail2ban Installation & Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install fail2ban
|
||||||
|
sudo pacman -S fail2ban
|
||||||
|
|
||||||
|
# Enable and start service
|
||||||
|
sudo systemctl enable fail2ban
|
||||||
|
sudo systemctl start fail2ban
|
||||||
|
|
||||||
|
# Create local configuration
|
||||||
|
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic SSH Protection Configuration
|
||||||
|
|
||||||
|
Edit `/etc/fail2ban/jail.local`:
|
||||||
|
```ini
|
||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
port = 2222
|
||||||
|
filter = sshd
|
||||||
|
logpath = /var/log/auth.log
|
||||||
|
maxretry = 5
|
||||||
|
bantime = 3600
|
||||||
|
findtime = 600
|
||||||
|
```
|
||||||
|
|
||||||
|
**Configuration explained:**
|
||||||
|
- `maxretry = 5`: Ban after 5 failed attempts
|
||||||
|
- `bantime = 3600`: Ban for 1 hour (3600 seconds)
|
||||||
|
- `findtime = 600`: 5 attempts within 10 minutes triggers ban
|
||||||
|
- `port = 2222`: Monitor custom SSH port
|
||||||
|
|
||||||
|
### Restart and Monitor
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Restart fail2ban to apply changes
|
||||||
|
sudo systemctl restart fail2ban
|
||||||
|
|
||||||
|
# Check status
|
||||||
|
sudo fail2ban-client status
|
||||||
|
sudo fail2ban-client status sshd
|
||||||
|
|
||||||
|
# View banned IPs
|
||||||
|
sudo fail2ban-client get sshd banned
|
||||||
|
```
|
||||||
|
|
||||||
## Router Configuration
|
## Router Configuration
|
||||||
|
|
||||||
@@ -195,10 +382,79 @@ Forward these ports to your homelab server:
|
|||||||
|
|
||||||
## Network Planning
|
## Network Planning
|
||||||
|
|
||||||
|
### Dual Network Interface Issue (Critical)
|
||||||
|
|
||||||
|
**Problem:** Server has both ethernet and WiFi interfaces. When switching between connections, IP address changes from ethernet (192.168.0.22) to different WiFi IP, breaking SSH connections and port forwards.
|
||||||
|
|
||||||
|
**Limitation:** Most routers don't allow DHCP reservation of same IP for multiple MAC addresses.
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
|
||||||
|
**Option 1: Static IP Configuration (Recommended)**
|
||||||
|
Configure both interfaces with same static IP:
|
||||||
|
```bash
|
||||||
|
# Check interface names
|
||||||
|
ip link show
|
||||||
|
|
||||||
|
# Configure ethernet interface
|
||||||
|
sudo systemctl edit --full systemd-networkd
|
||||||
|
# Create /etc/systemd/network/20-ethernet.network
|
||||||
|
[Match]
|
||||||
|
Name=enp*
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
DHCP=no
|
||||||
|
Address=192.168.0.100/24
|
||||||
|
Gateway=192.168.0.1
|
||||||
|
DNS=192.168.0.1
|
||||||
|
|
||||||
|
# Create /etc/systemd/network/25-wifi.network
|
||||||
|
[Match]
|
||||||
|
Name=wlp*
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
DHCP=no
|
||||||
|
Address=192.168.0.100/24
|
||||||
|
Gateway=192.168.0.1
|
||||||
|
DNS=192.168.0.1
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 2: Hostname-based Access**
|
||||||
|
Use local hostname resolution instead of IP:
|
||||||
|
```bash
|
||||||
|
# Access via hostname (works for both interfaces)
|
||||||
|
ssh hoborg@ak-homelab.local
|
||||||
|
# or configure local DNS/mDNS
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 3: Bridge Networking**
|
||||||
|
Create bridge combining both interfaces for automatic failover:
|
||||||
|
```bash
|
||||||
|
# Advanced: Bridge both interfaces
|
||||||
|
ip link add name br0 type bridge
|
||||||
|
ip link set enp3s0 master br0
|
||||||
|
ip link set wlp2s0 master br0
|
||||||
|
```
|
||||||
|
|
||||||
|
**Current Setup:**
|
||||||
|
- Router: 192.168.0.1
|
||||||
|
- Ethernet: 192.168.0.100 (static IP achieved)
|
||||||
|
- WiFi: Static IP needed (same .100)
|
||||||
|
- External: ak-homelab.duckdns.org ✅
|
||||||
|
- SSH: Port 2222 ✅
|
||||||
|
|
||||||
|
**Network Interface Identification:**
|
||||||
|
- **enp3s0f0**: First ethernet port (98:fa:9b:f1:06:d5)
|
||||||
|
- **enp4s0**: Second ethernet port (98:fa:9b:f1:06:d4) ← **Use this one**
|
||||||
|
- **wlp1s0**: WiFi interface (0c:dd:24:e6:0f:87)
|
||||||
|
|
||||||
|
**Issue Solved:** Dual ethernet ports caused MAC address confusion when cable was moved between ports. Stick to enp4s0 consistently.
|
||||||
|
|
||||||
### IP Address Scheme
|
### IP Address Scheme
|
||||||
- **Router**: 192.168.1.1
|
- **Router**: 192.168.0.1
|
||||||
- **Homelab server**: 192.168.1.100 (static)
|
- **Homelab server**: 192.168.0.100 (target static IP)
|
||||||
- **DHCP range**: 192.168.1.10-99
|
- **Current ethernet**: 192.168.0.22 (can migrate to .100)
|
||||||
|
- **DHCP range**: 192.168.0.10-99 (excluding static IPs)
|
||||||
- **VPN subnet**: 10.0.0.0/24
|
- **VPN subnet**: 10.0.0.0/24
|
||||||
|
|
||||||
### DNS Configuration
|
### DNS Configuration
|
||||||
|
|||||||
Reference in New Issue
Block a user