rsync Server 3.5.1
Overview
rsync is the standard tool for fast file synchronization, mirroring and backup. Its delta-transfer algorithm sends only the parts of files that changed, so repeated syncs of large trees take a fraction of the time and bandwidth of a full copy.
This SecureAnyCloud image runs rsync 3.5.1 in daemon mode (rsyncd) on TCP port 873, with one module, SecureAnyCloud. Your servers and workstations can push backups to it and pull files from it.
The guide covers the Rsync Server 3.5.1 on Ubuntu 24.04 AMI on Amazon EC2. It is one version of the SecureAnyCloud SFTP and file server listing on AWS Marketplace, and you choose it as the software version when you subscribe and launch.
What you get:
- A password unique to your instance. First boot creates a random 32-character password for the module user SecureAnyCloud and writes it to /root/rsync-credentials.txt. No password is baked into the image, and the daemon cannot start until first boot has created one.
- No anonymous access, nothing listed. Every transfer must log in. An anonymous client that asks the server for its module list gets an empty list.
- Every transfer in a jail. Each transfer is locked (chrooted) into
/srv/rsync/sacon a dedicated 20 GiB EBS data volume and runs as the unprivilegedrsyncdaccount. Paths like../../etc/passwdand symbolic links that point outside the module cannot reach the rest of the system. Device files are refused. - Closed until first boot, and fail closed. First boot creates the password, starts the daemon, proves a full round trip and every refusal, and checks that the password did not leak into a log. If any step fails, the daemon is stopped again and the password files are destroyed.
- Hardened service. The daemon runs in a systemd sandbox that can write only to
/srv/rsync, keeps only the five capabilities it needs, and is blocked from the instance metadata service. The AMI requires IMDSv2. - Fully patched base. Ubuntu 24.04 LTS, patched at build time, with unattended security upgrades switched on.
- 24/7 SecureAnyCloud support
Important: the rsync daemon protocol is not encrypted. The password check is a challenge-response, so the password itself never crosses the network. File names and file contents on TCP 873 do travel in cleartext.
Allow TCP 873 only from the addresses of the machines that sync with the server. For anything sensitive, or over the internet, keep 873 closed and tunnel the daemon through SSH (Step 9) or use rsync over SSH.
Image contents
- rsync 3.5.1, built from upstream source. SecureAnyCloud builds it from the upstream release at https://download.samba.org/pub/rsync/src/rsync-3.5.1.tar.gz instead of installing it from apt. Ubuntu 24.04's rsync package (3.2.7-1ubuntu1.5) does not include the fixes from the rsync 3.5.0 security release (33 CVEs published on 13 August 2026, for example CVE-2026-70456, an out-of-bounds heap write, and CVE-2026-70464, an unauthenticated denial of service). Before anything was compiled, the tarball's SHA-256 checksum and its OpenPGP signature by Andrew Tridgell's release key (fingerprint 9FEF 112D CE19 A0DC 7E88 2CB8 1BB2 4997 A853 5F6F) were both verified. The compiler was removed again afterwards.
- Updates. Because rsync is built from source, apt upgrade and unattended-upgrades do not update it. Ubuntu's rsync package is removed and pinned, so apt can never install it over the upstream build. The operating system and every other package still update through apt. When upstream releases an rsync security fix, SecureAnyCloud publishes a new image version on this listing. To update, launch the new version and move /srv/rsync across (Step 12), or rebuild rsync yourself using the steps in Step 12. Track upstream at https://download.samba.org/pub/rsync/ and https://github.com/RsyncProject/rsync/releases (this image: version 3.5.1).
ubuntu-standardremoved. Ubuntu'subuntu-standardmetapackage is the only package on the image that depends on Ubuntu's rsync package, so it was removed together with it. Every package it had pulled in (cron, logrotate, man-db, wget, nano and the rest) was first marked as manually installed and is still installed. The list is in/usr/local/share/doc/rsync/ubuntu-standard-deps.txt(Step 12). Because of the rsync pin,apt install ubuntu-standardis refused, since it would bring Ubuntu's rsync back. Install any of its individual packages as usual.- Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. The rsync tools are in
/usr/local/sbin(Step 8).
Default user: ubuntu. Architecture: x86_64. Recommended instance type: m5.large.
Prerequisites
- An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet.
- A security group that allows TCP 22 for SSH administration and, only if your clients connect to the daemon directly, TCP 873 from your clients' addresses only. With the SSH tunnel (Step 9), port 22 is all you need.
- An rsync client on the machines that sync with the server: rsync ships with almost every Linux distribution and with macOS (as
openrsync); on Windows use WSL.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick Rsync Server 3.5.1 on Ubuntu 24.04 as the software version, pick your Region, then choose Launch through EC2.
Choose m5.large, your key pair and a security group as described above. rsync needs little CPU, so size the instance for your transfer volume.
The AMI carries two volumes: the 8 GiB root volume and a 20 GiB data volume for /srv/rsync. You can make the data volume larger at launch, and first boot grows the file system to fill it.
To launch with the AWS CLI instead, replace the values in angle brackets. The second block device mapping sets the data volume size:
aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
--instance-type m5.large --key-name <your-key-pair> \
--security-group-ids <your-security-group> --subnet-id <your-subnet> \
--metadata-options HttpTokens=required,HttpEndpoint=enabled \
--block-device-mappings 'DeviceName=/dev/sdf,Ebs={VolumeSize=200,VolumeType=gp3}' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=rsync-server}]'Connect to your instance
Version SSH user
Rsync Server 3.5.1 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>Check the service
First boot creates the password, starts the daemon and proves a round trip before it finishes, usually in under a minute. Check the first boot unit:
systemctl is-active rsync rsync-prepare rsync-firstboot
sudo test -f /var/lib/sac/data/rsync-firstboot.done && echo FIRSTBOOT_DONEAll three units are active and the first boot marker is present:
active active active FIRSTBOOT_DONEOnly SSH and the rsync daemon listen on public addresses, and the daemon is the upstream 3.5.1 build:
sudo ss -lntp | awk 'NR>1 {print $4, $6}' | grep -v '127.0.0' | sort command -v rsync; rsync --version | sed -n 1p0.0.0.0:22 users:(("sshd",...)) 0.0.0.0:873 users:(("rsync",...)) [::]:22 users:(("sshd",...)) [::]:873 users:(("rsync",...)) /usr/local/bin/rsync rsync version 3.5.1 protocol version 33Get your user and password
sudo grep -vE '^(#|$)' /root/rsync-credentials.txtThe file is readable by root only:
RSYNC_HOST=ec2-<public-ip-dashed>.compute-1.amazonaws.com RSYNC_PORT=873 RSYNC_USER=sac RSYNC_PASSWORD=<RSYNC_PASSWORD> RSYNC_MODULE=sac RSYNC_URL=rsync://sac@ec2-<public-ip-dashed>.compute-1.amazonaws.com/sac/ RSYNC_MODULE_PATH=/srv/rsync/sacRSYNC_HOST is the instance's public DNS name from EC2 instance metadata (the public or private IP address when the subnet has no public DNS names). It is the name to use from your clients.
Sync from your own machine
Store the password in a file only you can read, because rsync refuses a password file that others can read. Then push a directory to the server and pull it back. rsync reads the password from the file, so it never appears on a command line or in your shell history:
read -rs PW && printf '%s\n' "$PW" > ~/.rsync-sac.pw && chmod 600 ~/.rsync-sac.pw; unset PW rsync -av --password-file=$HOME/.rsync-sac.pw ./projects/ rsync://sac@<RSYNC_HOST>/sac/projects/ rsync -av --password-file=$HOME/.rsync-sac.pw rsync://sac@<RSYNC_HOST>/sac/projects/ ./restore/Add --delete to make the copy on the server an exact mirror, so files you deleted locally are deleted on the server too. To schedule a nightly backup, put the push command in a cron job or systemd timer on the client.
Push and pull from the instance
This test pushes a file, lists the module, pulls the file back and mirrors a deletion. It goes through the daemon on the instance's own private address. The password is read from a temporary file that only root can read:
sudo bash -c ' F=/root/rsync-credentials.txt U=$(sed -n "s/^RSYNC_USER=//p" $F); M=$(sed -n "s/^RSYNC_MODULE=//p" $F) PWF=$(mktemp /run/rsync-pw.XXXXXX); sed -n "s/^RSYNC_PASSWORD=//p" $F > $PWF IP=$(hostname -I | cut -d" " -f1) mkdir -p /run/demo && echo "hello from sac" > /run/demo/report.txt rsync -a --password-file=$PWF /run/demo/ "rsync://$U@$IP/$M/demo/" && echo "push -> ok" echo "list -> $(rsync --password-file=$PWF "rsync://$U@$IP/$M/demo/" | awk "{print \$NF}" | tr "\n" " ")" rm -f /run/demo/report.txt; rsync -a --password-file=$PWF "rsync://$U@$IP/$M/demo/report.txt" /run/demo/ && echo "pull -> $(cat /run/demo/report.txt)" rm -f /run/demo/report.txt; rsync -a --delete --password-file=$PWF /run/demo/ "rsync://$U@$IP/$M/demo/" && echo "delete -> $(rsync --password-file=$PWF "rsync://$U@$IP/$M/demo/" | awk "{print \$NF}" | tr "\n" " ")" rm -rf /run/demo $PWF /srv/rsync/sac/demo 'push -> ok list -> . report.txt pull -> hello from sac delete -> .Pushed files land in /srv/rsync/sac, owned by the unprivileged rsyncd account. To place files there over SSH, copy them in and give them to that account (sudo chown -R rsyncd:rsyncd /srv/rsync/sac/<path>).
Run the built-in check
The image ships an end-to-end check that you can run at any time. First boot runs it too. It reads the credentials file itself and drives the daemon through the instance's private address:
sudo rsyncd-verify.shok anonymous module listing shows no module (rc 0) ok anonymous access refused (auth failed, rc 5) ok user 'anonymous' refused (auth failed, rc 5) ok wrong password refused (auth failed, rc 5) ok push sac-verify-<pid>/data.bin (256 KiB) ok module listing (authenticated) shows the upload ok pull byte-identical ok file stored in /srv/rsync/sac owned by rsyncd ok pull ../../etc/passwd refused (rc 23) ok pull /etc/shadow (absolute) refused (rc 23) ok push to ../../ stays inside the module ok symlink to /etc/shadow cannot be followed out of the module (rc 23) ok device file not created ok --write-devices refused (rc 4) ok live transfer runs as rsyncd (<process counts>) ok the only root process in rsync.service is the listener (pid <pid>) ok delete over rsync (--delete) ok test directory gone from /srv/rsync/sac RSYNCD_ROUNDTRIP_OK target <private-ip>The check takes about half a minute and leaves the module as it found it.
Security checks and the password
An anonymous client sees no modules and cannot log in:
IP=$(hostname -I | cut -d" " -f1); echo "listing: [$(rsync rsync://$IP/)]" (setsid -w rsync "rsync://$IP/sac/" </dev/null 2>&1 || true) | grep -o '@ERROR.*'listing: [] @ERROR: auth failed on module sacThe configuration jails every transfer, maps it to the rsyncd account, hides the module and refuses device files:
grep -vE '^[[:space:]]*(#|$)' /etc/rsyncd.confpid file = /run/rsyncd/rsyncd.pid lock file = /run/rsyncd/rsyncd.lock port = 873 use chroot = yes numeric ids = yes uid = rsyncd gid = rsyncd max connections = 10 timeout = 600 reverse lookup = no forward lookup = no proxy protocol = no syslog facility = daemon syslog tag = rsyncd transfer logging = yes refuse options = devices specials copy-devices write-devices [sac] comment = sac rsync module (per-instance password, chrooted) path = /srv/rsync/sac read only = no write only = no list = no auth users = sac secrets file = /etc/rsyncd.secrets strict modes = yesThe rsync daemon's challenge-response needs the password on the server, so it is kept in /etc/rsyncd.secrets, readable by root only, beside the credentials file:
sudo stat -c '%a %U:%G %n' /etc/rsyncd.conf /etc/rsyncd.secrets /root/rsync-credentials.txt /srv/rsync /srv/rsync/sac644 root:root /etc/rsyncd.conf 600 root:root /etc/rsyncd.secrets 600 root:root /root/rsync-credentials.txt 755 root:root /srv/rsync 750 rsyncd:rsyncd /srv/rsync/sacThe daemon runs the upstream build in a sandbox that can write only to the data volume, with five capabilities, and cannot reach the instance metadata service:
systemctl show rsync -p ExecStart -p ProtectSystem -p ReadWritePaths -p NoNewPrivileges -p IPAddressDeny -p CapabilityBoundingSet | cut -c1-120ExecStart={ path=/usr/local/bin/rsync ; argv[]=/usr/local/bin/rsync --daemon --no-detach --config=/etc/rsyncd.conf ; ign IPAddressDeny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 CapabilityBoundingSet=cap_dac_read_search cap_setgid cap_setuid cap_net_bind_service cap_sys_chroot ReadWritePaths=/srv/rsync ProtectSystem=strict NoNewPrivileges=yesNo per instance password reached a log, the journal, shell history, backups, the data volume or any file in /etc other than the secrets file:
sudo rsyncd-secret-leak-check.shLEAKCHECK_OK no per-instance password in the journal, auth.log, syslog, cloud-init, shell history, MOTD, /var/backups, /etc (outside the 0600 secrets file), /srv/rsync or /tmpThe daemon logs the address each client really connected from (never a DNS name or a header the client sends), including refused logins:
sudo journalctl -u rsync --no-pager -o cat | grep -E '^connect from|allowed access|auth failed' | tail -n 3connect from UNDETERMINED (<client-ip>) rsync allowed access on module sac from UNDETERMINED (<client-ip>) auth failed on module sac from UNDETERMINED (<client-ip>) for <user>: <reason>New password. rsyncd-passwd generates a new 32 character password (shown once) or reads one you choose from standard input, and updates /etc/rsyncd.secrets and /root/rsync-credentials.txt. The daemon reads the secrets file for every new connection, so no restart is needed:
sudo rsyncd-passwd read -rs PW && printf '%s\n' "$PW" | sudo rsyncd-passwd --password-stdin; unset PWMore users or modules. Add a user:password line to /etc/rsyncd.secrets and the user to the module's auth users (comma separated), or add another [name] block with its own path under /srv/rsync (create the directory owned by rsyncd:rsyncd, mode 0750). Every module must keep auth users and secrets file. To make a module append only (clients cannot delete), add delete to its refuse options. To filter clients inside the daemon as well as in the security group, add hosts allow = <your-cidr> under the module. Changes apply to the next connection.
Encrypt the transfer with an SSH tunnel
The daemon protocol is cleartext, so the safest setup keeps TCP 873 closed in the security group and reaches the daemon through SSH. The per-instance password still protects the module, and everything travels inside the SSH connection. On your client, run:
ssh -i <your-key.pem> -N -L 8873:127.0.0.1:873 ubuntu@<RSYNC_HOST> & rsync -av --password-file=$HOME/.rsync-sac.pw ./projects/ rsync://sac@127.0.0.1:8873/sac/projects/Alternatively, use rsync over SSH directly as the ubuntu user, with no daemon involved. To write into the module directory, run the remote side with sudo:
rsync -av -e "ssh -i <your-key.pem>" --rsync-path="sudo rsync" ./projects/ ubuntu@<RSYNC_HOST>:/srv/rsync/sac/projects/If clients must connect to TCP 873 directly, allow it only from their addresses in the security group, and from inside your VPC wherever possible.
Limits
The daemon serves at most 10 connections at a time (max connections) and drops a connection that is idle for 10 minutes (timeout = 600). For many simultaneous clients, raise these limits in /etc/rsyncd.conf. The change applies to the next connection.
The data volume
/srv/rsync is its own EBS volume, mounted by file system UUID with nodev,nosuid,noexec, so synced files can never be run as programs:
findmnt -no SOURCE,FSTYPE,OPTIONS /srv/rsync df -h --output=size,used,avail,target /srv/rsync/dev/nvme1n1 ext4 rw,nosuid,nodev,noexec,relatime Size Used Avail Mounted on 20G 28K 19G /srv/rsyncTo grow it, increase the volume's size in the EC2 console (Volumes > Modify volume), wait until the modification reaches the optimizing state, then grow the file system online (the next boot does it too):
sudo rsyncd-prepareBack it up with EBS snapshots or AWS Backup; a snapshot of the data volume holds every synced file.
Updates
The operating system updates through apt, and unattended security upgrades are on. rsync itself is the source build described in the overview, so apt does not touch it, and Ubuntu's rsync package cannot be installed over it. The version and where it came from:
rsync --version | sed -n 1p cat /usr/local/share/doc/rsync/SOURCE.txt apt-cache policy rsync | sed -n 1,3prsync version 3.5.1 protocol version 33 This rsync 3.5.1 was built by sac from the upstream release tarball https://download.samba.org/pub/rsync/src/rsync-3.5.1.tar.gz, whose SHA-256 checksum c55f9c9dc10fb8bec397b399a0fdded53cc9a2d8e30891bb0d63724d25c37bef and OpenPGP signature by Andrew Tridgell's release key 9FEF112DCE19A0DC7E882CB81BB24997A8535F6F (signed 2026-09-21) were both verified before the build, configured with: --prefix=/usr/local --with-rsyncd-conf=/etc/rsyncd.conf --disable-md2man --disable-idn. It replaces Ubuntu's rsync package (3.2.7-1ubuntu1.5, which lacks the rsync 3.5.0 security fixes); that package is removed and pinned so apt can never reinstall it, which also means apt and unattended-upgrades do NOT update rsync. sac publishes a new image version for every upstream rsync security release (upstream releases and announcements: https://download.samba.org/pub/rsync/ and https://github.com/RsyncProject/rsync/releases); update by launching the new image version, or rebuild from the steps in the user guide. rsync is free software under the GNU General Public License version 3 or later with an OpenSSL/xxhash linking exception; the licence text is in /usr/local/share/doc/rsync/COPYING and the release notes in /usr/local/share/doc/rsync/NEWS.md. rsync: Installed: (none) Candidate: (none)ubuntu-standard, the only package that depended on Ubuntu's rsync, was removed with it. Everything it had installed was kept as manually installed and is listed in /usr/local/share/doc/rsync/ubuntu-standard-deps.txt; apt refuses to reinstall the metapackage because of the rsync pin:
grep -vc '^#' /usr/local/share/doc/rsync/ubuntu-standard-deps.txt apt-get -s install ubuntu-standard >/dev/null 2>&1 || echo "apt refuses ubuntu-standard (it needs Ubuntu's rsync, which is pinned out)"50 apt refuses ubuntu-standard (it needs Ubuntu's rsync, which is pinned out)When an rsync release fixes a security issue, SecureAnyCloud adds a new image version to this listing. To move to it:
- Launch the new version next to the old instance.
- Stop the daemon on the old instance (
sudo systemctl stop rsync), take a snapshot of its data volume, and create a volume from that snapshot in the new instance's Availability Zone. - On the new instance stop the daemon, attach the volume, and copy the module directory into
/srv/rsync(keeping thersyncd:rsyncdowner), or mount the volume in place of the new one by its UUID in/etc/fstab. Copy any users you added to/etc/rsyncd.secrets(mode 0600) and start the daemon.
Rebuild rsync yourself. To apply a newer upstream release on a running instance, build it the same way the image did, on a temporary directory in /run: download rsync-<version>.tar.gz and its .asc from https://download.samba.org/pub/rsync/src/, verify the signature with gpg --verify against Andrew Tridgell's key (9FEF112DCE19A0DC7E882CB81BB24997A8535F6F), install the build tools (sudo apt-get install gcc make libssl-dev libxxhash-dev libzstd-dev liblz4-dev libpopt-dev libacl1-dev libattr1-dev), run ./configure --prefix=/usr/local --with-rsyncd-conf=/etc/rsyncd.conf --disable-md2man --disable-idn && make, copy the new rsync binary over /usr/local/bin/rsync, run sudo systemctl restart rsync, and remove the build tools again.
Server components
Component Version Path
rsync (daemon and client) 3.5.1 (upstream source build, protocol 33) /usr/local/bin/rsync (/usr/bin/rsync links to it)
OpenSSL, xxhash, zstd, lz4, popt, libacl Ubuntu 24.04, updated by apt system libraries
Ubuntu 24.04 LTS
Path Purpose
/etc/rsyncd.conf Daemon configuration (re-read for every connection)
/etc/rsyncd.secrets Module users and passwords (mode 0600)
/srv/rsync/sac The SecureAnyCloud module on the data volume
/root/rsync-credentials.txt Host, user, password and module (mode 0600)
/usr/local/share/doc/rsync/ Licence, release notes and SOURCE.txt
/etc/apt/preferences.d/sac-no-distro-rsync Keeps Ubuntu's rsync package (and so ubuntu-standard) from being installed
/usr/local/share/doc/rsync/ubuntu-standard-deps.txt The packages ubuntu-standard had pulled in, all kept installed
/usr/local/sbin/rsyncd-* Password, check, health check, leak check and volume tools
Logs go to the journal: journalctl -u rsync.
Troubleshooting
- @ERROR: auth failed on module SecureAnyCloud. Wrong user or password, or the client sent no password. Use rsync://sac@<host>/sac/ and --password-file (Step 5). The journal shows the reason (journalctl -u rsync).
ERROR: password file must not be other-accessible. Runchmod 600on your password file.- The connection times out. TCP 873 is not open from your address in the security group (or a network ACL or corporate firewall blocks it). Use the SSH tunnel (Step 9) if you prefer to keep 873 closed.
@ERROR: max connections (10) reached. Too many simultaneous clients; raisemax connections(Step 10).skipping non-regular file. Device and special files are refused on purpose.- Nothing answers after launch. Check
systemctl status rsync-firstbootandjournalctl -u rsync-firstboot. Until first boot completes, the daemon is deliberately closed.
Security recommendations
- Allow TCP 873 only from the addresses that sync with the server, or keep it closed and use the SSH tunnel; allow port 22 only from your administrators.
- Remember that data on TCP 873 is not encrypted (Step 9).
- Give each system its own user, keep password files at mode 0600, and change the password with
sudo rsyncd-passwdwhen someone leaves. - Move to new image versions when SecureAnyCloud publishes an rsync update (Step 12), and keep the operating system patched (unattended security upgrades are on).
- Back up the data volume (Step 11).
Support and licensing
rsync is free software under the GNU General Public License version 3 or later, with an exception that allows linking with OpenSSL and xxhash. The license text is at /usr/local/share/doc/rsync/COPYING. The source is at https://download.samba.org/pub/rsync/src/rsync-3.5.1.tar.gz and https://github.com/RsyncProject/rsync.
There is no per-user or per-CPU license fee. The AMI price covers SecureAnyCloud's build, hardening, first-boot setup and support. rsync is a trademark of its respective owner, and SecureAnyCloud is not affiliated with or endorsed by the rsync project.
- Email: sales@secureanycloud.com
- Website: https://secureanycloud.com
- Support: 24/7, with a 24 hour response SLA
Deploy on AWS
Launch Rsync Server 3.5.1 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com