{"id":18710,"date":"2022-04-26T09:00:52","date_gmt":"2022-04-26T07:00:52","guid":{"rendered":"https:\/\/www.credativ.de\/blog\/credativ-inside\/manually-create-an-apparmor-profile-for-nginx\/"},"modified":"2022-04-26T09:00:52","modified_gmt":"2022-04-26T07:00:52","slug":"manually-create-an-apparmor-profile-for-nginx","status":"publish","type":"post","link":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/","title":{"rendered":"Manually Create an AppArmor Profile for Nginx"},"content":{"rendered":"<p>As described in the previous post, access control on Unix-like systems is traditionally based on the principle of <a href=\"https:\/\/de.wikipedia.org\/wiki\/Discretionary_Access_Control\"><em>Discretionary Access Control<\/em><\/a> (DAC). Applications and services run under a specific user and group ID and are granted the corresponding access rights to files and folders. <\/p>\n<p><a href=\"https:\/\/apparmor.net\/\">AppArmor<\/a> implements a <a href=\"https:\/\/de.wikipedia.org\/wiki\/Mandatory_Access_Control\"><em>Mandatory Access Control<\/em><\/a> for Linux, based on the <em>Linux Security Modules<\/em>: an access control strategy that allows specific rights to be granted or denied to individual programs. This security layer exists in addition to the traditional <em>DAC<\/em>. <\/p>\n<p>Since Debian 10 <em>buster<\/em>, AppArmor has been included and activated in the kernel by default. The packages <a href=\"https:\/\/packages.debian.org\/bullseye\/apparmor\">apparmor<\/a> and <a href=\"https:\/\/packages.debian.org\/bullseye\/apparmor-utils\">apparmor-utils<\/a> provide tools for creating and maintaining AppArmor profiles. <\/p>\n<h1 id=\"mitgelieferte-profile\">Included Profiles<\/h1>\n<p>The two packages mentioned do not come with ready-made profiles, but only the <em>Abstractions<\/em> mentioned in the previous article: collections of rules that can be included in multiple profiles.<\/p>\n<p>Some programs include their profiles in their own packages, while others contain profiles if corresponding modules are installed later \u2013 for example, <code>mod_apparmor<\/code> for the Apache web server.<\/p>\n<p>The packages <a href=\"https:\/\/packages.debian.org\/bullseye\/apparmor-profiles\">apparmor-profiles<\/a> and <a href=\"https:\/\/packages.debian.org\/bullseye\/apparmor-profiles-extra\">apparmor-profiles-extra<\/a> contain AppArmor profiles that can be found after installation in the directories <code>\/etc\/apparmor.d<\/code> (for tested profiles) and <code>\/usr\/share\/apparmor\/extra-profiles<\/code> (for experimental profiles), respectively. These profiles can be used as a basis for custom profiles. <\/p>\n<h1 id=\"profile-selbst-erstellen\">Create Profiles Yourself<\/h1>\n<p>While at least experimental profiles are available for most common server services, such as the <em>Apache<\/em> web server, nothing can be found for the <a href=\"http:\/\/nginx.org\/\">nginx<\/a> web server. However, this is not a major issue, as a new AppArmor profile can be quickly created with the help of <a href=\"https:\/\/packages.debian.org\/bullseye\/apparmor-utils\">apparmor-utils<\/a>. <\/p>\n<h2 id=\"beispiel-nginx\">Nginx Example<\/h2>\n<p>The following assumes a simple base installation of <em>nginx<\/em> that only serves HTML files under  <code>\/var\/www\/html<\/code>  via <em>HTTP<\/em>. The focus here is primarily on the general approach, so repetitive steps will be skipped. <\/p>\n<p>The described approach can be applied to any other program. To find out about the paths and files used by a program, <code>dpkg<\/code> can be used with the <code>-L<\/code> option, which lists all paths of a package. It should be noted that several packages may need to be queried for this; for <a href=\"https:\/\/packages.debian.org\/bullseye\/nginx\">nginx<\/a>, the package of the same name provides hardly any useful information; this is only obtained with the <a href=\"https:\/\/packages.debian.org\/bullseye\/nginx-common\">nginx-common<\/a> package:  <\/p>\n<pre># dpkg -L nginx-common<\/pre>\n<p>For the following steps, it is recommended to have two terminals open with root privileges.<\/p>\n<p>Before the web server process can be observed for profile creation, all its running processes must be terminated:<\/p>\n<pre># systemctl stop nginx<\/pre>\n<p>Once all processes are stopped, <code>aa-genprof<\/code> is called in the second terminal with the path of the web server&#8217;s program file:<\/p>\n<pre># aa-genprof \/usr\/sbin\/nginx<\/pre>\n<p>Some information about the current call of <code>aa-genprof<\/code> appears, including the hint <code>Profiling: \/usr\/sbin\/nginx<\/code>, followed by  <code>Please start the application to be profiled in another window and exercise its functionality now.<\/code><\/p>\n<p>To comply with this, the web server process is restarted in the first terminal window:<\/p>\n<pre># systemctl start nginx<\/pre>\n<p>Before calling the <code>S<\/code> option in the second window to search the log files for AppArmor events, the web server should run for a few moments, and it should also be accessed from a browser so that as many typical activities of the process as possible are recorded.<\/p>\n<p>Once this is done, the log files can be searched for events by pressing the <code>S<\/code> key:<\/p>\n<pre>[(S)can system log for AppArmor events] \/ (F)inish\nReading log entries from \/var\/log\/syslog.\nUpdating AppArmor profiles in \/etc\/apparmor.d.\nComplain-mode changes:<\/pre>\n<p>If an event is found, the affected profile and the action recorded by AppArmor are displayed:<\/p>\n<pre>Profile: \/usr\/sbin\/nginx\nCapability: dac_override\nSeverity: 9\n\n [1 - capability dac_override,]\n(A)llow \/ [(D)eny] \/ (I)gnore \/ Audi(t) \/ Abo(r)t \/ (F)inish<\/pre>\n<p>Here, the program <code>\/usr\/sbin\/nginx<\/code> requests the <a href=\"https:\/\/manpages.debian.org\/bullseye\/manpages-de\/capabilities.7.de.html\"><em>Capability<\/em><\/a> <code>dac_override<\/code>, which was already described in the last article. It is indispensable for the operation of the web server and is allowed by pressing <code>A<\/code>. Alternatively, the request can be denied with <code>D<\/code> or ignored with <code>I<\/code>. With the <em>Audit<\/em> option, this request would continue to be recorded in the log file during operation.   <\/p>\n<pre>Profile: \/usr\/sbin\/nginx\nCapability: net_bind_service\nSeverity: 8\n\n [1 - #include <abstractions>]\n2 - capability net_bind_service,<\/abstractions><\/abstractions><\/pre>\n<p>The next event shows that the process requests the <em>Capability<\/em> <code>net_bind_service<\/code>, which is needed to open a port with a port number less than 1024.<\/p>\n<p>Unlike the first query, there are two ways to allow access in the future: the first option involves integrating <em>Abstractions<\/em> for <em>NIS<\/em>, the <em>Network Information Service<\/em>. In this <em>Abstraction<\/em>, which can be found under <code>\/etc\/apparmor.d\/abstractions\/nis<\/code>, in addition to a rule that allows access to rule sets for <em>NIS<\/em>, the <em>Capability<\/em> <code>net_bind_service<\/code> is also listed. <\/p>\n<p>However, since the HTTP server does not include <em>NIS<\/em> functionality, it is sufficient to only allow the <em>Capability<\/em>. By pressing <code>2<\/code> and <code>A<\/code>, this is adopted into the profile. <\/p>\n<p>The same applies to the <em>Abstractions<\/em> proposed in the following steps for <code>dovecot<\/code> and <code>postfix<\/code>: here it is sufficient to only allow the <em>Capabilities<\/em> <code>setgid<\/code> and <code>setuid<\/code>.<\/p>\n<p>Sometimes the designation of the <em>Abstractions<\/em> can be somewhat misleading: for example, the <em>Abstraction<\/em> <code>nameservice<\/code> contains, in addition to rules that allow read access to common nameservice files like <code>passwd<\/code> or <code>hosts<\/code>, also rules that permit network access. It is therefore always worthwhile to take a look at the respective file under <code>\/etc\/apparmor.d\/abstractions\/<\/code> to see if including the <em>Abstraction<\/em> is beneficial. <\/p>\n<p>After the web server process has received all necessary <em>Capabilities<\/em>, it apparently tries to open its error log file <code>\/var\/log\/nginx\/log<\/code> with write permissions. It is noticeable here that, in addition to the usual <em>Allow<\/em>, <em>Deny<\/em>, and <em>Ignore<\/em>, the options <em>Glob<\/em> and <em>Glob with Extension<\/em> have been added. <\/p>\n<pre>Profile: \/usr\/sbin\/nginx\nPath: \/var\/log\/nginx\/error.log\nNew Mode: w\nSeverity: 8\n\n [1 - \/var\/log\/nginx\/error.log w,]\n(A)llow \/ [(D)eny] \/ (I)gnore \/ (G)lob \/ Glob with (E)xtension \/ (N)ew \/ Audi(t) \/ Abo(r)t \/ (F)inish<\/pre>\n<p>Entering <code>E<\/code> adds another suggestion to the list:<\/p>\n<pre> 1 - \/var\/log\/nginx\/error.log w, \n [2 - \/var\/log\/nginx\/*.log w,]<\/pre>\n<p>The filename <code>error.log<\/code> has been replaced by a wildcard and the extension <code>.log<\/code>. This rule would grant write permissions to the file <code>\/var\/log\/nginx\/error.log<\/code> as well as, for example, to the file <code>\/var\/log\/nginx\/access.log<\/code> \u2013 these are (at least) two rules combined into a single one. <\/p>\n<p>These rules would already be sufficient for this example, but it might also be necessary to allow files that do not have the <code>.log<\/code> file extension to be written in the <code>\/var\/log<\/code> directory. By entering <code>G<\/code>, another suggestion is added to the list: <\/p>\n<pre>  1 - \/var\/log\/nginx\/error.log w,  \n 2 - \/var\/log\/nginx\/*.log w, \n [3 - \/var\/log\/nginx\/* w,]<\/pre>\n<p>The filename has now been replaced by a single wildcard, meaning the process would be allowed to open any files in <code>\/var\/log\/nginx<\/code> with write permissions.<\/p>\n<p>As already mentioned, the proposed rules only grant write permissions, but no read permissions, even if the file&#8217;s access rights would allow more. However, for a web server&#8217;s log file, write permissions are entirely sufficient. <\/p>\n<p>Subsequently, <em>nginx<\/em> requests read access to various configuration files, for example <code>\/etc\/nginx\/nginx.conf<\/code>. This file is located in the <em>nginx<\/em> web server&#8217;s configuration directory, which contains other files that should also be readable. <\/p>\n<pre>Profile: \/usr\/sbin\/nginx\nPath: \/etc\/nginx\/nginx.conf\nNew Mode: owner r\nSeverity: unknown\n\n [1 - owner \/etc\/nginx\/nginx.conf r,]<\/pre>\n<p>Here too, with <code>G<\/code>, the rule can be extended to all files in the <code>\/etc\/nginx<\/code> directory.<\/p>\n<pre> 1 - owner \/etc\/nginx\/nginx.conf r, \n [2 - owner \/etc\/nginx\/* r,]<\/pre>\n<p>The same applies to the subdirectories of the configuration directory; these can be covered by <em>globbing<\/em> as <code>\/etc\/nginx\/*\/<\/code>.<\/p>\n<p>A special case for globbing is the files contained in those subdirectories:<\/p>\n<pre>Profile: \/usr\/sbin\/nginx\nPath: \/etc\/nginx\/sites-available\/default\nNew Mode: owner r\nSeverity: unknown\n\n [1 - owner \/etc\/nginx\/sites-available\/default r,]<\/pre>\n<p>After entering <code>G<\/code> twice, the wildcard <code>**<\/code> is suggested after the wildcard <code>*<\/code> known from above, which, as described in the previous article, covers all files located in subdirectories (and their subdirectories).<\/p>\n<pre> 1 - owner \/etc\/nginx\/sites-available\/default r, \n 2 - owner \/etc\/nginx\/sites-available\/* r, \n [3 - owner \/etc\/nginx\/** r,]<\/pre>\n<p>The last steps also all contained the attribute <code>owner<\/code>: this ensures that a rule only applies if the accessing process is also the owner of the file. If the file exists but belongs to someone else, access is denied. <\/p>\n<p>There are still some other paths and files such as <code>\/usr\/share\/nginx\/modules-available\/<\/code>, <code>\/run\/nginx.pid<\/code>, and <code>\/proc\/sys\/kernel\/random\/boot_id<\/code>, which <em>nginx<\/em> also requires for proper operation. However, the procedure remains unchanged. <\/p>\n<p>Once all events have been processed, the program concludes with the message:<\/p>\n<pre>= Changed Local Profiles =\n\nThe following local profiles were changed. Would you like to save them? \n\n [1 - \/usr\/sbin\/nginx]\n(S)ave Changes \/ Save Selec(t)ed Profile \/ [(V)iew Changes] \/ View Changes b\/w (C)lean profiles \/ Abo(r)t<\/pre>\n<p>The options are clear: <code>S<\/code> saves changes, while <code>V<\/code> allows them to be viewed as a <em>Diff<\/em> beforehand. The following listing shows the profile generated in the run above. <\/p>\n<pre>include &lt;tunables\/global&gt;\n\nprofile nginx \/usr\/sbin\/nginx {\n include &lt;abstractions\/base&gt;\n include &lt;abstractions\/nameservice&gt;\n\n capability dac_override,\n capability dac_read_search,\n capability setgid,\n capability setuid,\n\n \/usr\/sbin\/nginx mr,\n\n \/var\/log\/nginx\/*.log w,\n\n \/var\/www\/html\/** r,\n\n owner \/etc\/nginx\/* r,\n owner \/etc\/nginx\/** r,\n\n owner \/run\/nginx.pid rw,\n\n owner \/usr\/share\/GeoIP\/*.mmdb r,\n owner \/usr\/share\/nginx\/modules-available\/*.conf r,\n\n owner \/var\/cache\/nginx\/** rw,\n owner \/var\/lib\/nginx\/** rw,\n}<\/pre>\n<p>After saving the changes, <code>aa-genprof<\/code> returns to its start screen. Here, one could search for events in log files again or exit the program with <code>F<\/code>. <\/p>\n<p>The program ends with the message:<\/p>\n<pre>Setting \/usr\/sbin\/nginx to enforce mode.\n\nReloaded AppArmor profiles in enforce mode.<\/pre>\n<p>The profile just created has therefore been loaded and put into <em>enforce mode<\/em>. This means that the program can only access what is allowed in the profile; all other access attempts are blocked by AppArmor and recorded in the <em>Syslog<\/em>. <\/p>\n<p>For simple programs, the creation of a profile is thus complete, and AppArmor can perform its work; more complex programs, however, will show previously unknown behavior later on, which would be prevented by the profile created so far. In such cases, it helps to switch the profile to <em>complain mode<\/em> using <code>aa-complain<\/code>. <\/p>\n<pre># aa-complain nginx<\/pre>\n<p>Accesses that go beyond the known profile are generally allowed in <em>complain mode<\/em> but are recorded in the <em>Syslog<\/em>.<\/p>\n<pre>Feb 18 15:25:50 web01 kernel: [ 9908.611408] audit: type=1400 audit(1645197950.338:100): apparmor=\"ALLOWED\" operation=\"open\" profile=\"nginx\" name=\"\/srv\/www\/index.html\" pid=4490 comm=\"nginx\" requested_mask=\"r\" denied_mask=\"r\" fsuid=33 ouid=0<\/pre>\n<p>In the excerpt from the <em>Syslog<\/em> above, the webroot directory on host <code>web01<\/code> was changed to <code>\/srv\/www<\/code>, but the previously created AppArmor profile was not adjusted. Since the profile is now in <em>complain mode<\/em>, access was still allowed: <code>apparmor=\"ALLOWED\"<\/code>; in <em>enforce mode<\/em>, it would say <code>DENIED<\/code> and access would be denied. <\/p>\n<p>The remaining information clearly shows what happened: the process with process ID (<em>pid<\/em>) <code>4190<\/code> tried to open the file <code>\/srv\/www\/index.html<\/code> (<em>name<\/em>) for reading (<em>requested_mask<\/em>), which would, however, be forbidden (<em>denied_mask<\/em>) due to the profile (<em>profile<\/em>) <code>nginx<\/code>.<\/p>\n<p>So, if software secured with AppArmor doesn&#8217;t work as expected, the first place to look is the <em>Syslog<\/em>!<\/p>\n<p>After some time, there will be several entries there that should then be incorporated into the AppArmor profile. For this, the program <code>aa-logprof<\/code> is used: it searches the <em>Syslog<\/em> for entries and, in the manner of <code>aa-genprof<\/code>, asks if and how entries should be created in the profile. This process can be repeated as often as necessary.  <\/p>\n<p>If no further entries are found in the Syslog, the profile has been sufficiently adjusted and can be switched back to <em>enforce mode<\/em> with <code>aa-enforce<\/code>:<\/p>\n<pre># aa-enforce nginx<\/pre>\n<p>This completes the basic creation of a simple AppArmor profile, and the <em>nginx<\/em> processes are controlled and monitored according to the rules defined within it.<\/p>\n<h1>We are Happy to Support You<\/h1>\n<p>Whether AppArmor, Debian, or PostgreSQL: with over 22+ years of development and service experience in the open-source sector, credativ GmbH can professionally support you with unparalleled and individually configurable support and assist you fully with all questions regarding your open-source infrastructure.<\/p>\n<p>Do you have questions about our article or would you like credativ&#8217;s specialists to look at another software of your choice?<br \/>\nThen visit us and contact us via our <a href=\"https:\/\/www.credativ.de\/kontakt\/\">contact form<\/a> or write us an email at <a href=\"mailto:info@credativ.de\">info@credativ.de<\/a>.<\/p>\n<h1>About Credativ<\/h1>\n<p><a href=\"https:\/\/www.credativ.de\">credativ GmbH<\/a> is a vendor-independent consulting and service company based in M\u00f6nchengladbach.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As described in the previous post, access control on Unix-like systems is traditionally based on the principle of Discretionary Access Control (DAC). Applications and services run under a specific user and group ID and are granted the corresponding access rights to files and folders. AppArmor implements a Mandatory Access Control for Linux, based on the [&hellip;]<\/p>\n","protected":false},"author":60,"featured_media":6774,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_improvement_type_select":"improve_an_existing","_thumb_yes_seoaic":false,"_frame_yes_seoaic":false,"seoaic_generate_description":"","seoaic_improve_instructions_prompt":"","seoaic_rollback_content_improvement":"","seoaic_idea_thumbnail_generator":"","thumbnail_generated":false,"thumbnail_generate_prompt":"","seoaic_article_description":"","seoaic_article_subtitles":[],"footnotes":""},"categories":[1883,1885],"tags":[1711,1775,1842,1761,1853,1861],"class_list":["post-18710","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-debian-en","category-howtos-en","tag-apparmor-en","tag-debian-en","tag-linux-en","tag-open-source-en","tag-security","tag-ubuntu-en"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.6 (Yoast SEO v27.6) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Manually Create an AppArmor Profile for Nginx - credativ\u00ae<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Manually Create an AppArmor Profile for Nginx\" \/>\n<meta property=\"og:description\" content=\"As described in the previous post, access control on Unix-like systems is traditionally based on the principle of Discretionary Access Control (DAC). Applications and services run under a specific user and group ID and are granted the corresponding access rights to files and folders. AppArmor implements a Mandatory Access Control for Linux, based on the [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/\" \/>\n<meta property=\"og:site_name\" content=\"credativ\u00ae\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/credativDE\/\" \/>\n<meta property=\"article:published_time\" content=\"2022-04-26T07:00:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.credativ.de\/wp-content\/uploads\/2022\/04\/apparmor_profile_2500x300.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2500\" \/>\n\t<meta property=\"og:image:height\" content=\"300\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Jan Bolle\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@bollejansson\" \/>\n<meta name=\"twitter:site\" content=\"@credativde\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jan Bolle\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/\"},\"author\":{\"name\":\"Jan Bolle\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#\\\/schema\\\/person\\\/f33560ea675ef6722c4459154b42606e\"},\"headline\":\"Manually Create an AppArmor Profile for Nginx\",\"datePublished\":\"2022-04-26T07:00:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/\"},\"wordCount\":1609,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/apparmor_profile_2500x300.png\",\"keywords\":[\"AppArmor\",\"Debian\",\"Linux\",\"Open Source\",\"Security\",\"Ubuntu\"],\"articleSection\":[\"Debian\",\"HowTos\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#respond\"]}],\"copyrightYear\":\"2022\",\"copyrightHolder\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/\",\"name\":\"Manually Create an AppArmor Profile for Nginx - credativ\u00ae\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/apparmor_profile_2500x300.png\",\"datePublished\":\"2022-04-26T07:00:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/apparmor_profile_2500x300.png\",\"contentUrl\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/apparmor_profile_2500x300.png\",\"width\":2500,\"height\":300},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Manually Create an AppArmor Profile for Nginx\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/\",\"name\":\"credativ GmbH\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Organization\",\"Place\"],\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#organization\",\"name\":\"credativ\u00ae\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/\",\"logo\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#local-main-organization-logo\"},\"image\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#local-main-organization-logo\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/credativDE\\\/\",\"https:\\\/\\\/x.com\\\/credativde\",\"https:\\\/\\\/mastodon.social\\\/@credativde\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/credativ-gmbh\",\"https:\\\/\\\/www.instagram.com\\\/credativ\\\/\"],\"description\":\"Die credativ GmbH ist ein f\u00fchrendes, auf Open Source Software spezialisiertes IT-Dienstleistungs- und Beratungsunternehmen. Wir bieten umfassende und professionelle Services, von Beratung und Infrastruktur-Betrieb \u00fcber 24\\\/7 Support bis hin zu individuellen L\u00f6sungen und Schulungen. Unser Fokus liegt auf dem ganzheitlichen Management von gesch\u00e4ftskritischen Open-Source-Systemen, darunter Betriebssysteme (z.B. Linux), Datenbanken (z.B. PostgreSQL), Konfigurationsmanagement (z.B. Ansible, Puppet) und Virtualisierung. Als engagierter Teil der Open-Source-Community unterst\u00fctzen wir unsere Kunden dabei, die Vorteile freier Software sicher, stabil und effizient in ihrer IT-Umgebung zu nutzen.\",\"legalName\":\"credativ GmbH\",\"foundingDate\":\"2025-03-01\",\"duns\":\"316387060\",\"numberOfEmployees\":{\"@type\":\"QuantitativeValue\",\"minValue\":\"11\",\"maxValue\":\"50\"},\"address\":{\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#local-main-place-address\"},\"geo\":{\"@type\":\"GeoCoordinates\",\"latitude\":\"51.1732374\",\"longitude\":\"6.392010099999999\"},\"telephone\":[\"+4921619174200\",\"08002733284\"],\"contactPoint\":{\"@type\":\"ContactPoint\",\"telephone\":\"08002733284\",\"email\":\"vertrieb@credativ.de\"},\"openingHoursSpecification\":[{\"@type\":\"OpeningHoursSpecification\",\"dayOfWeek\":[\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\"],\"opens\":\"09:00\",\"closes\":\"17:00\"},{\"@type\":\"OpeningHoursSpecification\",\"dayOfWeek\":[\"Saturday\",\"Sunday\"],\"opens\":\"00:00\",\"closes\":\"00:00\"}],\"email\":\"info@credativ.de\",\"areaServed\":\"D-A-CH\",\"vatID\":\"DE452151696\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/#\\\/schema\\\/person\\\/f33560ea675ef6722c4459154b42606e\",\"name\":\"Jan Bolle\",\"description\":\"Jan arbeitet seit 2020 an Projekten des Support\u2013Teams und der Internen IT, nachdem er bereits sein Praktikum im Rahmen seines Informatikstudiums bei credativ absolvierte und auch seine Bachelorarbeit zum Thema Einmalpassw\u00f6rter, Zwei\u2013Faktor\u2013Authentisierung und OpenVPN bei credativ schrieb. Bereits zu Schulzeiten interessierte er sich f\u00fcr Freie Software, Netzwerke und Telekommunikation und richtete zusammen mit Mitsch\u00fclern ein Internetcaf\u00e9 ein, auf dessen Server und Clients Debian GNU\\\/Linux seinen Dienst verrichtete.\",\"sameAs\":[\"https:\\\/\\\/x.com\\\/bollejansson\"]},{\"@type\":\"PostalAddress\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#local-main-place-address\",\"streetAddress\":\"Hennes-Weisweiler-Allee 23\",\"addressLocality\":\"M\u00f6nchengladbach\",\"postalCode\":\"41179\",\"addressRegion\":\"Deutschland\",\"addressCountry\":\"DE\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.credativ.de\\\/en\\\/blog\\\/howtos-en\\\/manually-create-an-apparmor-profile-for-nginx\\\/#local-main-organization-logo\",\"url\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/credativ-logo-right.svg\",\"contentUrl\":\"https:\\\/\\\/www.credativ.de\\\/wp-content\\\/uploads\\\/2025\\\/04\\\/credativ-logo-right.svg\",\"caption\":\"credativ\u00ae\"}]}<\/script>\n<meta name=\"geo.placename\" content=\"M\u00f6nchengladbach\" \/>\n<meta name=\"geo.position\" content=\"51.1732374;6.392010099999999\" \/>\n<meta name=\"geo.region\" content=\"Germany\" \/>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Manually Create an AppArmor Profile for Nginx - credativ\u00ae","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/","og_locale":"en_US","og_type":"article","og_title":"Manually Create an AppArmor Profile for Nginx","og_description":"As described in the previous post, access control on Unix-like systems is traditionally based on the principle of Discretionary Access Control (DAC). Applications and services run under a specific user and group ID and are granted the corresponding access rights to files and folders. AppArmor implements a Mandatory Access Control for Linux, based on the [&hellip;]","og_url":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/","og_site_name":"credativ\u00ae","article_publisher":"https:\/\/www.facebook.com\/credativDE\/","article_published_time":"2022-04-26T07:00:52+00:00","og_image":[{"width":2500,"height":300,"url":"https:\/\/www.credativ.de\/wp-content\/uploads\/2022\/04\/apparmor_profile_2500x300.png","type":"image\/png"}],"author":"Jan Bolle","twitter_card":"summary_large_image","twitter_creator":"@bollejansson","twitter_site":"@credativde","twitter_misc":{"Written by":"Jan Bolle","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#article","isPartOf":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/"},"author":{"name":"Jan Bolle","@id":"https:\/\/www.credativ.de\/en\/#\/schema\/person\/f33560ea675ef6722c4459154b42606e"},"headline":"Manually Create an AppArmor Profile for Nginx","datePublished":"2022-04-26T07:00:52+00:00","mainEntityOfPage":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/"},"wordCount":1609,"commentCount":0,"publisher":{"@id":"https:\/\/www.credativ.de\/en\/#organization"},"image":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#primaryimage"},"thumbnailUrl":"https:\/\/www.credativ.de\/wp-content\/uploads\/2022\/04\/apparmor_profile_2500x300.png","keywords":["AppArmor","Debian","Linux","Open Source","Security","Ubuntu"],"articleSection":["Debian","HowTos"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#respond"]}],"copyrightYear":"2022","copyrightHolder":{"@id":"https:\/\/www.credativ.de\/#organization"}},{"@type":"WebPage","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/","url":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/","name":"Manually Create an AppArmor Profile for Nginx - credativ\u00ae","isPartOf":{"@id":"https:\/\/www.credativ.de\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#primaryimage"},"image":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#primaryimage"},"thumbnailUrl":"https:\/\/www.credativ.de\/wp-content\/uploads\/2022\/04\/apparmor_profile_2500x300.png","datePublished":"2022-04-26T07:00:52+00:00","breadcrumb":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#primaryimage","url":"https:\/\/www.credativ.de\/wp-content\/uploads\/2022\/04\/apparmor_profile_2500x300.png","contentUrl":"https:\/\/www.credativ.de\/wp-content\/uploads\/2022\/04\/apparmor_profile_2500x300.png","width":2500,"height":300},{"@type":"BreadcrumbList","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.credativ.de\/en\/"},{"@type":"ListItem","position":2,"name":"Manually Create an AppArmor Profile for Nginx"}]},{"@type":"WebSite","@id":"https:\/\/www.credativ.de\/en\/#website","url":"https:\/\/www.credativ.de\/en\/","name":"credativ GmbH","description":"","publisher":{"@id":"https:\/\/www.credativ.de\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.credativ.de\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Organization","Place"],"@id":"https:\/\/www.credativ.de\/en\/#organization","name":"credativ\u00ae","url":"https:\/\/www.credativ.de\/en\/","logo":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#local-main-organization-logo"},"image":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#local-main-organization-logo"},"sameAs":["https:\/\/www.facebook.com\/credativDE\/","https:\/\/x.com\/credativde","https:\/\/mastodon.social\/@credativde","https:\/\/www.linkedin.com\/company\/credativ-gmbh","https:\/\/www.instagram.com\/credativ\/"],"description":"Die credativ GmbH ist ein f\u00fchrendes, auf Open Source Software spezialisiertes IT-Dienstleistungs- und Beratungsunternehmen. Wir bieten umfassende und professionelle Services, von Beratung und Infrastruktur-Betrieb \u00fcber 24\/7 Support bis hin zu individuellen L\u00f6sungen und Schulungen. Unser Fokus liegt auf dem ganzheitlichen Management von gesch\u00e4ftskritischen Open-Source-Systemen, darunter Betriebssysteme (z.B. Linux), Datenbanken (z.B. PostgreSQL), Konfigurationsmanagement (z.B. Ansible, Puppet) und Virtualisierung. Als engagierter Teil der Open-Source-Community unterst\u00fctzen wir unsere Kunden dabei, die Vorteile freier Software sicher, stabil und effizient in ihrer IT-Umgebung zu nutzen.","legalName":"credativ GmbH","foundingDate":"2025-03-01","duns":"316387060","numberOfEmployees":{"@type":"QuantitativeValue","minValue":"11","maxValue":"50"},"address":{"@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#local-main-place-address"},"geo":{"@type":"GeoCoordinates","latitude":"51.1732374","longitude":"6.392010099999999"},"telephone":["+4921619174200","08002733284"],"contactPoint":{"@type":"ContactPoint","telephone":"08002733284","email":"vertrieb@credativ.de"},"openingHoursSpecification":[{"@type":"OpeningHoursSpecification","dayOfWeek":["Monday","Tuesday","Wednesday","Thursday","Friday"],"opens":"09:00","closes":"17:00"},{"@type":"OpeningHoursSpecification","dayOfWeek":["Saturday","Sunday"],"opens":"00:00","closes":"00:00"}],"email":"info@credativ.de","areaServed":"D-A-CH","vatID":"DE452151696"},{"@type":"Person","@id":"https:\/\/www.credativ.de\/en\/#\/schema\/person\/f33560ea675ef6722c4459154b42606e","name":"Jan Bolle","description":"Jan arbeitet seit 2020 an Projekten des Support\u2013Teams und der Internen IT, nachdem er bereits sein Praktikum im Rahmen seines Informatikstudiums bei credativ absolvierte und auch seine Bachelorarbeit zum Thema Einmalpassw\u00f6rter, Zwei\u2013Faktor\u2013Authentisierung und OpenVPN bei credativ schrieb. Bereits zu Schulzeiten interessierte er sich f\u00fcr Freie Software, Netzwerke und Telekommunikation und richtete zusammen mit Mitsch\u00fclern ein Internetcaf\u00e9 ein, auf dessen Server und Clients Debian GNU\/Linux seinen Dienst verrichtete.","sameAs":["https:\/\/x.com\/bollejansson"]},{"@type":"PostalAddress","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#local-main-place-address","streetAddress":"Hennes-Weisweiler-Allee 23","addressLocality":"M\u00f6nchengladbach","postalCode":"41179","addressRegion":"Deutschland","addressCountry":"DE"},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.credativ.de\/en\/blog\/howtos-en\/manually-create-an-apparmor-profile-for-nginx\/#local-main-organization-logo","url":"https:\/\/www.credativ.de\/wp-content\/uploads\/2025\/04\/credativ-logo-right.svg","contentUrl":"https:\/\/www.credativ.de\/wp-content\/uploads\/2025\/04\/credativ-logo-right.svg","caption":"credativ\u00ae"}]},"geo.placename":"M\u00f6nchengladbach","geo.position":{"lat":"51.1732374","long":"6.392010099999999"},"geo.region":"Germany"},"_links":{"self":[{"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/posts\/18710","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/users\/60"}],"replies":[{"embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/comments?post=18710"}],"version-history":[{"count":0,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/posts\/18710\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/media\/6774"}],"wp:attachment":[{"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/media?parent=18710"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/categories?post=18710"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.credativ.de\/en\/wp-json\/wp\/v2\/tags?post=18710"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}