Chroot SSH Configuration on Linux|RHEL|CentOS

Chroot SSH

Using OpenSSH you can bind SSH or SFTP users to their home directory and restrict them to access other directories on the SSH server. In this article we will demonstrate Chroot SSH Configuration on Linux|RHEL|CentOS for selected ssh users or group.


Topic

  • How to configure chroot SSH on Linux?
  • How to configure chroot SSH on CentOS 7?
  • How to configure chroot SSH on RHEL 7?
  • Restrict SSH user to a specific directory
  • Restrict SSH user to home directory
  • Chroot SSH on Ubuntu
  • Chroot SSH on Debian
  • Chroot SSH on RHEL


Solution


Prerequisites

  • Install Openssh server
On Centos/RHEL:
# yum install openssh openssh-clients openssh-server

On Ubuntu/Debian:
# apt install openssh-client openssh-server

Configuration

Setting up a secure or chroot ssh environment requires a sandox environment which has its own libraries and binaries. In this article, we’ll bind all ssh users who are part of chrootssh group into /data/chroot-ssh directory.

There are 3 configuration steps used in this article to setup chroot SSH environment:

  1. Chroot Environment Setup
  2. Chroot Binary Setup
  3. Chroot User Account Setup

This article has been tested on CentOS 7 and RHEL 7. You can refer to the steps given in this article to configure chroot ssh on other Linux distributions. This article also contains 3 bash scripts to automate the setup. Login to the system with root account to perform the given steps.

Chroot Environment Setup [1]
  • Create a chroot environment directory named /data/chroot-ssh. You can create the chroot environment directory on any path of your choice.
# makdir -p /data/chroot-ssh

  • Create a chroot group named chrootssh. You can create the chroot group of your choice.
# groupadd chrootssh

  • Setup chroot environment with the following steps.
mkdir -p /data/chroot-ssh
mkdir -p /data/chroot-ssh/{bin,usr,etc,lib64,home,dev}

# These socket files are required for chroot accounts
mknod -m 666 /data/chroot-ssh/dev/null c 1 3
mknod -m 666 /data/chroot-ssh/dev/tty c 5 0
mknod -m 666 /data/chroot-ssh/dev/zero c 1 5
mknod -m 666 /data/chroot-ssh/dev/random c 1 8

# Permission
chmod o+t /data/chroot-ssh/dev/null /data/chroot-ssh/dev/tty  \
/data/chroot-ssh/dev/zero /data/chroot-ssh/dev/random

# Create Symlinks
cd /data/chroot-ssh/usr
ln -sf ../bin ./bin
ln -sf ../lib64 ./lib64

  • Append the following configuration to /etc/ssh/sshd_config file and then restart sshd service.
## Chroot SSH configuration. Replace chrootssh if needed. 
Match Group  chrootssh
        ChrootDirectory  
        X11Forwarding no
        AllowTcpForwarding no

  • We can automate the complete above steps given in Chroot Environment Setup section with the following bash script.
# cat chroot-base-setup.sh 

#!/bin/bash
# Description: Chroot binary and library setup script
# Author: Tekfik Blogging

CHROOT_DIR=$1
CHGROUP=$2
TARG=$#

## Check input args
if [ $TARG != 2 ];then
    echo "Bad Input. Execute the script as:"
    echo "sh chroot-base-setup.sh chroot_dir_location chroot_group_name"
    exit 1
fi

## Check and setup chroot dir 
if [ ! -d $CHROOT_DIR ]; then
    mkdir -p $CHROOT_DIR
    mkdir -p $CHROOT_DIR/{bin,usr,etc,lib64,home,dev}
    cd $CHROOT_DIR/usr
    ln -sf ../bin ./bin
    ln -sf ../lib64 ./lib64
    ##Dev Setup
    mknod -m 666 $CHROOT_DIR/dev/null c 1 3
    mknod -m 666 $CHROOT_DIR/dev/tty c 5 0
    mknod -m 666 $CHROOT_DIR/dev/zero c 1 5
    mknod -m 666 $CHROOT_DIR/dev/random c 1 8
    chmod o+t $CHROOT_DIR/dev/null $CHROOT_DIR/dev/tty $CHROOT_DIR/dev/zero $CHROOT_DIR/dev/random

    #Group setup
    if [[ ! `getent group $CHGROUP 2>/dev/null` ]];then
       groupadd $CHGROUP
    fi

else
    echo "Chroot setup already present. Delete the present chroot directory $CHROOT_DIR to setup from new."
    exit 0
fi

## Setup Complete
echo -e "\n\n============================Setup completed============================\n\n"
echo -e "1) Append the following configuration /etc/ssh/sshd_config file \
and then restart sshd service"

echo -e "\n## Chroot SSH configuration\nMatch Group $CHGROUP\n\tChrootDirectory $CHROOT_DIR \
\n\tX11Forwarding no\n\tAllowTcpForwarding no"

echo -e "\n\n2) Run chroot-binary-setup.sh script to setup allowed commands \
for chroot ssh user \n\n3) Execute chroot-user-setup.sh script to setup chroot users."

  • The above script needs two arguments 1) Chroot Directory path 2) Chroot Group Name.
  • Execute the following command to run the above script. Relace the directory path and group name of your choice.
# Login as root and run the script
sh chroot-base-setup.sh /data/chroot-ssh chrootssh


Chroot Binary Setup [2]

In this section, we’ll setup required binaries for chroot sandbox environment. Binaries are the commands allowed to execute in the chroot environment. Basically, we need the following mandatory commands or binaries for chroot environment but you can setup other commands if required.

  • /bin/{ls,cat,echo,rm,sh,touch,vi,mkdir}

  • Copy the above binaries to $CHROOT_DIR/bin directory.

cp -p /bin/ls /data/chroot-ssh/bin/
cp -p /bin/cat /data/chroot-ssh/bin/
cp -p /bin/rm /data/chroot-ssh/bin/
cp -p /bin/echo /data/chroot-ssh/bin/
cp -p /bin/sh /data/chroot-ssh/bin/
cp -p /bin/touch /data/chroot-ssh/bin/
cp -p /bin/vi /data/chroot-ssh/bin/
cp -p /bin/mkdir /data/chroot-ssh/bin/

  • Then copy dependent library files of those binaries/commands to $CHROOT_DIR/lib64 directory.
# Execute the following command to list dependent library files of a command
$ ldd /bin/ls
    linux-vdso.so.1 =>  (0x00007ffc16ac3000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fee03863000)
    libcap.so.2 => /lib64/libcap.so.2 (0x00007fee0365e000)
    libacl.so.1 => /lib64/libacl.so.1 (0x00007fee03455000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fee03087000)
    libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fee02e25000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fee02c21000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fee03a8a000)
    libattr.so.1 => /lib64/libattr.so.1 (0x00007fee02a1c000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fee02800000)

# Now copy the library files have valid path to $CHROOT_DIR/lib64 directory. 
cp --parents /lib64/libselinux.so.1 /data/chroot-ssh/
cp --parents /lib64/libcap.so.2 /data/chroot-ssh/l
cp --parents /lib64/libacl.so.1 /data/chroot-ssh/
cp --parents /lib64/libc.so.6 /data/chroot-ssh/
cp --parents /lib64/libpcre.so.1 /data/chroot-ssh/
cp --parents /lib64/libdl.so.2 /data/chroot-ssh/
cp --parents /lib64/libattr.so.1 /data/chroot-ssh/
cp --parents /lib64/libpthread.so.0 /data/chroot-ssh/

## Similarly copy library files of other command binary to $CHROOT_DIR/lib64 directory

  • Copy the following special binary file to $CHROOT_DIR/lib64 directory.
# If the system is a x86_64 architecture 
  cp --parents /lib64/ld-linux-x86-64.so.2 /data/chroot-ssh/

#  If the system is a 32/i386 architecture 
   cp --parents /lib/ld-linux.so.2 /data/chroot-ssh/

  • We can automate the complete above steps in Chroot Binary Setup section with the following bash script.
$ cat chroot-binary-setup.sh

#!/bin/bash
# Description: Chroot binary and library setup script
# Author: Tekfik Blogging

CHROOT_DIR=$1
BINARY_PATH=$2
TARG=$#

## Check input args
if [ $TARG != 2 ];then
    echo "Bad Input. Execute the script as:"
    echo "sh chroot-binary-setup.sh chroot_dir_location binary_path"
    exit 1
fi

## Check chroot dir 
if ! test -d $CHROOT_DIR -a -d $CHROOT_DIR/bin -a -d $CHROOT_DIR/usr -a -d $CHROOT_DIR/etc -a -d $CHROOT_DIR/lib64 -a -d $CHROOT_DIR/home -a -d $CHROOT_DIR/dev;then
    echo "Chroot directory structure is not found. Execute chroot-base-setup.sh script to setup chroot dir structure."
    exit 1
fi

## Check binary existence
if [ ! -f $BINARY_PATH ]; then
    echo "Binary $BINARY_PATH doesn't exist. Re-execute script with proper binary path"
    exit
fi

## Binary setup
cp -p $BINARY_PATH $CHROOT_DIR/bin/

B_LIB=$(ldd $BINARY_PATH |grep -v dynamic|awk -F " " '{print $3}'|grep -v "^$"|grep -v "^(")

for i in $B_LIB;do
    if [ -f $i ]; then
        cp --parent $i $CHROOT_DIR/
    else
        echo "$i doesn't exist, check manually on the system"
    fi
done

## Additional setup 
# x86_64 arc
if [ -f /lib64/ld-linux-x86-64.so.2 ] && [ ! -f $CHROOT_DIR/lib64/ld-linux-x86-64.so.2 ]; then
   cp --parents /lib64/ld-linux-x86-64.so.2 $CHROOT_DIR/
fi

# 32 bit arc
if [ -f  /lib/ld-linux.so.2 ] && [ ! -f $CHROOT_DIR/lib/ld-linux.so.2 ]; then
   cp --parents /lib/ld-linux.so.2 $CHROOT_DIR/
fi

echo -e "\nBinary setup completed. Now execute chroot-user-setup.sh script to create chroot users."

  • The above script needs two arguments 1) Chroot Directory path 2) absolute path of the binary or command.
  • Execute the following command to run the above script. Replace the directory path and binary name of your choice.
# Login as root and run the script
sh chroot-binary-setup.sh /data/chroot-ssh /bin/ls

# Execute the following for loop if you want to setup multiple binaries at a time. 
for i in /bin/{ls,cat,echo,rm,bash,sh,touch,vi,mkdir};do sh chroot-binary-setup.sh /data/chroot-ssh $i;done


Chroot User Account Setup [3]

In this section, we’ll setup user accounts with chroot privileges only. For exercise, we’ll use testssh account for chroot ssh login.

  • Create user account and add the user to chroot group chrootssh.
# Add user
/usr/sbin/useradd -g chrootssh -M -s /bin/bash testssh

# Set password
passwd testssh

  • Setup home directory for the chroot user account with the following steps.
mkdir -p /data/chroot-ssh/home/testssh
chown testssh:chrootssh /data/chroot-ssh/home/testssh
chmod 700 /data/chroot-ssh/home/testssh

# Link chroot home directory to /home. This is needed for password less ssh. 
ln -sf /data/chroot-ssh/home/testssh /home/testssh

  • We can automate the complete above steps in Chroot User Account Setup section with the following bash script. In the following script modify two variables 1) CHROOT_DIR 2) CHGROUP and put the value of your choice. In our case, CHROOT_DIR="/data/chroot-ssh" and CHGROUP="chrootssh".
$ cat chroot-user-setup.sh

#!/bin/bash
# Description: Chroot binary and library setup script
# Author: Tekfik Blogging

CHROOT_DIR="/data/chroot-ssh"
CHGROUP="chrootssh"
USER=$1
TARG=$#

## Check input args
if [ $TARG != 1 ];then
    echo "Bad Input. Modify the variable value of CHROOT_DIR and CHGROUP variables and then execute the script as:"
    echo "sh chroot-user-setup.sh user_name"
    exit 1
fi

## Check chroot dir 
if ! test -d $CHROOT_DIR -a -d $CHROOT_DIR/bin -a -d $CHROOT_DIR/usr -a -d $CHROOT_DIR/etc -a -d $CHROOT_DIR/lib64 -a -d $CHROOT_DIR/home -a -d $CHROOT_DIR/dev;then
    echo "Chroot directory structure is not found. Execute chroot-base-setup.sh script to setup chroot dir structure."
    exit 1
fi

## Add user
if [[ ! -n `id -u $USER 2>/dev/null` ]];then
    echo "Setting up user account $USER"
    sleep 2
    /usr/sbin/useradd -g $CHGROUP -M -s /bin/bash $USER
    mkdir -p $CHROOT_DIR/home/$USER
    chown $USER:$CHGROUP $CHROOT_DIR/home/$USER
    chmod 700 $CHROOT_DIR/home/$USER
    ln -sf $CHROOT_DIR/home/$USER /home/$USER
    ## Set user password
    passwd $USER
else
    echo "User $USER already present."
fi

echo -e "\n\n"
echo "User setup completed. Now you can test chroot ssh login."

  • The above script needs one argument user_name.
  • Execute the following command to run the above script. Relace the user_name of your choice.
# Login as root and run the script
sh chroot-user-setup.sh testssh

# Execute the following for loop if you want to setup multiple users at a time. 
for i in user1 user2 user3 user4;do sh chroot-user-setup.sh $i;done


Testing

Execute the following commands for chroot ssh login test.

$ ssh testssh@192.168.1.1
testssh@192.168.1.1's password: 
-bash-4.2$ ls

file


If you have enjoyed the above article, the following are add on articles related to Chroot SSH Configuration on Linux|RHEL|CentOS:


You May Also Like

avatar

About the Author: TekFik

TekFik is a technical blogging site helps techies and engineers to solve their day to day issues and also allows everyone to share knowledge and feedback. Please feel free to contact us at tekfik.rd@gmail.com if there is anything.

Leave a Reply

Your email address will not be published. Required fields are marked *