selinux-apache selinux-apache-it.xml,NONE,1.1

Francesco Tombolini (tombo) fedora-docs-commits at redhat.com
Sun Dec 4 16:40:10 UTC 2005


Author: tombo

Update of /cvs/docs/selinux-apache
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv22136/selinux-apache

Added Files:
	selinux-apache-it.xml 
Log Message:
First part of italian translation


--- NEW FILE selinux-apache-it.xml ---
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [

<!-- *************** Bring in Fedora entities *************** -->
<!ENTITY % FEDORA-ENTITIES-EN SYSTEM "../docs-common/common/fedora-entities-it.ent">
%FEDORA-ENTITIES-EN;

<!ENTITY BOOKID "selinux-apache-0.6 (2004-11-16-T21:30-0500)"> <!-- version of manual and date -->

<!-- ************** local entities *********** -->

<!ENTITY SEL "SELinux">
<!ENTITY APACHE "Apache HTTP">
<!ENTITY APACHEFULL "Apache HTTP Server">
<!ENTITY LOCALVER "3"> <!-- Local version variable when FCVER is a diff version -->
<!ENTITY LOCALRHELVER "4">
]>

<article id="selinux-apache" lang="it">
  <articleinfo>
    <title> Comprendere e personalizzare la policy &SEL; &APACHE;
      (Documento Beta)</title>
    <copyright>
      <year>2004</year>
      <holder>&FORMAL-RHI;</holder>
    </copyright>
    <authorgroup>
      <author>
        <surname>Walters</surname>
        <firstname>Colin</firstname>
      </author>
    </authorgroup>
    &LEGALNOTICE;
  </articleinfo>

  <section id="sn-why-protect-apache">
    <title>Perchè proteggere &APACHE; con &SEL;?</title>
    <note>
      <title>Documento beta</title>
      <para>
        Questo è un documento beta. I contenuti tecnici contenuti qui sono
	stati controllati, ma potrebbero non funzionare come ti aspetti sul tuo sistema. Le
	idee contenute qui sono accurate, ma per come sono scritte, potrebbero
	soffrire di mancanza di chiarezza. Se scopri un errore o vorresti
	comunque fare un commento, per favore riempi questo <ulink
          url="https://bugzilla.redhat.com/bugzilla/enter_bug.cgi?product=Fedora%20Core&op_sys=Linux&version=fc3&component=fedora-docs&component_text=&rep_platform=All&priority=normal&bug_severity=normal&bug_status=NEW&assigned_to=walters%40redhat.com&cc=kwade%40redhat.com&estimated_time=0.0&bug_file_loc=http%3A%2F%2Ffedora.redhat.com%2Fdocs%2Fselinux-apache%2F&short_desc=SELinux%20Apache%20tutorial%20-%20describe%20the%20bug&comment=Description%20of%20problem%3A%0D%0A%0D%0A%5Bprovide%20details%2C%20patches%2C%20etc.%5D%0D%0A%0D%0ADocument%20version%3A%0D%0A%0D%0Aselinux-apache-0.5-1%20%282004-10-19-T21%3A24-0500%29&keywords=&dependson=&blocked=136427&maketemplate=Remember%20values%20as%20bookmarkable%20template&form_name=enter_bug"> rapporto di errore 
          </ulink>, che ha la maggior parte dei campi precompilati.
      </para>
    </note>

    <para>
      &APACHEFULL; (<command>httpd</command>) è uno dei più
      complessi demoni distribuiti con &FC; o &RHEL;. Supporta molte
      specie di librerie condivise di estensioni, linguaggi
      di programmazione proprietari, e ha uno dei più potenti e
      complessi formati di file di configurazione. Supporta l'esecuzione dei CGI
      scripts da potenziali utenti non verificati, così come concede
      loro controllo sull'accesso mediante (<filename>.htaccess</filename>), ed
      molto altro.
    </para>
    <para>
      Quando esaminerai il sorgente della policy di sicurezza di &SEL; per &APACHE; per
      la prima volta, noterai che anch'essa sembra molto complessa. Certamente
      è la più complessa e configurabile di tutte le policies &SEL;.
      La verità è che è un software come Apache ad essere complesso
      - &SEL; sta solo rivelando questa complessità.
    </para>
    <para>
      Comunque, &SEL; è una tecnologia flessibile. Puoi usarla per
      sia per ottenere obbiettivi di sicurezza di ampio respiro come trattenere un
      Apache compromesso dal danneggiare il resto del sistema, sia
      obbiettivi più finemente granulati come prevenire ad uno
      script CGI wiki compromesso dal corrompere un blog installato dalla
      stessa persona che lo possiede.
    </para>
    <para>
      Questa guida guarda alla policy &APACHE; &SEL; distribuita con &FC;
      &LOCALVER;, e dimostra come usare &SEL; per proteggere
      &APACHE; in vari scenari.
    </para>
  </section>
  <section id="sn-getting-started">
    <title>Cominciamo</title>
    <note>
      <title>Questa guida è specifica per &FC; &LOCALVER; or &RHEL;
        &LOCALRHELVER;</title>
      <para>
        Mentre gran parte della teoria in questa guida è applicabile ad altri
	sistemi, i dettagli predefiniti della policy di
	&SEL;, la configurazione di &APACHE;, e la conformazione del file system
	della tua distribuzione, possono differire. In particolare, questa guida è indirizzata alla
	policy <firstterm>targeted</firstterm>, anche se in seguito
	si discuterà comunque della policy <firstterm>strict</firstterm>.
      </para>
    </note>
    <para>
      Il primo passo è installare il
      pacchetto <filename>httpd</filename>, e probabilmente i
      pacchetti <filename>httpd-suexec</filename> e
      <filename>httpd-manual</filename>. Il
      pacchetto <filename>selinux-policy-targeted</filename> dovrebbe essere
      già parte dell'installazione predefinita.  Se vuoi fare una qualsiasi
      personalizzazione della policy, dovrai installare anche il pacchetto
      <filename>selinux-policy-targeted-sources</filename>.
    </para>
    <para>
      Per impostazione predefinita la sicurezza &SEL; è attiva in modalità enforcing per &APACHE;.
      Per verificarlo, esegui <application>system-config-securitylevel</application>,
      e guarda nel tabulatore <guilabel>&SEL;</guilabel>. Clicca
      sull'albero delle <guilabel>Transazioni</guilabel> ed assicurati che
      <guilabel>Disabilita la protezione &SEL; per il demone httpd</guilabel>
      <emphasis>non</emphasis> sia segnata.
    </para>
    <para>
      Come ulteriore controllo, usa il comando <command>ps axZ | grep
      httpd</command>. Lo dovresti vedere in esecuzione sotto il
      <firstterm>security context</firstterm>
      <computeroutput>root_u:system_r:httpd_t</computeroutput>.
      La parte più importante è la terza componente, il
      <firstterm>type</firstterm> <computeroutput>httpd_t</computeroutput>.
      Nota che molti altri processi sul tuo sistema sono in esecuzione sotto il tipo
      <computeroutput>unconfined_t</computeroutput>. Essendo eseguito
      in un contesto di sicurezza separato con il
      tipo <computeroutput>httpd_t</computeroutput>, &APACHE; è
      confinato da &SEL;.
    </para>
  </section>
  <section id="sn-simple-setup">
    <title>Una semplice configurazione</title>
    <para>
      Assumiamo che tu abbia un semplicissimo, singolo
      sito web con i files <filename>.html</filename> in
      <filename>/var/www/html</filename>, nessuno script CGI, hosting
      virtuale, o amministratori Web multipli. Questi
      argomenti avanzati saranno coperti nella <xref linkend="sn-suexec-and-cgi-scripts"/>.
    </para>
    <para>
      L'obbiettivo di sicurezza è quello di essere sicuri che &APACHE; stia leggendo
      solamente il contenuto Web statico, e non faccia altro come
      scrivere sui conenuti, connettersi ai sockets dei database, leggere
      le home directories degli utenti, etc.
    </para>
    <para>
      Per scelta predefinita, la policy &SEL; di Fedora permette ad &APACHE; di eseguire
      gli scripts CGI e leggere direttamente dalle home directory degli utenti i contenuti. Per disabilitare
      queste opzioni per questa sezione, eseguite
      <application>system-config-securitylevel</application>, cliccate il
      tabulatore <guilabel>&SEL;</guilabel>, e sotto
      <guimenu>Servizio HTTPD</guimenu>, eliminate
      il contrassegno a fianco delle voci
      <guilabel>Permetti il supporto HTTPD cgi</guilabel> e
      <guilabel>Permetti ad HTTPD di leggere le home directory</guilabel>. In alternativa, puoi eseguire questi
      comandi da un terminale:
    </para>
<screen>
<command>setsebool httpd_enable_cgi false</command>
<command>setsebool httpd_enable_homedirs false</command>
</screen>
     <para>
       SELinux  e le booleane sono discusse in <xref
       linkend="sn-httpd-booleans"/>.
     </para>
    <para>
      In <xref linkend="sn-getting-started"/>, è stato menzionato che
      il processo &APACHE; è stato rietichettato
      <computeroutput>httpd_t</computeroutput> perciò ha le restrizioni &SEL;
      applicate.  In &SEL;, <emphasis>ogni</emphasis>
      oggetto del sistema, tipo i normali files, le porte di rete,
      processi, i descrittori dei file, etc., hanno un contesto di sicurezza
      associata ad essi.  Ecco i contesti dei files contenuti nel
      semplice sito web:
    </para>
    <screen>
<command>ls -aZ /var/www/</command>
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t .
drwxr-xr-x  root     root     system_u:object_r:var_t          ..
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_script_exec_t cgi-bin
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t error
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t html
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t icons
<command>ls -aZ /var/www/error</command>
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t .
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t ..
[...]
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t include
-rw-r--r--  root     root     system_u:object_r:httpd_sys_content_t noindex.html
-rw-r--r--  root     root     system_u:object_r:httpd_sys_content_t README
    </screen>
    <para>
      Nuovamente, la parte importante è la terza componente del contesto,
      il tipo <computeroutput>httpd_sys_content_t</computeroutput>.  La
      policy di sicurezza permette ad <computeroutput>httpd_t</computeroutput>
      (&APACHE;) di leggere files e directories con questo tipo, insieme
      ad altri files cruciali come gli
      <computeroutput>etc_t</computeroutput>.
    </para>
    <para>
      A questo punto, verifica che puntando il tuo Web
      browser su <ulink url="http://localhost"/>, puoi vedere la consueta
      pagina predefinita di &FC; o &RHEL;.  Poi, prova a creare un nuovo file tipo
      <filename>hello.html</filename> in
      <filename>/var/www/html</filename>, e verifica di poterlo vedere
      dal tuo Web browser:
    </para>
<screen>
<command>echo "Hello world" > /var/www/html/hello.html</command>
<command>ls -aZ /var/www/html/hello.html</command>
-rw-r--r--  root  root  system_u:object_r:httpd_sys_content_t hello.html
</screen>
    <para>
      Nota che quando crei un nuovo file in
      <filename>/var/www/html</filename>, per impostazione predefinita esso avrà ereditato il
      tipo <computeroutput>httpd_sys_content_t</computeroutput> dalla
      directory genitore. In questo modo &APACHE; (eseguito come
      <computeroutput>httpd_t</computeroutput>) può leggere il nuovo file.
    </para>
    <para>
      Quando hai usato
      <application>system-config-securitylevel</application> per impostare una
      bolena &SEL; che ha disattivato la capacità di &APACHE; di leggere le home
      directories, ciò ha assicurato che il
      dominio <computeroutput>httpd_t</computeroutput> non abbia
      i permessi di leggere lo
      <computeroutput>user_home_dir_t</computeroutput>.  Questo è il tipo
      assegnato alla home directory di un utente.  Poichè &APACHE; non può accedere alla
      toplevel directory, non può quindi accedere a qualsiasi file contenuto
      all'interno, anche se include contenuti Web.
    </para>
    <screen>
<command>ls -aZ /home/walters</command>
drwx------  walters  walters  root:object_r:user_home_dir_t    .
drwxr-xr-x  root     root     system_u:object_r:home_root_t    ..
-rw-r--r--  walters  walters  user_u:object_r:user_home_t      anaconda-ks.cfg
-rwxr-xr-x  walters  walters  user_u:object_r:user_home_t      anaconda.log
...
    </screen>
    <para>
      Un problema in cui puoi incorrere è la differenza fra i
      comandi <command>mv</command> e <command>cp</command>.
      Supponi di avere alcuni nuovi contenuti
      (<filename>about.html</filename>) da aggiungere al tuo sito.
      Dopo averlo creato nella tua home directory, successivamente fai
      qualcosa tipo: <command>sudo mv /home/walters/about.html
      /var/www/html</command>.  Il problema qui è che il
      comando <command>mv</command> per impostazione predefinita <emphasis>preserva</emphasis>
      le informazioni di contesto associate con il file, mentre
      <command>cp</command>, poichè crea un nuovo file, eredita
      quelle della directory genitore.  Per esempio, questo è il risultato
      dell'<command>mv</command> mensionato sopra:
    </para>
<screen>
<command>ls -aZ /var/www/html/</command>
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t .
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t ..
-rw-r--r--  root     root     system_u:object_r:httpd_sys_content_t index.html
-rw-r--r--  walters  walters  system_u:object_r:user_home_t about.html
</screen>
     <para>
       Se stai eseguendo &APACHE; e provi ad aprire
       <filename>about.html</filename> nel Web browser, otterrai
       un errore <errortext>"Forbidden"</errortext>. Se quindi guarderai in
       <filename>/var/log/messages</filename>, vedrai un
       messaggio simile a questo:
     </para>
<screen>
Oct 19 17:54:59 hostname kernel: audit(1098222899.827:0): avc:  \
denied  { getattr } for  pid=19029 exe=/usr/sbin/httpd \
path=/var/www/html/about.html dev=dm-0 ino=373900 \
scontext=root:system_r:httpd_t tcontext=user_u:object_r:user_home_t \
tclass=file
</screen>
     <para>
       Questo messaggio ti dice che
       <computeroutput>httpd_t</computeroutput> non può accedere ad un file
       con il tipo <computeroutput>user_home_t</computeroutput>. Lo
       <computeroutput>user_home_t</computeroutput> è, come già visto
       nel listato di <filename>/home/walters/</filename>, usato per un
       gran numero di files all'interno della home directory. La policy di sicurezza
       predefinita non consentirà mai ad <computeroutput>httpd_t</computeroutput>
       un qualsiasi accesso al tipo
       <computeroutput>user_home_t</computeroutput>.
     </para>
     <para>
      To relabel the file and allow &APACHE; to read it, you can use
      the <command>chcon</command> utility: <command>chcon -t
        httpd_sys_content_t /var/www/html/about.html</command>.
      Verify the context on the file is correct:
     </para>
<screen>
<command>ls -aZ /var/www/html/</command>
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t .
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t ..
-rw-r--r--  root     root     system_u:object_r:httpd_sys_content_t index.html
-rw-r--r--  walters  walters  system_u:object_r:httpd_sys_content_t about.html
</screen>
      <para>
	The <command>chcon</command> utility is similar in style to the
	UNIX command <command>chmod</command>.  For example, if you
	wanted to recursively change the types of a directory and all
	 the files it contains, you could use this command:
	 <command>chcon -R -h -t httpd_sys_content_t /path/to/directory</command>.
	 The <option>-R</option> switch means to operate recursively,
	 and the <option>-h</option> option means to not follow
	 symlinks (which is almost always what you want).
      </para>
      <tip>
	<title><command>chcon</command> vs. <command>restorecon</command></title>
	<para>
	  There is another command available for changing file labels,
	  called <command>restorecon</command>.  This command is
	  useful if you want to revert back to the default labels
	  on files.  For example, you can run
	  <command>restorecon -v -R /var/www/</command> to reset
	  all the file labels in the <filename>/var/www/</filename>
	  directory.  Internally, restorecon reads the
	  <filename>/etc/selinux/targeted/contexts/files/file_contexts</filename>
	  file, which has a set of regular expressions mapping file
	  paths to security contexts.
	</para>
      </tip>
  </section>
  <section id="sn-user-homedir">
    <title>Adding Per-User Content</title>
    <para>
      This section discusses per-user
      <filename>~/public_html</filename> directories.  You need to do
      three things:
    </para>
    <procedure>
      <step>
	<para>
	  Edit <filename>/etc/httpd/conf/httpd.conf</filename>.
	  Comment out the line <computeroutput>UserDir disable</computeroutput>
	  and change the <computeroutput>UserDir</computeroutput> option
	  to <computeroutput>public_html</computeroutput>.
	</para>
      </step>
      <step>
	<para>
	  Execute <command>service httpd reload</command>.
	</para>
      </step>
      <step>
	<para>
	  Start <application>system-config-securitylevel</application>. In
	  the <guilabel>&SEL;</guilabel> tab, open the <guimenu>Apache</guimenu>
	  menu under <guilabel>Modify SELinux Policy</guilabel>.  Switch
	  the Boolean <guilabel>Allow httpd to read home
	  directories</guilabel> back on.  Alternatively, use
	  <command>setsebool httpd_enable_homedirs true</command> from a
	  terminal.
	</para>
      </step>
    </procedure>
    <para>
      The rest of this process is from the perspective of a user
      wanting to maintain your own website.
    </para>
    <note>
      <title>Remember normal Linux permissions</title>
      <para>
	Make sure that you have your home directory set up with the
	normal Linux permissions for this: in particular, you may need
	to run <command>chmod a+x ~</command>.
      </para>
    </note>
    <para>
      In your home directory, execute <command>mkdir
      public_html</command>.  Examine the security context of the new
      directory:
    </para>
<screen>
<command>ls -adZ public_html</command>
drwxrwxr-x  walters  walters  user_u:object_r:user_home_t      public_html/
</screen>
    <para>
      Note that it has the type
      <computeroutput>user_home_t</computeroutput>, because &SEL; has
      a rule that says new files created in a user's home directory
      (<computeroutput>user_home_dir_t</computeroutput>), get assigned
      the type <computeroutput>user_home_t</computeroutput> by
      default.  A process running as
      <computeroutput>httpd_t</computeroutput> (i.e., &APACHE;) can't
      read a file with this type.  To change the file's type and allow
      &APACHE; to read the file, execute:
      <command>chcon -t httpd_sys_content_t public_html</command>
    </para>
    <note>
      <title>Targeted versus strict</title>
      <para>
	In the strict policy, normal users have to use the type
	<computeroutput>httpd_user_content_t</computeroutput>; the
	<computeroutput>_sys_</computeroutput> means it is reserved
	for the system administrator by default.  Using separate types
	like this allows stronger separation between the system and
	the user.
      </para>
    </note>
    <para>
      Now, create some content in your new
      <filename>public_html</filename> (perhaps
      <filename>index.html</filename>).  Test that you can browse to
      <ulink url="http://localhost/~username/index.html"/>, and see
      the expected data.  Try relabeling the file back: <command>chcon
      -t user_home_t index.html</command>. When you reload the page,
      the Web server will not have permission to read it any more.
    </para>
    <para>
      One key idea is that there are actually two
      independent layers of security involved.  There is the normal Unix
      permissions (which you modify with <command>chmod</command>),
      and the &SEL; file labels, which you modify with
      <command>chcon</command>.  Simply making a file world-readable
      with the Unix command <command>chmod a+r
      <replaceable>filename</replaceable></command> will not, with
      &SEL;, in general allow any process to read the file.  Each
      process must be explicitly authorized in the &SEL; policy for
      access to a particular file type.
    </para>
  </section>
  <section id="sn-security-overview">
    <title>Discussion of Overall Security</title> 
    <para> 
      Having gained an understanding of some basic &SEL; concepts, it
      is useful to step back and see what you have achieved so far, and
      examine some of the philosophy behind &SEL;.
    </para>
    <para>
      Running &APACHE; as <computeroutput>httpd_t</computeroutput>
      does ensure that even if the part of &APACHE; that is running as
      root is compromised or misconfigured, it is isolated from the
      rest of the system, and cannot delete or deface your website.
    </para>
    <para>
      This mention of misconfiguration is useful to elaborate on.  At
      a fundamental level, a hostile attacker trying to break into
      &APACHE; is not very different from a webmaster misconfiguring
      it.  Given &APACHE;'s extremely complex configuration file, all
      it takes is a one-line mistake such as the following to cause
      serious problems on your system:
    </para>
<programlisting>
PidFile /etc/passwd
</programlisting>
    <para>
      And there are plenty of other easier to make mistakes in your
      Apache configuration.
    </para>
    <para>
      &SEL; lets you separate your security policy (&APACHE; should
      never have direct access to <filename>/etc/passwd</filename>)
      from the rest of all the complexity in
      <filename>/etc/httpd/conf/httpd.conf</filename>.  Having
      specific labels for your Web content and &APACHE; also ensures a
      compromised or misconfigured name server
      (<computeroutput>named_t</computeroutput>) cannot read the
      website at all (which is useful if some parts of the website are
      password-protected by &APACHE;, for example).
    </para>
    <para>
      For a much more thorough discussion of the philosophy behind
      &SEL;, refer to <citetitle>The Inevitability Of
      Failure</citetitle> (<ulink url="http://www.nsa.gov/selinux/papers/inevit-abs.cfm">http://www.nsa.gov/selinux/papers/inevit-abs.cfm</ulink>.)
    </para>
  </section>
  <section id="sn-suexec-and-cgi-scripts">
    <title>Virtual Hosting, CGI scripts and suEXEC</title>
    <para>
      Most installations of &APACHE; have some sort of dynamic
      content; in particular, CGI scripts are very common.  This
      section examines a much more complicated use case for
      &SEL;: A website that has a number of users, each of whom owns
      a virtual host, out of which they are allowed to run CGI
      content.
    </para>
    <para>
      In this situation, we have a number of security goals:
      <itemizedlist>
	<listitem>
	  <para>
	    Protect the system from the users
	  </para>
	</listitem>
	<listitem>
	  <para>
	    Protect the users from each other
	  </para>
	</listitem>
	<listitem>
	  <para>
	    Protect the user's home directory from their own CGI scripts
	  </para>
	</listitem>
      </itemizedlist>
    </para>
    <para>
      One common method for approaching the first two goals on a
      non-&SEL; setup is to use an &APACHE; module called <firstterm>suEXEC</firstterm>.
      You can read more about suEXEC at <ulink
      url="http://httpd.apache.org/docs-2.0/suexec.html">http://httpd.apache.org/docs-2.0/suexec.html</ulink>.
      Using suEXEC protection, user CGI scripts run under their own
uid.  This
      ensures that user CGI scripts cannot interfere with the system
      &APACHE; daemon (since it runs under its own uid), nor with
      each other (since each user has their own uid).
    </para>
    <para>
      However, when CGI scripts are run via suEXEC using standard
      Linux security, a compromised, misconfigured, or simply buggy
      user CGI script has complete access to any other file the user
      owns, such as their home directory.  It also has access to any
      process running under the same uid, and so forth.  Given the
      security track record of Web software, protecting the user's
      personal data from CGI programs they may install is very
      desirable.
    </para>
    <para>
      The &SEL; policy specifies that when a user CGI script is
      executed by suEXEC, a <firstterm>domain transition</firstterm>
      occurs to change the script's security label to the 
      <computeroutput>httpd_sys_script_t</computeroutput> type.  This
      means the user's CGI scripts run in their own confined domain
      (but still the same uid).  In the default &FC; setup, the
      <computeroutput>httpd_sys_script_t</computeroutput> domain can read
      <emphasis>and write</emphasis> to files and directories that
      have the <computeroutput>httpd_sys_content_t</computeroutput>
      type.  But they still cannot access files with type
      <computeroutput>user_home_t</computeroutput>, in other words the
      user's home directory.
    </para>
    <para>
      To illustrate this, here are example user names, file names,
      and websites involved.  In this example, the virtual hosting
      provider has each user store their website in
      <filename>/var/www/<replaceable>sitename</replaceable></filename>,
      and the content is all owned by the user.  CGI scripts are
      allowed, and they can be installed anywhere in the user's site;
      the filename just has to end in <filename>.cgi</filename>.  Here
      is an overview of the filesystem layout:
    </para>
<screen>
<command>ls -Z /var/www/</command>
drwxr-xr-x  root     root     system_u:object_r:httpd_sys_content_t .
drwxr-xr-x  root     root     system_u:object_r:var_t          ..
drwxr-xr-x  bob      bob      system_u:object_r:httpd_sys_content_t widgets.com
drwxr-xr-x  jane     jane     system_u:object_r:httpd_sys_content_t yoyodyne.org
drwxr-xr-x  sam      sam      system_u:object_r:httpd_sys_content_t sammy.net
</screen>
    <para>
      Here is a sample of how the &APACHE; configuration for the
      <computeroutput>example.com</computeroutput> domain might look.
      Note particularly that &APACHE; has been configured to run CGI
      scripts as the user <computeroutput>bob</computeroutput>.
    </para>
    <programlisting>
NameVirtualHost 10.23.54.2:80

<VirtualHost 10.23.54.2:80>
    ServerAdmin webmaster at example.com
    DocumentRoot /var/www/example.com/
    ServerName web.example.com
    ServerAlias example.com www.example.com
    ErrorLog logs/example.com-error_log
    CustomLog logs/example.com-access_log common
    SuexecUserGroup bob bob

    <Directory /var/www/example.com/>
      Options +ExecCGI +Indexes
      AddHandler cgi-script .cgi
    </Directory>
</VirtualHost>
    </programlisting>
    <para>
      By using the normal &APACHE; suEXEC mechanism, together with
      &SEL;, you have achieved the major security goals set out at the
      beginning of this section.  However, this is still only a
      fraction of &SEL;'s power.
    </para>
  </section>
  <section id="sn-using-other-types">  
    <title>Using Other Types To Lock Down CGI Scripts</title>
    <para>
      In the section <xref linkend="sn-suexec-and-cgi-scripts"/> you
      saw that a user's CGI script running in the
      <computeroutput>httpd_sys_script_t</computeroutput> domain can
      read and write all Web content.  In many scenarios, this is
      undesirable.  For example, the Pyblosxom blog software (<ulink
        url="http://roughingit.subtlehints.net/pyblosxom/">http://roughingit.subtlehints.net/pyblosxom/</ulink>) 
      reads in a number of plain text blog entry files, and renders
      them to HTML on the fly to the client.  For this, it only needs
      read access to the blog entry files.  Ideally, if Pyblosxom was
      compromised or had a bug, it would not have the ability to
      modify or delete your Web log entries.
    </para>
    <para>
      &SEL; allows you to achieve this by defining more types.  You
      grant <computeroutput>httpd_sys_script_t</computeroutput> the
      access to those types that you desire.  The default &APACHE;
      policy defines a number of other types by default.
    </para>
    <variablelist>
      <title>User-controllable types defined by the &SEL;
        policy</title>
      <varlistentry>
        <term><computeroutput>httpd_sys_script_ro_t</computeroutput></term>
        <listitem>
          <para>
            A CGI script may only read files and directories with this
            type.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><computeroutput>httpd_sys_script_ra_t</computeroutput></term>
        <listitem>
          <para>
            Like the previous type, except a CGI script may also
            append more data (useful for log files, etc).
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><computeroutput>httpd_sys_script_rw_t</computeroutput></term>
        <listitem>
          <para>
            Content that a CGI script may change in any way, including
            deletion.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><computeroutput>httpd_sys_content_t</computeroutput></term>
        <listitem>
          <para>
            See below.
          </para>
        </listitem>
      </varlistentry>
      <varlistentry>
        <term><computeroutput>httpd_sys_script_exec_t</computeroutput></term>
        <listitem>
          <para>
            The type for CGI executables.
            <computeroutput>httpd_t</computeroutput> cannot execute
            other types such as
            <computeroutput>httpd_sys_script_rw_t</computeroutput>.
          </para>
        </listitem>
      </varlistentry>
      </variablelist>
    <para>
      The &FC; &LOCALVER; release introduces a new <firstterm>policy
        boolean</firstterm> called
      <computeroutput>httpd_unified</computeroutput>.  If this boolean
      is enabled, it means that
      <computeroutput>httpd_sys_content_t</computeroutput> (the type
      used for everything up until this point) is treated as the
      <emphasis>union</emphasis> of all the other types above.  If
      this boolean is disabled, it means that (for example) in order
      for a CGI script to be executed by
      <computeroutput>httpd_t</computeroutput>, it must be labeled
      with the
      <computeroutput>httpd_sys_script_exec_t</computeroutput> type.
      And it also means that in order for a CGI script to write data,
      the target file must be labeled with
      <computeroutput>httpd_sys_script_rw_t</computeroutput>, as
      above.
    </para>
    <para>
      The <computeroutput>httpd_unified</computeroutput> boolean
      was introduced so that one could, for the most part, use
      a typical &APACHE; installation without a good grasp on file labeling
      and security contexts.  However, disabling this boolean grants
      far greater security, and is highly recommended.
    </para>
    <para>
      Now, examine how Bob might set up a Pyblosxom installation:
    </para>
<screen>
# cd /var/www/example.com
# ls -aZ blog
drwxr-xr-x  bob  bob  user_u:object_r:httpd_sys_content_t .
drwxr-xr-x  bob  bob  user_u:object_r:httpd_sys_content_t ..
-rwxr-xr-x  bob  bob  user_u:object_r:httpd_sys_script_exec_t index.cgi
drwxr-xr-x  bob  bob  user_u:object_r:httpd_sys_script_ro_t pyblosxom
# cd pyblosxom
# ls -aZ
drwxr-xr-x  bob  bob  user_u:object_r:httpd_sys_script_ro_t .
drwxr-xr-x  bob  bob  user_u:object_r:httpd_sys_content_t ..
-rw-r--r--  bob  bob  user_u:object_r:httpd_sys_script_ro_t comment-form.rss
-rw-r--r--  bob  bob  user_u:object_r:httpd_sys_script_ro_t comment-story.rss
-rw-r--r--  bob  bob  user_u:object_r:httpd_sys_script_ro_t comment.rss
-rw-r--r--  bob  bob  user_u:object_r:httpd_sys_script_ro_t config.py
-rw-r--r--  bob  bob  user_u:object_r:httpd_sys_script_ro_t date_head.html
-rw-r--r--  bob  bob  user_u:object_r:httpd_sys_script_ro_t firstpost.txt
...
</screen>
    <para>Note that the index.cgi executable is marked as
      <computeroutput>httpd_sys_script_exec_t</computeroutput>, and
      the rest of the data is marked as
      <computeroutput>httpd_sys_script_ro_t</computeroutput>.  This
      protects all the blog data from a compromised, misconfigured, or
      buggy Pyblosxom.
    </para>
    <para>
      One other important thing to note about these types is that by
      default, <computeroutput>httpd_t</computeroutput>
      <emphasis>cannot</emphasis> access any of them except for
      <computeroutput>httpd_sys_content_t</computeroutput>.  In other
      words, by default &APACHE; cannot directly access content
      intended for your CGI scripts.
    </para>
    <para>
      Consider the case of a small intranet, accessed via a CGI
      script, which has some public content, and some
      password-protected content.  It stores its data in a large
      database file.  In this case, you would label the database file
      as <computeroutput>httpd_sys_script_rw_t</computeroutput> so
      that the intranet CGI could write to it.  But if you allow
      <computeroutput>httpd_t</computeroutput> access to
      <computeroutput>httpd_sys_script_rw_t</computeroutput>, then if
      &APACHE; was compromised or simply misconfigured, it could gain
      access to the database directly, bypassing the access control
      that the CGI script was doing for the password-protected
      content.
    </para>
  </section>
  <section id="sn-debugging-and-customizing">  
    <title>Debugging Problems and Customizing the Policy</title>
    <para>
      When first deploying &SEL; and &APACHE;, if your &APACHE;
      configuration varies far from the &FC; or &RHEL; defaults, you
      will likely encounter issues related to the &SEL; policy.  This
      section discusses analyzing policy denials, and doing simple
      customizations of the policy.
    </para>
    <section id="sn-httpd-booleans">
      <title>Simple Customization</title>
      <para>
	The first major tool for policy customization is
	<command>system-config-securitylevel</command>.  It
	has a number of policy booleans:
      </para>
      <variablelist>
	<title>Boolean options for &APACHE;</title>
	<varlistentry><term><computeroutput>httpd_enable_cgi</computeroutput> (Allow httpd cgi support)</term>
	<listitem>
	  <para>Whether or not to allow CGI scripts to run at all.</para>
	</listitem>
	</varlistentry>
	<varlistentry><term><computeroutput>httpd_enable_homedirs</computeroutput> (Allow httpd to read home directories)</term>
	<listitem>
	  <para>
	    Whether or not to allow &APACHE; to access top-level home
	    directories.  This does not allow for reading of the
	    <emphasis>content</emphasis> of home directories
	    (<computeroutput>user_home_t</computeroutput>).
	  </para>
	</listitem>
	</varlistentry>
	<varlistentry><term><computeroutput>httpd_ssi_exec</computeroutput> (Allow httpd to run SSI executables in the same domain as system CGI scripts)</term>
	<listitem>
	  <para>
	    If enabled, this boolean causes &APACHE; to transition to the
	    <computeroutput>httpd_sys_script_t</computeroutput> when
	    executing a shell.
	  </para>
	</listitem>
	</varlistentry>
	<varlistentry><term><computeroutput>httpd_unified</computeroutput> (Unify httpd handling of all content files)</term>
	<listitem>
	  <para>
	    This boolean controls whether
	    <computeroutput>httpd_sys_content_t</computeroutput> is
	    treated as the union of all the other types such as
	    <computeroutput>httpd_sys_script_exec_t</computeroutput>.  See
	    <xref linkend="sn-using-other-types"/>
	  </para>
	</listitem>
	</varlistentry>
      </variablelist>
      <para>
	In addition, you can disable &SEL; enforcement for &APACHE;
	entirely with <application>system-config-securitylevel</application>.
      </para>
      <procedure>
	<step>
	  <para>
	    First, click the <guilabel>&SEL;</guilabel> tab.
	  </para>
	</step>
	<step>
	  <para>
	    Click on the <guimenu>Transition</guimenu> tree.
	  </para>
	</step>
	<step>
	  <para>
	    Check <guilabel>Disable &SEL; protection for
	    &APACHE;</guilabel>
	  </para>
	</step>
	<step>
	  <para>
	    Execute <command>/etc/init.d/httpd restart</command>
	  </para>
	</step>
      </procedure>
    </section>
    <section id="sn-policy-debugging">
      <title>Policy Debugging</title>
      <para>
	It is very important to monitor
        <filename>/var/log/messages</filename> for any denials due to
        the &SEL; policy.  Suppose that you see the following denial:
      </para>
      <screen>
Oct 19 17:54:59 hostname kernel: audit(1098050626.859:0): avc:  denied  { write } \
for  pid=27422 exe=/usr/bin/python2.3 name=pyblosxom dev=dm-0 ino=4374593 \
scontext=system_u:system_r:httpd_sys_script_t \
tcontext=user_u:object_r:httpd_sys_script_ro_t tclass=dir
    </screen>
    <para>
      The <computeroutput>{ write }</computeroutput> is telling you
      that the denial involves writing to an object.  The
      <computeroutput>tclass=dir</computeroutput> says that the object
      in question is a directory.  The two most crucial parts are the
      <computeroutput>scontext</computeroutput> and
      <computeroutput>tcontext</computeroutput>, which contain the
      types of the subject
      (<computeroutput>httpd_sys_script_t</computeroutput>) and the
      object (<computeroutput>httpd_sys_script_ro_t</computeroutput>).
      Notice there is other auxilliary information as well; since the
      object is a file, there is its name
      (<computeroutput>pyblosxom</computeroutput>) and inode number
      (<computeroutput>4374593</computeroutput>).
    </para>
    <para>
      In other words, the Python CGI script is trying to write to
      a directory that is marked read-only.  There are many reasons this could
      happen; perhaps the script was misconfigured or buggy, for
      example.  But in this particular case, it turns out that the
      Python interpreter normally tries to generate
      <filename>.pyc</filename> files for each
      <filename>.py</filename> file it encounters.  If the directory
      is marked as
      <computeroutput>httpd_sys_script_ro_t</computeroutput>, then it
      will not be able to create new files in it, and you will see the
      denial.  This is a very common problem with Python CGI scripts.
    </para>
    </section>
    <section id="sn-simple-changes-to-policy-source">
      <title>Simple Changes to Policy Sources</title>
    <para>
      The issue with Python mentioned in <xref
      linkend="sn-policy-debugging"/> is not an issue with &SEL;,
      since it is Python that is trying to write to a directory of
      supposedly read-only objects.  To deal with these spurious
      errors that don't affect the functionality of the CGI script,
      you can direct &SEL; to ignore them.  &SEL; supports a
      <computeroutput>dontaudit</computeroutput> directive in the
      policy sources, but you must rebuild a policy from the source.
      To install the policy sources, use <command>up2date</command> or
      <command>yum</command> to install the
      <computeroutput>selinux-policy-targeted-sources</computeroutput>
      package.
    </para>
    <para>
      To get the rule syntax you need, you can use a
      <command>audit2allow</command>, which will generate the SELinux
      policy to allow a set of logged denials.  For example, you
      could invoke <command>audit2allow -i /var/log/messages
      -l</command>.  This generates allow rules for every denial since
      a policy was last loaded.  The output for the denial in <xref
      linkend="sn-policy-debugging"/> would look like this:
    </para>
<screen>
<command>audit2allow -i /var/log/messages -l</command>
allow httpd_sys_script_t httpd_sys_script_ro_t:dir { write };
</screen>
    <para>
      However, in this case you don't want to actually
      <emphasis>allow</emphasis> this operation, you simply want to
      avoid audit messages from it.  &SEL; supports a directive called
      <computeroutput>dontaudit</computeroutput> instead of
      <computeroutput>allow</computeroutput>.  Now your generated
      policy is <computeroutput>dontaudit httpd_sys_script_t
      httpd_sys_script_ro_t:dir { write };</computeroutput>.  To
      add this to the system policy, follow these steps:
    </para>
    <procedure>
      <step>
	<para>
	  <command>cd /etc/selinux/strict/src/policy</command>
	</para>
      </step>
      <step>
	<para>
	  Use your favorite editor to create the file
	  <filename>domains/misc/local.te</filename>, and
	  add the rule above to it (or <command>echo "dontaudit httpd_sys_script_t httpd_sys_script_ro_t:dir { write };" > domains/misc/local.te</command>).
	</para>
      </step>
      <step>
	<para>
	  <command>make reload</command>.
	</para>
      </step>
    </procedure>
    <caution>
      <title>Analyze <command>audit2allow</command> output carefully</title>
      <para>
	You should not simply place all of the output from
	<command>audit2allow</command> in your
	<filename>domains/misc/local.te</filename>.  It is very easy to
	compromise the security of your system that way; for example,
	using <computeroutput>allow</computeroutput> instead of
	<computeroutput>dontaudit</computeroutput> above would have
	rendered the security from the
	<computeroutput>httpd_sys_script_ro_t</computeroutput> type
	useless.
      </para>
      <para>
	For more information about policy debugging and customization
	in general, refer to the <citetitle>Red Hat &SEL; Policy
	Guide</citetitle>, available online at <ulink
	  url="http://www.redhat.com/docs">http://www.redhat.com/docs</ulink>.
      </para>
    </caution>
    </section>
  </section>
  <section id="sn-strict-policy">  
    <title>Differences Between Strict and Targeted Policy</title>
    <para>
      The fundamental difference with the strict policy is that it
      restricts every process, including user logins, instead of just
      a few selected daemons.  This has important ramifications for
      &APACHE;, because ordinary users are often involved in providing
      and controlling Web content.
    </para>
    <para>
      In the default strict policy, there are two user login types,
      <computeroutput>user_t</computeroutput> and
      <computeroutput>staff_t</computeroutput>.  The strict Apache
      policy defines an additional set of types for each user login
      type, replacing
      <computeroutput><replaceable>_sys_</replaceable></computeroutput>
      with <computeroutput>_user_</computeroutput> and
      <computeroutput>_staff_</computeroutput>.  For example, this gives
      <computeroutput>httpd_user_script_ro_t</computeroutput> and
      <computeroutput>httpd_staff_script_exec_t</computeroutput>.
      This provides for a stronger, mandatory separation between
      users, administrators, and the system.  An ordinary user is
      prevented from reading system Web content directly, and a
      compromised or misconfigured system CGI script is prevented from
      reading a user's content.
    </para>
  </section>
  <section id="sn-further-approaches">  
    <title>Further Approaches for Stronger Security</title>
    <para>
      For some, the default &APACHE; policy may actually not be
      expressive enough.  This section discusses extending
      and fundamentally rewriting the &APACHE; policy for even
      stronger security.  It is assumed that you are familiar with
      the concepts discussed earlier.  This section will generally
      only outline solutions, instead of going into step-by-step
      detail.
    </para>
    <section id="sn-cgi-subdomains">
      <title>Individual Domains for Particular CGI Scripts</title>
      <para>
        Using the default policy, a compromise of one CGI script means
        a compromise of <emphasis>all</emphasis> of them. This is
        because they all run in the same domain
        (<computeroutput>httpd_sys_script_t</computeroutput>) with
        access to the same other types (e.g.
        <computeroutput>httpd_sys_script_rw_t</computeroutput>). Put a
        different way, types are security equivalence classes.
      </para>
      <para>
        Most of the type definitions and permissions regarding CGI
        scripts are in
        <filename>/etc/selinux/<replaceable>policyname</replaceable>/src/policy/macros/program/apache_macros.te</filename>. 
        Open that file up in your favorite editor.  This entire file
        is definining an <command>m4</command> macro called
        <computeroutput>apache_domain</computeroutput>.
      </para>

      <note>
        <title>Understanding <command>m4</command> in one paragraph</title>
        <para>
          The
          <computeroutput>define(`apache_domain',`</computeroutput>
          begins the macro definition.  Inside the definition, the
          <computeroutput>$1</computeroutput> represents the parameter
          passed to the macro.
        </para>
      </note>
      <para>
        If you then look in
        <filename>/etc/selinux/<replaceable>policyname</replaceable>/src/policy/domains/program/apache.te</filename>, 
        you'll see the following invocation:
      </para>
<programlisting>
apache_domain(sys)
</programlisting>
      <para>
        This single line then generates a large set of types and
        rules, substituting <computeroutput>sys</computeroutput> for
        every <computeroutput>$1</computeroutput>.  Suppose that you
        have two CGI programs you want to protect: a blog
        installation, and a wiki installation.  Because these domains
        will be largely similar, you will create a macro. Open up the
        file you are using for local policy,
        <filename>/etc/selinux/<replaceable>policyname</replaceable>/src/policy/domains/misc/local.te</filename>.
      </para>
      <para>
        In order to separate the blog and the wiki, you need to create
        separate types (domains) for them, allow
        <computeroutput>httpd_t</computeroutput> the ability to
        transition to those domains, and create new derived types to
        label their data.  This is very similar to what most of
        <computeroutput>apache_domain</computeroutput> already does,
        but unfortunately that macro does too much for your simple
        needs. However, you can use that macro as a guide for creating
        your macro.
      </para>
      <procedure>
        <step>
          <para>
            Start with the macro skeleton:
          </para>
<programlisting>
define(`apache_script_domain',`

# macro content goes here

') dnl end of apache_script_domain
</programlisting>
        </step>
        <step>
          <para>
            Define types for the CGI script executables (similar to
            <computeroutput>httpd_sys_script_exec_t</computeroutput>),
            and domains for the script processes (similar to
            <computeroutput>httpd_sys_script_t</computeroutput>). You
            also need to authorize the
            <computeroutput>system_r</computeroutput> role for the
            type.
          </para>
<programlisting>
type httpd_sys_$1_exec_t, file_type, sysadmfile;
type httpd_sys_$1_t, domain, privmail;
role system_r types httpd_sys_$1_t;
</programlisting>
        </step>
        <step>
          <para>
            Allow &APACHE; to execute the script, and cause it to
            transition to the script domain.  You also want it to be
            able to signal your CGI script.
          </para>
<programlisting>
domain_auto_trans(httpd_t, httpd_sys_$1_exec_t, httpd_sys_$1_t)
allow httpd_t httpd_sys_$1_t:process { signal sigkill sigstop };
</programlisting>
        </step>
        <step>
          <para>
            Define new types for content.  The following demonstrates
            a read-only type and a read-write type, but you can easily
            define different, more refined types.  After defining
            them, grant your CGI domain the access to them that you
            want.
          </para>
<programlisting>
type httpd_sys_$1_ro_t, file_type, sysadmfile;
type httpd_sys_$1_rw_t, file_type, sysadmfile;

r_dir_file(httpd_sys_$1_t, httpd_sys_$1_ro_t)
create_dir_file(httpd_sys_$1_t, httpd_sys_$1_rw_t)
</programlisting>
          <note>
            <title>User domains in strict policy</title>
            <para>
              On a strict policy system, you also need to allow the
              user domain to manage files with your new types.  See
              <computeroutput>apache_domain</computeroutput>.
            </para>
          </note>
        </step>
        <step>
          <para>
            Now at this point, you need to give your new domain
            permissions.  There are a lot of permissions defined in
            <computeroutput>apache_domain</computeroutput>.  You can
            copy the core of those.
          </para>
<programlisting>
# Copied from apache_macros, more is needed
allow httpd_sys_$1_t httpd_t:fd use;
allow httpd_sys_$1_t httpd_t:process sigchld;

uses_shlib(httpd_sys_$1_t)
can_network(httpd_sys_$1_t)
can_ypbind(httpd_sys_$1_t)
allow httpd_sys_$1_t { usr_t lib_t }:file { getattr read ioctl };
allow httpd_sys_$1_t usr_t:lnk_file { getattr read };

allow httpd_sys_$1_t self:process { fork signal_perms };
...
</programlisting>
          <para>
            There are actually more permissions likely to be
            necessary; they have been omitted for brevity.
          </para>
        </step>
        <step>
          <para>
            You can now use your new macro to create the actual types:
          </para>
<programlisting>
apache_script_domain(wiki)
apache_script_domain(blog)
</programlisting>
          <para>
            Looking at your macro definition, you can mentally
            substitute <computeroutput>wiki</computeroutput> and
            <computeroutput>blog</computeroutput> for
            <computeroutput>$1</computeroutput> and see what has
            happened.  You can easily define quite a bit of policy,
            having built the macro.
          </para>
        </step>
        <step>
          <para>
            Execute a <command>make reload</command> in the source
            directory.  Debug any problems that occur.
          </para>
        </step>
        <step>
          <para>
            Finally, you need to label your data.  Use the
            <command>chcon</command> command to do this.  For example,
            the wiki CGI executable should be labeled as
            <computeroutput>httpd_sys_wiki_exec_t</computeroutput>,
            its read-only data as
            <computeroutput>httpd_sys_wiki_ro_t</computeroutput>, and
            its database as
            <computeroutput>httpd_sys_wiki_rw_t</computeroutput>, etc.
            Similarly for the blog.
          </para>
        </step>
      </procedure>
    </section>
    <section id="sn-multiple-httpd-subdomains">
      <title>Multiple HTTP Subdomains</title>
      <para>
        In the virtual hosting setup outlined in <xref
        linkend="sn-suexec-and-cgi-scripts"/>, a compromise or
        misconfiguration of the main &APACHE;
        (<computeroutput>httpd_t</computeroutput>) means all sites are
        affected.  It would be nice if you could actually have
        multiple &APACHE; servers, each running in their own domain;
        for example,
        <computeroutput>httpd_<replaceable>site</replaceable>_t</computeroutput>.
        This subsection simply discusses the problems and outlines
        possible solutions.
      </para>
      <para>
        Looking at the current policy, it is fairly obvious that in
        order to accomplish this goal, you will need to essentially
        rewrite it from scratch.  The entire policy is predicated on a
        single <computeroutput>httpd_t</computeroutput>.  The main
        idea would be to change it into a macro, along the lines of what you did
        with <computeroutput>apache_script_domain</computeroutput> in
	<xref linkend="sn-cgi-subdomains"/>.
        In fact, if you also want to have individual domains on
        CGI scripts, you will end up with types of the form:
        <computeroutput>httpd_<replaceable>vhost</replaceable>_sys_<replaceable>script</replaceable>_t</computeroutput>. 
        For example,
        <computeroutput>httpd_examplecom_sys_wiki_t</computeroutput> would be
	a wiki CGI for <computeroutput>example.com</computeroutput>.
      </para>
      <para>
        Assuming that you have a macro
        <computeroutput>apache_server_domain</computeroutput> which
        defines all of the desired types and rules.  If you are
        fortunate enough that you have an IP address per domain, one
        approach is simply to copy the
        <computeroutput>/usr/sbin/httpd</computeroutput> binary
        multiple times, but label each one differently:
      </para>
<screen>
<command> ls -aZ /usr/sbin/httpd.*</command>
-rwxr-xr-x  root     root     system_u:object_r:httpd_examplecom_exec_t   /usr/sbin/httpd.examplecom
-rwxr-xr-x  root     root     system_u:object_r:httpd_barorg_exec_t   /usr/sbin/httpd.barorg
</screen>
      <para>
        Next, have your init scripts give each one a separate
        configuration, for example <command>/usr/sbin/httpd.foocom -f
          foocom.com</command>.
      </para>
      <para>
        If you have to serve multiple virtual sites from one IP
        address, one approach might be to modify the &APACHE; source
        code so that once it has read the desired domain from a
        requesting client, it passes off the request to a child which
        is running in the domain for that site.
      </para>
    </section>
    <section id="sn-defining-webmaster">
      <title>Defining a Webmaster Role</title>
      <para>
        This guide has posited that, from a security point of view, a
        misconfigured &APACHE; is no different from a compromised one.
        &SEL; deliberately separates the security policy from the
        configuration of every daemon on the system.  One neat
        consequence of this is that it allows you to actually create a
        <firstterm>webmaster</firstterm> role that is allowed to
        modify the &APACHE; configuration file
        <filename>/etc/httpd/conf/httpd.conf</filename>, restart the
        daemon, etc.  But no matter how the webmaster changes the
        configuration, <command>httpd</command> is still restricted by
        the security policy.
      </para>
      <para>
        In order to do this, you would need to use the strict policy.
        The overall approach is to create a new account with a uid of
        0, but only allowed to log in with the
        <computeroutput>webmaster_r</computeroutput> role, which is
        only authorized for the
        <computeroutput>webmaster_t</computeroutput> type.  You could
        create <computeroutput>webmaster_t</computeroutput> with
        <computeroutput>full_user_role(webmaster)</computeroutput>,
        and then proceeed to add a few permissions, such as:
      </para>
<programlisting>
create_dir_file(webmaster_t, httpd_config_t)
</programlisting>
      <para>
	Since you are giving uid 0
	(<computeroutput>root</computeroutput>) access to the
	webmaster, in this setup you are entirely relying on the &SEL;
	policy.  There is more to do here (making init scripts work
	will be slightly tricky), but this outlines the general idea.
	The remainder is left as an exercise for you.
      </para>
    </section>
  </section>
</article>
<!-- Local Variables:
fill-column: 70
End:
-->




More information about the Fedora-docs-commits mailing list