## For instruction on writing tutorials ## http://www.ros.org/wiki/WritingTutorials #################################### ##FILL ME IN #################################### ## for a custom note with links: ## note = ## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links ## note.0= ## descriptive title for the tutorial ## title = Customizing AppArmor Profiles for ROS ## multi-line description to be displayed in search ## description = This tutorial explains how to customizing AppArmor Profiles to be used for securing ROS. ## the next tutorial description (optional) ## next = ## links to next tutorial (optional) ## next.0.link= ## next.1.link= ## what level user is this tutorial for ## level= IntermediateCategory ## keywords = SROS, AppArmor, Linux Security Module #################################### <<IncludeCSTemplate(TutorialCSHeaderTemplate)>> {{{#!wiki tip '''If you are new to AppArmor''': You may find it helpful to first read an introduction on AppArmor and Mandatory Access Control based profiles. A quick guide to the profile lanuage can be found [[http://wiki.apparmor.net/index.php/QuickProfileLanguage|here]], and a more general list of getting started documentation can be found [[http://wiki.apparmor.net/index.php/Documentation|here]]. }}} Now that we have the policy profile library for ROS installed, we have all the building blocks we need to build our own policprovile for our custom ROS application. Once you have one written, you can save it to your systems configuration directory for AppArmor, `/etc/apparmor.d/`, then reload AppArmor to have the changes take effect. For this example, we'll use the traditional talker/listener ros launch example. Let's work our way through the profile file: {{{ #!highlight python block=roslaunch_talker_listener #include <tunables/global> #include <tunables/ros> profile ros/roslaunch @{ROS_INSTALL_BIN}/{,s}roslaunch { #include <ros/nodes/roslaunch> @{ROS_INSTALL_BIN}/roslaunch rix, } profile ros/rosmaster @{ROS_INSTALL_BIN}/rosmaster { #include <ros/base> #include <ros/node> #include <ros/python> @{ROS_INSTALL_BIN}/rosmaster rix, } profile ros/roscore @{ROS_INSTALL_BIN}/{,s}roscore { #include <ros/nodes/roslaunch> @{HOME}/.rnd r, @{ROS_INSTALL_BIN}/roslaunch rix, @{ROS_INSTALL_BIN}/{,s}roscore rix, } profile ros/rosout @{ROS_INSTALL_LIB}/rosout/* { #include <ros/base> #include <ros/node> @{ROS_INSTALL_LIB}/rosout/rosout rix, } profile ros/talker_listener_py @{ROS_INSTALL_SHARE}/rospy_tutorials/001_talker_listener/{talker,listener}* { #include <ros/base> #include <ros/node> #include <ros/python> @{ROS_INSTALL_SHARE}/rospy_tutorials/001_talker_listener/talker.py r, @{ROS_INSTALL_SHARE}/rospy_tutorials/001_talker_listener/listener.py r, } profile ros/talker_listener_cpp @{ROS_INSTALL_LIB}/roscpp_tutorials/{talker,listener}* { #include <ros/base>command #include <ros/node> @{ROS_INSTALL_LIB}/roscpp_tutorials/listener rix, @{ROS_INSTALL_LIB}/roscpp_tutorials/talker rix, } }}} Let's go over this in a little more detail. <<CodeRef(roslaunch_talker_listener,1,2)>> We'll need to include some essential attributes necessary for ROS; this enatils many covenant global abstractions such as home directory and common aliases, then also abstractions that are ROS specific such as variables defining `ROS_HOME`, `ROS_ROOT` annd ect... <<CodeRef(roslaunch_talker_listener,4,8)>> Now we can define our first profile section for `roslaunch`. This executable requires some additional permissions in order to enable `roslaunch` to function normally, e.g. utilized shell enfoments to launch nodes, send signals child nodes to stop, adapt ldconfig for node runtimes. All necessary permissions are included through the specified subprofile, and then the roslaunch made executable, inheriting the current profile. <<CodeRef(roslaunch_talker_listener,10,16)>> For this profile section, we'll make the allowances for `rosmaster`. This is also a python based executable, so in addition to the base abstractions of being able to receive signals and signal itself, and the node abstractions of being able to read shared ROS libraries, we also include abstractions that are python specific. <<CodeRef(roslaunch_talker_listener,18,24)>> The profile section for `roscore` is much the same as that for `roslaunch`, as roscore mainly uses roslaunch under the hood to bootstrap and launch fundamental ROS services. Take note on how both the attachment specification and the executable path make use of the globbing syntax, `{,s}`, to abstract the policy coverage to encompass both original and secure implementations. <<CodeRef(roslaunch_talker_listener,26,32)>> The profile section for `rosout`, as seen from the attachment specification is generalised for all things under rosout, where in particular, only the rosout binary is made executable within that profile. Because `rosout` is a simple C++ node, it only requires the base and node abstractions. <<CodeRef(roslaunch_talker_listener,33,49)>> These last two profile sections are custom to the Python and C++ node implementations of the talker and listener examples. Here in the attachment specification we again use globbing, `{talker,listener}*`, to capture both scripts, binary files and links with the common name, and then define an appropriate policy pertinent to Python's or C++'s runtime behavior. ## AUTOGENERATED DO NOT DELETE ## SROSTutorialCategory ## FILL IN THE STACK TUTORIAL CATEGORY HERE