<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>AppArmor on My personal blog</title>
        <link>https://www.matteobianchi.eu/tags/apparmor/</link>
        <description>Recent content in AppArmor on My personal blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <lastBuildDate>Tue, 12 May 2026 09:00:00 +0200</lastBuildDate><atom:link href="https://www.matteobianchi.eu/tags/apparmor/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>AppArmor</title>
        <link>https://www.matteobianchi.eu/p/apparmor/</link>
        <pubDate>Tue, 12 May 2026 09:00:00 +0200</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/apparmor/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/apparmor/cover.png" alt="Featured image of post AppArmor" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/selinux/&#34; &gt;SELinux&lt;/a&gt; è potentissimo ma usa etichette e type, che molti trovano
ostici. &lt;strong&gt;AppArmor&lt;/strong&gt; persegue lo stesso scopo — controllo d&amp;rsquo;accesso obbligatorio che confina i
programmi — con un modello diverso: &lt;strong&gt;profili basati sui percorsi&lt;/strong&gt;. Un profilo dice, in un file di
testo leggibile, &amp;ldquo;questo programma può leggere qui, scrivere lì, usare queste capabilities, e
nient&amp;rsquo;altro&amp;rdquo;. È il MAC di default su Ubuntu e SUSE, ed è spesso più immediato da capire e da scrivere.&lt;/p&gt;
&lt;h2 id=&#34;lo-stato-dei-profili&#34;&gt;Lo stato dei profili
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aa-status            &lt;span class=&#34;c1&#34;&gt;# quali profili sono caricati e in quale modalità&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# apparmor module is loaded.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 30 profiles are in enforce mode.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#    /usr/sbin/nginx ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 5 profiles are in complain mode.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Come SELinux, ha due modalità operative per profilo:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;enforce   → applica il profilo: ciò che non è permesso viene bloccato (produzione)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;complain  → non blocca, ma LOGGA le violazioni → per mettere a punto un profilo nuovo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aa-enforce /etc/apparmor.d/usr.sbin.nginx    &lt;span class=&#34;c1&#34;&gt;# metti un profilo in enforce&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aa-complain /etc/apparmor.d/usr.sbin.nginx   &lt;span class=&#34;c1&#34;&gt;# mettilo in complain (diagnosi)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;leggere-un-profilo&#34;&gt;Leggere un profilo
&lt;/h2&gt;&lt;p&gt;I profili vivono in &lt;code&gt;/etc/apparmor.d/&lt;/code&gt;. La sintassi è esplicita e leggibile:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;#include &amp;lt;tunables/global&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/usr/local/bin/myapp {
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  #include &amp;lt;abstractions/base&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  capability net_bind_service,          # può aprire porte basse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  /etc/myapp/** r,                      # legge la sua config
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  /var/lib/myapp/** rw,                 # legge e scrive i suoi dati
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  /var/log/myapp/app.log w,             # scrive il suo log
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  network inet stream,                  # socket TCP
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  # tutto ciò che non è elencato è NEGATO
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;La filosofia è la stessa del &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/principio-minimo-privilegio/&#34; &gt;privilegio minimo&lt;/a&gt;:
elenchi ciò che è permesso, tutto il resto è vietato. Se &lt;code&gt;myapp&lt;/code&gt; viene compromesso, non può leggere
&lt;code&gt;/etc/shadow&lt;/code&gt; né scrivere fuori dalle sue directory: non è nel profilo.&lt;/p&gt;
&lt;h2 id=&#34;mettere-a-punto-un-profilo-nuovo&#34;&gt;Mettere a punto un profilo nuovo
&lt;/h2&gt;&lt;p&gt;AppArmor ha strumenti che &lt;em&gt;generano&lt;/em&gt; il profilo osservando l&amp;rsquo;applicazione in funzione:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aa-genprof /usr/local/bin/myapp     &lt;span class=&#34;c1&#34;&gt;# avvia la generazione guidata: usa l&amp;#39;app, poi conferma gli accessi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;aa-logprof                          &lt;span class=&#34;c1&#34;&gt;# rivede i log e propone di aggiungere al profilo gli accessi visti&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Il flusso tipico: metti il profilo in &lt;code&gt;complain&lt;/code&gt;, usi l&amp;rsquo;applicazione normalmente, poi &lt;code&gt;aa-logprof&lt;/code&gt;
legge cosa ha fatto e ti chiede quali accessi autorizzare. Confermi solo quelli legittimi, passi a
&lt;code&gt;enforce&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;selinux-o-apparmor&#34;&gt;SELinux o AppArmor?
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;AppArmor  → profili per-percorso, leggibili, rapidi da scrivere; default Ubuntu/SUSE
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SELinux   → etichette/type, più granulare e rigoroso; default RHEL/Fedora/Android
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Non si scelgono: di solito &lt;strong&gt;usi quello della tua distribuzione&lt;/strong&gt; (sono alternativi, non si installano
insieme). Il principio è identico — una politica obbligatoria che confina i programmi oltre il DAC —
e vale la regola d&amp;rsquo;oro di entrambi: davanti a un problema, &lt;strong&gt;metti in complain/permissive e diagnostica,
non disabilitare&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;AppArmor confina i programmi con profili per-percorso leggibili, in enforce o complain, con strumenti
che li generano osservando l&amp;rsquo;app: lo stesso MAC di SELinux con un&amp;rsquo;ergonomia diversa. Confinamento e
controlli sono in posto; ma un sistema sicuro è anche un sistema &lt;em&gt;osservato&lt;/em&gt;. Passiamo al monitoraggio:
l&amp;rsquo;&lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/auditd/&#34; &gt;auditing con auditd&lt;/a&gt;, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
