基于Debian的AppArmor配置

AppArmor介绍

AppArmor是一个有效且易于使用的Linux应用安全系统。AppArmor通过执行良好的行为并防止已知和未知的应用程序缺陷被利用,主动保护操作系统和应用程序免受外部或内部威胁,甚至是零日攻击。

AppArmor通过提供强制访问控制(mandatory access control, MAC)来补充传统的Unix自主存取控制(discretionary access control, DAC)模式。自2.6.36版以来,它已经包含在Linux的主线内核中。

自主存取控制(Discretionary Access Control 简称DAC):

  • 用户对不同的数据对象有不同的存取权限
  • 不同的用户对同一对象也有不同的权限
  • 用户还可以将其拥有的存取权限转授给其他用户 ACL(访问控制列表)就是DAC的一种实现

强制存取控制(Mandatory Access Control 简称 MAC):

  • 每一个数据库对象被标以一定的密级
  • 每一个用户被授予某一个级别的许可证
  • 对于任意一个对象,只有具备合法许可证的用户才可以存取

AppArmor是一个建立在Linux的LSM(Linux安全模块)接口上的强制访问控制(MAC)系统。在实践中,内核在每次系统调用之前都会查询AppArmor,以了解进程是否被授权进行特定的操作。通过这种机制,AppArmor将程序限制在一组有限的资源中。

官方网站: https://apparmor.net/

AppArmor对每个程序应用一套规则(配置文件,profile)。被内核所应用的配置文件取决于正在执行的程序的安装路径。与SELinux相反,应用的配置文件不取决于用户。所有的用户在执行同一个程序时都面临着相同的规则(但传统的用户权限仍然适用,可能会导致不同的行为)。

AppArmor的配置文件保存在/etc/apparmor.d/。它们包含了每个程序可以利用的资源的访问控制规则列表。这些配置文件可以利用apparmor_parser命令进行编译和加载到内存。

假设有一个应用程序保存在/usr/local/bin/test,如果要使用AppArmor对其进行访问控制的话,需要在/etc/apparmor.d/文件夹下创建一个配置文件usr.local.bin.test

每个配置文件都能被以强制(enforcing)或者学习(complaining/learning)模式加载。

  • Enforcing模式下,配置文件里列出的限制条件都会得到执行,并且对于违反这些限制条件的程序会进行日志记录。
  • Compalining模式下,配置文件里的限制条件不会得到执行,Apparmor只是对程序的行为进行记录。例如程序可以写一个在配置文件里注明只读的文件,但Apparmor不会对程序的行为进行限制,只是进行记录。

启用AppArmor与管理配置文件

Debian原生提供AppArmor的内置内核支持。

使用以下命令即可启用:

1
# apt install apparmor apparmor-profiles apparmor-utils

使用以下命令确认安装情况:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# aa-status
apparmor module is loaded.
32 profiles are loaded.
15 profiles are in enforce mode.
   /usr/bin/man
[...]
17 profiles are in complain mode.
   /usr/sbin/dnsmasq
[...]
1 processes have profiles defined.
1 processes are in enforce mode.
   /usr/sbin/libvirtd (468) libvirtd
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.

apparmor-profiles软件包包含由上游AppArmor社区管理的配置文件。要获得更多的配置文件,你可以安装apparmor-profiles-extra,它包含由Ubuntu和Debian社区开发的配置文件。

通过调用aa-enforceaa-complain,每个配置文件的状态可以在enforcingcomplaining之间切换,并给出可执行文件的路径或策略文件的路径作为参数。

此外,一个配置文件可以通过aa-disable完全禁用,或者通过aa-audit进入审计模式(同时记录接受的system calls)。

1
2
# aa-enforce /usr/bin/pidgin
Setting /usr/bin/pidgin to enforce mode.
1
2
# aa-complain /usr/sbin/dnsmasq
Setting /usr/sbin/dnsmasq to complain mode.

创建配置文件

尽管创建AppArmor的配置文件非常简单,但大多数程序没有预置规则。

需要限制的最重要的程序是面向网络的程序,因为这些程序是远程攻击者最可能的目标。

这就是为什么AppArmor提供了一个便捷的命令aa-unconfined来列出没有相关的配置文件而且暴露开放的网络套接字(network sockets)的程序。使用--paranoid选项,可以得到至少有一个活动网络连接的所有非封闭进程。

1
2
3
4
 --paranoid
   Displays all processes from /proc filesystem with 
   tcp or udp ports that do not have AppArmor profiles 
   loaded.

更多指令查询:https://manpages.ubuntu.com/manpages/kinetic/en/man8/aa-unconfined.8.html

通过aa-genprof命令可以快速创建配置文件。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# aa-genprof dhclient
Writing updated profile for /usr/sbin/dhclient.
Setting /usr/sbin/dhclient to complain mode.

Before you begin, you may wish to check if a
profile already exists for the application you
wish to confine. See the following wiki page for
more information:
https://gitlab.com/apparmor/apparmor/wikis/Profiles

Profiling: /usr/sbin/dhclient

Please start the application to be profiled in
another window and exercise its functionality now.

Once completed, select the "Scan" option below in 
order to scan the system logs for AppArmor events. 

For each AppArmor event, you will be given the 
opportunity to choose whether the access should be 
allowed or denied.

[(S)can system log for AppArmor events] / (F)inish
S
Reading log entries from /var/log/syslog.

Profile:  /usr/sbin/dhclient 1
Execute:  /usr/sbin/dhclient-script
Severity: unknown

(I)nherit / (C)hild / (P)rofile / (N)amed / (U)nconfined / (X) ix On / (D)eny / Abo(r)t / (F)inish
P

Should AppArmor sanitise the environment when
switching profiles?

Sanitising environment is more secure,
but some applications depend on the presence
of LD_PRELOAD or LD_LIBRARY_PATH.

[(Y)es] / (N)o
Y
Writing updated profile for /usr/sbin/dhclient-script.
Complain-mode changes:

Profile:    /usr/sbin/dhclient 2
Capability: net_raw
Severity:   8

 [1 - capability net_raw,]
(A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish
A
Adding capability net_raw, to profile.

Profile:    /usr/sbin/dhclient
Capability: net_bind_service
Severity:   8

 [1 - #include <abstractions/nis>]
  2 - capability net_bind_service,
(A)llow / [(D)eny] / (I)gnore / Audi(t) / Abo(r)t / (F)inish
A
Adding #include <abstractions/nis> to profile.

Profile:  /usr/sbin/dhclient 3
Path:     /etc/ssl/openssl.cnf
New Mode: owner r
Severity: 2

 [1 - #include <abstractions/lightdm>]
  2 - #include <abstractions/openssl>
  3 - #include <abstractions/ssl_keys>
  4 - owner /etc/ssl/openssl.cnf r,
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / (O)wner permissions off / Abo(r)t / (F)inish
2

Profile:  /usr/sbin/dhclient
Path:     /etc/ssl/openssl.cnf
New Mode: owner r
Severity: 2

  1 - #include <abstractions/lightdm> 
 [2 - #include <abstractions/openssl>]
  3 - #include <abstractions/ssl_keys>
  4 - owner /etc/ssl/openssl.cnf r, 
[(A)llow] / (D)eny / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Abo(r)t / (F)inish / (M)ore
A
[...]
Profile:  /usr/sbin/dhclient-script 4
Path:     /usr/bin/dash
New Mode: owner r
Severity: unknown

  1 - #include <abstractions/gvfs-open>
 [2 - #include <abstractions/lightdm>]
  3 - #include <abstractions/ubuntu-browsers.d/plugins-common>
  4 - #include <abstractions/xdg-open>
  5 - owner /usr/bin/dash r,
(A)llow / [(D)eny] / (I)gnore / (G)lob / Glob with (E)xtension / (N)ew / Audi(t) / (O)wner permissions off / Abo(r)t / (F)inish
A
Adding #include <abstractions/lightdm> to profile.
Deleted 2 previous matching profile entries.

= Changed Local Profiles =

The following local profiles were changed. Would you like to save them?

 [1 - /usr/sbin/dhclient]
  2 - /usr/sbin/dhclient-script
(S)ave Changes / Save Selec(t)ed Profile / [(V)iew Changes] / View Changes b/w (C)lean profiles / Abo(r)t
S
Writing updated profile for /usr/sbin/dhclient.
Writing updated profile for /usr/sbin/dhclient-script.

Profiling: /usr/sbin/dhclient

Please start the application to be profiled in
another window and exercise its functionality now.

Once completed, select the "Scan" option below in
order to scan the system logs for AppArmor events.

For each AppArmor event, you will be given the
opportunity to choose whether the access should be
allowed or denied.

[(S)can system log for AppArmor events] / (F)inish
F
Setting /usr/sbin/dhclient to enforce mode.
Setting /usr/sbin/dhclient-script to enforce mode.

Reloaded AppArmor profiles in enforce mode.

Please consider contributing your new profile!
See the following wiki page for more information:
https://gitlab.com/apparmor/apparmor/wikis/Profiles

Finished generating profile for /usr/sbin/dhclient.

修改配置文件

以为nginx创建的AppArmor配置文件为例,通过上述方法,利用aa-prof命令创建配置文件。

1
aa-prof nginx

开始监听后,在其他窗口中执行nginx。

1
nginx -t

然后根据引导选择基本规则,生成配置文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <tunables/global>

/usr/sbin/nginx flags=(complain) {
  #include <abstractions/base>
  #include <abstractions/evince>
  #include <abstractions/nameservice>
  #include <abstractions/openssl>
  #include <abstractions/postfix-common>

  capability dac_override,

  /usr/sbin/nginx mr,
  /var/log/nginx/access.log w,
  /var/log/nginx/error.log w,
  owner /etc/nginx/conf.d/ r,
  owner /etc/nginx/mime.types r,
  owner /etc/nginx/modules-enabled/ r,
  owner /etc/nginx/nginx.conf r,
  owner /etc/nginx/sites-available/default r,
  owner /etc/nginx/sites-enabled/ r,
  owner /run/nginx.pid rw,
}

确认配置后,尝试禁止nginx读取网页文件,增加下面一行。

1
deny /var/www/html/* rwx,

然后重载AppArmor

1
systemctl reload apparmor

打开网页,显示404。

查看日志

通过查看内核日志,观察AppAarmor的输出。

1
tail -f /var/log/kern.log

可以使用aa-audit命令调整为审计模式,从日志中抓取应用行为。

1
2
3
4
5
6
Feb  4 19:05:50 debian-gnu-linux-11 kernel: [28749.677705] audit: type=1400 audit(1675508750.126:516): apparmor="AUDIT" operation="getattr" profile="/usr/sbin/nginx" name="/var/www/html/" pid=81716 comm="nginx" requested_mask="r" fsuid=33 ouid=0
Feb  4 19:05:50 debian-gnu-linux-11 kernel: [28749.677712] audit: type=1400 audit(1675508750.126:517): apparmor="AUDIT" operation="getattr" profile="/usr/sbin/nginx" name="/var/www/html/" pid=81716 comm="nginx" requested_mask="r" fsuid=33 ouid=0
Feb  4 19:05:50 debian-gnu-linux-11 kernel: [28749.677714] audit: type=1400 audit(1675508750.126:518): apparmor="AUDIT" operation="getattr" profile="/usr/sbin/nginx" name="/var/www/html/" pid=81716 comm="nginx" requested_mask="r" fsuid=33 ouid=0
Feb  4 19:05:50 debian-gnu-linux-11 kernel: [28749.677717] audit: type=1400 audit(1675508750.126:519): apparmor="AUDIT" operation="getattr" profile="/usr/sbin/nginx" name="/var/www/html/index.nginx-debian.html" pid=81716 comm="nginx" requested_mask="r" fsuid=33 ouid=0
Feb  4 19:05:50 debian-gnu-linux-11 kernel: [28749.677719] audit: type=1400 audit(1675508750.126:520): apparmor="AUDIT" operation="getattr" profile="/usr/sbin/nginx" name="/var/www/html/index.nginx-debian.html" pid=81716 comm="nginx" requested_mask="r" fsuid=33 ouid=0
Feb  4 19:05:50 debian-gnu-linux-11 kernel: [28749.677721] audit: type=1400 audit(1675508750.126:521): apparmor="DENIED" operation="open" profile="/usr/sbin/nginx" name="/var/www/html/index.nginx-debian.html" pid=81716 comm="nginx" requested_mask="r" denied_mask="r" fsuid=33 ouid=0

References


Built with Hugo
主题 StackJimmy 设计