Implementing Restricted SSH Read-Only Access to Specific Directory Subtrees on Debian


5 views

When granting external parties controlled access to server resources, we need a solution that:

  • Restricts users to read-only operations
  • Jails them within specified directory subtrees
  • Maintains system security without manual permission changes

The most robust approach combines rssh (restricted shell) with chroot (directory jail):

# Install required packages
sudo apt-get install rssh -y

# Create restricted user
sudo useradd -m -s /usr/bin/rssh restricted_user
sudo passwd restricted_user

# Configure rssh
sudo nano /etc/rssh.conf

Add these configuration lines:

allowscp
allowsftp
umask = 022
chrootpath = /restricted/data
user=restricted_user:011:00010:/restricted/data

Create the restricted environment with proper permissions:

sudo mkdir -p /restricted/data
sudo chown root:root /restricted
sudo chmod 755 /restricted
sudo chown restricted_user:restricted_user /restricted/data

Modify /etc/ssh/sshd_config:

Match User restricted_user
    ChrootDirectory /restricted
    ForceCommand internal-sftp
    X11Forwarding no
    AllowTcpForwarding no
    PermitTunnel no
    GatewayPorts no

Then restart SSH: sudo systemctl restart sshd

For more complex scenarios where you need to expose specific paths without copying files:

# Add to /etc/fstab
/data/reports /restricted/data/reports none bind,ro 0 0

# Mount all bind entries
sudo mount -a

Test the configuration by attempting various operations:

# As restricted user
sftp restricted_user@yourserver
cd /
ls -la
put testfile  # Should fail
get existingfile  # Should succeed
  • Regularly audit permissions with auditd
  • Implement fail2ban for brute force protection
  • Consider setting up separate user groups for different access levels
  • Monitor access logs: /var/log/auth.log

For managing multiple users, create a setup script:

#!/bin/bash
USERNAME=$1
BASEPATH="/restricted/$USERNAME"

useradd -m -s /usr/bin/rssh "$USERNAME" && \
mkdir -p "$BASEPATH/data" && \
chown root:root "$BASEPATH" && \
chmod 755 "$BASEPATH" && \
chown "$USERNAME:$USERNAME" "$BASEPATH/data" && \
echo "user=$USERNAME:011:00010:$BASEPATH/data" >> /etc/rssh.conf

html

When providing external access to a Linux server, security is paramount. We often need to create users with strictly limited permissions - specifically read-only access to certain directories. The challenge is to implement this without manually adjusting permissions for every file and folder in the subtree.

We'll leverage several Linux features:

  • rssh (Restricted Shell)
  • Filesystem permissions
  • Linux groups
  • Jailkit (optional for chroot environments)

First, let's create a dedicated group for our read-only users:

sudo groupadd readonlyusers

Create a new user and assign them to this group:

sudo useradd -G readonlyusers -s /usr/bin/rssh readonlyuser1
sudo passwd readonlyuser1

For our example, let's assume we want to provide read access to /var/www/shared_docs:

sudo mkdir -p /var/www/shared_docs
sudo chown root:readonlyusers /var/www/shared_docs
sudo chmod 750 /var/www/shared_docs

Install rssh if not already available:

sudo apt-get install rssh

Edit /etc/rssh.conf to allow only sftp:

allowscp
allowsftp
allowrsync
# Add our user to the configuration
user=readonlyuser1:011:00011:/var/www/shared_docs

For more complex directory structures, consider bind mounts:

sudo mkdir -p /home/readonlyuser1/shared
sudo mount --bind /var/www/shared_docs /home/readonlyuser1/shared

Make it persistent by adding to /etc/fstab:

/var/www/shared_docs /home/readonlyuser1/shared none bind,ro 0 0

Test the configuration by attempting to log in:

sftp readonlyuser1@yourserver

Attempt to create a file to verify read-only access:

touch testfile
# Should result in "Permission denied"

For even more isolation, consider setting up a chroot jail:

sudo apt-get install jailkit
sudo jk_init -j /home/readonlyuser1/jail /bin/bash /usr/bin/rssh /lib64/ld-linux-x86-64.so.2

Then configure the user's shell accordingly:

sudo usermod -s /usr/sbin/jk_chrootsh readonlyuser1

If users can't access files:

  • Verify group membership with groups readonlyuser1
  • Check directory permissions with ls -ld /var/www/shared_docs
  • Inspect auth logs: tail -f /var/log/auth.log