Every five minutes, the Raspberry Pi system at the lake sends a short timelapse segment to Scootercam’s webserver. Here’s what happens next.
Security-Hardened Timelapse System
A PHP-based timelapse video management system that receives video segments from cameras and combines them into daily period videos with automatic 8-hour rotation and comprehensive security controls.
Overview
This system manages timelapse videos from multiple cameras with enterprise-grade security by:
- Receiving authenticated video segments via HTTP uploads
- Appending segments to period-based daily videos
- Auto-rotating videos every 8 hours via cron
- Archiving completed videos for long-term storage
- Comprehensive security logging and monitoring
- Rate limiting and access controls
System Architecture
Cameras: 2 (Amcrest, Reolink)
Periods: 3 per day (Night: 00:00-08:00, Day: 08:00-16:00, Evening: 16:00-24:00)
Total Videos: Maximum 6 active videos at any time
Rotation: Every 8 hours via cron (00:00, 08:00, 16:00)
Security: Two-tier API key authentication, rate limiting, comprehensive validation
Directory Structure
/home/scootercam/public_html/timelapse/
├── upload.php # Main secure script
├── videos/ # Active videos (max 6 files)
│ ├── amcrest_day_20250901.mp4
│ ├── amcrest_evening_20250901.mp4
│ ├── amcrest_night_20250902.mp4
│ ├── reolink_day_20250901.mp4
│ ├── reolink_evening_20250901.mp4
│ └── reolink_night_20250902.mp4
├── videos/archive/ # Archived videos
│ ├── amcrest_day_20250831_235959.mp4
│ └── reolink_evening_20250831_235959.mp4
├── temp/ # Temporary processing files
├── security.log # Security audit trail
└── rate_limit.json # Rate limiting data
Security Features
🔐 Two-Tier API Authentication
- Upload Key: Cameras can upload segments and basic operations
- Admin Key: Full system control including rotation and status
🛡️ Comprehensive File Validation
- File size limits (50MB maximum)
- MIME type verification (video/mp4, video/quicktime)
- File header validation (MP4 format check)
- Upload method verification
- Path traversal protection
⚡ Rate Limiting
- Maximum 10 uploads per minute per IP address
- Automatic blocking of excessive requests
- Rate limit data logging and monitoring
📊 Security Monitoring
- All access attempts logged with IP tracking
- Suspicious activity alerts
- Failed authentication tracking
- File operation audit trail
🔒 Input Sanitization
- Strict camera name validation (whitelist only)
- Command injection prevention
- Path traversal protection
- Error information hiding
Setup
1. Generate API Keys
# Generate secure upload key (64 characters)
openssl rand -hex 32
# Generate secure admin key (64 characters)
openssl rand -hex 32
2. Configure Script
Edit upload.php
and replace the placeholder API keys:
private $api_keys = [
'upload' => 'your_64_char_upload_key_here',
'admin' => 'your_64_char_admin_key_here'
];
3. Set File Permissions
chmod 755 /home/scootercam/public_html/timelapse/upload.php
chmod 750 /home/scootercam/public_html/timelapse/videos
chmod 750 /home/scootercam/public_html/timelapse/temp
chmod 640 /home/scootercam/public_html/timelapse/security.log
chown -R scootercam:scootercam /home/scootercam/public_html/timelapse/
4. Update Cron Job
# Replace with your actual admin API key
0 0,8,16 * * * /usr/bin/curl --silent "http://scootercam.net/timelapse/upload.php?action=rotate&api_key=YOUR_ADMIN_KEY_HERE" > /dev/null 2>&1
5. Configure Web Server Security
Add to .htaccess
:
# Deny access to sensitive files
<Files "security.log">
Deny from all
</Files>
<Files "rate_limit.json">
Deny from all
</Files>
# Optional: Basic DDoS protection
<IfModule mod_evasive24.c>
DOSPageCount 5
DOSPageInterval 1
DOSBlockingPeriod 300
</IfModule>
6. Verify FFmpeg
which ffmpeg
# Should return: /bin/ffmpeg
API Endpoints
Upload Video Segment
POST upload.php?action=receive
(default)
Authentication: Upload or Admin API key required
Parameters:
camera
(POST):amcrest
orreolink
api_key
(POST): Valid upload or admin API keyvideo
(FILE): MP4 video segment (max 50MB)
Response:
{
"status": "success",
"message": "Segment appended",
"period": "day",
"camera": "amcrest"
}
Example:
curl -X POST \
-F "camera=amcrest" \
-F "api_key=your_upload_key_here" \
-F "video=@segment.mp4" \
http://scootercam.net/timelapse/upload.php
Security Validations:
- API key authentication
- Rate limiting (10 requests/minute/IP)
- File type validation (MP4/MOV only)
- File size validation (≤50MB)
- MIME type verification
- File header validation
Manual Rotation
GET upload.php?action=rotate&api_key=ADMIN_KEY
Authentication: Admin API key required
Moves all active videos to archive directory.
Response:
{
"status": "success",
"message": "Rotated 6 videos"
}
Example:
curl "http://scootercam.net/timelapse/upload.php?action=rotate&api_key=your_admin_key_here"
System Status
GET upload.php?action=status&api_key=ADMIN_KEY
Authentication: Admin API key required
Response:
{
"status": "success",
"current_period": "day",
"videos": [
{
"camera": "amcrest",
"period": "day",
"exists": true,
"size": 15728640,
"modified": "2025-09-01 14:30:15"
}
]
}
Archive Cleanup
GET upload.php?action=cleanup&days=7&api_key=ADMIN_KEY
Authentication: Admin API key required
Deletes archive files older than specified days (1-30 day range enforced).
Response:
{
"status": "success",
"message": "Deleted 12 old archive files"
}
Example:
curl "http://scootercam.net/timelapse/upload.php?action=cleanup&days=5&api_key=your_admin_key_here"
How It Works
1. Secure Upload Process
- Rate Limiting: Check IP hasn’t exceeded 10 uploads/minute
- Authentication: Validate API key (upload or admin level)
- File Validation: Comprehensive security checks on uploaded file
- Camera Validation: Ensure camera name is in allowed whitelist
- Period Detection: Determine current time period (night/day/evening)
- Secure Processing: Append to appropriate daily video using validated paths
- Cleanup: Remove temporary files and log successful operation
2. Video Concatenation
Uses FFmpeg’s concat demuxer with security controls:
ffmpeg -f concat -safe 0 -i concat_list.txt -c copy -avoid_negative_ts make_zero output.mp4
3. Automatic Rotation
- Cron triggers rotation every 8 hours with admin API key
- All videos in
/videos/
moved to/videos/archive/
with timestamp - Security logging of rotation operations
- Fresh videos created as new segments arrive
4. Security Monitoring
- All operations logged to
security.log
with timestamps and IP addresses - Rate limiting data tracked in
rate_limit.json
- Failed authentication attempts logged as warnings
- Suspicious activity (invalid files, path traversal attempts) logged as errors
5. File Naming Convention
Active Videos: {camera}_{period}_{date}.mp4
amcrest_day_20250901.mp4
Archived Videos: {camera}_{period}_{date}_{time}.mp4
amcrest_day_20250901_160002.mp4
Camera Configuration
Update Camera Upload Scripts
Cameras must now include API keys in their upload requests:
Amcrest Camera:
#!/bin/bash
API_KEY="your_upload_key_here"
CAMERA="amcrest"
SEGMENT="/path/to/segment.mp4"
curl -X POST \
-F "camera=${CAMERA}" \
-F "api_key=${API_KEY}" \
-F "video=@${SEGMENT}" \
http://scootercam.net/timelapse/upload.php
Reolink Camera:
#!/bin/bash
API_KEY="your_upload_key_here"
CAMERA="reolink"
SEGMENT="/path/to/segment.mp4"
curl -X POST \
-F "camera=${CAMERA}" \
-F "api_key=${API_KEY}" \
-F "video=@${SEGMENT}" \
http://scootercam.net/timelapse/upload.php
Monitoring
Security Log Monitoring
# Real-time security monitoring
tail -f /home/scootercam/public_html/timelapse/security.log
# Check for suspicious activity
grep "WARNING\|ERROR" /home/scootercam/public_html/timelapse/security.log
# Monitor rate limiting
grep "Rate limit" /home/scootercam/public_html/timelapse/security.log
System Status Monitoring
# Check current system status (requires admin key)
curl "http://scootercam.net/timelapse/upload.php?action=status&api_key=your_admin_key_here"
# Verify active video count (should be ≤6)
ls -la /home/scootercam/public_html/timelapse/videos/*.mp4 | wc -l
Disk Usage Monitoring
# Check active videos disk usage
du -sh /home/scootercam/public_html/timelapse/videos/
# Check archive disk usage
du -sh /home/scootercam/public_html/timelapse/videos/archive/
# Overall system disk usage
df -h
Performance Monitoring
# Check recent uploads (last 24 hours)
find /home/scootercam/public_html/timelapse/videos/ -name "*.mp4" -mtime -1 -ls
# Monitor temp directory (should be empty most of the time)
ls -la /home/scootercam/public_html/timelapse/temp/
Troubleshooting
Problem: Upload Rejected (401 Unauthorized)
Cause: Invalid or missing API key
Solution:
- Verify API key in camera configuration
- Check
security.log
for failed authentication attempts - Ensure API key matches configuration in
upload.php
Problem: Upload Rejected (429 Rate Limited)
Cause: Too many requests from same IP
Solution:
- Check rate limiting in
security.log
- Wait for rate limit reset (1 minute)
- Investigate if camera is sending duplicate requests
Problem: Upload Rejected (400 Bad Request)
Cause: File validation failure
Solution:
- Check file size (must be ≤50MB)
- Verify file format (MP4/MOV only)
- Ensure camera name is valid (
amcrest
orreolink
) - Check
security.log
for specific validation errors
Problem: FFmpeg Concatenation Failures
Check:
- FFmpeg availability:
which ffmpeg
- Temporary directory permissions:
ls -la temp/
- Video codec compatibility
- Security log for FFmpeg errors
Problem: Too Many Active Videos (>6)
Solution: Force rotation
curl "http://scootercam.net/timelapse/upload.php?action=rotate&api_key=your_admin_key_here"
Problem: Large Archive Directory
Solution: Clean old archives
curl "http://scootercam.net/timelapse/upload.php?action=cleanup&days=5&api_key=your_admin_key_here"
Security Incident Response
Suspicious Activity Detection
Monitor security.log
for these indicators:
- Multiple failed authentication attempts from same IP
- Invalid file upload attempts
- Path traversal attempts
- Unusual upload patterns or timing
Immediate Response Actions
- Block suspicious IPs at firewall level
- Rotate API keys if compromised
- Review and analyze security logs
- Verify system integrity
API Key Compromise Response
# 1. Generate new API keys
openssl rand -hex 32 # New upload key
openssl rand -hex 32 # New admin key
# 2. Update upload.php with new keys
# 3. Update camera configurations
# 4. Update cron job with new admin key
# 5. Clear rate limiting data
rm -f /home/scootercam/public_html/timelapse/rate_limit.json
Maintenance
Daily Tasks
- Monitor security log for suspicious activity
- Verify 6 or fewer active videos exist
- Check cron rotation is working (00:00, 08:00, 16:00)
- Monitor disk usage
Weekly Tasks
- Review security log trends
- Clean old archives (automated with API call)
- Verify video quality and completeness
- Update API keys if security policy requires
Monthly Tasks
- Security audit and log analysis
- Performance optimization review
- Archive storage management
- System backup verification
Emergency Procedures
Complete System Reset:
# 1. Backup all data
mkdir /home/scootercam/timelapse_emergency_backup
cp -r /home/scootercam/public_html/timelapse/* /home/scootercam/timelapse_emergency_backup/
# 2. Stop all uploads temporarily (block at firewall)
# 3. Force rotation with admin key
curl "http://scootercam.net/timelapse/upload.php?action=rotate&api_key=your_admin_key_here"
# 4. Clear rate limiting
rm -f /home/scootercam/public_html/timelapse/rate_limit.json
# 5. Restart system monitoring
Expected Performance
File Sizes (approximate):
- 8-hour period video: 15-25 MB
- Daily total per camera: 45-75 MB
- Archive growth: ~100-150 MB per day
Processing Performance:
- Segment append: <2 seconds
- Authentication check: <0.1 seconds
- File validation: <0.5 seconds
- Rotation: <10 seconds for all videos
- Rate limiting check: <0.1 seconds
Security Overhead:
- Minimal performance impact (<5% processing overhead)
- Comprehensive logging with efficient file I/O
- Rate limiting with memory-efficient tracking
Compliance & Auditing
Security Audit Trail
All operations are logged with:
- Timestamp (Y-m-d H:i:s format)
- Client IP address (with proxy detection)
- Action performed
- Success/failure status
- Error details (for failures)
Log Retention
- Security logs: Recommend 90-day retention minimum
- Rate limit data: Automatic cleanup (5 minutes retention)
- Archive videos: Configurable cleanup (default 7 days)
Access Control Summary
- Upload Operations: Upload or Admin API key required
- System Status: Admin API key required
- Manual Rotation: Admin API key required
- Archive Cleanup: Admin API key required
- Log Access: File system level permissions
Version History
v3.0 – Security-Hardened System
- Added two-tier API key authentication
- Implemented comprehensive file validation
- Added rate limiting per IP address
- Security logging and audit trail
- Path traversal protection
- Command injection prevention
- Input sanitization and validation
- Error information hiding
- File size and type restrictions
v2.0 – Simplified System
- Removed sunset/golden hour logic
- Fixed multiple file creation issue
- Improved cron-based rotation
- Added status monitoring endpoint
v1.0 – Original System
- Basic file upload and concatenation
- Manual rotation support
- Archive functionality