使用Unison/Rsync实现SFTP上传用户与开发者目录的镜像同步
Alright, let's break down a concrete, working solution for your two-user sync scenario—this is a super common setup, and we can get it running smoothly with rsync (for syncing) and inotifywait (for real-time change detection), plus proper user permissions. Here's the step-by-step playbook:
First, let's create your two users and lock down their permissions properly:
- Create the SFTP upload user (restricted to SFTP only, no shell access):
sudo useradd -m sftp_upload -s /usr/sbin/nologin sudo passwd sftp_upload - Create the developer user:
sudo useradd -m dev_user sudo passwd dev_user - Create a shared group to ensure both users can access the sync directories:
sudo groupadd sync_group sudo usermod -aG sync_group sftp_upload sudo usermod -aG sync_group dev_user - Set up the sync directories with correct permissions:
# SFTP upload root (chrooted for security) sudo mkdir -p /sftp/uploads sudo chown sftp_upload:sync_group /sftp/uploads sudo chmod g+rwx /sftp/uploads sudo chown root:root /sftp # Required for chroot to work # Developer working directory sudo mkdir -p /dev/files sudo chown dev_user:sync_group /dev/files sudo chmod g+rwx /dev/files
To make sure the sftp_upload user can only upload files (no editing/deleting existing files via SFTP, no shell access), edit your SSH config:
Open /etc/ssh/sshd_config with your favorite editor, then add this block at the bottom:
Match User sftp_upload ForceCommand internal-sftp PasswordAuthentication yes ChrootDirectory /sftp PermitTunnel no AllowAgentForwarding no AllowTcpForwarding no X11Forwarding no
Restart SSH to apply changes:
sudo systemctl restart sshd
Now sftp_upload can only connect via SFTP, and their "root" directory will be /sftp—so they'll only see the uploads folder and can upload/create folders there.
We'll use inotifywait (part of inotify-tools) to monitor directory changes, and trigger rsync to sync the changes instantly.
First, install inotify-tools:
- Debian/Ubuntu:
sudo apt install inotify-tools - RHEL/CentOS/Rocky:
sudo yum install inotify-tools
Script 1: Sync SFTP Uploads → Developer Directory
Create a script called sync_sftp_to_dev.sh:
#!/bin/bash SFTP_DIR="/sftp/uploads" DEV_DIR="/dev/files" # Monitor for create/delete/modify/move events (recursive) inotifywait -m -r -e create,delete,modify,move "$SFTP_DIR" | while read -r dir events file; do # Sync changes, preserving permissions and deleting files that are removed rsync -avz --delete "$SFTP_DIR/" "$DEV_DIR/" echo "Synced SFTP → Dev at $(date)" >> /var/log/sftp_sync.log done
Script 2: Sync Developer Changes → SFTP Directory
Create another script called sync_dev_to_sftp.sh:
#!/bin/bash DEV_DIR="/dev/files" SFTP_DIR="/sftp/uploads" # Monitor the same events on the developer directory inotifywait -m -r -e create,delete,modify,move "$DEV_DIR" | while read -r dir events file; do rsync -avz --delete "$DEV_DIR/" "$SFTP_DIR/" echo "Synced Dev → SFTP at $(date)" >> /var/log/sftp_sync.log done
Make both scripts executable:
sudo chmod +x sync_sftp_to_dev.sh sync_dev_to_sftp.sh
To make sure the sync runs automatically even after a reboot, create systemd service files.
Service for SFTP → Dev Sync
Create /etc/systemd/system/sftp-to-dev-sync.service:
[Unit] Description=Sync SFTP uploads to developer directory After=network.target [Service] User=root ExecStart=/path/to/your/sync_sftp_to_dev.sh Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
Service for Dev → SFTP Sync
Create /etc/systemd/system/dev-to-sftp-sync.service:
[Unit] Description=Sync developer changes to SFTP directory After=network.target [Service] User=root ExecStart=/path/to/your/sync_dev_to_sftp.sh Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
Enable and start the services:
sudo systemctl daemon-reload sudo systemctl enable --now sftp-to-dev-sync.service dev-to-sftp-sync.service
Let's verify everything works:
- Connect as
sftp_uploadvia SFTP, upload a file or create a folder—check/dev/filesto see if it syncs instantly. - Log in as
dev_user, edit a file, delete a file, or create a new one—check/sftp/uploadsto confirm the changes are mirrored. - Check the log file
/var/log/sftp_sync.logif you need to debug any issues.
- Conflict Handling: If both users modify the same file at the same time,
rsyncwill use the version with the latest timestamp. For more robust conflict resolution, you'd need to add version control (like Git), but this setup is designed for a simple mirror. - Permissions: We used a shared group to ensure both users can access the synced files—this keeps permissions consistent across both directories.
- Security: The chroot setup for the SFTP user ensures they can't access any other parts of your system beyond their upload folder.
内容的提问来源于stack exchange,提问作者josias

