public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Sven Vermeulen" <sven.vermeulen@siphos.be>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/hardened-docs:master commit in: xml/selinux/
Date: Sat, 15 Oct 2011 15:18:45 +0000 (UTC)	[thread overview]
Message-ID: <52cac2568b9cd904e76e35f6dbe088bbba4b3a34.SwifT@gentoo> (raw)

commit:     52cac2568b9cd904e76e35f6dbe088bbba4b3a34
Author:     Sven Vermeulen <sven.vermeulen <AT> siphos <DOT> be>
AuthorDate: Sat Oct 15 15:18:31 2011 +0000
Commit:     Sven Vermeulen <sven.vermeulen <AT> siphos <DOT> be>
CommitDate: Sat Oct 15 15:18:31 2011 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/hardened-docs.git;a=commit;h=52cac256

Update on commands, start on selinux policy types and modes

---
 xml/selinux/hb-using-commands.xml |   82 +++++++++--
 xml/selinux/hb-using-states.xml   |  290 +++++++++++++++++++++++++++++++++++++
 2 files changed, 356 insertions(+), 16 deletions(-)

diff --git a/xml/selinux/hb-using-commands.xml b/xml/selinux/hb-using-commands.xml
index d0a1cb3..ae55d83 100644
--- a/xml/selinux/hb-using-commands.xml
+++ b/xml/selinux/hb-using-commands.xml
@@ -7,8 +7,8 @@
 <!-- $Header: /var/cvsroot/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-commands.xml,v 1.3 2011/06/07 19:46:52 klondike Exp $ -->
 
 <sections>
-<version>5</version>
-<date>2011-07-13</date>
+<version>6</version>
+<date>2011-10-15</date>
 
 <section>
 <title>SELinux Information Commands</title>
@@ -40,7 +40,7 @@ The first command we will talk about is <c>sestatus</c>.
 </p>
 
 <pre caption="Running sestatus">
-~# <i>sestatus</i>
+# <i>sestatus</i>
 SELinux status:                 enabled
 SELinuxfs mount:                /selinux
 Current mode:                   permissive
@@ -55,6 +55,56 @@ the <e>permissive</e> mode. It also tells you that the system is configured to
 run in <e>strict</e> mode - so no unconfined_t domain here.
 </p>
 
+<p>
+The <c>sestatus</c> command also has an extended output if you run it with the
+<c>-v</c> option. When this is done, the command returns the contexts of
+important processes and files:
+</p>
+
+<pre caption="Running sestatus -v">
+# <i>sestatus -v</i>
+SELinux status:                 enabled
+SELinuxfs mount:                /selinux
+Current mode:                   enforcing
+Mode from config file:          enforcing
+Policy version:                 24
+Policy from config file:        strict
+
+Process contexts:
+Current context:                staff_u:sysadm_r:sysadm_t
+Init context:                   system_u:system_r:init_t
+/sbin/agetty                    system_u:system_r:getty_t
+/usr/sbin/sshd                  system_u:system_r:sshd_t
+
+File contexts:
+Controlling term:               staff_u:object_r:user_devpts_t
+/sbin/init                      system_u:object_r:init_exec_t
+/sbin/agetty                    system_u:object_r:getty_exec_t
+/bin/login                      system_u:object_r:login_exec_t
+/sbin/rc                        system_u:object_r:rc_exec_t
+/usr/sbin/sshd                  system_u:object_r:sshd_exec_t
+/sbin/unix_chkpwd               system_u:object_r:chkpwd_exec_t
+/etc/passwd                     system_u:object_r:etc_t
+/etc/shadow                     system_u:object_r:shadow_t
+/bin/sh                         system_u:object_r:bin_t -> system_u:object_r:shell_exec_t
+/bin/bash                       system_u:object_r:shell_exec_t
+/usr/bin/newrole                system_u:object_r:newrole_exec_t
+/lib/libc.so.6                  system_u:object_r:lib_t -> system_u:object_r:lib_t
+/lib/ld-linux.so.2              system_u:object_r:lib_t -> system_u:object_r:ld_so_t
+</pre>
+
+<p>
+Another general SELinux status command is <c>getenforce</c>, which allows you to
+quickly see if your SELinux is running in enforcing mode (SELinux policies are
+enforced), permissive (SELinux policies are checked and logged, but not
+enforced) or disabled (SELinux policy is not loaded and thus not checked).
+</p>
+
+<pre caption="Using the getenforce command">
+# <i>getenforce</i>
+Enforcing
+</pre>
+
 </body>
 </subsection>
 <subsection>
@@ -95,9 +145,9 @@ attribute set.
 </p>
 
 <pre caption="Using seinfo">
-~# <i>seinfo -tcrontab_t</i>
+# <i>seinfo -tcrontab_t</i>
   crontab_t
-~# <i>seinfo -ruser_r -x</i>
+# <i>seinfo -ruser_r -x</i>
   user_r
     Dominated Roles:
       user_r
@@ -105,7 +155,7 @@ attribute set.
       [...]
       crontab_t
       [...]
-~# <i>seinfo -acron_spool_type -x</i>
+# <i>seinfo -acron_spool_type -x</i>
   cron_spool_type
     user_cron_spool_t
     system_cron_spool_t
@@ -136,7 +186,7 @@ shadow_t domain:
 </p>
 
 <pre caption="Querying allow rules with sesearch">
-~# <i>sesearch -t shadow_t -c file -p write -A</i>
+# <i>sesearch -t shadow_t -c file -p write -A</i>
 Found 8 semantic av rules:
   [...]
   allow portage_t shadow_t : file { ioctl read write ... };
@@ -163,7 +213,7 @@ that this is only portage:
 </p>
 
 <pre caption="Querying domains with file-write privileges to file_type domains">
-~# <i>sesearch -t file_type -c file -p write -A -d</i>
+# <i>sesearch -t file_type -c file -p write -A -d</i>
 Found 1 semantic av rules:
   allow portage_t file_type : file { ioctl read write ... };
 </pre>
@@ -190,7 +240,7 @@ boolean is set:
 </p>
 
 <pre caption="Checking the policy regarding the global_ssp boolean">
-~# <i>sesearch -b global_ssp -A -C -d</i>
+# <i>sesearch -b global_ssp -A -C -d</i>
 Found 2 semantic av rules:
 ET allow domain device_t : dir { getattr search open } ; [ global_ssp ]
 ET allow domain urandom_device_t : chr_file { ioctl read getattr lock open } ; [ global_ssp ]
@@ -237,7 +287,7 @@ To get the security context of a process, use <c>ps -Z</c>:
 </p>
 
 <pre caption="Getting a process security context">
-~# <i>ps -Z $(pidof init)</i>
+# <i>ps -Z $(pidof init)</i>
 LABEL                             PID TTY      STAT   TIME COMMAND
 system_u:system_r:init_t            1 ?        Ss     0:00 init [3]  
 </pre>
@@ -283,7 +333,7 @@ this area).
 </p>
 
 <pre caption="Listing the available SELinux booleans">
-~# <i>semanage boolean -l</i>
+# <i>semanage boolean -l</i>
 SELinux boolean                 Description
 
 allow_ptrace            -> off  allow_ptrace
@@ -301,7 +351,7 @@ You can set a boolean with both <c>setsebool</c> and <c>semanage</c>:
 </p>
 
 <pre caption="Setting SELinux boolean values">
-~# <i>semanage boolean -m --on -F user_dmesg</i>
+# <i>semanage boolean -m --on -F user_dmesg</i>
 </pre>
 
 </body>
@@ -316,7 +366,7 @@ you to map a Unix account to a SELinux user:
 </p>
 
 <pre caption="Listing the SELinux logins">
-~# <i>semanage login -l</i>
+# <i>semanage login -l</i>
 Login Name          SELinux User
 
 __default__         user_u
@@ -339,7 +389,7 @@ can be accomplished as follows (example with the Unix account <e>anna</e>):
 </p>
 
 <pre caption="Letting 'anna' log on as 'staff_u'">
-~# <i>semanage login -a -s staff_u anna</i>
+# <i>semanage login -a -s staff_u anna</i>
 </pre>
 
 <impo>
@@ -354,7 +404,7 @@ roles. To list the available roles, you can use <c>semanage user -l</c>:
 </p>
 
 <pre caption="Listing login / role mappings">
-~# <i>semanage user -l</i>
+# <i>semanage user -l</i>
 SELinux User        SELinux Roles
 
 root                staff_r sysadm_r
@@ -375,7 +425,7 @@ overview of which domains are assigned to which ports (or port ranges) use
 </p>
 
 <pre caption="Listing SELinux managed ports">
-~# <i>semanage port -l | grep '22$'</i>
+# <i>semanage port -l | grep '22$'</i>
 ssh_port_t             tcp     22
 </pre>
 

diff --git a/xml/selinux/hb-using-states.xml b/xml/selinux/hb-using-states.xml
new file mode 100644
index 0000000..63d3f52
--- /dev/null
+++ b/xml/selinux/hb-using-states.xml
@@ -0,0 +1,290 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!DOCTYPE sections SYSTEM "/dtd/book.dtd">
+
+<!-- The content of this document is licensed under the CC-BY-SA license -->
+<!-- See http://creativecommons.org/licenses/by-sa/1.0 -->
+
+<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/proj/en/hardened/selinux/hb-using-commands.xml,v 1.3 2011/06/07 19:46:52 klondike Exp $ -->
+
+<sections>
+<version>1</version>
+<date>2011-10-15</date>
+
+<section>
+<title>SELinux States</title>
+<subsection>
+<title>Introduction</title>
+<body>
+
+<p>
+When SELinux is available, it will generally be in one of three states on your
+system: disabled, permissive or enforcing.
+</p>
+
+</body>
+</subsection>
+<subsection>
+<title>Disabled</title>
+<body>
+
+<p>
+When <c>getenforce</c> returns "Disabled", then SELinux is not running on your
+system. Even though it might be built in your kernel, it is definitely disabled.
+Your system will still run with regular discretionary access controls (the usual
+permission rules for standard Linux environments) but the mandatory access
+controls are not active.
+</p>
+
+<p>
+When SELinux is disabled, it also means that files, directories, etc that are
+modified or created will not get the proper SELinux context assigned to them.
+When you later start your system with SELinux enabled (permissive or enforcing),
+issues will arise since the SELinux subsystem will not know which label the
+files have (it will default the label to one that is not accessible by most
+domains).
+</p>
+
+<p>
+The best way to go forward in such case is to boot in permissive mode and then
+relabel the entire file system:
+</p>
+
+<pre caption="Relabeling the entire file system">
+# <i>rlpkg -a -r</i>
+</pre>
+
+</body>
+</subsection>
+<subsection>
+<title>Permissive</title>
+<body>
+
+<p>
+When SELinux is enabled in permissive mode (<c>getenforce</c> returns
+"Permissive"), then SELinux is enabled and it has a policy loaded. Every access
+a process makes is checked against the policy rules and, if an access is not
+allowed, it will be logged (unless the denial is marked as dontaudit) but it
+will <e>not</e> be prohibited.
+</p>
+
+<p>
+The permissive mode is perfect to get acquainted with SELinux and have the
+system made ready for future "enforcing" mode. While running in permissive mode,
+applications <e>that are not SELinux aware</e> will behave as if SELinux is not
+running. This is perfect to validate if a problem is caused by SELinux or not:
+if in permissive mode the problem still persists, then it is not caused by
+SELinux.
+</p>
+
+<p>
+There is one caveat though: if the application is <e>SELinux-aware</e> (it knows
+that it can run in a SELinux environment and is able to make SELinux-specific
+calls) it might still react differently. Although this is often (but not always)
+a bad programming practice, some applications check if SELinux is enabled and
+base their functional flow on the results, regardless of the state being
+permissive or enforcing.
+</p>
+
+<p>
+To find out if an application is SELinux aware, simply check if it is linked
+against libselinux (with <c>ldd</c> or <c>scanelf</c> - part of
+<path>app-misc/pax-utils</path>):
+</p>
+
+<pre caption="Checking if /bin/ls is SELinux-aware">
+# <i>scanelf -n /bin/ls</i>
+ TYPE     NEEDED FILE
+ET_DYN   libselinux.so.1,librt.so.1,libc.so.6   /bin/ls
+</pre>
+
+</body>
+</subsection>
+<subsection>
+<title>Enforcing</title>
+<body>
+
+<p>
+If <c>getenforce</c> returns "Enforcing", then SELinux is loaded and will act
+based on the policy. When a process tries some activity that is not allowed by
+the policy, it will be logged (unless a dontaudit is set) and the activity will
+not go through. This is the only mode where you can truely say that SELinux is
+active, because it is only now that the policy is acted upon.
+</p>
+
+</body>
+</subsection>
+<subsection>
+<title>Switching States</title>
+<body>
+
+<p>
+Depending on your Linux kernel configuration, you can switch between states
+using one of the following methods. The kernel configuration however can be made
+so that some of these options are disabled (for instance, a fully hardened
+system will not allow disabling SELinux in any way).
+</p>
+
+<p>
+Using the command <c>setenforce</c>:
+</p>
+
+<pre caption="Switching between enforcing and permissive">
+<comment>(Switching to permissive mode)</comment>
+# <i>setenforce 0</i>
+
+<comment>(Switching to enforcing mode)</comment>
+# <i>setenforce 1</i>
+</pre>
+
+<p>
+Using the kernel boot option <c>enforcing</c>:
+</p>
+
+<pre caption="Switching between enforcing and permissive through boot options">
+<comment>(The following GRUB kernel line would boot in permissive mode)</comment>
+kernel /kernel-2.6.39-hardened-r8 root=/dev/md3 rootflags=data=journal <i>enforcing=0</i>
+</pre>
+
+<p>
+Using the <path>/etc/selinux/config</path> <c>SELINUX</c> variable:
+</p>
+
+<pre caption="/etc/selinux/config SELINUX setting">
+# <i>cat /etc/selinux/config</i>
+# This file controls the state of SELinux on the system on boot.
+
+# SELINUX can take one of these three values:
+#       enforcing - SELinux security policy is enforced.
+#       permissive - SELinux prints warnings instead of enforcing.
+#       disabled - No SELinux policy is loaded.
+<i>SELINUX=enforcing</i>
+
+# SELINUXTYPE can take one of these four values:
+#       targeted - Only targeted network daemons are protected.
+#       strict   - Full SELinux protection.
+#       mls      - Full SELinux protection with Multi-Level Security
+#       mcs      - Full SELinux protection with Multi-Category Security 
+#                  (mls, but only one sensitivity level)
+SELINUXTYPE=strict
+</pre>
+
+</body>
+</subsection>
+</section>
+
+<section>
+<title>SELinux Policy Types</title>
+<subsection>
+<title>Introduction</title>
+<body>
+
+<p>
+Next to the SELinux state, SELinux also offers different policy types. These
+types differentiate themselves in specific SELinux features that are enabled or
+disabled. Within Gentoo, three are supported (and a fourth is available):
+<c>targeted</c>, <c>strict</c>, <c>mcs</c> (and <c>mls</c>).
+</p>
+
+<p>
+The type used on a system is declared in <path>/etc/selinux/config</path>:
+</p>
+
+<pre caption="The SELINUXTYPE information in /etc/selinux/config">
+# <i>cat /etc/selinux/config</i>
+# This file controls the state of SELinux on the system on boot.
+
+# SELINUX can take one of these three values:
+#       enforcing - SELinux security policy is enforced.
+#       permissive - SELinux prints warnings instead of enforcing.
+#       disabled - No SELinux policy is loaded.
+SELINUX=enforcing
+
+# SELINUXTYPE can take one of these four values:
+#       targeted - Only targeted network daemons are protected.
+#       strict   - Full SELinux protection.
+#       mls      - Full SELinux protection with Multi-Level Security
+#       mcs      - Full SELinux protection with Multi-Category Security 
+#                  (mls, but only one sensitivity level)
+<i>SELINUXTYPE=strict</i>
+</pre>
+
+</body>
+</subsection>
+<subsection>
+<title>strict (without unconfined domains)</title>
+<body>
+
+<p>
+The <c>strict</c> policy type is the policy type that was described in the
+earlier chapters, and coincidentally the type that is the easiest to understand.
+With the strict policy type, each and every application runs in a domain that
+has limited privileges. Although there are highly privileged domains, they are
+never truely unlimited in their privileges.
+</p>
+
+</body>
+</subsection>
+<subsection>
+<title>targeted (using unconfined domains)</title>
+<body>
+
+<p>
+The <c>targeted</c> policy type is similar to the strict one, with one major
+addition: support for unconfined domains. Applications (or users) that run in an
+unconfined domain are almost unlimited in their privileges. The unconfined
+domains are usually used for users and user applications, but also the init
+system and other domains are marked as "unconfined" domains.
+</p>
+
+<p>
+The idea behind the targeted policy is that network-facing services are running
+in (confined) regular domains whereas the rest uses the standard discretionary
+access controls offered by Linux. These other domains are running as
+"unconfined".
+</p>
+
+</body>
+</subsection>
+<subsection>
+<title>mcs (using multiple categories)</title>
+<body>
+
+<p>
+The introduction of <c>mls</c> and <c>mcs</c> offers the ability for
+<e>multi-tenancy</e>: multiple instances of the same application should be able
+to run, but each instance should be confined with respect to the others (instead
+of all these processes running in the same domain and, hence, the same
+privileges).
+</p>
+
+<p>
+A simple example is virtualization: a virtual guest which runs in the
+<c>qemu_t</c> domain needs write privileges on the image file that contains the
+guest operating system. However, if you run two guests, you do not want each
+guest to write to the other guests' file. With regular domains, you will need to
+provide this. With <c>mcs</c>, you can give each running instance a specific
+category (number) and only grant it write privileges to the guest file with the
+correct category (number).
+</p>
+
+</body>
+</subsection>
+<subsection>
+<title>mls (using multiple security levels)</title>
+<body>
+
+<p>
+The <c>mls</c> policy type is available but not yet supported by Gentoo
+Hardened. With this policy type, it is possible to give sensitivity levels on
+files and resources as well as domains. Sensitivity levels can best be expressed
+in terms of <e>public</e>, <e>private</e>, <e>confidential</e> or <e>strictly
+confidential</e>. With MLS, you can mark a file as one (or a set of)
+sensitivity level(s) and ensure that only domains with the right sensitivity
+level can access it.
+</p>
+
+</body>
+</subsection>
+</section>
+
+</sections>



             reply	other threads:[~2011-10-15 15:18 UTC|newest]

Thread overview: 95+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-10-15 15:18 Sven Vermeulen [this message]
  -- strict thread matches above, loose matches on Subject: below --
2012-05-07 20:20 [gentoo-commits] proj/hardened-docs:master commit in: xml/selinux/ Sven Vermeulen
2012-05-07 20:07 Sven Vermeulen
2012-05-05 18:56 Sven Vermeulen
2012-04-29 14:22 Sven Vermeulen
2012-04-10 18:22 Sven Vermeulen
2012-04-10 18:22 Sven Vermeulen
2012-04-10 18:22 Sven Vermeulen
2012-04-05 16:24 Sven Vermeulen
2012-03-01 20:09 Sven Vermeulen
2012-01-29 12:42 Sven Vermeulen
2012-01-21 13:20 Sven Vermeulen
2011-12-17 10:52 Sven Vermeulen
2011-12-11 14:39 Sven Vermeulen
2011-12-11 14:36 Sven Vermeulen
2011-12-10 14:00 Sven Vermeulen
2011-11-22 20:08 Sven Vermeulen
2011-11-11 19:59 Sven Vermeulen
2011-10-27 19:18 José María Alonso
2011-10-26 22:05 José María Alonso
2011-10-23 13:01 Sven Vermeulen
2011-10-19 12:55 Sven Vermeulen
2011-10-15 18:24 Sven Vermeulen
2011-10-15 17:43 Sven Vermeulen
2011-10-15 17:12 Sven Vermeulen
2011-10-15 15:54 Sven Vermeulen
2011-10-15 13:04 Sven Vermeulen
2011-10-15 13:04 Sven Vermeulen
2011-09-30 17:36 Sven Vermeulen
2011-09-18 13:49 Sven Vermeulen
2011-09-11  9:51 Sven Vermeulen
2011-09-04 19:22 Sven Vermeulen
2011-08-16 16:58 José María Alonso
2011-08-12 21:00 Sven Vermeulen
2011-07-22 16:03 Sven Vermeulen
2011-07-21 19:11 Sven Vermeulen
2011-07-13 21:39 Sven Vermeulen
2011-07-09 18:56 Sven Vermeulen
2011-06-09 18:54 José María Alonso
2011-06-09 17:49 Sven Vermeulen
2011-06-09 17:40 Francisco Blas Izquierdo Riera
2011-06-09 17:24 Sven Vermeulen
2011-06-07 19:38 Sven Vermeulen
2011-06-07 19:26 Sven Vermeulen
2011-06-02 19:50 Sven Vermeulen
2011-06-02 11:57 Sven Vermeulen
2011-06-02 11:55 Sven Vermeulen
2011-06-02 11:03 Sven Vermeulen
2011-06-02 11:03 Sven Vermeulen
2011-05-31 20:22 Sven Vermeulen
2011-05-31 20:16 Sven Vermeulen
2011-05-31 20:16 Sven Vermeulen
2011-05-24 20:39 Sven Vermeulen
2011-05-24 19:56 Sven Vermeulen
2011-05-20 19:32 Sven Vermeulen
2011-05-14 12:51 Sven Vermeulen
2011-05-13 19:43 Sven Vermeulen
2011-05-03 20:47 Sven Vermeulen
2011-05-03 20:12 Sven Vermeulen
2011-04-22 21:43 Sven Vermeulen
2011-04-22 19:30 Sven Vermeulen
2011-04-22 19:28 Sven Vermeulen
2011-04-22 19:05 Sven Vermeulen
2011-04-22 19:05 Sven Vermeulen
2011-04-22 10:32 Sven Vermeulen
2011-04-22 10:32 Sven Vermeulen
2011-04-16  9:06 Sven Vermeulen
2011-04-15 19:10 Sven Vermeulen
2011-04-15 17:52 Sven Vermeulen
2011-04-15 17:52 Sven Vermeulen
2011-04-10  7:49 Sven Vermeulen
2011-04-01 17:45 Sven Vermeulen
2011-03-09 16:54 Sven Vermeulen
2011-03-02 20:48 Sven Vermeulen
2011-03-02 20:38 Sven Vermeulen
2011-03-02 20:38 Sven Vermeulen
2011-03-02 20:13 Sven Vermeulen
2011-03-02 20:13 Sven Vermeulen
2011-03-02 20:13 Sven Vermeulen
2011-03-02 15:53 Sven Vermeulen
2011-02-24 21:19 Sven Vermeulen
2011-02-20 13:26 Sven Vermeulen
2011-02-19 17:00 Francisco Blas Izquierdo Riera
2011-02-19  3:21 Francisco Blas Izquierdo Riera
2011-02-19  3:12 Francisco Blas Izquierdo Riera
2011-02-13 18:20 Sven Vermeulen
2011-02-12 23:44 Sven Vermeulen
2011-02-12 23:44 Sven Vermeulen
2011-02-12 20:50 Sven Vermeulen
2011-02-12 20:49 Sven Vermeulen
2011-02-12 20:47 Sven Vermeulen
2011-02-12 20:47 Sven Vermeulen
2011-02-12 20:47 Sven Vermeulen
2011-02-12 17:33 Sven Vermeulen
2011-02-06 19:53 Sven Vermeulen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=52cac2568b9cd904e76e35f6dbe088bbba4b3a34.SwifT@gentoo \
    --to=sven.vermeulen@siphos.be \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox