PhotonBBS includes comprehensive security features to protect against dictionary attacks, brute-force login attempts, and other malicious activities. The security system includes:
- Failed Login Tracking - Monitors and records failed login attempts
- Automatic IP Banning - Auto-bans IPs after repeated failures
- Manual IP Management - Sysop tools for managing bans
- Fail2Ban Integration - Works with fail2ban for iptables blocking
- IP Whitelisting - Protect trusted IPs from being banned
All security settings are in modules/pb-defaults:
## Security settings
sec_track_failed_logins => "1", # Track failed login attempts (1 = Yes, 0 = No)
sec_failed_threshold => "5", # Number of failed logins before auto-ban
sec_failed_window => "600", # Time window in seconds (default: 10 minutes)
sec_autoban_duration => "3600", # Auto-ban duration in seconds (default: 1 hour, 0 = permanent)
sec_log_failures => "1", # Log failed login attempts (1 = Yes, 0 = No)
sec_whitelist_enabled => "0", # Enable IP whitelist (1 = Yes, 0 = No)- sec_track_failed_logins: Enable/disable tracking of failed logins
- sec_failed_threshold: Number of failures before auto-ban (default: 5)
- sec_failed_window: Time window for counting failures in seconds (default: 600 = 10 minutes)
- sec_autoban_duration: How long auto-bans last in seconds (0 = permanent, default: 3600 = 1 hour)
- sec_log_failures: Log failed attempts to syslog (default: enabled)
- sec_whitelist_enabled: Enable IP whitelist protection (default: disabled)
When a user enters an incorrect password:
- The attempt is logged to
/appdata/failed_logins - Entry format:
timestamp|ip_address|username - If syslog logging is enabled, event is logged to syslog
After each failed login:
- System counts recent failures from that IP
- If count exceeds
sec_failed_thresholdwithinsec_failed_window:- IP is added to
/appdata/banned_ip - Ban entry includes:
ip|reason|expiry_timestamp - Connection is immediately terminated
- Event is logged to syslog
- IP is added to
When a connection is attempted:
- PhotonBBS daemon checks
/appdata/banned_ip - If IP matches (supports regex patterns):
- Checks if ban has expired
- If active, connection is rejected immediately
- User sees "banned IP" message and is disconnected
Auto-bans can be temporary or permanent:
- Temporary:
sec_autoban_duration > 0(e.g., 3600 = 1 hour) - Permanent:
sec_autoban_duration = 0
Expired bans are automatically ignored without requiring cleanup.
Format: ip_address|reason|expiry_timestamp
Example:
192.168.1.100|Auto-ban: 5 failed logins|1735603200
10.0.0.50|Manually banned by sysop|0
- Field 1: IP address or regex pattern
- Field 2: Reason for ban
- Field 3: Unix timestamp when ban expires (0 = never)
Format: timestamp|ip_address|username
Example:
1735599600|192.168.1.100|admin
1735599620|192.168.1.100|root
1735599640|192.168.1.100|sysop
Old entries are automatically cleaned up to prevent file growth.
Format: One IP or pattern per line (when enabled)
Example:
# Whitelist file
127.0.0.1
192.168.1.0/24
10.0.0.5
Whitelisted IPs are never banned, even if they trigger the threshold.
Command: Add to BBS menu or create door script
Function: security_dashboard() from pb-security-admin module
Features:
- View all banned IPs with reasons and expiry times
- See recent failed login attempts (last 20)
- View security statistics
- Access ban management commands
Menu Entry Example:
S:sysop_menu:Security Dashboard
INTERNAL:security_dashboard
-
(B)an IP - Manually ban an IP address
- Enter IP address or pattern
- Specify reason
- Set duration (seconds, 0 = permanent)
-
(U)nban IP - Remove an IP from ban list
- Enter exact IP to unban
- Immediately takes effect
-
(W)hitelist - Manage whitelisted IPs
- View current whitelist
- Add IP to whitelist
- Enable/disable whitelist (requires config change)
-
(R)efresh - Reload dashboard data
-
(Q)uit - Return to main menu
PhotonBBS includes fail2ban jail and filter configurations for additional protection.
-
Copy jail configuration:
sudo cp configs/fail2ban/jail.d/photonbbs.conf /etc/fail2ban/jail.d/
-
Copy filter configuration:
sudo cp configs/fail2ban/filter.d/photonbbs.conf /etc/fail2ban/filter.d/
-
Test the configuration:
sudo fail2ban-client reload sudo fail2ban-client status photonbbs
- Monitors syslog for PhotonBBS failed login messages
- Counts failures per IP within time window
- When threshold is exceeded:
- Creates iptables rule to block IP
- Blocks ALL ports (not just telnet)
- Ban duration is independent of PhotonBBS auto-ban
In /etc/fail2ban/jail.d/photonbbs.conf:
maxretry = 5 # Failures before ban
findtime = 600 # Time window (10 minutes)
bantime = 3600 # Ban duration (1 hour)# View PhotonBBS jail status
sudo fail2ban-client status photonbbs
# View currently banned IPs
sudo fail2ban-client get photonbbs banned
# Manually unban an IP
sudo fail2ban-client set photonbbs unbanip 192.168.1.100- Connect via telnet to PhotonBBS
- Try to login with wrong password 5 times
- Should be auto-banned after 5th attempt
- Try to reconnect - should be rejected immediately
- Set
sec_autoban_duration = 60(1 minute) - Trigger auto-ban (5 failed logins)
- Wait 61 seconds
- Try to connect - should be allowed
- Set
sec_whitelist_enabled = 1in config - Add your IP to
/appdata/whitelist_ip - Try failed logins from that IP
- Should not be banned
# View PhotonBBS security events in syslog
sudo grep "photonbbs.*SECURITY" /var/log/syslog
# View failed login attempts
sudo grep "photonbbs.*WARN.*incorrect password" /var/log/syslog
# View auto-ban events
sudo grep "photonbbs.*Auto-banned" /var/log/syslogOld entries are automatically cleaned during failed login tracking. Manual cleanup is not normally required.
- Use Security Dashboard (sysop command)
- Or manually check
/appdata/banned_ip
Expired bans are automatically ignored and don't need removal.
For manual cleanup:
# Backup ban file
cp /appdata/banned_ip /appdata/banned_ip.backup
# Remove expired bans (manual script needed)
# Or use Security Dashboard to unban manuallyFor production BBS:
sec_track_failed_logins => "1", # Always track
sec_failed_threshold => "5", # Standard threshold
sec_failed_window => "600", # 10 minute window
sec_autoban_duration => "3600", # 1 hour temporary ban
sec_log_failures => "1", # Always log
sec_whitelist_enabled => "1", # Enable for trusted IPsFor high-security BBS:
sec_failed_threshold => "3", # Stricter threshold
sec_failed_window => "900", # 15 minute window
sec_autoban_duration => "0", # Permanent bans- Enable fail2ban - Provides iptables-level blocking
- Monitor logs regularly - Check for attack patterns
- Whitelist your IPs - Prevent accidental lockout
- Review bans weekly - Check for false positives
- Keep syslog enabled - Essential for forensics
If you're worried about locking yourself out:
-
Add your IP to whitelist:
echo "your.ip.address" >> /appdata/whitelist_ip
-
Enable whitelist:
sec_whitelist_enabled => "1",
-
Keep localhost whitelisted:
echo "127.0.0.1" >> /appdata/whitelist_ip
If you're locked out:
# SSH to server
ssh your-server
# Remove your IP from ban list
sed -i '/your.ip.address/d' /appdata/banned_ip
# Or disable security temporarily
mv /appdata/banned_ip /appdata/banned_ip.disabled- Check fail2ban:
sudo fail2ban-client status photonbbs - Your IP may be banned by fail2ban, not PhotonBBS
- Unban from fail2ban:
sudo fail2ban-client set photonbbs unbanip YOUR_IP
- Check
sec_track_failed_logins = 1in pb-defaults - Verify pb-security module is loading
- Check file permissions on
/appdata/failed_logins
- Verify threshold/window settings are correct
- Check that pb-security functions are being called
- Review syslog for security messages
- Verify
sec_whitelist_enabled = 1 - Check whitelist file exists:
/appdata/whitelist_ip - Ensure IP format is correct in whitelist file
# Record a failed login attempt
# Returns 1 if IP should be auto-banned, 0 otherwise
my $banned = record_failed_login($ip, $username);
# Check if an IP is banned
# Returns (banned, reason, expires_at) or (0, undef, undef)
my ($is_banned, $reason, $expires) = check_ip_banned($ip);
# Manually ban an IP
# $expires: Unix timestamp or 0 for permanent
my $success = manual_ban_ip($ip, $reason, $expires);
# Unban an IP
my $success = unban_ip($ip);
# Get all banned IPs
# Returns array of hashrefs: { ip, reason, expires }
my @bans = get_banned_ips();
# Get failed login statistics
# Returns array of hashrefs: { timestamp, ip, username, ago }
my @attempts = get_failed_login_stats($limit);
# Check if IP is whitelisted
my $is_whitelisted = is_ip_whitelisted($ip);
# Clean up old login attempts
cleanup_old_login_attempts();# Display security dashboard (sysop only)
security_dashboard();
# Ban IP via interactive prompt
ban_ip_command();
# Unban IP via interactive prompt
unban_ip_command();
# Manage whitelist via interactive menu
manage_whitelist();- Initial security system implementation
- Failed login tracking
- Automatic IP banning with expiry
- Fail2ban integration
- Sysop security dashboard
- IP whitelist support
For issues or questions:
- GitHub: https://github.com/fewtarius/photonbbs
- BBS: telnet bbs.terminaltavern.com
PhotonBBS Security System Copyright (C) 2025 Fewtarius GNU General Public License v2