Forward Secure Sealing
Forward Secure Sealing (FSS) provides cryptographic tamper-evidence for Ghaf audit logs. It uses HMAC-SHA256 chains to seal journal entries at regular intervals, ensuring any modification to sealed entries is detectable.
Overview
Section titled “Overview”FSS addresses a critical security requirement: ensuring audit logs cannot be tampered with by attackers who gain root access. Traditional logging provides no cryptographic guarantees—an attacker can modify or delete entries without detection. FSS solves this by:
- Cryptographic sealing: Journal entries are sealed with HMAC-SHA256 at configurable intervals
- Forward security: The sealing key evolves forward; compromising the current key cannot forge past entries
- Per-component isolation: Each Ghaf component (host and VMs) maintains independent FSS keys
Configuration
Section titled “Configuration”FSS is automatically enabled when ghaf.logging.enable = true. Configuration options:
ghaf.logging.fss = { enable = true; # Enable FSS (default: follows ghaf.logging.enable) sealInterval = "15min"; # Interval between seals (default: 15min) verifyOnBoot = true; # Run verification on boot (default: true) verifySchedule = "hourly"; # Periodic verification schedule (default: hourly)};Seal Interval Considerations
Section titled “Seal Interval Considerations”| Interval | Tamper Granularity | Storage Overhead | Verification Time |
|---|---|---|---|
| 5min | Fine | Higher (~2%) | Longer |
| 15min | Moderate | Moderate (~0.5%) | Moderate |
| 1h | Coarse | Lower (~0.1%) | Faster |
Key Management
Section titled “Key Management”Key Locations
Section titled “Key Locations”| Component | Sealing Key | Verification Key |
|---|---|---|
| Host | /var/log/journal/<id>/fss | /persist/common/journal-fss/ghaf-host/verification-key |
| VMs | /var/log/journal/<id>/fss | /etc/common/journal-fss/<vm-name>/verification-key |
Verification Key Backup
Section titled “Verification Key Backup”Critical: Back up verification keys to secure offline storage immediately after first boot.
# On host, copy all verification keyscp -r /persist/common/journal-fss/ /secure-backup/
# Or for a specific componentcat /persist/common/journal-fss/ghaf-host/verification-keyThe verification key enables:
- Independent verification of exported journal archives
- Audit by external parties without access to the live system
- Disaster recovery verification
Operations
Section titled “Operations”Manual Verification
Section titled “Manual Verification”# Basic verification (uses local key)journalctl --verify
# Verify with explicit keyjournalctl --verify --verify-key=$(cat /persist/common/journal-fss/ghaf-host/verification-key)Service Status
Section titled “Service Status”# Check FSS setup statussystemctl status journal-fss-setup
# Check verification timersystemctl list-timers journal-fss-verify
# View FSS-related logsjournalctl -t journal-fssHardware Testing
Section titled “Hardware Testing”A test script is available for deployed systems:
# Build the testnix build .#checks.x86_64-linux.fss-test
# Deploy and runscp result/bin/fss-test root@ghaf-host:/tmp/ssh root@ghaf-host /tmp/fss-testThe test verifies:
- FSS setup service completed
- Sealing key exists
- Verification key extracted
- Initialization sentinel present
- Journal integrity passes
- Verification timer active
- Audit rules configured
Key Rotation
Section titled “Key Rotation”Key rotation destroys the existing tamper-evidence chain. Only rotate when necessary:
# 1. Archive and verify existing journalsjournalctl --verifyjournalctl -o export > /backup/journal-archive-$(date +%Y%m%d).export
# 2. Remove initialization sentinelrm /persist/common/journal-fss/ghaf-host/initialized
# 3. Clear sealing key (optional, regenerated on boot)rm /var/log/journal/*/fss
# 4. Reboot to regenerate keysreboot
# 5. Backup new verification keycat /persist/common/journal-fss/ghaf-host/verification-key > /secure-backup/Offline Verification
Section titled “Offline Verification”To verify journals on a separate system:
# On the Ghaf system: export journalsjournalctl -o export > journal.export
# Transfer journal.export and verification-key to verification system
# On verification system: verify the exportjournalctl --verify --verify-key=<verification-key> --file=journal.exportTroubleshooting
Section titled “Troubleshooting”Verification Fails with “FAIL”
Section titled “Verification Fails with “FAIL””Indicates potential tampering or corruption:
# Check which files failedjournalctl --verify 2>&1 | grep FAIL
# If only .journal~ files fail, these are temp files (not critical)# Real failures affect .journal files“Failed to parse seed” Error
Section titled ““Failed to parse seed” Error”The verification key is malformed:
# Check key format (should be ~35 bytes with '/' separator)cat /persist/common/journal-fss/ghaf-host/verification-key | wc -c
# Regenerate if necessary (see Key Rotation above)Service Not Starting
Section titled “Service Not Starting”# Check conditionssystemctl show journal-fss-setup --property=ConditionResult
# Common issues:# - /var/log/journal not writable (check permissions)# - Already initialized (check for initialized sentinel)Security Considerations
Section titled “Security Considerations”What FSS Protects Against
Section titled “What FSS Protects Against”- Modification of sealed log entries
- Insertion of false entries into sealed ranges
- Backdating of events
What FSS Does Not Protect Against
Section titled “What FSS Does Not Protect Against”- Deletion of entire journal files (mitigated by remote log forwarding)
- Real-time tampering before sealing (mitigated by short seal intervals)
- Denial of service against logging
Audit Integration
Section titled “Audit Integration”FSS integrates with Ghaf’s audit subsystem. The following events are monitored:
journal_fss_keys: Write/attribute changes to FSS key directoryjournal_sealed_logs: Write/attribute changes to journal filesmachine_id_read: Reads of machine-id (used in journal path)