Innovate | Connect | Transform
ContactService statusUSD $

GICT knowledge base

Restrict an OpenSSH SFTP Account to One Directory

Published

Linux Administration
How to Restrict SFTP Users to One Directory

OpenSSH can confine a dedicated SFTP account to a directory using ChrootDirectory and force its sessions into internal-sftp. This is a self-managed server-administration procedure, not a shared-hosting entitlement or a reason to edit panel-managed SSH settings without vendor guidance.

Prepare a recoverable change

Keep a working administrative session and console recovery available. Back up the existing SSH configuration privately under a new name. Inspect included configuration files and existing Match blocks before adding another one. Confirm your installed OpenSSH supports each directive; validation must pass before reloading anything.

Create a dedicated account and jail layout

Use a dedicated group such as sftponly and a non-administrative account such as uploaduser. Check that the names do not already belong to another purpose before creating them. Do not add an existing administrator to this group. Account expiry, PAM policy and locked-account handling can still reject public-key login; resolve those narrowly according to the distribution, without enabling password login globally.

For a jail at /srv/sftp/uploaduser, every component of the chroot path must be root-owned and not writable by another user or group. Create a writable child such as /srv/sftp/uploaduser/upload owned only as required by the transfer account. Inside the jail that child appears as /upload. Do not make the jail root user-writable to fix an upload error.

On GNU/Linux, namei -l /srv/sftp/uploaduser/upload helps inspect each ancestor. Use precise ownership and mode changes on the new paths, not recursive repairs on /srv or other accounts. A dedicated host-side key directory such as /etc/ssh/authorized_keys can hold root-managed per-user authorized-key files. It must permit the access SSH needs while preventing unauthorized writes: for this public-key-only layout, root-owned mode 755 for that directory and 644 for each public-key file are suitable examples. Store no private keys there.

Scope the SSH restrictions to the dedicated group

This configuration fragment assumes the account, jail, writable child and authorized public key already exist. It is not a complete replacement sshd_config. Place it with deliberate Match boundaries so later settings are not accidentally included, and retain the distribution’s appropriate global SFTP Subsystem configuration.

Match Group sftponly
    ChrootDirectory /srv/sftp/%u
    ForceCommand internal-sftp -d /upload -u 0077
    AuthorizedKeysFile /etc/ssh/authorized_keys/%u
    AuthenticationMethods publickey
    PubkeyAuthentication yes
    PasswordAuthentication no
    KbdInteractiveAuthentication no
    DisableForwarding yes
    PermitTTY no
    PermitTunnel no

The server reads this authorized-key path before entering the chroot. The forced internal SFTP server avoids needing to copy shells and libraries into the jail. -u 0077 restricts newly created permissions; it does not retroactively fix existing files or override all ACL behavior. Forcing SFTP alone does not disable forwarding, which is why forwarding is explicitly restricted.

Validate effective settings, then reload carefully

sshd -t
sshd -T -C user=uploaduser,host=client.example,addr=192.0.2.10

Run the installed server binary with appropriate administrative privileges and its actual configuration path. The test address is documentation space; substitute the relevant connection attributes. Syntax success does not prove the intended Match block wins. Inspect the effective chroot, forced command, authentication and forwarding settings for both the dedicated user and an administrator who should remain unaffected.

Only after successful validation, reload the correct distribution service using its documented mechanism; service names differ. Do not close the original administrative session until a separate administrator login still works and the SFTP account’s restrictions have been tested.

Test both permitted and denied behavior

  1. Connect with a maintained SFTP client, verifying the server fingerprint independently.
  2. Upload and download a harmless file in /upload, compare bytes and remove only that file.
  3. Confirm writing to the jail root is denied and the account cannot see the host’s real filesystem root.
  4. Confirm a requested remote shell command does not execute and forwarding is disabled. A successful SFTP login alone is not a complete confinement test.
  5. Check server logs for the exact failure if login is denied. Investigate account policy, authorized keys and jail ownership without disabling host-key checks or weakening unrelated users.

Legacy SCP needs a remote shell and is incompatible with a forced-SFTP account. Modern OpenSSH scp uses SFTP by default, subject to client/server path support. A chroot is not a universal sandbox: review shared mounts, hard links, ACLs and every other service through which that account’s files are accessible.

References: OpenSSH server configuration, internal SFTP options and current scp behavior.

Reviewed October 15, 2026. The fragment and a loopback-only synthetic account were tested in a disposable container, including a writable child, denied jail-root write, forced SFTP and effective forwarding restrictions. No customer SSH service was reloaded.

Related guides

Account services are unavailable until the production backend is configured.