binkterm-php is a modern Fidonet mailer that provides both a web interface and native binkp TCP/IP connectivity for FTN (Fidonet Technology Network) message handling. It combines traditional FTN packet processing with contemporary web technologies to create a user-friendly experience for Fidonet system operators.
binkterm-php was largely written by Anthropic's Claude with prompting by awehttam. It was meant to be a fun little excercise to see what Claude would come up with for an older technology mixed up with a modern interface.
There are no doubt bugs and omissions in the project as it was written by an AI. YMMV. This code is released under the terms of a BSD License.
awehttam runs an instance of BinktermPHP over at https://mypoint.lovelybits.org
- Screen shots
- Features
- Installation
- Configuration
- Database Management
- Command Line Scripts
- Operation
- Troubleshooting
- Customization
- Security Considerations
- File Structure
- Contributing
- License
- Support
- Acknowledgments
- Modern Bootstrap 5 UI - Clean, responsive interface accessible from any device including mobile phones.
- Netmail Management - Send and receive private network mail messages
- Echomail Support - Participate in public discussion areas (forums). Sortable and threaded view available.
- Address Book Support A handy address book to keep track of your netmail contacts
- Message Sharing - Share echomail messages via secure web links with privacy controls
- Message Saving - Ability to save messages
- Search Capabilities - Full-text search across messages and echo areas
- Web Terminal - SSH terminal access through the web interface with configurable proxy support
- Installable PWA - Installable both on mobile and desktop for a more seamless application experience
- FTS-1026 Compliant - Full (really?) binkp/1.0 protocol implementation
- TCP/IP Connectivity - Direct connections over internet (port 24554)
- Automated Scheduling - Cron-style polling with configurable intervals
- File Transfer - Reliable packet exchange with resume support (not FREQIT)
- Password Authentication - Uplink authentication
- Connection Management - Multiple concurrent connections with limits
- Message Posting - CLI tool for automated netmail/echomail posting
- Connection Testing - Debug and test binkp connections
- Server Management - Start/stop binkp server daemon (Linux/UNIX only)
- Status Monitoring - Real-time system and connection status
- Scheduling Control - Manage automated polling schedules
- Weather Reports - Configurable weather forecast generator for posting to echomail areas (details)
- Echomail Maintenance - Purge old messages by age or count limits to manage database size (details)
- PHP 8.0+ with extensions: PDO, PostgreSQL, Sockets, JSON, DOM
- Web Server - Apache, Nginx, or PHP built-in server
- Composer - For dependency management
- Operating System - Windows, Linux, or macOS
git clone https://github.com/awehttam/binkterm-php
cd binkterm-phpcomposer installUse the installation script for automated setup:
# Interactive installation (prompts for admin credentials)
php scripts/install.php
# Non-interactive installation (creates admin/admin123 - CHANGE IMMEDIATELY!)
php scripts/install.php --non-interactiveAlternatively, use the setup script which auto-detects whether to install or upgrade:
php scripts/setup.php<VirtualHost *:80>
ServerName binktest.local
DocumentRoot /path/to/binktest/public_html
<Directory /path/to/binktest/public_html>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>server {
listen 80;
server_name binktest.local;
root /path/to/binktest/public_html;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.0-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}cd public_html
php -S localhost:8080Edit config/binkp.json to configure your system.
- sysop must match the sysop user's name otherwise netmail destined to 'sysop' will fail.
{
"system": {
"name": "Claude's BBS",
"address": "1:1/0.123",
"sysop": "Your Name",
"location": "Your City, State",
"hostname": "your.domain.com",
"website": "https://yourbbs.com",
"timezone": "UTC"
},
"binkp": {
"port": 24554,
"timeout": 300,
"max_connections": 10,
"bind_address": "0.0.0.0",
"inbound_path": "data/inbound",
"outbound_path": "data/outbound",
"preserve_processed_packets": false
},
"uplinks": [
{
"default": true,
"address": "1:1/0.0",
"hostname": "hub.fidonet.org",
"port": 24554,
"password": "your_password",
"poll_schedule": "0 */4 * * *",
"enabled": true,
"compression": false,
"crypt": false
}
]
}- name: The system's name
- address: Your FTN address (zone:net/node.point)
- sysop: System operator name. Must match the actual real name as the sysops user account.
- location: Geographic location
- hostname: Your internet hostname
- website: Optional website URL (displayed in message origin lines)
- timezone: The system's timezone (https://www.php.net/manual/en/timezones.php)
Note: When the website field is configured, it will be included in FidoNet message origin lines:
- Without website:
* Origin: My BBS System (1:234/567) - With website:
* Origin: My BBS System <https://mybbs.com> (1:234/567)
The web terminal feature provides SSH access through the browser interface. This requires both configuration in the .env file and a proxy server to handle WebSocket-to-SSH connections.
Add these settings to your .env file:
# Web Terminal Configuration
TERMINAL_ENABLED=true
TERMINAL_HOST=your.ssh.server.com
TERMINAL_PORT=22
TERMINAL_PROXY_HOST=your.proxy.server.com
TERMINAL_PROXY_PORT=443
TERMINAL_TITLE=Terminal Gateway- TERMINAL_ENABLED: Set to
trueto enable terminal access,falseto disable - TERMINAL_HOST: The SSH server hostname/IP that users will connect to
- TERMINAL_PORT: SSH server port (typically 22)
- TERMINAL_PROXY_HOST: WebSocket proxy server hostname/IP
- TERMINAL_PROXY_PORT: WebSocket proxy server port (typically 443 for HTTPS)
- TERMINAL_TITLE: Custom title displayed on the terminal page
You can customize the welcome messages displayed to users in various parts of the system by creating optional text files in the config/ directory:
Create config/terminal_welcome.txt to display a custom message on the terminal login page. If this file exists, it replaces the default "SSH Connection to host:port" message. The content supports multiple lines and will be displayed exactly as written.
Example config/terminal_welcome.txt:
Welcome to MyBBS Terminal Gateway!
Connect to our shell server to access:
- Email and messaging systems
- File areas and downloads
- Games and utilities
- Community forums
Enter your credentials below to connect.
Create config/newuser_welcome.txt to customize the welcome email sent to newly registered users. This email template is sent automatically after user registration is approved by an administrator and can include instructions, rules, or helpful information for new users. The template supports basic text formatting and will be sent via the configured SMTP server.
Create config/welcome.txt to display a custom welcome message on the main page or login screen. This can be used for general announcements, system information, or greeting messages for all users.
The web terminal requires a WebSocket-to-SSH proxy server to bridge browser WebSocket connections to SSH servers. You can use a proxy server like Terminal Gateway which provides:
- WebSocket to SSH connection bridging
- Session management and authentication
- Security isolation between web and SSH connections
- Support for multiple concurrent sessions
- Users must be authenticated in the web interface to access the terminal
- The terminal is disabled by default (
TERMINAL_ENABLED=false) - SSH authentication is handled separately from web authentication
- Consider network security for both the proxy server and target SSH server
- The proxy server should be properly secured and regularly updated
- port: TCP port for binkp server (default: 24554)
- timeout: Connection timeout in seconds
- max_connections: Maximum simultaneous connections
- bind_address: IP address to bind to (0.0.0.0 for all)
- inbound_path: Directory for incoming files
- outbound_path: Directory for outgoing files
- preserve_processed_packets: Move packets to the processed directory after processing
- default: Whether this is the default uplink or not
- address: Uplink FTN address
- hostname: Uplink hostname or IP
- port: Uplink port (usually 24554)
- password: Authentication password
- poll_schedule: Cron expression for polling (e.g., "0 */4 * * *" = every 4 hours)
- enabled: Whether uplink is active
- compression: Enable compression (not yet implemented)
- crypt: Enable encryption (not yet implemented)
BinktermPHP includes scripts for database installation and schema migrations:
composer installPostgres, SMTP, web terminal, and other miscellaneous settings are controlled through ".env" in the main directory. See .env.example for reference.
Create config/binkp.json (see binkp.json.example for reference) with appropriate parameters.
# Install fresh database with admin user
php scripts/install.php # Interactive mode
php scripts/install.php --non-interactive # Uses defaults
# Auto-detect and run install or upgrade
php scripts/setup.php # Smart setup
php scripts/setup.php status # Show system status
# Database migrations
php scripts/upgrade.php # Apply pending migrations
php scripts/upgrade.php status # Show migration status
php scripts/upgrade.php create 1.3.0 "add feature" # Create new migrationThe directories:
data/outbound data/logs
must be writable by the web server and the user that runs the binkp_ scripts. Quick but not optimal permissions would be:
chmod 777 data/outbound chmod g+s data/outbound chmod 777 data/logs
but a better model would be to collaborate with the group id your web server or php runner runs as.
Database changes are managed through versioned SQL migration files stored in database/migrations/:
- Filename format:
vX.Y.Z_description.sql(e.g.,v1.1.0_add_user_preferences.sql) - Automatic tracking: Migration status is recorded in
database_migrationstable - Safe execution: Each migration runs in a transaction with rollback on failure
- Comment support: SQL comments are automatically stripped during execution
Post netmail or echomail from command line:
# Send netmail
php scripts/post_message.php --type=netmail \
--from=1:153/149.57599 --from-name="John Doe" \
--to=1:153/149 --to-name="Jane Smith" \
--subject="Test Message" \
--text="Hello, this is a test!"
# Post to echomail
php scripts/post_message.php --type=echomail \
--from=1:153/149.57599 --from-name="John Doe" \
--echoarea=GENERAL --subject="Discussion Topic" \
--file=message.txt
# List available users and echo areas
php scripts/post_message.php --list-users
php scripts/post_message.php --list-areasGenerate detailed weather forecasts for posting to echomail areas:
# Generate weather report using configured locations
php scripts/weather_report.php
# Test with demo data (no API key required)
php scripts/weather_report.php --demo
# Post weather report to echomail area
php scripts/weather_report.php --post --areas=WEATHER --user=admin
# Use custom configuration file
php scripts/weather_report.php --config=/path/to/custom/weather.jsonThe weather script is fully configurable via JSON configuration files, supporting any worldwide locations with descriptive forecasts and current conditions. See scripts/README_weather.md for detailed setup instructions and configuration examples.
Manage echomail storage by purging old messages based on age or message count limits:
# Delete messages older than 90 days from all echoes
php scripts/echomail_maintenance.php --echo=all --max-age=90
# Keep only newest 500 messages per echo
php scripts/echomail_maintenance.php --echo=all --max-count=500
# Preview what would be deleted (dry run)
php scripts/echomail_maintenance.php --echo=COOKING --max-age=180 --dry-run
# Combined age and count limits for specific echo
php scripts/echomail_maintenance.php --echo=SYNCDATA --max-age=90 --max-count=2000The maintenance script provides flexible echomail cleanup with age-based deletion, count-based limits, dry-run preview mode, and per-echo or bulk processing. See scripts/README_echomail_maintenance.md for detailed documentation, cron job examples, and best practices.
Manage user accounts from the command line:
# List all active non-admin users
php scripts/user-manager.php list
# List all users including admins and inactive
php scripts/user-manager.php list --show-admin --show-inactive
# Show detailed information for a user
php scripts/user-manager.php show username
# Change a user's password (interactive)
php scripts/user-manager.php passwd username
# Create a new user (interactive)
php scripts/user-manager.php create alice --real-name="Alice Smith" --email=alice@example.com
# Create an admin user with password (non-interactive)
php scripts/user-manager.php create sysop --admin --password=secret123
# Delete a user (requires confirmation)
php scripts/user-manager.php delete testuser --confirm
# Activate or deactivate user accounts
php scripts/user-manager.php activate username
php scripts/user-manager.php deactivate usernameOptions:
--password=<pwd>: Set password non-interactively--real-name=<name>: Set real name for new users--email=<email>: Set email for new users--admin: Create user as administrator--show-admin: Include admins in user list--show-inactive: Include inactive users in list--confirm: Confirm destructive operations--non-interactive: Don't prompt for input
Polling is supported on all platforms, except for Windows where binkp_server will not operate.
# Start server in foreground
php scripts/binkp_server.php
# Start as daemon (Unix-like systems)
php scripts/binkp_server.php --daemon
# Custom port and logging
php scripts/binkp_server.php --port=24554 --log-level=DEBUG# Poll specific uplink
php scripts/binkp_poll.php 1:153/149
# Poll all configured uplinks
php scripts/binkp_poll.php --all
# Test connection without polling
php scripts/binkp_poll.php --test 1:153/149# Show all status information
php scripts/binkp_status.php
# Show specific information
php scripts/binkp_status.php --uplinks
php scripts/binkp_status.php --queues
php scripts/binkp_status.php --config
# JSON output for scripting
php scripts/binkp_status.php --json# Start scheduler daemon
php scripts/binkp_scheduler.php --daemon
# Run once and exit
php scripts/binkp_scheduler.php --once
# Show schedule status
php scripts/binkp_scheduler.php --status
# Custom interval (seconds)
php scripts/binkp_scheduler.php --interval=120# Detailed connection debugging
php scripts/debug_binkp.php 1:153/149# Process inbound packets
php scripts/process_packets.php- Start Web Server: Ensure Apache/Nginx is running, or use PHP built-in server
- Start Binkp Server:
php scripts/binkp_server.php --daemon- not fully tested, see alternative polling - Polling Configure cron to run
scripts/binkp_poll.php --allperiodically - Start Scheduler:
php scripts/binkp_scheduler.php --daemon - Process Packets: Set up cron job for
php scripts/process_packets.php
- Navigate to your binktest URL
- Login with your credentials
- Use the Binkp tab to monitor connections and manage uplinks
- Send/receive messages via Netmail and Echomail tabs
- Monitor status:
php scripts/binkp_status.php - Manual poll:
php scripts/binkp_poll.php --all - Post messages:
php scripts/post_message.php [options]
Add these entries to your crontab for automated operation:
# Process inbound packets every 5 minutes
*/3 * * * * /usr/bin/php /path/to/binktest/scripts/process_packets.php
*/5 * * * * /usr/bin/php /path/to/binktest/scripts/binkp_poll.php
# Backup database daily
0 2 * * * cp /path/to/binktest/data/binktest.db /path/to/backups/binktest-$(date +\%Y\%m\%d).db
# Rotate logs weekly
0 0 * * 0 find /path/to/binktest/data/logs -name "*.log" -mtime +7 -deleteProblem: Cannot connect to uplink Solutions:
- Check network connectivity:
ping uplink.hostname.com - Verify port is open:
telnet uplink.hostname.com 24554 - Run debug script:
php scripts/debug_binkp.php 1:153/149 - Check logs in
data/logs/directory - Verify password in configuration
Problem: Password mismatch errors Solutions:
- Verify password in
config/binkp.jsonmatches uplink configuration - Check that uplink address is correct
- Ensure uplink has your address and password configured
- Run debug script to see exact authentication flow
Problem: Files not transferring properly Solutions:
- Check file permissions on inbound/outbound directories
- Verify disk space availability
- Check for firewall blocking data transfer
- Review transfer logs for specific error messages
- Test with smaller files first
Problem: Cannot access web interface Solutions:
- Check web server error logs
- Verify PHP extensions are installed
- Check file permissions on web directory
- Test PHP configuration:
php -m - Verify database file permissions
Monitor these log files for troubleshooting:
data/logs/binkp_server.log- Server daemon logsdata/logs/binkp_poll.log- Polling activitydata/logs/binkp_scheduler.log- Automated schedulingdata/logs/binkp_debug.log- Debug connection issuesdata/logs/binkp_web.log- Web interface API calls
Enable detailed logging for troubleshooting:
# Start server with debug logging
php scripts/binkp_server.php --log-level=DEBUG
# Debug specific connection
php scripts/debug_binkp.php 1:153/149
# Monitor logs in real-time
tail -f data/logs/binkp_server.logYou can inject analytics tracking code into the page header by creating a template named templates/custom/header.insert.twig.
See templates/custom/header.insert.twig.example for reference with Google Analytics and other tracking examples.
BinktermPHP provides several ways to customize the look and feel without modifying core files:
- Custom Stylesheet: Set
STYLESHEET=/css/mytheme.cssin.env(includes built-in dark theme at/css/dark.css) - Template Overrides: Copy any template to
templates/custom/to override it - Custom Routes: Create
routes/web-routes.local.phpto add new pages - System News: Create
templates/custom/systemnews.twigfor dashboard content - Header Insertions: Add CSS/JS via
templates/custom/header.insert.twig - Welcome Messages: Customize login page via
config/welcome.txt
All customizations are upgrade-safe and won't be overwritten when updating BinktermPHP.
For detailed instructions including Bootstrap 5 components, Twig template variables, and code examples, see CUSTOMIZING.md.
- Increase
max_connectionsin configuration - Use faster storage for inbound/outbound directories
- Consider SSD storage for database
- Monitor system resources during peak times
- Optimize PHP opcache settings
- Monitor PHP memory usage
- Process packets more frequently to avoid large queues
- Clean up old log files regularly
- Consider increasing PHP memory limit
If you encounter issues not covered here:
- Check the debug logs with maximum verbosity
- Test with minimal configuration (one uplink)
- Verify your FTN address is correct and authorized
- Contact your uplink administrator to verify connectivity
- Create issues on the project GitHub repository with:
- Full error messages
- Configuration details (remove passwords)
- Debug log excerpts
- System information (OS, PHP version)
- Binkp server listens on all interfaces by default
- Consider firewall rules to restrict access
- Monitor connection logs for unauthorized attempts
- Use strong passwords for uplink authentication
- Inbound directory should not be web-accessible
- Set appropriate file permissions (755 for directories, 644 for files)
- Regular backup of database and configuration files
- Monitor disk space to prevent DoS via large files
- Use HTTPS in production environments
- Implement proper session management
- Regular security updates of dependencies
- Consider rate limiting for API endpoints
binktest/
├── config/
│ └── binkp.json # Binkp configuration
├── src/
│ ├── Auth.php # Authentication
│ ├── Database.php # Database connection
│ ├── MessageHandler.php # Message processing
│ ├── BinkdProcessor.php # Packet processing
│ ├── Template.php # Twig rendering
│ └── Binkp/ # Binkp implementation
│ ├── Protocol/ # Protocol classes
│ ├── Connection/ # Connection management
│ ├── Config/ # Configuration
│ ├── Queue/ # Queue processing
│ └── Web/ # Web interface
├── scripts/
│ ├── binkp_server.php # Binkp server daemon
│ ├── binkp_poll.php # Manual polling
│ ├── binkp_status.php # System status
│ ├── binkp_scheduler.php # Automated scheduler
│ ├── debug_binkp.php # Debug connections
│ ├── post_message.php # Message posting tool
│ └── process_packets.php # Packet processor
├── templates/ # Twig templates
│ └── custom/ # Custom template insertions
├── public_html/ # Web root
│ ├── css/ # Stylesheets
│ ├── js/ # JavaScript
│ └── index.php # Main application
├── data/
│ ├── inbound/ # Incoming packets
│ ├── outbound/ # Outgoing packets (shared permissions between web server and shell account)
│ ├── logs/ # Log files (shared permissions between web server and shell account)
└── database/
└── migrations/ # Database migration files
We welcome contributions to BinktermPHP! Please see our Contributing Guide for detailed information on:
- Development setup and code conventions
- Pull request workflow
- Database migrations
- Testing guidelines
- Security considerations
All contributions must be submitted via pull request and will be reviewed by project maintainers.
This project is licensed under a BSD License. See LICENSE.md for more information.
- Documentation: This README and inline code comments
- Issues: GitHub issue tracker
- Community: Fidonet echo areas and developer forums
- Fidonet Technical Standards Committee for protocol specifications
- Original binkd developers for reference implementation
- Bootstrap and jQuery communities for web interface components
- PHP community for excellent documentation and tools







