
- Remove duplicate sma user definition from incus.nix module - The sma user is properly defined in modules/users/sma.nix with incus-admin group - This resolves the isNormalUser/isSystemUser assertion failure blocking congenital-optimist rebuild - Clean up grey-area configuration and modularize services - Update SSH keys with correct IP addresses for grey-area and reverse-proxy
298 lines
7.4 KiB
Markdown
298 lines
7.4 KiB
Markdown
# SSH Forwarding Solutions for Git Server
|
|
|
|
## Overview
|
|
|
|
This document researches solutions for forwarding SSH traffic from the reverse-proxy (VPS) to the grey-area Forgejo git instance. The goal is to enable Git operations over SSH at `git@git.geokkjer.eu` while maintaining security and reliability.
|
|
|
|
## Current Setup
|
|
|
|
- **Reverse Proxy (VPS)**: `46.226.104.98` running nginx, listening on ports 80/443
|
|
- **Git Server (grey-area)**: Forgejo instance accessible via Tailscale at `apps:3000`
|
|
- **Domain**: `git.geokkjer.eu` currently configured for HTTPS proxying only
|
|
- **Target**: Enable SSH access on port 22 for Git operations
|
|
|
|
## Architecture Constraints
|
|
|
|
1. **Single Public IP**: Only one public IP available (VPS)
|
|
2. **Port 22 Limitation**: Standard SSH port needed for Git compatibility
|
|
3. **Security**: SSH access should be restricted to Git operations only
|
|
4. **Tailscale Network**: Backend services accessible via private Tailscale network
|
|
5. **Existing SSH**: VPS already uses port 22 for administrative SSH access
|
|
|
|
## Solution Options
|
|
|
|
### 1. HAProxy TCP Mode (Recommended)
|
|
|
|
**Approach**: Replace nginx with HAProxy or add HAProxy for SSH forwarding
|
|
|
|
**Pros**:
|
|
- Native TCP/SSH forwarding support
|
|
- Battle-tested for SSH proxying
|
|
- Can handle both HTTP and SSH traffic
|
|
- Excellent connection handling
|
|
- Built-in health checking
|
|
|
|
**Cons**:
|
|
- Requires replacing or complementing nginx
|
|
- Additional service to manage
|
|
- More complex configuration
|
|
|
|
**Implementation**:
|
|
```haproxy
|
|
global
|
|
stats socket /var/run/haproxy.sock mode 600 level admin
|
|
stats timeout 2m
|
|
|
|
defaults
|
|
mode tcp
|
|
timeout client 60s
|
|
timeout server 60s
|
|
timeout connect 5s
|
|
|
|
# SSH forwarding to Git server
|
|
frontend ssh_frontend
|
|
bind *:22
|
|
mode tcp
|
|
# Use SNI or other method to distinguish Git SSH from admin SSH
|
|
default_backend git_ssh_backend
|
|
|
|
backend git_ssh_backend
|
|
mode tcp
|
|
server git1 apps:22 check
|
|
|
|
# HTTP/HTTPS forwarding
|
|
frontend http_frontend
|
|
bind *:80
|
|
bind *:443 ssl crt /etc/ssl/certs/
|
|
mode http
|
|
default_backend nginx_backend
|
|
|
|
backend nginx_backend
|
|
mode http
|
|
server nginx1 127.0.0.1:8080
|
|
```
|
|
|
|
**Complexity**: Medium
|
|
**Security**: High
|
|
**Reliability**: High
|
|
|
|
### 2. NGINX Stream Module
|
|
|
|
**Approach**: Enable NGINX stream module for TCP forwarding
|
|
|
|
**Pros**:
|
|
- Keeps existing nginx setup
|
|
- Native TCP proxying support
|
|
- Good performance
|
|
- Integrated with current SSL/certificate management
|
|
|
|
**Cons**:
|
|
- Requires nginx with stream module compiled
|
|
- Cannot distinguish SSH traffic types on same port
|
|
- Conflicts with existing SSH access
|
|
|
|
**Implementation**:
|
|
```nginx
|
|
# In nginx.conf
|
|
stream {
|
|
upstream git_ssh_backend {
|
|
server apps:22;
|
|
}
|
|
|
|
server {
|
|
listen 2222; # Alternative port for Git SSH
|
|
proxy_pass git_ssh_backend;
|
|
proxy_timeout 60s;
|
|
proxy_connect_timeout 5s;
|
|
}
|
|
}
|
|
|
|
http {
|
|
# Existing HTTP configuration
|
|
server {
|
|
listen 80;
|
|
listen 443 ssl;
|
|
server_name git.geokkjer.eu;
|
|
# ... existing config
|
|
}
|
|
}
|
|
```
|
|
|
|
**Complexity**: Low
|
|
**Security**: Medium (requires alternative port)
|
|
**Reliability**: High
|
|
|
|
### 3. SSH Port Forwarding with systemd
|
|
|
|
**Approach**: Use SSH tunneling with autossh/systemd for persistence
|
|
|
|
**Pros**:
|
|
- Simple setup
|
|
- Uses existing SSH infrastructure
|
|
- Automatic reconnection
|
|
- No additional services
|
|
|
|
**Cons**:
|
|
- Less robust than dedicated proxy
|
|
- Potential authentication complexity
|
|
- Single point of failure
|
|
- Not designed for high-throughput Git operations
|
|
|
|
**Implementation**:
|
|
```bash
|
|
# SSH tunnel command
|
|
ssh -N -L 2222:apps:22 geir@grey-area-tailscale-ip
|
|
|
|
# systemd service for persistence
|
|
[Unit]
|
|
Description=SSH tunnel for Git forwarding
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=git
|
|
ExecStart=/usr/bin/ssh -N -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -L 2222:apps:22 geir@grey-area
|
|
Restart=always
|
|
RestartSec=5
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
**Complexity**: Low
|
|
**Security**: Medium
|
|
**Reliability**: Medium
|
|
|
|
### 4. iptables DNAT (Network Address Translation)
|
|
|
|
**Approach**: Use iptables to redirect SSH traffic to backend
|
|
|
|
**Pros**:
|
|
- Kernel-level forwarding (fast)
|
|
- Transparent to applications
|
|
- No additional services
|
|
- Can work on same port
|
|
|
|
**Cons**:
|
|
- Requires careful firewall management
|
|
- Complex routing setup with Tailscale
|
|
- Difficult to debug
|
|
- Less visibility into connections
|
|
|
|
**Implementation**:
|
|
```bash
|
|
# Forward port 2222 to backend Git server
|
|
iptables -t nat -A PREROUTING -p tcp --dport 2222 -j DNAT --to-destination apps:22
|
|
iptables -t nat -A POSTROUTING -p tcp -d apps --dport 22 -j MASQUERADE
|
|
|
|
# Allow forwarding
|
|
iptables -A FORWARD -p tcp --dport 22 -d apps -j ACCEPT
|
|
```
|
|
|
|
**Complexity**: High
|
|
**Security**: Medium
|
|
**Reliability**: Medium
|
|
|
|
### 5. Hybrid Solution: Port-Based Routing
|
|
|
|
**Approach**: Use different ports for different SSH services
|
|
|
|
**Pros**:
|
|
- Clear separation of concerns
|
|
- Maintains existing admin SSH on port 22
|
|
- Simple to implement and debug
|
|
- Good security boundaries
|
|
|
|
**Cons**:
|
|
- Non-standard Git SSH port
|
|
- Requires client configuration
|
|
- Less user-friendly
|
|
|
|
**Implementation**:
|
|
```nginx
|
|
stream {
|
|
upstream git_ssh {
|
|
server apps:22;
|
|
}
|
|
|
|
server {
|
|
listen 2222; # Git SSH port
|
|
proxy_pass git_ssh;
|
|
proxy_timeout 300s;
|
|
proxy_connect_timeout 10s;
|
|
}
|
|
}
|
|
```
|
|
|
|
**Client Configuration**:
|
|
```bash
|
|
# ~/.ssh/config
|
|
Host git.geokkjer.eu
|
|
Port 2222
|
|
User git
|
|
```
|
|
|
|
**Complexity**: Low
|
|
**Security**: High
|
|
**Reliability**: High
|
|
|
|
## Recommended Solution
|
|
|
|
### Phase 1: Implement NGINX Stream Module with Alternative Port
|
|
|
|
**Why**:
|
|
- Lowest risk implementation
|
|
- Maintains existing services
|
|
- Easy to test and validate
|
|
- Can be upgraded later
|
|
|
|
**Configuration**:
|
|
1. Enable nginx stream module
|
|
2. Configure Git SSH on port 1337
|
|
3. Update Forgejo SSH_DOMAIN setting
|
|
4. Test with alternative port
|
|
|
|
### Phase 2: Consider HAProxy Migration (Future)
|
|
|
|
**Why**:
|
|
- More robust for mixed TCP/HTTP traffic
|
|
- Better connection handling for Git operations
|
|
- Industry standard for this use case
|
|
- Enables port 22 for Git SSH
|
|
|
|
## Security Considerations
|
|
|
|
1. **SSH Key Management**: Ensure proper SSH key authentication
|
|
2. **Rate Limiting**: Implement connection rate limits
|
|
3. **Monitoring**: Log SSH connections for security auditing
|
|
4. **Firewall Rules**: Restrict SSH forwarding to specific sources if possible
|
|
5. **Fail2ban**: Extend fail2ban rules to cover Git SSH attempts
|
|
|
|
## Testing Strategy
|
|
|
|
1. **Basic Connectivity**: Test TCP connection to backend
|
|
2. **SSH Handshake**: Verify SSH protocol negotiation
|
|
3. **Git Operations**: Test clone, push, pull operations
|
|
4. **Performance**: Measure latency and throughput
|
|
5. **Failover**: Test behavior during backend unavailability
|
|
|
|
## Implementation Priority
|
|
|
|
1. **High Priority**: NGINX Stream Module (Phase 1)
|
|
2. **Medium Priority**: HAProxy migration evaluation
|
|
3. **Low Priority**: Advanced features (rate limiting, monitoring)
|
|
|
|
## Next Steps
|
|
|
|
1. Check if nginx has stream module compiled
|
|
2. Implement NGINX stream configuration for port 2222
|
|
3. Update Forgejo SSH configuration
|
|
4. Test Git operations via new port
|
|
5. Document client configuration for users
|
|
6. Monitor performance and reliability
|
|
|
|
## References
|
|
|
|
- [NGINX Stream Module Documentation](http://nginx.org/en/docs/stream/ngx_stream_core_module.html)
|
|
- [HAProxy TCP Mode Configuration](https://www.haproxy.org/download/2.8/doc/configuration.txt)
|
|
- [Git SSH Configuration Best Practices](https://docs.github.com/en/authentication/connecting-to-github-with-ssh)
|