References for the content of this article:
Summary of Linux security module AppArmor - CSDN blog ,
AppArmor Configuration (2)_domybest_nsg's Blog-CSDN Blog
Continued from the previous article: AppArmor Zero Knowledge Learning Thirteen, Practice and Practice (1)
The previous article enabled AppArmor, but currently there are no applications with configuration files in the system. This article will add access control rules so that there are applications with configuration files in the system.
2. Add access control rules
1. Write the test routine
First write a test routine, the code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
FILE *f;
int i = 0;
char ch;
if(3 == argc)
{
f = fopen(argv[1], "w");
if(!f)
{
fprintf(stderr, "fopen failed with w, error: %s\n", strerror(errno));
return 2;
}
while(i < strlen(argv[2]))
{
fputc(argv[2][i], f);
i++;
}
fclose(f);
}
else if(argc == 2)
{
f = fopen(argv[1], "r");
if(!f)
{
fprintf(stderr, "fopen failed with r, error: %s\n", strerror(errno));
return 2;
}
while((ch=fgetc(f)) != EOF)
printf(" %c", ch);
fclose(f);
}
else
{
printf("Usage:\n");
printf("\ttest_app file \"string\"\n");
printf("\ttest_app file\n");
return 3;
}
return 0;
}
Compile and simply test the test routine. As follows:
$ gcc test_app.c -o test_app
$ ls
test_app test_app.c
$ ./test_app kkk
fopen failed with r, error: No such file or directory
$ ./test_app kkk 1234
$ ./test_app kkk
1 2 3 4
2. Create a rule
Use genprof to create rules. Proceed as follows:
(1) Go to the directory where the test routine is created
penghao@Ding-Perlis-MP260S48:~/AppArmor$ cd sample_code/
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls
kkk test_app test_app.c
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ rm kkk
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls
test_app test_app.c
(2) Create rules
$ aa-genprof test_app
正在在 /etc/apparmor.d 中更新 AppArmor 配置文件。Writing updated profile for /home/penghao/AppArmor/sample_code/test_app.
ERROR: [Errno 13] Permission denied: '/etc/apparmor.d/tmpdy6clx3q~'
Add sudo in front and execute the above command again:
$ sudo aa-genprof test_app
[sudo] penghao 的密码:正在在 /etc/apparmor.d 中更新 AppArmor 配置文件。Writing updated profile for /home/penghao/AppArmor/sample_code/test_app.
正在将 /home/penghao/AppArmor/sample_code/test_app 设置为投诉模式。
在开始之前,您可能希望检查您希望限制的应用程序的配置文件是否已经存在。有关详细信息,请参考以下维基页面:https://gitlab.com/apparmor/apparmor/wikis/Profiles
分析中: /home/penghao/AppArmor/sample_code/test_app
请启动要在另一个窗口中分析的应用程序,并立即执行其功能。
完成后,选择下面的“扫描”选项,以扫描系统日志中的AppArmor事件。
对于每个 AppArmor 事件,您将有机会选择是应允许还是拒绝访问。
[扫描系统日志以查找 AppArmor 事件(S)] / 完成(F)
Press the 'F' key (no need to enter) to complete the process as shown below:
[扫描系统日志以查找 AppArmor 事件(S)] / 完成(F)
正在设置 /home/penghao/AppArmor/sample_code/test_app 到强制模式
重启 AppArmor 到强制模式
请考虑贡献您的新配置文件!参阅以下 wiki 页面获取更多信息:https://gitlab.com/apparmor/apparmor/wikis/Profiles
已完成为 /home/penghao/AppArmor/sample_code/test_app 生成配置文件。
Check the content under /etc/apparmor.d/:
Compare with previous content:
It can be seen that the biggest change is that there is an additional home.penghao.AppArmor.sample_code.test_app file under /etc/apparmor.d/, and the file name is the absolute path of the file, but changed from '/' to '.' . The content of the file is as follows:
# Last Modified: Wed Apr 19 10:23:02 2023
abi <abi/3.0>,
include <tunables/global>
/home/penghao/AppArmor/sample_code/test_app {
include <abstractions/base>
/home/penghao/AppArmor/sample_code/test_app mr,
}
At this time, use the aa-status command mentioned in the previous article查看当前
AppArmor
的运行状态和具有配置文件的应用程序。命令及结果如下所示:
$ sudo aa-status
apparmor module is loaded.
1 profiles are loaded.
1 profiles are in enforce mode.
/home/penghao/AppArmor/sample_code/test_app
0 profiles are in complain mode.
0 profiles are in kill mode.
0 profiles are in unconfined mode.
0 processes have profiles defined.
0 processes are in enforce mode.
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
0 processes are in mixed mode.
0 processes are in kill mode.
Compare the results when no rules were set before:
$ sudo apparmor_status
apparmor module is loaded.
(3) Modify the rules
Modify the /etc/apparmor.d/home.penghao.AppArmor.sample_code.test_app file, and add the following content in the braces of the file:
/home/penghao/AppArmor/sample_code/abcde rwm,
/home/penghao/AppArmor/sample_code/abcd w,
/home/penghao/AppArmor/sample_code/abc r,
The former part is the file name, and the latter part is the permission.
The modified file content is as follows:
# Last Modified: Wed Apr 19 10:23:02 2023
abi <abi/3.0>,
include <tunables/global>
/home/penghao/AppArmor/sample_code/test_app {
include <abstractions/base>
/home/penghao/AppArmor/sample_code/test_app mr,
/home/penghao/AppArmor/sample_code/abcde rwm,
/home/penghao/AppArmor/sample_code/abcd w,
/home/penghao/AppArmor/sample_code/abc r,
}
(4) Reload
Execute the following command to reload:
sudo /etc/init.d/apparmor reload
The actual commands and results are as follows:
$ sudo /etc/init.d/apparmor reload
sudo: /etc/init.d/apparmor:找不到命令
In fact, the /etc/init.d/apparmor file is only available under Ubuntu. Since the author's computer system is not Ubuntu, this file does not exist. Copy the /etc/init.d/apparmor file under Ubuntu. The content of the file is as follows:
#!/bin/sh
# ----------------------------------------------------------------------
# Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
# NOVELL (All rights reserved)
# Copyright (c) 2008, 2009 Canonical, Ltd.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public
# License published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
# ----------------------------------------------------------------------
# Authors:
# Steve Beattie <[email protected]>
# Kees Cook <[email protected]>
#
# /etc/init.d/apparmor
#
# Note: "Required-Start: $local_fs" implies that the cache may not be available
# yet when /var is on a remote filesystem. The worst consequence this should
# have is slowing down the boot.
#
### BEGIN INIT INFO
# Provides: apparmor
# Required-Start: $local_fs
# Required-Stop: umountfs
# Default-Start: S
# Default-Stop:
# Short-Description: AppArmor initialization
# Description: AppArmor init script. This script loads all AppArmor profiles.
### END INIT INFO
APPARMOR_FUNCTIONS=/lib/apparmor/rc.apparmor.functions
# Functions needed by rc.apparmor.functions
. /lib/lsb/init-functions
aa_action() {
STRING=$1
shift
$*
rc=$?
if [ $rc -eq 0 ] ; then
aa_log_success_msg $"$STRING "
else
aa_log_failure_msg $"$STRING "
fi
return $rc
}
aa_log_action_start() {
log_action_begin_msg $@
}
aa_log_action_end() {
log_action_end_msg $@
}
aa_log_success_msg() {
log_success_msg $@
}
aa_log_warning_msg() {
log_warning_msg $@
}
aa_log_failure_msg() {
log_failure_msg $@
}
aa_log_skipped_msg() {
if [ -n "$1" ]; then
log_warning_msg "${1}: Skipped."
fi
}
aa_log_daemon_msg() {
log_daemon_msg $@
}
aa_log_end_msg() {
log_end_msg $@
}
# Source AppArmor function library
if [ -f "${APPARMOR_FUNCTIONS}" ]; then
. ${APPARMOR_FUNCTIONS}
else
aa_log_failure_msg "Unable to find AppArmor initscript functions"
exit 1
fi
usage() {
echo "Usage: $0 {start|stop|restart|reload|force-reload|status}"
}
test -x ${PARSER} || exit 0 # by debian policy
# LSM is built-in, so it is either there or not enabled for this boot
test -d /sys/module/apparmor || exit 0
# do not perform start/stop/reload actions when running from liveCD
test -d /rofs/etc/apparmor.d && exit 0
rc=255
case "$1" in
start)
if [ -x /usr/bin/systemd-detect-virt ] && \
systemd-detect-virt --quiet --container && \
! is_container_with_internal_policy; then
aa_log_daemon_msg "Not starting AppArmor in container"
aa_log_end_msg 0
exit 0
fi
apparmor_start
rc=$?
;;
restart|reload|force-reload)
if [ -x /usr/bin/systemd-detect-virt ] && \
systemd-detect-virt --quiet --container && \
! is_container_with_internal_policy; then
aa_log_daemon_msg "Not starting AppArmor in container"
aa_log_end_msg 0
exit 0
fi
apparmor_restart
rc=$?
;;
stop)
aa_log_daemon_msg "Leaving AppArmor profiles loaded"
cat >&2 <<EOM
No profiles have been unloaded.
Unloading profiles will leave already running processes permanently
unconfined, which can lead to unexpected situations.
To set a process to complain mode, use the command line tool
'aa-complain'. To really tear down all profiles, run 'aa-teardown'."
EOM
;;
status)
apparmor_status
rc=$?
;;
*)
usage
rc=1
;;
esac
exit $rc
Execute the reload command again, the result is as follows:
$ sudo /etc/init.d/apparmor reload
sudo: /etc/init.d/apparmor:找不到命令
Executable permissions need to be added, the commands and results are as follows:
$ ls /etc/init.d/ -l
总计 12
-rw-rw-r-- 1 root root 3740 4月19日 14:36 apparmor
-rwxr-xr-x 1 root root 1893 2月15日 03:03 fuse
-rw-r--r-- 1 root root 1151 2月15日 00:36 README
$ sudo chmod 755 /etc/init.d/apparmor
$
$ ls /etc/init.d/ -l
总计 12
-rwxr-xr-x 1 root root 3740 4月19日 14:36 apparmor
-rwxr-xr-x 1 root root 1893 2月15日 03:03 fuse
-rw-r--r-- 1 root root 1151 2月15日 00:36 README
Execute again, the result is as follows:
$ sudo /etc/init.d/apparmor reload
/etc/init.d/apparmor:行43: /lib/lsb/init-functions: 没有那个文件或目录
Under Ubuntu, there will be a /lib/lsb/init-functions file, which is not in the author's system. Don't "toss", restart directly, and see if it takes effect after restarting.
3. Test
Enter the directory where the routine is located, and execute the following commands in sequence:
$ pwd
/home/penghao/AppArmor/sample_code
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls
apparmor test_app test_app.c
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abc 1abc
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcd 2abcd
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcde 3abcde
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls
abc abcd abcde apparmor test_app test_app.c
It can be seen that the three files can be generated normally, and the contents of the three files are checked in turn:
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abc
1abc
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcd
2abcd
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcde
3abcde
There are also file contents. Then there is a problem, the above rules:
/home/penghao/AppArmor/sample_code/abcde rwm,
/home/penghao/AppArmor/sample_code/abcd w,
/home/penghao/AppArmor/sample_code/abc r,
It is required that abc can only be read, and abcd can only be written. Why didn't it work? View the system log /var/log/syslog, theoretically you should be able to see information similar to the following:
kernel: [140321.028000] audit(1191433716.584:1578): type=1502 operation=”inode_create” requested_mask=”w” denied_mask=”w” name=”/home/n1/Desktop/abc” pid=4864 profile=”/home/n1/Desktop/testapp”
kernel: [140362.236000] audit(1191433758.086:1579): type=1502 operation=”inode_permission” requested_mask=”r” denied_mask=”r” name=”/home/n1/Desktop/abcd” pid=4877 profile=”/home/n1/Desktop/testapp”
Indicates that although the operation is allowed, the abc file is "booked" when it is written, and the abcd file is "booked" when it is read. Because they do not have corresponding permissions in /etc/apparmor.d/home.penghao.AppArmor.sample_code.test_app. But unfortunately, the author did not see similar information under /var/log/syslog. It may be that there are still some problems with the configuration of AppArmor logs.
Regardless of this problem, let's take a look at the situation when it is set to enforce, that is, mandatory mode.
Execute the following command to enter enforcing mode:
$ sudo aa-enforce /etc/apparmor.d/home.penghao.AppArmor.sample_code.test_app
正在设置 /etc/apparmor.d/home.penghao.AppArmor.sample_code.test_app 到强制模式
At this time, execute the above three commands in sequence again (first delete the previously generated abc, abcd, abcde files), and the results are as follows:
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ rm abc
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ rm abcd
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ rm abcde
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abc 1abc
fopen failed with w, error: Permission denied
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abc
cat: abc: 没有那个文件或目录
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ echo "1abc" > abc
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls abc
abc
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abc
1abc
It can be seen that test_app only has read permission and no write permission for the abc file, and other programs (processes) are not subject to this restriction.
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcd 2abcd
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls abcd
abcd
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcd
fopen failed with r, error: Permission denied
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcd
2abcd
It can be seen that test_app only has write permission to the abcd file, but no read permission, and other programs (processes) have no such restrictions.
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcde 3abcde
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ls abcde
abcde
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcde
3 a b c d e
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcde
3abcde
It can be seen that test_app has both write permission and read permission for the abcde file, which is the most normal.
If the permission of the abcde file is set to 0444, let's take a look at the result:
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ chmod 444 abcde
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ echo "1abc" > abcde
bash: abcde: 权限不够
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app 1abc abcde
fopen failed with w, error: Permission denied
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ cat abcde
3abcde
penghao@Ding-Perlis-MP260S48:~/AppArmor/sample_code$ ./test_app abcde
3 a b c d e
The above test shows that in the enhanced (enforce) mode, apparmor works normally.
The above is the simplest application. Create a rule file through aa-genprof, and only add the minimum required file read and write permission rules, which
can realize the read and write file control of an unknown program in addition to the file system permission (the file name in the rule file The path can contain wildcards).
To cancel, just delete the corresponding file under /etc/apparmor.d/ and restart the apparmor service.