Adding development-containers that we used to develop fail2ban-ui, can also be used for easy and fast stack-testing

This commit is contained in:
2026-01-19 18:21:24 +01:00
parent 1190aa4f38
commit 62ab6dede3
9 changed files with 1421 additions and 0 deletions

5
development/ssh_and_local/.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
fail2ban-config-local
fail2ban-config-ssh
f2b-run-local
f2b-run-ssh
ssh-keys

View File

@@ -0,0 +1,250 @@
# SSH and Local Fail2ban Development Setup
This setup provides a complete testing environment for Fail2ban UI with:
- **Local Fail2ban instance** (container) - for testing local connector
- **Remote Fail2ban instance via SSH** (container) - for testing SSH connector
## Services
### 1. Fail2ban-Local
- **Container:** `DEV_fail2ban-local`
- **Purpose:** Local Fail2ban instance for testing local connector
- **Network:** `host` mode (for iptables access)
- **Config:** `./fail2ban-config-local/`
- **Socket:** `./f2b-run-local/`
### 2. Fail2ban-SSH
- **Container:** `DEV_fail2ban-ssh`
- **Purpose:** Remote Fail2ban instance accessible via SSH
- **Network:** Bridge mode
- **SSH Port:** `2222` (mapped from container port 22)
- **SSH User:** `testuser`
- **SSH Key:** Auto-generated in `./ssh-keys/`
- **Config:** `./fail2ban-config-ssh/`
### 3. Fail2ban-UI
- **Container:** `DEV_fail2ban-ui`
- **Port:** `3080`
- **URL:** `http://172.16.10.18:3080` (or configured BIND_ADDRESS)
- **Purpose:** Main application for managing both Fail2ban instances
## Setup Instructions
### 1. Build the Fail2ban-UI Image
```bash
cd /opt/fail2ban-ui
podman build -t localhost/fail2ban-ui:dev .
# or
docker build -t localhost/fail2ban-ui:dev .
```
### 2. Start the Services
```bash
cd /opt/fail2ban-ui/development/ssh_and_local
podman compose up -d
# or
docker-compose up -d
```
### 3. Wait for SSH Container Setup
The SSH container takes a moment to:
- Generate SSH keys (if not present)
- Configure SSH server
- Set up user permissions
- Configure sudoers
Check logs to verify:
```bash
podman logs DEV_fail2ban-ssh
```
Look for:
```
========================================
SSH Test Container Ready
========================================
```
### 4. Configure Fail2ban-UI
1. **Access Fail2ban UI:**
- Open `http://172.16.10.18:3080` (or your configured BIND_ADDRESS:PORT)
- Or if using host network: `http://localhost:3080`
2. **Add Local Server:**
- Go to "Manage Servers"
- The local Fail2ban instance should be auto-detected
- Enable the local connector
3. **Add SSH Server:**
- Go to "Manage Servers"
- Click "Add Server"
- Configure:
- **Name:** `SSH Test Server`
- **Type:** `SSH`
- **Host:** `127.0.0.1`
- **Port:** `2222`
- **SSH User:** `testuser`
- **SSH Key:** Select `/config/.ssh/id_rsa` (auto-mounted)
- Enable the connector
- Click "Test Connection" to verify
## SSH Connection Details
- **Host:** `127.0.0.1`
- **Port:** `2222`
- **User:** `testuser`
- **Key Path (in container):** `/config/.ssh/id_rsa`
- **Key Path (host):** `./ssh-keys/id_rsa`
### Test SSH Connection Manually
```bash
# From host
podman exec -it DEV_fail2ban-ui ssh \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-o BatchMode=yes \
-i /config/.ssh/id_rsa \
-p 2222 \
testuser@127.0.0.1
```
## Configuration
### Fail2ban-UI Environment Variables
Edit `container-compose.yml` to customize:
```yaml
environment:
- PORT=3080
- BIND_ADDRESS=172.16.10.18 # Change to your IP or 0.0.0.0
# OIDC settings (if testing OIDC)
- OIDC_ENABLED=false # Set to true to enable OIDC
```
### SSH Container Customization
The SSH container is pre-configured with:
- Passwordless SSH key authentication
- Sudo permissions for fail2ban-client commands
- Proper file permissions (FACLs) for Fail2ban config directories
- Root access for network management
To modify SSH configuration, edit the `command` section in `container-compose.yml`.
## Volume Structure
```
./config/ # Fail2ban-UI configuration and database
./ssh-keys/ # SSH key pair (shared between containers)
./fail2ban-config-local/ # Local Fail2ban configuration
./f2b-run-local/ # Local Fail2ban socket directory
./fail2ban-config-ssh/ # SSH Fail2ban configuration
```
## Testing Scenarios
### 1. Local Connector Test
1. Enable local connector in Fail2ban-UI
2. Create a test jail
3. Verify jail appears in dashboard
4. Test ban/unban operations
5. Verify configuration changes persist
### 2. SSH Connector Test
1. Add SSH server in Fail2ban-UI
2. Test connection (should succeed)
3. Create a test jail on remote server
4. Verify jail appears in dashboard
5. Test ban/unban operations
6. Verify configuration changes sync to remote
### 3. Multi-Server Management
1. Enable both local and SSH connectors
2. Verify both servers appear in server selector
3. Switch between servers
4. Verify each server's jails are isolated
5. Test operations on each server independently
## Troubleshooting
### SSH Connection Fails
1. **Check SSH container is ready:**
```bash
podman logs DEV_fail2ban-ssh | tail -20
```
2. **Verify SSH keys exist:**
```bash
ls -la ./ssh-keys/
```
3. **Test SSH manually:**
```bash
podman exec -it DEV_fail2ban-ui ssh -v -i /config/.ssh/id_rsa -p 2222 testuser@127.0.0.1
```
4. **Check SSH container port:**
```bash
netstat -tlnp | grep 2222
```
### Local Connector Issues
1. **Check socket exists:**
```bash
ls -la ./f2b-run-local/
```
2. **Verify permissions:**
```bash
podman exec -it DEV_fail2ban-local ls -la /var/run/fail2ban/
```
3. **Check Fail2ban status:**
```bash
podman exec -it DEV_fail2ban-local fail2ban-client status
```
### Permission Errors
- Ensure volumes have correct SELinux labels (`:z` or `:Z`)
- Check container is running with required capabilities
- Verify file permissions in mounted directories
## Cleanup
To remove all containers and volumes:
```bash
podman compose down -v
# or
docker-compose down -v
```
This will remove:
- All containers
- Volume data (configs, SSH keys, databases)
**Note:** This deletes all development data. SSH keys will be regenerated on next start.
## Production Considerations
⚠️ **This setup is for development only!**
For production:
- Use proper SSH key management (not this auto-generated key)
- Use dedicated service accounts (not testuser)
- Use HTTPS/TLS (not HTTP) / Configure proper reverse proxy
- Use strong, randomly generated secrets
- Use secure session secrets
- Enable proper logging and monitoring

View File

@@ -0,0 +1,137 @@
services:
fail2ban-local:
image: lscr.io/linuxserver/fail2ban:latest
container_name: DEV_fail2ban-local
cap_add:
# Required for fail2ban container: Allows to manage network interfaces and iptables from the container
- NET_ADMIN
# Required for fail2ban container: Allows to create raw sockets (needed for fail2ban.sock)
- NET_RAW
# Required for fail2ban container: Allows to run as root (needed to manage network interfaces and raw sockets)
- SYS_ADMIN
#privileged: true
network_mode: host # needed to add iptables rules to the host network
environment:
- TZ=Europe/Zurich
- VERBOSITY=-vv
volumes:
# To make sure linuxserver-fail2ban configs are persistent across container restarts (also needed by fail2ban-ui to modify configs)
- ./fail2ban-config-local:/config:z
# Directory that contains fail2ban.sock for communication between fail2ban-ui and fail2ban container
- ./f2b-run-local:/var/run/fail2ban:z
# Log sources for fail2ban container
- /var/log:/var/log:ro
- /var/log/httpd:/remotelogs/apache2:ro
restart: unless-stopped
fail2ban-ui:
#image: registry.swissmakers.ch/infra/fail2ban-ui:latest
image: localhost/fail2ban-ui:dev
container_name: DEV_fail2ban-ui
privileged: true
network_mode: host
environment:
- PORT=3080
- BIND_ADDRESS=172.16.10.18
volumes:
# Required for fail2ban-ui: Stores SQLite database, application settings, and SSH keys of the fail2ban-ui container
- ./config:/config:Z
# Mount persistent SSH keys directory
- ./ssh-keys:/config/.ssh:z
# Required for fail2ban-ui: Used for testing, that logpath is working, before enabeling a jail. Without this read only access the fail2ban-ui will not be able to enable jails (logpath-test would fail)
- /var/log:/var/log:ro
- /var/log/httpd:/remotelogs/apache2:ro # this mounts the apache2 logs of a RPM based system (e.g. Rocky Linux) to the default location set by linuxserver-fail2ban. (on debian based systems this is /var/log/apache2 and currently hardcoded in the linuxserver-fail2ban container)
# Required for compose-local fail2ban instance: We mount the same Fail2Ban config as the linuxserver-fail2ban container (under /config/fail2ban to fail2ban-ui can modify configs)
- ./fail2ban-config-local/fail2ban:/etc/fail2ban:z
# Required for compose-local fail2ban instance: Mount the same run directory that contains fail2ban.sock for communication between fail2ban-ui and the linuxserver-fail2ban container
- ./f2b-run-local:/var/run/fail2ban:z
restart: unless-stopped
fail2ban-ssh:
image: lscr.io/linuxserver/fail2ban:latest
container_name: DEV_fail2ban-ssh
cap_add:
- NET_ADMIN
- NET_RAW
- SYS_ADMIN
network_mode: bridge
ports:
- "2222:22" # SSH port mapping
environment:
- TZ=Europe/Zurich
- VERBOSITY=-vv
- PUID=0 # Run as root for SSH setup
- PGID=0
volumes:
- ./fail2ban-config-ssh:/config:z
- /var/log:/var/log:ro
- /var/log/httpd:/remotelogs/apache2:ro
# Mount persistent SSH keys - shared between containers
- ./ssh-keys:/mnt/ssh-keys:z
# We use entrypoint override to run SSH setup before the container's init
entrypoint: /bin/sh
command: >
-c "
apk update && apk add --no-cache openssh-server openssh-keygen sudo acl;
ssh-keygen -A;
useradd -m -s /bin/bash testuser 2>/dev/null || true;
passwd -d testuser 2>/dev/null || usermod -U testuser 2>/dev/null || true;
chage -E -1 testuser 2>/dev/null || true;
mkdir -p /home/testuser/.ssh;
if [ ! -f /mnt/ssh-keys/id_rsa ]; then
echo 'Generating new SSH key pair...';
ssh-keygen -t rsa -b 4096 -m PEM -f /mnt/ssh-keys/id_rsa -N '';
chmod 600 /mnt/ssh-keys/id_rsa;
chmod 644 /mnt/ssh-keys/id_rsa.pub;
echo 'SSH key pair generated in persistent volume';
else
echo 'Using existing SSH key pair from persistent volume';
fi;
cp /mnt/ssh-keys/id_rsa /home/testuser/.ssh/id_rsa;
cp /mnt/ssh-keys/id_rsa.pub /home/testuser/.ssh/id_rsa.pub;
cat /mnt/ssh-keys/id_rsa.pub > /home/testuser/.ssh/authorized_keys;
chmod 700 /home/testuser/.ssh;
chmod 600 /home/testuser/.ssh/id_rsa;
chmod 644 /home/testuser/.ssh/id_rsa.pub;
chmod 600 /home/testuser/.ssh/authorized_keys;
chown -R testuser:testuser /home/testuser/.ssh;
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config;
echo 'PasswordAuthentication no' >> /etc/ssh/sshd_config;
echo 'PubkeyAuthentication yes' >> /etc/ssh/sshd_config;
echo 'LogLevel VERBOSE' >> /etc/ssh/sshd_config;
echo 'AuthorizedKeysFile .ssh/authorized_keys' >> /etc/ssh/sshd_config;
echo 'SyslogFacility AUTH' >> /etc/ssh/sshd_config;
mkdir -p /etc/sudoers.d;
echo 'testuser ALL=(ALL) NOPASSWD: /usr/bin/fail2ban-client *' > /etc/sudoers.d/fail2ban-ui;
echo 'testuser ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart fail2ban' >> /etc/sudoers.d/fail2ban-ui;
echo 'testuser ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload fail2ban' >> /etc/sudoers.d/fail2ban-ui;
chmod 440 /etc/sudoers.d/fail2ban-ui;
mkdir -p /etc/fail2ban/jail.d /etc/fail2ban/filter.d /etc/fail2ban/action.d;
setfacl -Rm u:testuser:rwX /etc/fail2ban 2>/dev/null || true;
setfacl -dRm u:testuser:rwX /etc/fail2ban 2>/dev/null || true;
[ -d /etc/fail2ban/action.d ] && setfacl -m u:testuser:rwX /etc/fail2ban/action.d 2>/dev/null || true;
[ -d /etc/fail2ban/filter.d ] && setfacl -m u:testuser:rwX /etc/fail2ban/filter.d 2>/dev/null || true;
[ -d /etc/fail2ban/jail.d ] && setfacl -m u:testuser:rwX /etc/fail2ban/jail.d 2>/dev/null || true;
[ -d /config/fail2ban/action.d ] && setfacl -m u:testuser:rwX /config/fail2ban/action.d 2>/dev/null || true;
[ -d /config/fail2ban/filter.d ] && setfacl -m u:testuser:rwX /config/fail2ban/filter.d 2>/dev/null || true;
[ -d /config/fail2ban/jail.d ] && setfacl -m u:testuser:rwX /config/fail2ban/jail.d 2>/dev/null || true;
echo '========================================';
echo 'SSH Test Container Ready';
echo '========================================';
echo 'Host: 127.0.0.1';
echo 'Port: 2222';
echo 'User: testuser';
echo 'Key: /config/.ssh/id_rsa (in fail2ban-ui container)';
echo 'Test command: podman exec -it DEV_fail2ban-ui ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o BatchMode=yes -i /config/.ssh/id_rsa -p 2222 testuser@127.0.0.1';
echo '========================================';
/usr/sbin/sshd -D -e &
exec /init
"
restart: unless-stopped