[Libguestfs] [PATCH 2/2] builder: Add --selinux-relabel option to perform SELinux relabelling.

Richard W.M. Jones rjones at redhat.com
Fri Jan 24 19:52:00 UTC 2014


This adds the --selinux-relabel option which enables selinux in the
appliance and runs:

  load_policy && fixfiles restore && rm -f /.autorelabel

at the end of installation.

This fixes SELinux labels in the guest and makes the autorelabel step
unnecessary.

Some notes:

 - The previous commit is required so that load_policy works.

 - During the build, SELinux is enabled but no policy is loaded.  This
   works because SELinux is in permissive mode.

 - It's possible this flag will not work if the appliance kernel and
   the guest have greatly differing versions, eg. a Fedora 20 guest
   and a RHEL 6 appliance.  I have not tested it.

 - It's not clear if loading guest policy is safe.  All the more
   reason to trust the virt-builder templates and to use libguestfs
   confinement for additional protection.
---
 builder/builder.ml       | 12 ++++++++++--
 builder/cmdline.ml       |  8 ++++++--
 builder/virt-builder.pod | 46 +++++++++++++++++++++++++---------------------
 3 files changed, 41 insertions(+), 25 deletions(-)

diff --git a/builder/builder.ml b/builder/builder.ml
index f3ada95..4b5dcb8 100644
--- a/builder/builder.ml
+++ b/builder/builder.ml
@@ -40,8 +40,8 @@ let main () =
     edit, firstboot, run, format, gpg, hostname, install, list_format, links,
     memsize, mkdirs,
     network, output, password_crypto, quiet, root_password, scrub,
-    scrub_logfile, size, smp, sources, sync, timezone, update, upload,
-    writes =
+    scrub_logfile, selinux_relabel, size, smp, sources, sync, timezone,
+    update, upload, writes =
     parse_cmdline () in
 
   (* Timestamped messages in ordinary, non-debug non-quiet mode. *)
@@ -578,6 +578,8 @@ let main () =
     (match smp with None -> () | Some smp -> g#set_smp smp);
     g#set_network network;
 
+    g#set_selinux selinux_relabel;
+
     (* The output disk is being created, so use cache=unsafe here. *)
     g#add_drive_opts ~format:output_format ~cachemode:"unsafe" output_filename;
 
@@ -890,6 +892,12 @@ exec >>%s 2>&1
       do_run ~display:cmd cmd
   ) run;
 
+  if selinux_relabel then (
+    msg (f_"SELinux relabelling");
+    let cmd = "load_policy && fixfiles restore && rm -f /.autorelabel" in
+    do_run ~display:"load_policy && fixfiles restore" cmd
+  );
+
   (* Clean up the log file:
    *
    * If debugging, dump out the log file.
diff --git a/builder/cmdline.ml b/builder/cmdline.ml
index e3b1484..a6cb6c5 100644
--- a/builder/cmdline.ml
+++ b/builder/cmdline.ml
@@ -180,6 +180,7 @@ let parse_cmdline () =
   let add_scrub s = scrub := s :: !scrub in
 
   let scrub_logfile = ref false in
+  let selinux_relabel = ref false in
 
   let size = ref None in
   let set_size arg = size := Some (parse_size ~prog arg) in
@@ -287,6 +288,8 @@ let parse_cmdline () =
     "--run",     Arg.String add_run,        "script" ^ " " ^ s_"Run script in disk image";
     "--run-command", Arg.String add_run_cmd, "cmd+args" ^ " " ^ s_"Run command in disk image";
     "--scrub",   Arg.String add_scrub,      "name" ^ " " ^ s_"Scrub a file";
+    "--selinux-relabel", Arg.Set selinux_relabel,
+                                            " " ^ s_"Relabel files with correct SELinux labels";
     "--size",    Arg.String set_size,       "size" ^ " " ^ s_"Set output disk size";
     "--smp",     Arg.Int set_smp,           "vcpus" ^ " " ^ s_"Set number of vCPUs";
     "--source",  Arg.String add_source,     "URL" ^ " " ^ s_"Set source URL";
@@ -351,6 +354,7 @@ read the man page virt-builder(1).
   let root_password = !root_password in
   let scrub = List.rev !scrub in
   let scrub_logfile = !scrub_logfile in
+  let selinux_relabel = !selinux_relabel in
   let size = !size in
   let smp = !smp in
   let sources = List.rev !sources in
@@ -457,5 +461,5 @@ read the man page virt-builder(1).
   edit, firstboot, run, format, gpg, hostname, install, list_format, links,
   memsize, mkdirs,
   network, output, password_crypto, quiet, root_password, scrub,
-  scrub_logfile, size, smp, sources, sync, timezone, update, upload,
-  writes
+  scrub_logfile, selinux_relabel, size, smp, sources, sync, timezone,
+  update, upload, writes
diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod
index f72ab30..227b767 100644
--- a/builder/virt-builder.pod
+++ b/builder/virt-builder.pod
@@ -27,6 +27,7 @@ virt-builder - Build virtual machine images quickly
     [--link TARGET:LINK[:LINK]]
     [--edit FILE:EXPR]
     [--delete FILE] [--scrub FILE]
+    [--selinux-relabel]
     [--run SCRIPT] [--run-command 'CMD ARGS ...']
     [--firstboot SCRIPT] [--firstboot-command 'CMD ARGS ...']
     [--firstboot-install PKG,[PKG...]]
@@ -593,6 +594,12 @@ It cannot delete directories, only regular files.
 
 =back
 
+=item B<--selinux-relabel>
+
+Relabel files in the guest so that they have the correct SELinux label.
+
+You should only use this option for guests which support SELinux.
+
 =item B<--size> SIZE
 
 Select the size of the output disk, where the size can be specified
@@ -1029,6 +1036,10 @@ Scripts are run (I<--run>, I<--run-command>).
 
 Scripts run in the order they appear on the command line.
 
+=item *
+
+SELinux relabelling is done (I<--selinux-relabel>).
+
 =back
 
 =head2 IMPORTING THE DISK IMAGE
@@ -1714,30 +1725,23 @@ raw-format guests.
 Guests which use SELinux (such as Fedora and Red Hat Enterprise Linux)
 require that each file has a correct SELinux label.
 
-Since virt-builder does not know how to give new files a correct
-label, the guest templates have an empty file C</.autorelabel> and
-this causes the guest to relabel itself at first boot.
+Virt-builder does not know how to give new files a correct label, so
+there are two possible strategies to give newly created files a
+correct label:
 
-This usually means that these guests will reboot themselves once the
-first time you use them.  B<This is normal, and harmless.>  However if
-you want to perform the relabelling at build time instead of delaying
-it to the first boot, you can boot the guest with the qemu
-I<-no-reboot> option (which means it will shut down after the relabel
-is complete without booting "for real").  Only do this if you are sure
-it is an SELinux guest:
+=over 4
 
- qemu-system-x86_64 \
-   -no-reboot \
-   -nographic \
-   -machine accel=kvm:tcg \
-   -cpu host \
-   -m 2048 \
-   -drive file=disk.img,format=raw,if=virtio \
-   -serial stdio \
-   -monitor none
+=item Using I<--selinux-relabel>
 
-(For further information on the topic of SELinux labelling, see:
-L<https://www.redhat.com/archives/libguestfs/2014-January/msg00183.html>)
+This runs L<fixfiles(8)> just before finalizing the guest, which
+sets SELinux labels correctly.
+
+=item Using C</.autorelabel>
+
+This runs fixfiles at first boot.  Guests will reboot themselves once
+the first time you use them, which is normal and harmless.
+
+=back
 
 =head1 ENVIRONMENT VARIABLES
 
-- 
1.8.4.2




More information about the Libguestfs mailing list