Restricting administrative operations in SSH
About this page
This page explains you how to restrict administrative operations by selecting roles before starting SSH login shell.
Step 1: Compiling the program
Decide what roles you want to define. In this page, we use 3 roles ("Web server administrator", "Mail server administrator", "Security administrator").
Compile the below program. In this page, we assume the location of compiled program as /bin/sshd_login . We assume the location of SSH server program as /usr/sbin/sshd .
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <syslog.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define SSHD_EXECUTABLE_PATH "/usr/sbin/sshd" int main(int raw_argc, char *raw_argv[]) { int i; int argc; int envc; char *filename; char **argv; char **envp; { /* Check that I'm an execute handler process. */ int fd = open("/proc/ccs/.execute_handler", O_RDONLY); close(fd); if (fd == EOF) { fprintf(stderr, "FATAL: I'm not execute_handler.\n"); return 1; } } if (raw_argc < 7) return 1; filename = raw_argv[4]; argc = atoi(raw_argv[5]); envc = atoi(raw_argv[6]); if (raw_argc != argc + envc + 7) return 1; for (i = 5; i < argc + 5; i++) raw_argv[i] = raw_argv[i + 2]; raw_argv[argc + 5] = NULL; for (i = argc + 6; i < argc + envc + 6; i++) raw_argv[i] = raw_argv[i + 1]; raw_argv[argc + envc + 6] = NULL; argv = raw_argv + 5; envp = raw_argv + argc + 6; /* "/usr/sbin/sshd" executes "/usr/sbin/sshd" with "-R" option. */ if (argc == 2 && !strcmp(argv[1], "-R") && !strcmp(raw_argv[2], SSHD_EXECUTABLE_PATH) && !strcmp(filename, SSHD_EXECUTABLE_PATH)) { execve(filename, argv, envp); return 1; } /* Don't allow 'shell -c "command"' request. */ if (argc == 3 && !strcmp(argv[1], "-c")) { fprintf(stderr, "You are not permitted to run %s\n", argv[2]); return 1; } printf("Select your role.\n\n"); printf("1: Web administrator\n"); printf("2: Mail administrator\n"); printf("3: Security administrator\n\n"); while (1) { int c = getchar(); if (c == EOF) break; if (c == '1') { execve("/bin/webadmin-auth", argv, envp); break; } if (c == '2') { execve("/bin/mailadmin-auth", argv, envp); break; } if (c == '3') { execve("/bin/securityadmin-auth", argv, envp); break; } } return 1; }
Save the program listed below as /bin/webadmin-auth and set executable bit.
#! /bin/sh echo "Enter password for web administrator." stty -echo read stty echo [ "$REPLY" == "webadmin" ] && exec /bin/bash echo "Authentication failure" sleep 5 exit 1
Save the program listed below as /bin/mailadmin-auth and set executable bit.
#! /bin/sh echo "Enter password for mail administrator." stty -echo read stty echo [ "$REPLY" == "mailadmin" ] && exec /bin/bash echo "Authentication failure" sleep 5 exit 1
Save the program listed below as /bin/securityadmin-auth and set executable bit.
#! /bin/sh echo "Enter password for security administrator." stty -echo read stty echo [ "$REPLY" == "securityadmin" ] && exec /bin/bash echo "Authentication failure" sleep 5 exit 1
Step 2: Install and initialize AKARI
Install AKARI and run below commandline in order to initialize AKARI.
# /usr/lib/ccs/init_policy --module_name=akari
Then, please do below operations before you reboot using AKARI kernel.
Append below line to /etc/ccs/exception_policy.conf in order to initialize domain transition when /usr/sbin/sshd is executed.
initialize_domain /usr/sbin/sshd from any
Append below lines to /etc/ccs/domain_policy.conf so that program execution requests from /usr/sbin/sshd are passed to /bin/sshd_login .
<kernel> /usr/sbin/sshd task auto_execute_handler /bin/sshd_login
Step 3: Learning and operation
Now, you are ready to start operation. Please reboot using AKARI kernel.
Access the SSH server. Confirm that a prompt is shown by /bin/sshd_login after passing existing SSH authentication. Logout the SSH session by pressing Ctrl-C. Now, the domain for /bin/sshd_login was created as "<kernel> /usr/sbin/sshd /bin/sshd_login".
Change access control mode to learning mode by assigning profile 1 so that we can restrict operations from /bin/sshd_login .
# /usr/sbin/ccs-setprofile -r 1 '<kernel> /usr/sbin/sshd /bin/sshd_login'
Access the SSH server. Please select 1 for the prompt shown by /bin/sshd_login and enter "webadmin" to the prompt shown by /bin/webadmin-auth . Now, the domain for "Web server administrator" was created as "<kernel> /usr/sbin/sshd /bin/sshd_login /bin/webadmin-auth /bin/bash".
Then, please do operations you want to allow for "Web server administrator". In the above movie, below operations are done.
# service httpd restart # cd /var/www/html/ # tar -zxf ~/htdocs.tar.gz --strip 1 # less /var/log/httpd/access_log
Logout from the SSH session after you finished doing all operations you want to allow.
Access the SSH server. Please select 2 for the prompt shown by /bin/sshd_login and enter "mailadmin" for the prompt shown by /bin/mailadmin-auth . Now, the domain for "Mail server administrator" was created as "<kernel> /usr/sbin/sshd /bin/sshd_login /bin/mailadmin-auth /bin/bash".
Then, please do operations you want to allow for "Mail server administrator". In the above movie, below operations are done.
# service sendmail restart # mailq # less /var/log/maillog
Logout from the SSH session after you finished doing all operations you want to allow.
Access the SSH server. Please select 3 for the prompt shown by /bin/sshd_login and enter "securityadmin" for the prompt shown by /bin/securityadmin-auth . Now, the domain for "Security administrator" was created as "<kernel> /usr/sbin/sshd /bin/sshd_login /bin/securityadmin-auth /bin/bash".
Then, please do operations you want to allow for "Security administrator". In the above movie, below operations are done.
# less /var/log/tomoyo/reject_log.conf
Logout from the SSH session after you finished doing all operations you want to allow.
Change access control mode to permissive mode by assigning profile 2 and verify that you can do operations you want to allow.
# /usr/sbin/ccs-setprofile -r 2 '<kernel> /usr/sbin/sshd /bin/sshd_login'
Change access control mode to enforcing mode by assigning profile 3. Now, the operations are restricted.
# /usr/sbin/ccs-setprofile -r 3 '<kernel> /usr/sbin/sshd /bin/sshd_login'
Explanation
We divide roles in the following way. We insert 3 programs ( /bin/webadmin-auth /bin/mailadmin-auth /bin/securityadmin-auth ) between /usr/sbin/sshd and login shell for SSH session. As a result, we get 3 domains with different parent domain ("<kernel> /usr/sbin/sshd /bin/sshd_login /bin/webadmin-auth /bin/bash", "<kernel> /usr/sbin/sshd /bin/sshd_login /bin/mailadmin-auth /bin/bash", "<kernel> /usr/sbin/sshd /bin/sshd_login /bin/securityadmin-auth /bin/bash" ). We assign these 3 domains to 3 roles ("Web server administrator", "Mail server administrator", "Security administrator") by granting only necessary operations for each domain. Since these programs are just for example, we used simple shell scripts. When you use at real systems, please use appropriate programs with appropriate authentication functionality.
AKARI's execute_handler functionality intercepts program execution requests from /usr/sbin/sshd and passes the program execution requests to /bin/sshd_login . Then, /bin/sshd_login shows a prompt for selecting role and receives response from the user.
The role selection is applied after SSH authentication. Thus, operations without shell execution (e.g. TCP port forwarding) are permitted. If you want to restrict operations without shell execution, you need to develop policy for SSH server process and apply enforcing mode to the SSH server processes.
Regarding within each domain, domain transition occurs whenever a program is executed. If you want to suppress domain transition within each domain, you can append "keep_domain" lines (like shown below) to /etc/ccs/exception_policy.conf .
keep_domain any from <kernel> /usr/sbin/sshd /bin/sshd_login /bin/webadmin-auth /bin/bash keep_domain any from <kernel> /usr/sbin/sshd /bin/sshd_login /bin/mailadmin-auth /bin/bash keep_domain any from <kernel> /usr/sbin/sshd /bin/sshd_login /bin/securityadmin-auth /bin/bash