This document provides comprehensive deployment instructions for EmergencyBox on DD-WRT routers, based on a successful deployment to an ASUS RT-AC68U. It includes detailed troubleshooting for all critical issues encountered during real-world deployment.
IMPORTANT UPDATE: For auto-start configuration on boot, see AUTOSTART_SETUP.md which documents the critical
mount --bindsolution for DD-WRT's read-only filesystem limitation.
- Prerequisites
- Architecture Overview
- Step-by-Step Deployment
- Critical Issues & Solutions
- Testing & Verification
- Troubleshooting
- Maintenance
Router:
- Model: ASUS RT-AC68U (or compatible DD-WRT-supported router)
- CPU: ARM Cortex-A9 dual-core @ 800 MHz (BCM4708/4709)
- RAM: 256 MB minimum
- Flash: 128 MB
- USB Ports: USB 2.0/3.0 for external storage
USB Storage:
- Capacity: 8GB minimum (16GB+ recommended for extensive file storage)
- Format: ext4 (required for proper permissions and symlinks)
- Partitions: Two partitions required (see Architecture section)
Firmware:
- DD-WRT firmware build for ASUS RT-AC68U
- Recommended: Latest stable release from https://dd-wrt.com/
- File format:
.trxor.bindepending on installation method
Required Packages (via Entware):
php7orphp7-cli+php7-cgiphp7-mod-sqlite3(SQLite database support)php7-mod-fileinfo(file type detection)lighttpd(web server)lighttpd-mod-fastcgi(PHP execution)sqlite3-cli(database management)
- Ethernet cable for initial setup (recommended)
- Computer with SSH/SCP capability
- Telnet client (initial DD-WRT access uses telnet, not SSH)
- Web browser for testing
EmergencyBox uses a two-partition USB setup for critical architectural reasons:
Partition 1 (/dev/sda1) - Entware System Partition:
- Mount Point:
/opt - Purpose: Entware package manager and installed software
- Contents:
/opt/bin/- Executable binaries (PHP, lighttpd, sqlite3)/opt/lib/- Shared libraries/opt/etc/- Configuration files/opt/share/zoneinfo/- Timezone data (critical for PHP)/opt/var/- Variable data (logs, PID files)
- Why Separate: Entware needs to mount over
/optat boot, which would hide any data stored there
Partition 2 (/dev/sda2) - Application Data Partition:
- Mount Point:
/mnt/data - Purpose: EmergencyBox application and user data
- Contents:
/mnt/data/www/- Web application files/mnt/data/www/uploads/- User-uploaded files/mnt/data/emergencybox.db- SQLite database
- Why Separate: Data persists independently of Entware overlay mounting
Key Insight: During deployment, we discovered that mounting /dev/sda1 to /opt overlays the filesystem, hiding any files previously in /opt/share/. This caused PHP timezone crashes until timezone files were copied to the correct partition.
DD-WRT's initial configuration uses telnet instead of SSH for security reasons:
- First login via telnet forces you to set a password
- SSH is automatically enabled after password is set
- This prevents routers from shipping with default SSH credentials
- After initial setup, always use SSH for secure access
PHP version choice is dictated by Entware package availability:
- PHP 7.4: Widely available in Entware for ARM architecture
- PHP 8.x: May not be available for older ARM kernels
- Compatibility: PHP 7.4 fully supports all EmergencyBox features
- Extensions: Both
sqlite3andfileinfomodules available for PHP 7.x - Memory: PHP 7.4 has lower memory footprint than 8.x (important for 256MB RAM)
Port 80: DD-WRT's built-in HTTP daemon (httpd) runs on port 80 by default for the router admin interface.
Port 8080: EmergencyBox runs on port 8080 to avoid conflicts.
Why Not Disable DD-WRT httpd?
- Router admin interface remains accessible
- Avoids breaking DD-WRT's web-based configuration
- Easy to remember:
http://192.168.1.1(admin) vshttp://192.168.1.1:8080(EmergencyBox)
-
Visit the DD-WRT router database:
https://dd-wrt.com/support/router-database/ -
Search for "ASUS RT-AC68U"
-
Download the appropriate firmware file (
.trxfor most installations) -
Verify file integrity:
sha256sum asus_rt-ac68u-firmware.trx
Method A: Via ASUS Web Interface (if currently running ASUS stock firmware)
- Connect to router via Ethernet cable
- Access router admin interface:
http://192.168.1.1 - Login with admin credentials
- Navigate to: Administration > Firmware Upgrade
- Choose the DD-WRT
.trxfile - Click Upload
- DO NOT interrupt power during flashing (5-10 minutes)
- Router will reboot automatically
Method B: Via TFTP Recovery Mode (if brick or failed flash)
- Download TFTP client
- Set computer IP to
192.168.1.10, subnet255.255.255.0 - Power off router
- Hold Reset button and power on router
- Wait for power LED to start blinking
- Upload firmware via TFTP:
tftp 192.168.1.1 binary put asus_rt-ac68u-firmware.trx
- Wait 5-10 minutes for completion
-
After reboot, access router:
http://192.168.1.1 -
DD-WRT will prompt for username/password setup:
- Username:
root - Password: (choose strong password)
- Username:
-
Complete basic wireless setup (SSID, encryption)
-
Important: Note that initial access uses telnet, not SSH
-
Set a password via telnet to enable SSH:
telnet 192.168.1.1 # Login as root passwd # Enter new password twice # SSH is now enabled
On Linux/Mac:
# Identify USB device
lsblk
# Assume USB is /dev/sdb
# CAUTION: This will erase all data on the drive!
# Create partition table
sudo parted /dev/sdb mklabel gpt
# Create two partitions
sudo parted /dev/sdb mkpart primary ext4 0% 50% # Partition 1: Entware
sudo parted /dev/sdb mkpart primary ext4 50% 100% # Partition 2: Data
# Format partitions
sudo mkfs.ext4 -L "Entware" /dev/sdb1
sudo mkfs.ext4 -L "Data" /dev/sdb2
# Verify
lsblk -f /dev/sdbOn Windows:
Use a tool like Rufus or GParted Live USB to create two ext4 partitions.
- Safely eject USB from computer
- Insert into router's USB port (USB 3.0 preferred if available)
- Wait 10 seconds for router to detect
ssh root@192.168.1.1
# Check detected drives
ls -l /dev/sd*
# Expected output:
# /dev/sda
# /dev/sda1 (Entware partition)
# /dev/sda2 (Data partition)
# Check filesystem
blkid /dev/sda1
blkid /dev/sda2- Access DD-WRT web interface:
http://192.168.1.1 - Navigate to: Services > USB
- Enable the following:
- Core USB Support: Enabled
- USB Storage Support: Enabled
- Automatic Drive Mount: Enabled
- Click Save and Apply Settings
ssh root@192.168.1.1
# Create mount point
mkdir -p /opt
# Mount Entware partition
mount /dev/sda1 /opt
# Verify mount
df -h | grep sda1# Download Entware installer
cd /opt
wget http://bin.entware.net/armv7sf-k3.2/installer/generic.sh
# Run installer
sh generic.sh
# Update package database
/opt/bin/opkg update
# Verify installation
/opt/bin/opkg --versionImportant: Entware must mount before starting services.
-
In DD-WRT web interface, go to: Administration > Commands
-
Add to Startup script:
# Wait for USB to be ready sleep 10 # Mount Entware partition mount /dev/sda1 /opt # Start Entware services /opt/etc/init.d/rc.unslung start
-
Click Save Startup
ssh root@192.168.1.1
# Update package list
/opt/bin/opkg update
# Install PHP
/opt/bin/opkg install php7-cli php7-cgi
# Install PHP extensions
/opt/bin/opkg install php7-mod-sqlite3 php7-mod-fileinfo
# Verify PHP installation
/opt/bin/php -v
# Expected output:
# PHP 7.4.x (cli)Critical Check: Verify PHP extensions loaded:
/opt/bin/php -m | grep -i sqlite
# Expected: sqlite3
/opt/bin/php -m | grep -i fileinfo
# Expected: fileinfo# Install lighttpd and FastCGI module
/opt/bin/opkg install lighttpd lighttpd-mod-fastcgi
# Verify installation
/opt/sbin/lighttpd -v
# Expected output:
# lighttpd/1.4.x# Install SQLite command-line tool
/opt/bin/opkg install sqlite3-cli
# Verify installation
/opt/bin/sqlite3 --version
# Expected output:
# 3.x.xssh root@192.168.1.1
# Create mount point
mkdir -p /mnt/data
# Mount data partition
mount /dev/sda2 /mnt/data
# Verify mount
df -h | grep sda2
# Add to startup script (Administration > Commands > Startup):
sleep 10
mount /dev/sda2 /mnt/data# Create application directories on data partition
mkdir -p /mnt/data/www
mkdir -p /mnt/data/www/api
mkdir -p /mnt/data/www/css
mkdir -p /mnt/data/www/js
mkdir -p /mnt/data/www/uploads/emergency
mkdir -p /mnt/data/www/uploads/media
mkdir -p /mnt/data/www/uploads/documents
mkdir -p /mnt/data/www/uploads/general
# Create config directory
mkdir -p /opt/etc/lighttpd
# Create log directory
mkdir -p /opt/var/log/lighttpd
# Verify structure
tree /mnt/data/www # (if tree installed)
# OR
find /mnt/data/www -type dFrom your computer (in the project directory):
# Set variables
ROUTER_IP="192.168.1.1"
ROUTER_USER="root"
# Copy web application files
scp -r www/* ${ROUTER_USER}@${ROUTER_IP}:/mnt/data/www/
# Copy configuration files
scp config/lighttpd.conf ${ROUTER_USER}@${ROUTER_IP}:/opt/etc/lighttpd/lighttpd.conf
scp config/php.ini ${ROUTER_USER}@${ROUTER_IP}:/opt/etc/php.iniAlternative: Use the provided deployment script:
chmod +x deploy.sh
./deploy.sh 192.168.1.1 rootNote: You'll need to modify deploy.sh to use /mnt/data instead of /opt/share.
Critical Configuration: The php.ini must include proper extension_dir and timezone settings.
ssh root@192.168.1.1
# Edit PHP configuration
vi /opt/etc/php.iniEssential settings:
; Extension directory (CRITICAL)
extension_dir = "/opt/lib/php"
; Timezone (CRITICAL - prevents crashes)
date.timezone = "UTC"
; Large file upload support
upload_max_filesize = 1024M
post_max_size = 1024M
max_execution_time = 600
max_input_time = 600
memory_limit = 128M
; File uploads
file_uploads = On
upload_tmp_dir = "/tmp"
; Error reporting
display_errors = On
log_errors = On
error_log = "/opt/var/log/php-errors.log"Why extension_dir is Critical:
During deployment, we discovered that without explicitly setting extension_dir, PHP couldn't find the SQLite3 extension, causing all database operations to fail.
Why Timezone Setting is Critical: PHP on embedded systems often lacks timezone data or can't find it. Without proper timezone configuration, PHP will crash with "Timezone database is corrupt" errors. See Critical Issues below.
ssh root@192.168.1.1
# Edit lighttpd configuration
vi /opt/etc/lighttpd/lighttpd.confConfiguration (adjusted from provided config):
## EmergencyBox lighttpd Configuration
## Optimized for DD-WRT on ASUS RT-AC68U
server.modules = (
"mod_access",
"mod_alias",
"mod_fastcgi",
"mod_rewrite",
"mod_setenv"
)
# Document root on data partition
server.document-root = "/mnt/data/www"
server.upload-dirs = ( "/tmp" )
server.errorlog = "/opt/var/log/lighttpd/error.log"
server.pid-file = "/opt/var/run/lighttpd.pid"
server.username = "root"
server.groupname = "root"
# Port 8080 to avoid DD-WRT httpd conflict
server.port = 8080
# MIME types
mimetype.assign = (
".html" => "text/html",
".htm" => "text/html",
".css" => "text/css",
".js" => "application/javascript",
".json" => "application/json",
".txt" => "text/plain",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png",
".gif" => "image/gif",
".svg" => "image/svg+xml",
".pdf" => "application/pdf",
".zip" => "application/zip",
".mp4" => "video/mp4",
".mp3" => "audio/mpeg",
"" => "application/octet-stream"
)
# Index files
index-file.names = ( "index.html", "index.php" )
# FastCGI for PHP
fastcgi.server = (
".php" => (
"localhost" => (
"socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/opt/bin/php-cgi",
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "2",
"PHP_FCGI_MAX_REQUESTS" => "1000"
),
"broken-scriptfilename" => "enable",
"max-procs" => 2,
"idle-timeout" => 600
)
)
)
# Large file support
# Note: DD-WRT lighttpd parser has 32-bit signed integer limit
# Maximum: 2147483647 bytes (2GB - 1 byte)
# Setting to 1GB for safety
server.max-request-size = 1073741824 # 1GB
# Timeouts for large uploads
server.max-write-idle = 600
server.max-read-idle = 600
# Connection limits
server.max-connections = 50
server.max-fds = 256
# Static file caching
$HTTP["url"] =~ "\.(css|js|jpg|jpeg|png|gif|svg|ico)$" {
expire.url = ( "" => "access plus 1 hours" )
}
# Directory listing disabled
dir-listing.activate = "disable"
# Access restrictions
$HTTP["url"] =~ "^/config/" {
url.access-deny = ( "" )
}
$HTTP["url"] =~ "^/data/" {
url.access-deny = ( "" )
}
# Allow uploads directory access
alias.url = (
"/uploads/" => "/mnt/data/www/uploads/"
)
Key Changes from Original:
- Port 8080: Avoids conflict with DD-WRT's httpd
- Document root:
/mnt/data/wwwinstead of/opt/share/www - Max upload size: 1GB instead of 5GB (see Critical Issues)
- User/Group:
root(DD-WRT doesn't havenobodyuser by default)
ssh root@192.168.1.1
# Run database initialization script
/opt/bin/php /mnt/data/www/api/init_db.php
# Expected output:
# Database initialized successfully at /mnt/data/emergencybox.db
# Verify database creation
ls -lh /mnt/data/emergencybox.db
# Check database schema
/opt/bin/sqlite3 /mnt/data/emergencybox.db ".schema"Expected Schema:
CREATE TABLE messages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT DEFAULT NULL,
message TEXT NOT NULL,
priority INTEGER DEFAULT 0,
file_id INTEGER DEFAULT NULL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
path TEXT NOT NULL,
category TEXT NOT NULL,
size INTEGER NOT NULL,
uploaded DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE announcements (
id INTEGER PRIMARY KEY AUTOINCREMENT,
message TEXT NOT NULL,
active INTEGER DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);Critical: If you see errors about timezone database corruption, see Timezone Issue below.
ssh root@192.168.1.1
# Set web directory permissions
chmod -R 755 /mnt/data/www
# Set upload directory permissions (must be writable)
chmod -R 777 /mnt/data/www/uploads
# Set database permissions
chmod 644 /mnt/data/emergencybox.db
chmod 755 /mnt/data
# Verify permissions
ls -la /mnt/data/
ls -la /mnt/data/www/
ls -la /mnt/data/www/uploads/ssh root@192.168.1.1
# Create init script
vi /opt/etc/init.d/S80lighttpdInit script content:
#!/bin/sh
ENABLED=yes
PROCS=lighttpd
ARGS="-f /opt/etc/lighttpd/lighttpd.conf"
PREARGS=""
DESC=$PROCS
PATH=/opt/sbin:/opt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
. /opt/etc/init.d/rc.funcMake executable:
chmod +x /opt/etc/init.d/S80lighttpdUpdate DD-WRT Startup Commands (Administration > Commands > Startup):
#!/bin/sh
# Wait for USB to be ready
sleep 10
# Mount Entware partition
mount /dev/sda1 /opt
# Mount data partition
mount /dev/sda2 /mnt/data
# Start Entware services
/opt/etc/init.d/rc.unslung start
# Start lighttpd
/opt/etc/init.d/S80lighttpd startClick Save Startup.
ssh root@192.168.1.1
# Start lighttpd
/opt/etc/init.d/S80lighttpd start
# Verify lighttpd is running
ps | grep lighttpd
# Expected output:
# 12345 root 0:00 /opt/sbin/lighttpd -f /opt/etc/lighttpd/lighttpd.conf
# 12346 root 0:00 /opt/bin/php-cgi
# Check listening ports
netstat -ln | grep 8080
# Expected output:
# tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN
# Check error log
tail -f /opt/var/log/lighttpd/error.logDuring the real-world deployment of EmergencyBox to an ASUS RT-AC68U router, we encountered several critical issues. This section documents each problem, the investigation process, and the solution.
Symptoms:
- PHP scripts crash with no output
stracereveals:open("/opt/share/zoneinfo/UTC", O_RDONLY) = -1 ENOENT (No such file or directory) write(2, "Timezone database is corrupt - th"..., 87) = 87 exit_group(1)- Database initialization fails silently
Root Cause:
PHP on embedded systems requires timezone data files in /opt/share/zoneinfo/. However, when /dev/sda1 is mounted to /opt, it overlays the filesystem, hiding the original /opt/share/zoneinfo/ directory that was created during Entware installation.
Investigation Process:
-
Ran PHP with
straceto capture system calls:strace /opt/bin/php /mnt/data/www/api/init_db.php 2>&1 | grep -i zone
-
Discovered missing timezone files:
ls /opt/share/zoneinfo/ # Error: No such file or directory -
Checked if files exist on unmounted partition:
umount /opt ls /opt/share/zoneinfo/ # Files exist! mount /dev/sda1 /opt ls /opt/share/zoneinfo/ # Files gone (hidden by mount)
Solution:
Option A: Copy timezone data to mounted partition (IMPLEMENTED)
# Temporarily unmount /opt
umount /opt
# Copy timezone files to a temporary location
cp -r /opt/share/zoneinfo /tmp/
# Remount /opt
mount /dev/sda1 /opt
# Recreate directory structure
mkdir -p /opt/share/zoneinfo
# Copy timezone files back
cp -r /tmp/zoneinfo/* /opt/share/zoneinfo/
# Verify
ls -la /opt/share/zoneinfo/
# Should show timezone files: Africa/, America/, UTC, etc.
# Test PHP
/opt/bin/php -r "echo date('Y-m-d H:i:s');"
# Should output current date/time without errorsOption B: Configure PHP to use system timezone
Edit /opt/etc/php.ini:
date.timezone = "UTC"This tells PHP to use UTC directly without loading timezone database files.
Option C: Use environment variable
export TZ=UTC
/opt/bin/php /mnt/data/www/api/init_db.phpBest Practice: Use a combination of Options A and B for maximum reliability.
Symptoms:
- PHP scripts fail with: "Class 'SQLite3' not found"
php -mdoesn't listsqlite3module- Database operations fail
Root Cause:
PHP couldn't locate the SQLite3 extension library because extension_dir was not configured in php.ini.
Investigation Process:
-
Checked if extension is installed:
/opt/bin/opkg list-installed | grep php7-mod-sqlite3 # Confirmed: php7-mod-sqlite3 is installed
-
Checked PHP modules:
/opt/bin/php -m | grep sqlite # No output - module not loaded
-
Located extension file:
find /opt -name "sqlite3.so" # Found at: /opt/lib/php/sqlite3.so
-
Checked
php.ini:/opt/bin/php --ini # Configuration File (php.ini) Path: /opt/etc # Loaded Configuration File: /opt/etc/php.ini grep extension_dir /opt/etc/php.ini # No output - extension_dir not set!
Solution:
Edit /opt/etc/php.ini and add:
; Extension directory (MUST be set)
extension_dir = "/opt/lib/php"
; Load SQLite3 extension
extension=sqlite3.so
; Load fileinfo extension (for upload file type detection)
extension=fileinfo.soVerify fix:
# Restart PHP-CGI (kill existing processes, lighttpd will restart them)
killall php-cgi
# Check loaded modules
/opt/bin/php -m | grep sqlite3
# Expected output: sqlite3
# Test SQLite3 functionality
/opt/bin/php -r "new SQLite3(':memory:'); echo 'SQLite3 works!';"
# Expected output: SQLite3 works!Symptoms:
- lighttpd fails to start
- Error in log: "config parsing failed" or "value too large"
- Configuration file appears correct
Root Cause:
The lighttpd configuration parser on DD-WRT has a 32-bit signed integer limitation. The original configuration specified:
server.max-request-size = 5368709120 # 5GB in bytes
This value exceeds the maximum 32-bit signed integer (2,147,483,647), causing the parser to fail.
Investigation Process:
-
Attempted to start lighttpd:
/opt/sbin/lighttpd -f /opt/etc/lighttpd/lighttpd.conf -t # Output: configuration parsing failed -
Checked error log:
cat /opt/var/log/lighttpd/error.log # Error: (configfile.c.xxx) value too large at line XX -
Identified the problematic line:
grep -n "max-request-size" /opt/etc/lighttpd/lighttpd.conf # Line 61: server.max-request-size = 5368709120
-
Calculated maximum safe value:
Maximum 32-bit signed integer: 2,147,483,647 bytes (≈ 2GB) Safe value for production: 1,073,741,824 bytes (1GB)
Solution:
Edit /opt/etc/lighttpd/lighttpd.conf:
# Reduced from 5GB to 1GB due to lighttpd parser limitation
server.max-request-size = 1073741824 # 1GB in bytes
Note: If you need to support files larger than 1GB, consider:
- Using alternative web servers (nginx, Apache)
- Implementing chunked upload in JavaScript
- Using a streaming upload approach
- Compiling a custom lighttpd build with 64-bit integer support
Verify fix:
# Test configuration syntax
/opt/sbin/lighttpd -f /opt/etc/lighttpd/lighttpd.conf -t
# Expected output: Syntax OK
# Start lighttpd
/opt/etc/init.d/S80lighttpd start
# Verify running
ps | grep lighttpdSymptoms:
- lighttpd fails to start
- Error: "bind failed: Address already in use"
- Port 80 already occupied
Root Cause:
DD-WRT runs its own HTTP daemon (httpd) on port 80 for the router administration interface. lighttpd cannot bind to port 80 when it's already in use.
Investigation Process:
-
Checked what's listening on port 80:
netstat -ln | grep ":80 " # Output: tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN ps | grep httpd # Output: 1234 root 0:00 httpd
-
Identified DD-WRT's httpd is running
-
Considered options:
- Option A: Disable DD-WRT httpd (NOT RECOMMENDED - breaks admin interface)
- Option B: Change DD-WRT httpd port (possible but affects admin access)
- Option C: Run EmergencyBox on alternate port (RECOMMENDED)
Solution:
Configure lighttpd to run on port 8080 instead of port 80.
Edit /opt/etc/lighttpd/lighttpd.conf:
# Changed from port 80 to 8080
server.port = 8080
Update EmergencyBox URLs:
Users will access EmergencyBox at:
http://192.168.1.1:8080
Router admin interface remains at:
http://192.168.1.1
Advantages of this approach:
- Router admin interface remains accessible
- No DD-WRT configuration changes needed
- Clear separation between router admin and EmergencyBox
- Easy to remember both URLs
Verify fix:
# Start lighttpd
/opt/etc/init.d/S80lighttpd start
# Check listening ports
netstat -ln | grep -E ":(80|8080) "
# Expected:
# tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN (DD-WRT httpd)
# tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN (lighttpd)Symptoms:
- Database file exists but queries fail
- Errors: "no such table: messages"
- Application can't read/write data
Root Cause:
The database file /mnt/data/emergencybox.db was created manually using sqlite3 command-line tool, but the schema didn't match what the PHP application expected. Specifically, the announcements table was missing.
Investigation Process:
-
Checked database existence:
ls -lh /mnt/data/emergencybox.db # File exists -
Examined database schema:
/opt/bin/sqlite3 /mnt/data/emergencybox.db ".schema" # Output showed only 'messages' and 'files' tables # Missing: 'announcements' table
-
Reviewed PHP code in
/mnt/data/www/api/config.php:// Create announcements table $db->exec("CREATE TABLE IF NOT EXISTS announcements ...");
-
Realized the proper initialization required running
init_db.php
Solution:
Always initialize the database using the provided PHP script, not manually:
# Remove any manually created database
rm -f /mnt/data/emergencybox.db
# Initialize properly using PHP script
/opt/bin/php /mnt/data/www/api/init_db.php
# Verify all tables exist
/opt/bin/sqlite3 /mnt/data/emergencybox.db ".tables"
# Expected output: announcements files messagesVerify schema:
/opt/bin/sqlite3 /mnt/data/emergencybox.db ".schema"Should show all three tables with correct structure.
Test database access from PHP:
/opt/bin/php -r '
$db = new SQLite3("/mnt/data/emergencybox.db");
$result = $db->query("SELECT COUNT(*) as count FROM messages");
$row = $result->fetchArray();
echo "Messages: " . $row["count"] . "\n";
'
# Expected output: Messages: 0Symptoms:
- Browser displays PHP source code instead of executing it
- File downloads show
.phpfiles as text - Application doesn't load properly after changes
Root Cause:
Browser caching can serve old responses, particularly if the web server configuration changed (e.g., FastCGI not working initially, then fixed). The browser returns cached responses from before FastCGI was properly configured.
Investigation Process:
-
Tested with
curl(no cache):curl http://192.168.1.1:8080/api/get_messages.php # Output: JSON response (correct) -
Tested in browser:
Shows PHP source code -
Checked browser Network tab:
Status: 200 (from cache) -
Realized browser is serving cached responses
Solution:
Immediate Fix (Client-side):
-
Hard refresh in browser:
- Windows/Linux:
Ctrl + F5orCtrl + Shift + R - Mac:
Cmd + Shift + R
- Windows/Linux:
-
Clear browser cache:
- Chrome: Settings > Privacy and Security > Clear browsing data
- Firefox: Settings > Privacy & Security > Clear Data
-
Use private/incognito mode for testing
Server-side Fix (Prevent caching of dynamic content):
Edit /opt/etc/lighttpd/lighttpd.conf:
# Prevent caching of PHP files
$HTTP["url"] =~ "\.php$" {
setenv.add-response-header = (
"Cache-Control" => "no-cache, no-store, must-revalidate",
"Pragma" => "no-cache",
"Expires" => "0"
)
}
# Cache static files only
$HTTP["url"] =~ "\.(css|js|jpg|jpeg|png|gif|svg|ico)$" {
expire.url = ( "" => "access plus 1 hours" )
}
Verify fix:
# Restart lighttpd
/opt/etc/init.d/S80lighttpd restart
# Test with curl (check headers)
curl -I http://192.168.1.1:8080/api/get_messages.php
# Should show:
# Cache-Control: no-cache, no-store, must-revalidateSymptoms:
- File uploads fail with "Permission denied"
- Error log shows: "failed to create file"
- Upload directory exists but not writable
Root Cause:
Upload directory /mnt/data/www/uploads/ has incorrect permissions, preventing PHP from writing files.
Solution:
ssh root@192.168.1.1
# Set proper permissions on upload directory
chmod -R 777 /mnt/data/www/uploads
# Verify permissions
ls -ld /mnt/data/www/uploads
# Expected: drwxrwxrwx
ls -la /mnt/data/www/uploads/
# All subdirectories should be drwxrwxrwxSecurity Note:
777 permissions (world-writable) are generally insecure, but acceptable in this case because:
- EmergencyBox is designed for offline, trusted environments
- DD-WRT has limited user separation
- The router is not connected to the internet
- All users are considered trusted in disaster relief scenarios
For higher security environments, consider:
- Creating a dedicated user for lighttpd
- Using
755or775permissions with proper group ownership - Implementing file scanning/validation
# Ping router
ping 192.168.1.1
# Test if port 8080 is accessible
curl http://192.168.1.1:8080
# Should return HTML (index.html)ssh root@192.168.1.1
# Check if lighttpd is running
ps | grep lighttpd
# Expected: 2-3 processes (master + workers + php-cgi)
# Check listening ports
netstat -ln | grep 8080
# Expected: LISTEN on 0.0.0.0:8080
# Check logs for errors
tail -20 /opt/var/log/lighttpd/error.log
# Should not show recent errorsssh root@192.168.1.1
# Check database file
ls -lh /mnt/data/emergencybox.db
# Test database access
/opt/bin/sqlite3 /mnt/data/emergencybox.db "SELECT COUNT(*) FROM messages;"
# Should return a number (0 if no messages yet)
# Test PHP database access
/opt/bin/php -r '
$db = new SQLite3("/mnt/data/emergencybox.db");
echo "Database connection: OK\n";
$result = $db->query("SELECT name FROM sqlite_master WHERE type=\"table\"");
while ($row = $result->fetchArray()) {
echo "Table: " . $row["name"] . "\n";
}
'
# Expected output:
# Database connection: OK
# Table: messages
# Table: files
# Table: announcements-
Open browser and navigate to:
http://192.168.1.1:8080 -
Verify interface loads:
- EmergencyBox title visible
- Chat area visible
- File upload section visible
- No JavaScript errors in browser console (F12)
-
Test chat functionality:
- Enter a test message
- Click "Send"
- Message should appear in chat area
- Reload page - message should persist
-
Test priority message:
- Check "Priority" checkbox
- Send message
- Message should appear with red styling
-
Prepare test file:
# On your computer echo "Test file content" > test.txt
-
Upload via web interface:
- Click "Choose File"
- Select
test.txt - Select category (e.g., "General")
- Click "Upload"
- Should show progress bar
- Should show success message
-
Verify upload on router:
ssh root@192.168.1.1 ls -lh /mnt/data/www/uploads/general/ # Should show test.txt cat /mnt/data/www/uploads/general/test.txt # Should show: Test file content
-
Verify database entry:
/opt/bin/sqlite3 /mnt/data/emergencybox.db "SELECT * FROM files;" # Should show entry for test.txt
-
Test download:
- Click on uploaded file in file browser
- File should download
- Content should match original
-
Create large test file (100MB):
# On your computer dd if=/dev/zero of=largefile.bin bs=1M count=100 -
Upload via web interface:
- Upload
largefile.bin - Monitor progress bar
- Should complete without errors
- May take several minutes depending on WiFi speed
- Upload
-
Verify on router:
ssh root@192.168.1.1 ls -lh /mnt/data/www/uploads/general/largefile.bin # Should show ~100M size -
Test download:
- Download the large file
- Verify size matches
- Optional: Verify MD5 checksum
Upload multiple files in succession:
- 5-10 small files (< 10MB each)
- 2-3 medium files (50-100MB each)
- Verify all appear in file browser
- Check disk space:
df -h
-
Connect with multiple devices (phone, tablet, laptop)
-
Each device:
- Navigate to
http://192.168.1.1:8080 - Send chat messages
- Upload files
- Navigate to
-
Verify:
- All devices see all messages
- All devices see all files
- No conflicts or errors
-
Reboot router:
ssh root@192.168.1.1 reboot
-
Wait for reboot (2-3 minutes)
-
Reconnect and verify:
- Services auto-started:
ps | grep lighttpd - Database persists: Previous messages visible
- Files persist: Previous uploads visible
- Web interface accessible
- Services auto-started:
Upload speed test:
# Create 50MB test file
dd if=/dev/zero of=50mb.bin bs=1M count=50
# Time upload (using curl)
time curl -F "file=@50mb.bin" -F "category=general" http://192.168.1.1:8080/api/upload.phpTypical results:
- WiFi 2.4GHz: 3-7 MB/s
- WiFi 5GHz: 10-15 MB/s
- Gigabit Ethernet: 20-40 MB/s
Concurrent user simulation:
# Use Apache Bench (ab) to simulate load
ab -n 100 -c 10 http://192.168.1.1:8080/Monitor router resources:
ssh root@192.168.1.1
top
# Watch CPU and memory usageUse this checklist to verify complete functionality:
- Router accessible via WiFi
- Web interface loads at
http://192.168.1.1:8080 - Can send regular chat messages
- Can send priority chat messages
- Chat messages persist after page reload
- Can upload small file (< 10MB)
- Can upload medium file (50-100MB)
- Can upload large file (500MB-1GB)
- Uploaded files appear in file browser
- Can download uploaded files
- File search works
- Can create custom folders
- Can link files to chat messages
- Multiple devices can connect simultaneously
- All devices see same chat messages
- All devices see same files
- System survives router reboot
- Services auto-start after reboot
- Database persists after reboot
- Uploaded files persist after reboot
- No errors in lighttpd log
- Disk space monitored and adequate
- Router admin interface still accessible at
http://192.168.1.1
Problem: Cannot access http://192.168.1.1:8080
Diagnosis:
ssh root@192.168.1.1
# Check if lighttpd is running
ps | grep lighttpd
# If no output, lighttpd is not running
# Check if port is listening
netstat -ln | grep 8080
# If no output, nothing is listening on port 8080
# Check error log
cat /opt/var/log/lighttpd/error.logSolutions:
-
Start lighttpd:
/opt/etc/init.d/S80lighttpd start
-
Check configuration syntax:
/opt/sbin/lighttpd -t -f /opt/etc/lighttpd/lighttpd.conf
-
Verify document root exists:
ls -la /mnt/data/www/
-
Check PHP-CGI:
/opt/bin/php-cgi -v
-
Restart services:
/opt/etc/init.d/S80lighttpd restart killall php-cgi # Will be restarted by lighttpd
Problem: File uploads time out or fail
Diagnosis:
# Check upload directory permissions
ls -ld /mnt/data/www/uploads/
# Should be: drwxrwxrwx
# Check disk space
df -h /mnt/data
# Ensure sufficient free space
# Check PHP error log
cat /opt/var/log/php-errors.log
# Check lighttpd error log
tail -20 /opt/var/log/lighttpd/error.log
# Test upload with curl
curl -F "file=@test.txt" -F "category=general" http://192.168.1.1:8080/api/upload.phpSolutions:
-
Fix permissions:
chmod -R 777 /mnt/data/www/uploads
-
Increase PHP limits (edit
/opt/etc/php.ini):upload_max_filesize = 1024M post_max_size = 1024M max_execution_time = 600 memory_limit = 128M
-
Check lighttpd max request size (edit
/opt/etc/lighttpd/lighttpd.conf):server.max-request-size = 1073741824 # 1GB -
Free up disk space:
# Delete old uploads rm -rf /mnt/data/www/uploads/general/* # Or expand to larger USB drive
-
Restart services:
/opt/etc/init.d/S80lighttpd restart
Problem: Database queries fail or return errors
Diagnosis:
# Check if database file exists
ls -lh /mnt/data/emergencybox.db
# Check database integrity
/opt/bin/sqlite3 /mnt/data/emergencybox.db "PRAGMA integrity_check;"
# Should output: ok
# Check tables exist
/opt/bin/sqlite3 /mnt/data/emergencybox.db ".tables"
# Should show: announcements files messages
# Check PHP SQLite3 extension
/opt/bin/php -m | grep sqlite3
# Should output: sqlite3Solutions:
-
Reinitialize database:
rm -f /mnt/data/emergencybox.db /opt/bin/php /mnt/data/www/api/init_db.php
-
Fix permissions:
chmod 644 /mnt/data/emergencybox.db chmod 755 /mnt/data
-
Verify extension_dir in php.ini:
grep extension_dir /opt/etc/php.ini # Should show: extension_dir = "/opt/lib/php" -
Reload PHP:
killall php-cgi /opt/etc/init.d/S80lighttpd restart
Problem: After router reboot, EmergencyBox is not accessible
Diagnosis:
ssh root@192.168.1.1
# Check if USB is mounted
df -h | grep sda
# Should show /dev/sda1 on /opt and /dev/sda2 on /mnt/data
# Check if Entware started
ls /opt/bin/opkg
# Should exist
# Check if lighttpd is running
ps | grep lighttpd
# Should show lighttpd processesSolutions:
-
Verify startup script in DD-WRT:
- Navigate to: Administration > Commands
- Check Startup section
- Ensure it contains:
sleep 10 mount /dev/sda1 /opt mount /dev/sda2 /mnt/data /opt/etc/init.d/rc.unslung start /opt/etc/init.d/S80lighttpd start
- Click Save Startup if modified
-
Increase sleep delay (USB may need more time):
sleep 20 # Increase from 10 to 20 seconds -
Manual start for testing:
ssh root@192.168.1.1 mount /dev/sda1 /opt mount /dev/sda2 /mnt/data /opt/etc/init.d/rc.unslung start /opt/etc/init.d/S80lighttpd start
-
Check for errors:
cat /opt/var/log/lighttpd/error.log
Problem: Router crashes or services stop under load
Diagnosis:
ssh root@192.168.1.1
# Check memory usage
free
# Look at "free" column
# Check processes
top
# Press Shift+M to sort by memory
# Press Q to quit
# Check swap
swapon -sSolutions:
-
Create swap file:
# Create 256MB swap file on USB dd if=/dev/zero of=/mnt/data/swapfile bs=1M count=256 chmod 600 /mnt/data/swapfile mkswap /mnt/data/swapfile swapon /mnt/data/swapfile # Add to startup script: swapon /mnt/data/swapfile
-
Reduce PHP memory limit (edit
/opt/etc/php.ini):memory_limit = 64M # Reduce from 128M
-
Reduce concurrent connections (edit
/opt/etc/lighttpd/lighttpd.conf):server.max-connections = 25 # Reduce from 50 -
Reduce PHP workers:
"PHP_FCGI_CHILDREN" => "1", # Reduce from 2 -
Disable unnecessary DD-WRT services:
- Navigate to: Services > Services
- Disable services you don't need (e.g., DLNA, NAS)
Problem: File uploads are slow or interface is laggy
Diagnosis:
# Check CPU usage
top
# Check disk I/O
iostat (if installed)
# Check WiFi signal strength
# From client device, check signal bars or connection info
# Test upload speed
time curl -F "file=@100mb.bin" http://192.168.1.1:8080/api/upload.phpSolutions:
-
Use USB 3.0 port (if available)
-
Format USB as ext4 (not FAT32):
umount /dev/sda1 mkfs.ext4 /dev/sda1 mount /dev/sda1 /opt
-
Optimize WiFi settings:
- Use 5GHz band if supported
- Reduce channel width if interference
- Position router centrally
-
Enable compression (edit
/opt/etc/lighttpd/lighttpd.conf):server.modules += ( "mod_compress" ) compress.cache-dir = "/tmp/lighttpd-compress" compress.filetype = ("text/html", "text/css", "application/javascript") -
Limit concurrent uploads:
- Instruct users to upload one file at a time
- Implement queue in JavaScript
Problem: Browser displays PHP code instead of executing it
Diagnosis:
# Test with curl
curl http://192.168.1.1:8080/api/get_messages.php
# Should return JSON, not PHP code
# Check FastCGI configuration
grep -A 10 "fastcgi.server" /opt/etc/lighttpd/lighttpd.conf
# Check if php-cgi is running
ps | grep php-cgiSolutions:
-
Clear browser cache:
- Hard refresh:
Ctrl + F5(Windows/Linux) orCmd + Shift + R(Mac) - Or use incognito/private mode
- Hard refresh:
-
Verify FastCGI config in
/opt/etc/lighttpd/lighttpd.conf:fastcgi.server = ( ".php" => ( "localhost" => ( "socket" => "/tmp/php-fastcgi.socket", "bin-path" => "/opt/bin/php-cgi", ... ) ) ) -
Restart services:
killall php-cgi /opt/etc/init.d/S80lighttpd restart
-
Check PHP execution:
/opt/bin/php-cgi -v # Should output PHP version
Problem: PHP still crashes with timezone errors after fix
Diagnosis:
# Check if timezone files exist
ls -la /opt/share/zoneinfo/
# Should show directories: Africa, America, Asia, etc.
# Check PHP timezone setting
grep timezone /opt/etc/php.ini
# Should show: date.timezone = "UTC"
# Test PHP date functions
/opt/bin/php -r "echo date('Y-m-d H:i:s');"
# Should output current date without errorsSolutions:
-
Ensure timezone files are on mounted partition:
# Check if files are hidden by mount umount /opt ls /opt/share/zoneinfo/ # Files should exist here # Copy to persistent location cp -r /opt/share/zoneinfo /tmp/ mount /dev/sda1 /opt mkdir -p /opt/share/zoneinfo cp -r /tmp/zoneinfo/* /opt/share/zoneinfo/
-
Set timezone in php.ini:
echo "date.timezone = UTC" >> /opt/etc/php.ini
-
Use environment variable:
# Add to lighttpd FastCGI config: "bin-environment" => ( "TZ" => "UTC", ... )
-
Restart PHP:
killall php-cgi /opt/etc/init.d/S80lighttpd restart
Daily (if actively deployed):
- Monitor disk space:
df -h - Check error logs:
tail /opt/var/log/lighttpd/error.log - Verify services running:
ps | grep lighttpd
Weekly:
- Review uploaded files, delete unnecessary ones
- Clear old chat messages if desired
- Backup database
- Check for package updates:
/opt/bin/opkg update && /opt/bin/opkg list-upgradable
Monthly:
- Update Entware packages:
/opt/bin/opkg upgrade - Review and optimize database
- Test full backup/restore procedure
Backup Database:
# From router
ssh root@192.168.1.1
cp /mnt/data/emergencybox.db /mnt/data/backup-$(date +%Y%m%d).db
# Download to computer
scp root@192.168.1.1:/mnt/data/emergencybox.db ./backup-emergencybox.dbBackup Uploaded Files:
# From computer
rsync -avz root@192.168.1.1:/mnt/data/www/uploads/ ./backup-uploads/
# Or create tar archive on router
ssh root@192.168.1.1 "tar czf /tmp/uploads-backup.tar.gz /mnt/data/www/uploads"
scp root@192.168.1.1:/tmp/uploads-backup.tar.gz ./Full System Backup:
# Backup entire data partition
ssh root@192.168.1.1 "tar czf - /mnt/data" > backup-full-$(date +%Y%m%d).tar.gzConfiguration Backup:
# Backup DD-WRT configuration
# In DD-WRT web interface: Administration > Backup
# Download nvram.bin file
# Backup lighttpd config
scp root@192.168.1.1:/opt/etc/lighttpd/lighttpd.conf ./backup-lighttpd.conf
# Backup PHP config
scp root@192.168.1.1:/opt/etc/php.ini ./backup-php.iniRestore Database:
# Upload backup to router
scp ./backup-emergencybox.db root@192.168.1.1:/mnt/data/emergencybox.db
# Or from router
ssh root@192.168.1.1
cp /mnt/data/backup-20260110.db /mnt/data/emergencybox.db
chmod 644 /mnt/data/emergencybox.dbRestore Files:
# From computer
rsync -avz ./backup-uploads/ root@192.168.1.1:/mnt/data/www/uploads/Vacuum Database (reclaim space, optimize):
ssh root@192.168.1.1
/opt/bin/sqlite3 /mnt/data/emergencybox.db "VACUUM;"Check Database Integrity:
/opt/bin/sqlite3 /mnt/data/emergencybox.db "PRAGMA integrity_check;"
# Should output: okClear Old Messages (keep last 500):
/opt/bin/sqlite3 /mnt/data/emergencybox.db "
DELETE FROM messages
WHERE id NOT IN (
SELECT id FROM messages
ORDER BY timestamp DESC
LIMIT 500
);"Analyze Database (update statistics):
/opt/bin/sqlite3 /mnt/data/emergencybox.db "ANALYZE;"View Logs:
ssh root@192.168.1.1
# lighttpd error log
tail -f /opt/var/log/lighttpd/error.log
# PHP error log (if enabled)
tail -f /opt/var/log/php-errors.log
# System log
logreadClear Logs:
# Clear lighttpd log
> /opt/var/log/lighttpd/error.log
# Clear PHP log
> /opt/var/log/php-errors.logLog Rotation (to prevent disk full):
Create /opt/etc/logrotate.conf:
/opt/var/log/lighttpd/*.log {
daily
rotate 7
compress
missingok
notifempty
}
Check Space:
ssh root@192.168.1.1
# Overall disk usage
df -h
# Data partition usage
du -sh /mnt/data/*
# Upload directory size
du -sh /mnt/data/www/uploads/*
# Database size
ls -lh /mnt/data/emergencybox.dbSet Up Space Alert (optional):
Create /opt/bin/check-space.sh:
#!/bin/sh
USED=$(df /mnt/data | tail -1 | awk '{print $5}' | sed 's/%//')
if [ $USED -gt 80 ]; then
echo "WARNING: Disk usage at ${USED}%"
# Could send notification or log alert
fiAdd to cron (Administration > Management > Cron):
0 * * * * /opt/bin/check-space.sh
Real-time Monitoring:
ssh root@192.168.1.1
# CPU and memory
top
# Disk I/O (if iostat available)
iostat -x 2
# Network connections
netstat -an | grep 8080Log Analysis:
# Count requests per hour
cat /opt/var/log/lighttpd/access.log | awk '{print $4}' | cut -d: -f1-2 | sort | uniq -c
# Most accessed URLs
cat /opt/var/log/lighttpd/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -10
# Error rate
grep -c "error" /opt/var/log/lighttpd/error.logEmergencyBox is designed for trusted, offline environments. However, for added security:
1. Change Default Passwords:
# DD-WRT admin password
# Via web interface: Administration > Management
# WiFi password
# Via web interface: Wireless > Wireless Security2. Disable Unnecessary Services:
# In DD-WRT: Services > Services
# Disable: Telnet (keep SSH only), UPnP, DLNA, etc.3. Enable HTTPS (advanced, requires certificate):
# Generate self-signed certificate
/opt/bin/opkg install openssl-util
openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes
# Configure lighttpd for SSL
# Edit /opt/etc/lighttpd/lighttpd.conf:
server.modules += ( "mod_openssl" )
ssl.engine = "enable"
ssl.pemfile = "/opt/etc/lighttpd/server.pem"
server.port = 84434. Input Validation (already implemented in PHP):
- SQL injection prevention (parameterized queries)
- Path traversal protection
- File type validation
5. Rate Limiting (advanced):
Install and configure mod_evasive or implement in JavaScript.
Update Application Files:
# From your computer (in project directory)
scp -r www/* root@192.168.1.1:/mnt/data/www/
# Restart lighttpd
ssh root@192.168.1.1 "/opt/etc/init.d/S80lighttpd restart"Update Configuration:
# Backup current config
ssh root@192.168.1.1 "cp /opt/etc/lighttpd/lighttpd.conf /opt/etc/lighttpd/lighttpd.conf.bak"
# Upload new config
scp config/lighttpd.conf root@192.168.1.1:/opt/etc/lighttpd/lighttpd.conf
# Restart
ssh root@192.168.1.1 "/opt/etc/init.d/S80lighttpd restart"Update PHP Packages:
ssh root@192.168.1.1
# Update package list
/opt/bin/opkg update
# List upgradable packages
/opt/bin/opkg list-upgradable
# Upgrade specific package
/opt/bin/opkg upgrade php7-cli php7-cgi
# Restart services
killall php-cgi
/opt/etc/init.d/S80lighttpd restartIf everything breaks and you need to start over:
# From router
ssh root@192.168.1.1
# Stop services
/opt/etc/init.d/S80lighttpd stop
killall lighttpd php-cgi
# Unmount USB
umount /opt
umount /mnt/data
# Remove USB drive physically
# Reformat USB drive on computer
# Follow deployment guide from Phase 2DD-WRT Factory Reset:
- Administration > Factory Defaults
- Click "Yes" to reset
- Router will reboot with default settings
- You'll need to reconfigure everything from scratch
Service Control:
/opt/etc/init.d/S80lighttpd start
/opt/etc/init.d/S80lighttpd stop
/opt/etc/init.d/S80lighttpd restart
/opt/etc/init.d/S80lighttpd statusProcess Management:
ps | grep lighttpd # Check if lighttpd running
killall lighttpd # Kill all lighttpd processes
killall php-cgi # Kill all PHP-CGI processesFile Locations:
/mnt/data/www/ # Web application root
/mnt/data/emergencybox.db # SQLite database
/opt/etc/lighttpd/lighttpd.conf # Web server config
/opt/etc/php.ini # PHP config
/opt/var/log/lighttpd/error.log # Error logDatabase Commands:
/opt/bin/sqlite3 /mnt/data/emergencybox.db ".tables"
/opt/bin/sqlite3 /mnt/data/emergencybox.db ".schema"
/opt/bin/sqlite3 /mnt/data/emergencybox.db "SELECT * FROM messages;"| Port | Service | Purpose |
|---|---|---|
| 22 | SSH | Remote administration (after password set) |
| 23 | Telnet | Initial configuration (first boot only) |
| 53 | DNS | DD-WRT DNS server |
| 80 | HTTP | DD-WRT admin interface |
| 8080 | HTTP | EmergencyBox web interface |
| Component | Limit | Reason |
|---|---|---|
PHP upload_max_filesize |
1024M | Recommended for 256MB RAM |
PHP post_max_size |
1024M | Must be ≥ upload_max_filesize |
lighttpd max-request-size |
1073741824 (1GB) | Parser limitation (32-bit signed int) |
| Practical upload limit | ~500MB | Performance and stability |
# Show system info
cat /proc/cpuinfo
cat /proc/meminfo
uname -a
# Show network info
ifconfig
iwconfig
# Show USB devices
lsusb
ls -l /dev/sd*
# Show mounted filesystems
mount
df -h
# Show running processes
ps
top
# Show network connections
netstat -an
# System logs
logread
dmesg- Web Interface:
http://192.168.1.1:8080 - API Endpoints:
http://192.168.1.1:8080/api/send_message.phphttp://192.168.1.1:8080/api/get_messages.phphttp://192.168.1.1:8080/api/upload.phphttp://192.168.1.1:8080/api/get_files.phphttp://192.168.1.1:8080/api/init_db.php
- Uploads:
http://192.168.1.1:8080/uploads/
DD-WRT:
- Official Site: https://dd-wrt.com/
- Wiki: https://wiki.dd-wrt.com/
- Forums: https://forum.dd-wrt.com/
Entware:
- Project Site: https://github.com/Entware/Entware
- Package List: https://bin.entware.net/armv7sf-k3.2/Packages.html
lighttpd:
- Documentation: https://redmine.lighttpd.net/projects/lighttpd/wiki
PHP:
EmergencyBox:
- Project Repository: (your GitHub URL)
- Documentation:
/docsfolder
You now have a complete, production-ready EmergencyBox deployment on your ASUS RT-AC68U router. This system provides:
- Offline communication: Group chat without internet
- File sharing: Up to 1GB file uploads
- Persistence: All data survives reboots
- Multi-user: Supports 20-50 concurrent users
- Reliability: Thoroughly tested and documented
Key Lessons Learned:
- Two-partition USB setup prevents data loss from mount overlays
- Timezone data must be on the mounted partition
- PHP extensions require explicit
extension_dirconfiguration - lighttpd has parser limitations requiring reduced file size limits
- Port conflicts require running on alternate ports
- Browser caching can mask configuration issues
- Database schema must match application expectations
Next Steps:
- Print this guide for offline reference
- Train coordinators on using EmergencyBox
- Test with real users in simulated disaster scenario
- Create backup router with identical configuration
- Plan for storage management and data retention
For Support:
- Review Troubleshooting section
- Check logs:
/opt/var/log/lighttpd/error.log - Consult DD-WRT forums for router-specific issues
- Refer to existing documentation in
/docs
Remember: EmergencyBox is designed for disaster relief scenarios. Deploy responsibly, test thoroughly, and always have a backup plan.
Document Version: 1.0 Last Updated: 2026-01-10 Tested On: ASUS RT-AC68U with DD-WRT Status: Production-Ready