Setting up a Linux server
Usually nothing to install — so it comes down to the key, whether the account has a shell, and the session limits that decide how fast a job runs.
Check what's already there
Unlike Windows, there is usually nothing to install: almost every Linux distribution ships OpenSSH and most server images have it running on boot. So this is a check rather than a setup step.
On the machine:
systemctl status ssh 2>/dev/null || systemctl status sshdThe unit is called ssh on Debian and Ubuntu and sshd on RHEL, Fedora, Alma, Rocky and SUSE — which is the only reason that command has two halves. If it isn't installed, apt install openssh-server or dnf install openssh-server.
Then let us reach it. Every connection BucketPilot makes comes from 3.111.107.194, so allow that one address on your SSH port rather than opening it to the internet:
# ufw (Debian/Ubuntu)
sudo ufw allow from 3.111.107.194 to any port 22 proto tcp
# firewalld (RHEL family)
sudo firewall-cmd --permanent --add-rich-rule="rule family=ipv4 source address=3.111.107.194/32 port port=22 protocol=tcp accept"
sudo firewall-cmd --reloadIf the machine is on a cloud provider, the security group or network ACL in front of it needs the same address — a host firewall being open doesn't help if the network drops the packet first.
The SFTP subsystem has to be enabled, and on a default install it is. /etc/ssh/sshd_config should contain Subsystem sftp internal-sftp (or a path like /usr/lib/openssh/sftp-server). A server that authenticates and then can't open SFTP is nearly always this line commented out.
The key, and the permissions that silently reject it
The key goes exactly where you'd expect — ~/.ssh/authorized_keys in the home directory of the account you're connecting as. There's no shared file and no equivalent of the Windows administrators trap.
What does catch people is permissions, because sshd's StrictModes is on by default and it refuses a key rather than explaining itself. The log on the server says it; the client just sees authentication fail.
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# paste the public key as ONE line
chmod 600 ~/.ssh/authorized_keysThree things StrictModes will reject:
- •
~/.sshreadable or writable by anyone but the owner — hence700. - •
authorized_keyswritable by group or other — hence600. - •The home directory itself being group-writable. This is the one that surprises people, because the
.sshpermissions look right.chmod g-w ~fixes it.
The key must be one line. A public key wrapped across several lines by a text editor or a copy-paste through a narrow terminal is not a key sshd can read, and it fails the same way a wrong key does.
Or use a password. Passwords are encrypted at rest and never returned by any API. If you use one, the server needs PasswordAuthentication yes in /etc/ssh/sshd_config — many hardened images and most cloud images ship it set to no, in which case a correct password fails with the same "authentication failed" as a wrong one.
Give the account only what it needs. For a migration source that is read access to the folders being copied; a drive or a restore destination needs write access where it will write. BucketPilot never needs root, and nothing it does requires sudo.
A shell is what makes a scan fast
This is the part with no Windows equivalent worth comparing, and the one that decides whether indexing a large tree takes seconds or hours.
When the account BucketPilot connects as can run commands, a scan enumerates the whole tree with a single find on your server and reads back one stream. When it can't, BucketPilot falls back to walking the tree over SFTP instead — which is correct, produces the same index, and pays a round trip per directory. On a tree with tens of thousands of folders that difference is the whole job.
Three things send it down the slow path, and none of them is an error you'll see:
- •A shell that can't run anything — an account whose shell is
/sbin/nologinor/bin/false. - •
ForceCommand internal-sftpor aMatchblock that does the same, which is a common way to lock an account to file transfer. - •
findwithout-printf. BusyBox and BSDfinddon't have it — so Alpine-based images and the BSDs take the slow path even with a full shell. GNUfind, which is what every mainstream Linux distribution ships, has it.
If you want the fast path, give the account a real shell and leave ForceCommand off. If your security posture says no, that is a perfectly reasonable trade — just expect a first scan of a deep tree to take considerably longer.
Re-scans only look at what changed. After the first full scan, a re-run asks only for files modified or created since the last one. Both halves matter: a folder dropped in with cp -a, rsync -a, tar -m or a mv from another host keeps its original modification time, which is older than the watermark — so a scan that only looked at modification times would miss an entire directory somebody just copied in, while catching a one-byte edit. A full walk still runs periodically, because only a full pass can notice that something was deleted.
Symbolic links are followed by default, and a job can be set not to. Whichever you choose applies to the whole scan, so a symlinked root either descends or doesn't — it won't be inconsistent between the check and the walk.
Session limits, and why a job goes slower instead of failing
BucketPilot opens more than one SSH connection to a server when a job is moving many files — up to 8, one for roughly every 16 files in flight. That is worth knowing because your server decides how many it will actually allow.
The extra connections are best-effort by design. If MaxSessions caps them, or MaxStartups throttles the rate they're opened at, or fail2ban decides a burst looks hostile, the job runs on the connections it got: slower, not failed. You will not see an error, so a job that is unexpectedly sluggish on a healthy network is worth checking here.
Beyond that, BucketPilot backs off the way TCP does. When the server refuses a session it halves the number of transfers it runs at once, then creeps back up one at a time as they succeed — so a brief cap doesn't leave the job crawling for the rest of the run, and a hard one settles at whatever the server is happy with instead of hammering it.
If you want to raise the ceiling, /etc/ssh/sshd_config:
MaxSessions 16
MaxStartups 30:30:60Then sudo systemctl reload ssh (or sshd). If you'd rather not, nothing breaks — this is a throughput setting, not a requirement.
⚠️ If the server is an SFTP appliance rather than a general-purpose Linux box, its limit may be much lower than sshd's defaults and not configurable at all. That is exactly the case the back-off exists for.
Rooting a drive
A drive on a Linux server browses like any other bucket. One rule is worth reading before you create one: don't root it at /. That is the whole machine, and BucketPilot will browse it but refuse to index it — no search, no size breakdown, no size alerts. Why, and what the switch looks like
Root it at the folder you actually care about — /srv/shares, /home/projects, /var/www — and index that.
The first scan of a drive is always a full one. After that, hourly auto-sync is safe.