Gateway-to-NAS Rsync Setup Guide
See also:
- SEP-024: Gateway Data Sync Service for the event-driven sync architecture
- SEP-012: Gateway-to-Storage Data Transport for the broader transport architecture
This guide configures rsync-over-SSH for gateways to push Parquet data to the central NAS. This is the preferred transport method (not NFS) because:
- Works reliably over VPN connections
- Handles interruptions gracefully (
--partialflag for resume) - SSH keys provide per-device authentication
- Clean separation: rsync for transport, container for analysis
Architecture
Gateway (writes locally) --[rsync/SSH via VPN]--> NAS (/volume1/eq/data/)
|
v
Data Lake container
(read-only mount)
Gateway Configuration
Rsync settings are stored in Redis via eq config:
# View current settings
eq config get storage.rsync
# Configure manually (usually done by provisioning from setup.yml)
eq config set storage.rsync.enabled true
eq config set storage.rsync.host 172.16.0.10
eq config set storage.rsync.user eqd
eq config set storage.rsync.path /volume1/eq/data/EQG-0001
Provisioning reads from /var/lib/eq-synapse/setup.yml (or template at /usr/lib/eq-gateway/setup.yml) and writes to Redis:
storage:
data_path: /mnt/eqdata
local_retention_days: 30 # Keep 30 days locally, prune after rsync
rsync:
enabled: true
target_host: "172.16.0.10" # NAS IP (Synology at nas/172.16.0.10)
target_user: "eqd" # SSH user on NAS
target_path: "/volume1/eq/data/EQG-0001" # Device-specific path
SSH Key Setup (Per Gateway)
On the gateway, the SSH key is generated automatically during provisioning at /var/lib/eq-synapse/.ssh/id_nas. To copy it to the NAS:
# Copy public key to NAS
sudo ssh-copy-id -i /var/lib/eq-synapse/.ssh/id_nas.pub eqd@172.16.0.10
If the key needs to be regenerated manually:
sudo ssh-keygen -t ed25519 -f /var/lib/eq-synapse/.ssh/id_nas -N "" -C "EQG-0001@eq.systems"
On the NAS, verify the key was added:
cat /var/services/homes/eqd/.ssh/authorized_keys
✅ NAS Setup (One-Time or Periodic Maintenance)
1. Set ownership to root:eqd
Ensure company-level control and consistent group access:
sudo chown -R root:eqd /volume1/eq/data/
2. Set directory permissions to rwxrwsr-x (2775)
Sets the setgid bit so new files/dirs inherit the eqd group:
sudo find /volume1/eq/data/ -type d -exec chmod 2775 {} \;
3. Set file permissions to rw-rw-r-- (664)
Gives read/write to group; others get read-only:
sudo find /volume1/eq/data/ -type f -exec chmod 664 {} \;
✅ Rsync Command (From Gateway to NAS)
To transfer data from the gateway to the Synology NAS without permission errors and without altering group ownership or permissions, use:
rsync -e "ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=3" -avP --bwlimit=1500 --partial --no-owner --no-perms --no-times \
/mnt/eqdata/ \
kdavies@172.16.0.10:/volume1/eq/data/AD-Nagasaki-Furnace/
Replaces kdavies with your user id on the NAS.
Notes:
--no-perms --no-times: Prevents rsync from trying to set file permissions or timestamps, avoidingOperation not permittederrors from NFS.- Files will inherit
eqdgroup ownership if:- The destination directory has the
setgidbit set:sudo chmod -R g+s /volume1/eq/data - And has the correct group:
sudo chown -R root:eqd /volume1/eq/data
- The destination directory has the
- Confirm that
kdaviesis in theeqdgroup on the NAS:id kdavies - You may optionally add
--bwlimit=1500to limit bandwidth:rsync -avP --no-perms --no-times --bwlimit=1500 ...
🔁 Optional: Post-Rsync Fix-Up (if needed)
To re-normalize permissions:
sudo chown -R root:eqd /volume1/eq/data/AD-Nagasaki-Furnace/
sudo find /volume1/eq/data/AD-Nagasaki-Furnace/ -type d -exec chmod 2775 {} \;
sudo find /volume1/eq/data/AD-Nagasaki-Furnace/ -type f -exec chmod 664 {} \;
Automated Rsync (Event-Driven Service)
When rsync is enabled in setup.yml, provisioning automatically:
- Writes rsync settings to Redis via
eq config set storage.rsync.* - Enables
eq-synapse-sync.service(event-driven, runs continuously)
The sync service reads config from Redis (ground truth) and uses Redis pub/sub (SEP-024) for near-realtime sync:
- Writers LPUSH file paths to
eq:files:readywhen complete - Sync service uses BLPOP to wait efficiently for files
- Files are synced immediately on arrival (no polling, no batching)
View/modify config:
eq config get storage.rsync
eq config set storage.rsync.enabled true
Check service status:
systemctl status eq-synapse-sync.service
eq system status # Shows sync in "Data Sync" group
View logs:
journalctl -u eq-synapse-sync.service -f
File state tracking:
data/cpow/2024-01-15_14.parquet.active # Currently being written (incomplete)
data/cpow/2024-01-15_13.parquet # Complete, pending sync
data/cpow/synced/2024-01-15_12.parquet # Uploaded to NAS
This ensures:
- Incomplete files (
.activesuffix) are never queued for sync - Files are synced within 1-2 minutes of completion
- Synced files moved to
synced/subfolder, safe for disk manager to delete first
VPN Connectivity
Rsync runs over the VPN tunnel:
- Current: WireGuard (NAS at
172.16.0.10) - Future: Nebula mesh (device identity via certificates)
When migrating to Nebula, the SSH keys become optional since Nebula handles device authentication. However, keeping SSH keys provides defense-in-depth.
Troubleshooting
Connection refused:
# Check VPN is up
ping 172.16.0.10
# Check SSH works
ssh -i /var/lib/eq-synapse/.ssh/id_nas eqd@172.16.0.10 "ls -la /volume1/eq/data/"
Permission denied:
# Verify key is authorized on NAS
ssh eqd@172.16.0.10 "cat ~/.ssh/authorized_keys"
# Check NAS directory permissions
ssh eqd@172.16.0.10 "ls -la /volume1/eq/data/"
Partial files after interruption:
# Resume with --partial (already in our rsync flags)
rsync -avP --partial ...
© 2026 EQ Systems Inc.