Skip to content

Commit 417db77

Browse files
authored
Implementation of jailed shells (hestiacp#4052)
* feat: Initial implementation of jailed bash shell * Remove error messages if jail is not installed Jail not being installed is a expected default state. This way a user that wants a non-jailed bash shell has the ability to keep using those. * Fix error with nologin chroot not being kept intact and add bash jail test * Make sure the group and bash shell is added to the jail * Make hestia depend on jailkit * allow admin to enable jail for packages and users * Make sure jail is created correctly * Remove some duplicate calls and add some more of explanation * Add more explanation on why changes can be reverted * Move homedir in chroot and fix issues with add and remove To make ssh jails work properly we need to move the homedir to the same root of the jail as the original location. We also need php and a user writable /tmp in the jail. * fix tests to show the new mount location * fix small issues with conf not being read properly * install all server php versions in the user jail and remove fpm * Add validation for some unwanted shell with jail combinations * Add unzip, zip and zstd to jail * remove cli docs reference * fix spacing in v-list-user * make default jail enabled no * change way ssl certificates are handled * fixed jail errors for groups and added node and npm
1 parent e076333 commit 417db77

29 files changed

+792
-71
lines changed

bin/v-add-sys-ssh-jail

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/bin/bash
2+
# info: add system ssh jail
3+
# options: [RESTART]
4+
#
5+
# example: v-add-sys-ssh-jail yes
6+
#
7+
# This function enables ssh jailed environment.
8+
9+
#----------------------------------------------------------#
10+
# Variables & Functions #
11+
#----------------------------------------------------------#
12+
13+
# Includes
14+
# shellcheck source=/etc/hestiacp/hestia.conf
15+
source /etc/hestiacp/hestia.conf
16+
# shellcheck source=/usr/local/hestia/func/main.sh
17+
source $HESTIA/func/main.sh
18+
# load config file
19+
source_conf "$HESTIA/conf/hestia.conf"
20+
21+
restart=$1
22+
23+
#----------------------------------------------------------#
24+
# Verifications #
25+
#----------------------------------------------------------#
26+
27+
# Checking if jailkit is installed
28+
if [ ! -x /sbin/jk_init ]; then
29+
exit
30+
fi
31+
32+
# Perform verification if read-only mode is enabled
33+
check_hestia_demo_mode
34+
35+
#----------------------------------------------------------#
36+
# Action #
37+
#----------------------------------------------------------#
38+
39+
# Checking sshd directives
40+
config='/etc/ssh/sshd_config'
41+
ssh_i=$(grep -n "^# Hestia SSH Chroot" $config)
42+
43+
# Enabling jailed ssh
44+
if [ -z "$ssh_i" ]; then
45+
echo " " >> $config
46+
echo "# Hestia SSH Chroot" >> $config
47+
echo "Match Group ssh-jailed" >> $config
48+
echo " ChrootDirectory /srv/jail/%u" >> $config
49+
echo " X11Forwarding no" >> $config
50+
echo " AllowTCPForwarding no" >> $config
51+
restart='yes'
52+
fi
53+
54+
# Validating opensshd config
55+
if [ "$restart" = 'yes' ]; then
56+
subj="OpenSSH restart failed"
57+
email=$(grep CONTACT "$HESTIA/data/users/$ROOT_USER/user.conf" | cut -f 2 -d \')
58+
/usr/sbin/sshd -t > /dev/null 2>&1
59+
if [ "$?" -ne 0 ]; then
60+
mail_text="OpenSSH can not be restarted. Please check config:
61+
\n\n$(/usr/sbin/sshd -t)"
62+
echo -e "$mail_text" | $SENDMAIL -s "$subj" $email
63+
else
64+
service sshd restart > /dev/null 2>&1
65+
fi
66+
fi
67+
68+
# Adding group
69+
groupadd ssh-jailed 2> /dev/null
70+
71+
# Checking jailkit init
72+
jk_init='/etc/jailkit/jk_init.ini'
73+
jk_php_i=$(grep -n "^# Hestia Jail Settings" $jk_init)
74+
75+
# Add PHP to jailkit init to allow usage of it within jail
76+
if [ -z "$jk_php_i" ]; then
77+
cp -f $HESTIA_COMMON_DIR/jailkit/jk_init.ini /etc/jailkit
78+
fi
79+
80+
# Restart ssh service
81+
if [ "$restart" = 'no' ]; then
82+
# Skip restart of SSH daemon
83+
echo "" > /dev/null 2>&1
84+
else
85+
service ssh restart > /dev/null 2>&1
86+
fi
87+
88+
# Jails need maintenance to update the binaries within the jail. To do so we just reset the chroot
89+
# and reapply the jail
90+
for user in $("$BIN/v-list-users" list); do
91+
check_jail_enabled=$(grep "SHELL_JAIL_ENABLED='yes'" $HESTIA/data/users/$user/user.conf)
92+
93+
# If jail enabled try to jail the user
94+
if [ -n "$check_jail_enabled" ]; then
95+
$BIN/v-add-user-ssh-jail "$user" "no"
96+
fi
97+
done
98+
99+
# Add v-add-sys-ssh-jail to startup
100+
if [ ! -e "/etc/cron.d/hestia-ssh-jail" ]; then
101+
echo "@reboot root sleep 60 && /usr/local/hestia/bin/v-add-sys-ssh-jail > /dev/null" > /etc/cron.d/hestia-ssh-jail
102+
fi
103+
104+
#----------------------------------------------------------#
105+
# Hestia #
106+
#----------------------------------------------------------#
107+
108+
# Logging
109+
log_event "$OK" "$ARGUMENTS"
110+
111+
exit

bin/v-add-user

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ check_hestia_demo_mode
6969
pkg_data=$(cat $HESTIA/data/packages/$package.pkg | egrep -v "TIME|DATE")
7070

7171
# Checking shell
72-
shell_conf=$(echo "$pkg_data" | grep 'SHELL' | cut -f 2 -d \')
72+
shell_conf=$(echo "$pkg_data" | grep -m1 'SHELL' | cut -f 2 -d \')
7373
shell=$(grep -w "$shell_conf" /etc/shells | head -n1)
7474

7575
# Adding user
@@ -274,6 +274,11 @@ fi
274274
# Adding jailed sftp env
275275
$BIN/v-add-user-sftp-jail $user
276276

277+
# Adding jailed ssh env
278+
if [ "$SHELL_JAIL_ENABLED" = 'yes' ]; then
279+
$BIN/v-add-user-ssh-jail $user
280+
fi
281+
277282
#----------------------------------------------------------#
278283
# Hestia #
279284
#----------------------------------------------------------#

bin/v-add-user-package

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ is_package_consistent() {
8181
fi
8282

8383
is_format_valid_shell "$SHELL"
84+
is_boolean_format_valid "$SHELL_JAIL_ENABLED" 'SHELL_JAIL_ENABLED'
8485
}
8586

8687
#----------------------------------------------------------#
@@ -132,6 +133,7 @@ DISK_QUOTA='$DISK_QUOTA'
132133
BANDWIDTH='$BANDWIDTH'
133134
NS='$NS'
134135
SHELL='$SHELL'
136+
SHELL_JAIL_ENABLED='$SHELL_JAIL_ENABLED'
135137
BACKUPS='$BACKUPS'
136138
TIME='$time'
137139
DATE='$date'

bin/v-add-user-ssh-jail

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#!/bin/bash
2+
# info: add user ssh jail
3+
# options: USER [RESTART]
4+
#
5+
# example: v-add-user-ssh-jail admin
6+
#
7+
# This function enables ssh jailed environment
8+
9+
#----------------------------------------------------------#
10+
# Variables & Functions #
11+
#----------------------------------------------------------#
12+
13+
# Argument definition
14+
user=$1
15+
restart=$3
16+
17+
# Includes
18+
# shellcheck source=/etc/hestiacp/hestia.conf
19+
source /etc/hestiacp/hestia.conf
20+
# shellcheck source=/usr/local/hestia/func/main.sh
21+
source $HESTIA/func/main.sh
22+
# load config file
23+
source_conf "$HESTIA/conf/hestia.conf"
24+
25+
chroot="/srv/jail/$user"
26+
27+
#----------------------------------------------------------#
28+
# Verifications #
29+
#----------------------------------------------------------#
30+
31+
# Checking if jailkit is installed
32+
if [ ! -x /sbin/jk_init ]; then
33+
exit
34+
fi
35+
36+
check_args '1' "$#" 'USER'
37+
is_format_valid 'user'
38+
39+
# Perform verification if read-only mode is enabled
40+
check_hestia_demo_mode
41+
42+
#----------------------------------------------------------#
43+
# Action #
44+
#----------------------------------------------------------#
45+
46+
# Get shell full path
47+
shell_path=$(grep "^$user:" /etc/passwd | cut -f 7 -d :)
48+
49+
# Set home folder permission to root
50+
if [ -d "/home/$user" ]; then
51+
chown root:root /home/$user
52+
fi
53+
54+
add_chroot_jail "$user"
55+
56+
# Add user to the ssh-jailed group to allow jailed ssh
57+
# This needs to be done first to make sure these groups are made available in the jail
58+
usermod -a -G ssh-jailed $user
59+
60+
# Installing shell files into the user chroot directory
61+
# - IMPORTANT - MODIFY THE FOLLOWING LINES AND THE FILE jk_init.ini ACCORDING TO YOUR SYSTEM AND YOUR PREFERENCES
62+
/sbin/jk_init -f -j $chroot extendedshell netutils ssh sftp scp git php php5_6 php7_0 php7_1 php7_2 php7_3 php7_4 php8_0 php8_1 php8_2 > /dev/null 2>&1
63+
/sbin/jk_cp -f -j $chroot /bin/id > /dev/null 2>&1
64+
65+
# Jailing user to make sure passwd and groups are set correctly within the jail.
66+
# This command also does a little too much by changing the users homedir and
67+
# shell in /etc/passwd. The next commands reverts those changes for compatibility
68+
# with hestia.
69+
/sbin/jk_jailuser -n -s $shell_path -j $chroot $user
70+
71+
# Reset home directory and shell again for hestiacp because jailkit changes these.
72+
# Normally these are needed to redirect the ssh user to it's chroot but because we
73+
# use a custom sshd_config to redirect the user to it's chroot we don't need it to be
74+
# changed in /etc/passwd for the user.
75+
usermod -d /home/$user $user
76+
usermod -s $shell_path $user
77+
78+
#----------------------------------------------------------#
79+
# Hestia #
80+
#----------------------------------------------------------#
81+
82+
# Enabling user jail
83+
update_user_value "$user" '$SHELL_JAIL_ENABLED' "yes"
84+
85+
# Restart ssh service
86+
if [ "$restart" = 'no' ]; then
87+
# Skip restart of SSH daemon
88+
echo "" > /dev/null 2>&1
89+
else
90+
service sshd restart > /dev/null 2>&1
91+
fi
92+
93+
# Logging
94+
log_event "$OK" "$ARGUMENTS"
95+
96+
exit

bin/v-change-user-package

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ DISK_QUOTA='$DISK_QUOTA'
9999
BANDWIDTH='$BANDWIDTH'
100100
NS='$NS'
101101
SHELL='$SHELL'
102+
SHELL_JAIL_ENABLED='$SHELL_JAIL_ENABLED'
102103
BACKUPS='$BACKUPS'
103104
CONTACT='$CONTACT'
104105
CRON_REPORTS='$CRON_REPORTS'
@@ -169,8 +170,9 @@ check_hestia_demo_mode
169170
change_user_package
170171

171172
# Update user shell
172-
shell_conf=$(cat "$HESTIA/data/packages/$package.pkg" | grep 'SHELL' | cut -f 2 -d \')
173-
$BIN/v-change-user-shell "$user" "$shell_conf"
173+
shell_conf=$(cat "$HESTIA/data/packages/$package.pkg" | grep -m1 'SHELL' | cut -f 2 -d \')
174+
shell_jail_enabled_conf=$(cat "$HESTIA/data/packages/$package.pkg" | grep 'SHELL_JAIL_ENABLED' | cut -f 2 -d \')
175+
$BIN/v-change-user-shell "$user" "$shell_conf" "$shell_jail_enabled_conf"
174176

175177
# Run template trigger
176178
if [ -x "$HESTIA/data/packages/$package.sh" ]; then

bin/v-change-user-shell

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/bin/bash
22
# info: change user shell
3-
# options: USER SHELL
3+
# options: USER SHELL JAIL_ENABLED
44
#
5-
# example: v-change-user-shell admin nologin
5+
# example: v-change-user-shell admin nologin no
66
#
77
# This function changes system shell of a user. Shell gives ability to use ssh.
88

@@ -13,6 +13,7 @@
1313
# Argument definition
1414
user=$1
1515
shell=$2
16+
shell_jail_enabled=${3-no}
1617

1718
# Includes
1819
# shellcheck source=/etc/hestiacp/hestia.conf
@@ -26,8 +27,8 @@ source $HESTIA/conf/hestia.conf
2627
# Verifications #
2728
#----------------------------------------------------------#
2829

29-
check_args '2' "$#" 'USER SHELL'
30-
is_format_valid 'user' 'shell'
30+
check_args '3' "$#" 'USER SHELL SHELL_JAIL_ENABLED'
31+
is_format_valid 'user' 'shell shell_jail_enabled'
3132
is_object_valid 'user' 'USER' "$user"
3233
is_object_unsuspended 'user' 'USER' "$user"
3334

@@ -52,6 +53,13 @@ else
5253
$BIN/v-delete-user-sftp-jail "$user" > /dev/null 2>&1
5354
fi
5455

56+
# Adding jailed ssh env
57+
if [[ "$shell_jail_enabled" =~ yes ]]; then
58+
$BIN/v-add-user-ssh-jail "$user" > /dev/null 2>&1
59+
else
60+
$BIN/v-delete-user-ssh-jail "$user" > /dev/null 2>&1
61+
fi
62+
5563
#----------------------------------------------------------#
5664
# Hestia #
5765
#----------------------------------------------------------#

bin/v-delete-sys-ssh-jail

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/bin/bash
2+
# info: delete system ssh jail
3+
# options: NONE
4+
#
5+
# example: v-delete-sys-ssh-jail
6+
#
7+
# This function disables ssh jailed environment
8+
9+
#----------------------------------------------------------#
10+
# Variables & Functions #
11+
#----------------------------------------------------------#
12+
13+
# Includes
14+
# shellcheck source=/etc/hestiacp/hestia.conf
15+
source /etc/hestiacp/hestia.conf
16+
# shellcheck source=/usr/local/hestia/func/main.sh
17+
source $HESTIA/func/main.sh
18+
# load config file
19+
source_conf "$HESTIA/conf/hestia.conf"
20+
21+
#----------------------------------------------------------#
22+
# Verifications #
23+
#----------------------------------------------------------#
24+
25+
# Perform verification if read-only mode is enabled
26+
check_hestia_demo_mode
27+
28+
#----------------------------------------------------------#
29+
# Action #
30+
#----------------------------------------------------------#
31+
32+
# Checking sshd directives
33+
config='/etc/ssh/sshd_config'
34+
ssh_i=$(grep -n "^# Hestia SSH Chroot" $config)
35+
36+
# Backing up config
37+
cp $config $config.bak
38+
39+
# Disabling jailed ssh
40+
if [ -n "$ssh_i" ]; then
41+
fline=$(echo "$ssh_i" | cut -f 1 -d :)
42+
lline=$((fline + 4))
43+
sed -i "${fline},${lline}d" $config
44+
restart='yes'
45+
fi
46+
47+
# Validating opensshd config
48+
if [ "$restart" = 'yes' ]; then
49+
subj="OpenSSH restart failed"
50+
email=$(grep CONTACT "$HESTIA/data/users/$ROOT_USER/user.conf" | cut -f 2 -d \')
51+
/usr/sbin/sshd -t > /dev/null 2>&1
52+
if [ "$?" -ne 0 ]; then
53+
mail_text="OpenSSH can not be restarted. Please check config:
54+
\n\n$(/usr/sbin/sshd -t)"
55+
echo -e "$mail_text" | $SENDMAIL -s "$subj" $email
56+
else
57+
service sshd restart > /dev/null 2>&1
58+
fi
59+
fi
60+
61+
# Remove group ssh-jailed
62+
groupdel ssh-jailed 2> /dev/null
63+
64+
#----------------------------------------------------------#
65+
# Hestia #
66+
#----------------------------------------------------------#
67+
68+
# Logging
69+
$BIN/v-log-action "system" "Warning" "Plugins" "SSH Chroot Jail disabled."
70+
log_event "$OK" "$ARGUMENTS"
71+
72+
exit

bin/v-delete-user

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ sed -i "/ $user$/d" "$HESTIA/data/queue/traffic.pipe"
8989
# Deleting sftp jail
9090
$BIN/v-delete-user-sftp-jail "$user"
9191

92+
# Deleting ssh jail
93+
$BIN/v-delete-user-ssh-jail "$user"
94+
9295
# Deleting system user
9396
/usr/sbin/userdel -f "$user" >> /dev/null 2>&1
9497
if [ $? -ne 0 ]; then

0 commit comments

Comments
 (0)