Author: | Ted Yin <[email protected]> |
---|
AppArmor is a Mandatory Access Control (MAC) system which is a kernel (LSM) enhancement to confine programs to a limited set of resources. Instead of binding access control attributes to users, it confines specific programs.
AppArmor is shipped with Ubuntu, which means it is fairly easy to get started.
In order to ease the maintenance, we first install the utilities by
sudo apt-get install apparmor-utils
To demonstrate the typical use of AppArmor, we try to confine the behavior of the Python interpreter:
First, to avoid system-wide change, we make a duplicate of the Python interpreter binary:
sudo -i cd # The working directory in this example is under /root cp /usr/bin/python confined_python
Note that we have to copy the file instead of simply creating a symbolic link because AppArmor does not support symbolic links. See [1]
Then, we make use of aa-autodep to generate a initial configuration of
confined_python
:aa-autodep confined_python
Next, we can edit the configuration file located at
/etc/apparmor.d/root.confined_python
. The naming rule is to substitute all intermediate slashes in the path name of the program to dots, for example:/this/is/a/path
corresponds tothis.is.a.path
.For demonstration, we do not change the content of configuration, which leads to the strictest control. It is worth noticing that there are two working modes in AppArmor, one is called "complain", while the other is "enforce". As the name suggests, only the latter mode actually confines the behavior of a program. So we shall turn on the "enforce" mode:
aa-enforce confined_python
Now we can start the program to see the result:
./confined_python
You can try to test whether AppArmor becomes effective by opening a file, sending a HTTP request, or spawning a subprocess in Python, if the default configuration works correctly, all permission invoked by these operations is denied:
>>> f = open("test.out", "w") Traceback (most recent call last): File "<stdin>", line 1, in <module> PermissionError: [Errno 13] Permission denied: 'test.out' Error in sys.excepthook: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 63, in apport_excepthook from apport.fileutils import likely_packaged, get_recent_crashes File "/usr/lib/python3/dist-packages/apport/__init__.py", line 5, in <module> from apport.report import Report File "/usr/lib/python3/dist-packages/apport/report.py", line 30, in <module> import apport.fileutils File "/usr/lib/python3/dist-packages/apport/fileutils.py", line 23, in <module> from apport.packaging_impl import impl as packaging File "/usr/lib/python3/dist-packages/apport/packaging_impl.py", line 20, in <module> import apt File "/usr/lib/python3/dist-packages/apt/__init__.py", line 23, in <module> import apt_pkg ImportError: /usr/lib/python3/dist-packages/apt_pkg.cpython-34m-x86_64-linux-gnu.so: failed to map segment from shared object: Permission denied >>> import httplib >>> conn = httplib.HTTPConnection('www.tedyin.com') >>> conn.request('GET', '/index.html') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/httplib.py", line 973, in request self._send_request(method, url, body, headers) File "/usr/lib/python2.7/httplib.py", line 1007, in _send_request self.endheaders(body) File "/usr/lib/python2.7/httplib.py", line 969, in endheaders self._send_output(message_body) File "/usr/lib/python2.7/httplib.py", line 829, in _send_output self.send(msg) File "/usr/lib/python2.7/httplib.py", line 791, in send self.connect() File "/usr/lib/python2.7/httplib.py", line 772, in connect self.timeout, self.source_address) File "/usr/lib/python2.7/socket.py", line 553, in create_connection for res in getaddrinfo(host, port, 0, SOCK_STREAM): socket.gaierror: [Errno -2] Name or service not known >>> import subprocess >>> subprocess.check_call(["ls", "-l"]) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/subprocess.py", line 535, in check_call retcode = call(*popenargs, **kwargs) File "/usr/lib/python2.7/subprocess.py", line 522, in call return Popen(*popenargs, **kwargs).wait() File "/usr/lib/python2.7/subprocess.py", line 710, in __init__ errread, errwrite) File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child raise child_exception OSError: [Errno 13] Permission denied
[1] | http://serverfault.com/questions/290828/creating-a-linux-sandbox-with-apparmor |