Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-3765

service providers not utilizing selinux



    • Night's Watch


      Puppet on SELinux enabled systems currently has an issue where the init provider does not start programs into their correct SELinux context.

      While this problem was first discovered with Gentoo's openrc provider, this applies for sure to redhat and probably debian as well. Though I don't have a test case for debian at the moment.

      The problem is setup like this.

      When you start a service under selinux, the program inherits the contexts of the current SELinux user/role/context unless there's a transition to move it to a more appropriate domain.

      Thre is a selinux userspace utility called run_init to "help" this along so that init scripts can be called via userspace into their proper context.

      The problem illustrated:

      This is how sshd likes to run on EL6:

      # ps auxZ | grep /usr/sbin/sshd
      system_u:system_r:sshd_t:s0-s0:c0.c1023 root 1932 0.0 0.0 66688 1252 ? Ss Dec14 0:00 /usr/sbin/sshd

      Now restart the service and see what context it runs under. This, by the way, is how puppet will restart a service. Either with "service" or directly calling the init script - either way the result is the same.

      # service sshd restart
      Stopping sshd: [ OK ]
      Starting sshd: [ OK ]

      # ps auxZ | grep /usr/sbin/sshd
      unconfined_u:system_r:sshd_t:s0-s0:c0.c1023 root 3955 0.5 0.0 66688 1220 ? Ss 03:02 0:00 /usr/sbin/sshd

      It should not be too surprising that the root user's selinux user is unconfined_u under EL6:

      # id -Z

      Now when sshd is restarted with run_init:

      # run_init service sshd restart
      Authenticating root.
      Stopping sshd: [ OK ]
      Starting sshd: [ OK ]

      # ps auxZ | grep /usr/sbin/sshd
      system_u:system_r:sshd_t:s0-s0:c0.c1023 root 3981 0.0 0.0 66688 1228 ? Ss 03:03 0:00 /usr/sbin/sshd

      Correct context!

      I'm reasonably close to a solution, but it requires tweaking for non-selinux cases and has a few engineering "concerns".

      In short:

      1) Drop a run_init command into the provider:

      has_command(:run_init, '/usr/sbin/run_init') do

      2) Modify the service calls accordingly.

      Eg, statuscmd in the openrc.rb provider goes from this:

      command(:rcservice), @resource[:name], :status

      ...to this:

      command(:run_init), command(:rcservice), @resource[:name], :status

      This works happily in the openrc example, though it does not work so well in the non-selinux case due to an additional space being prepended to the run_init command being nonexistent.

      I'm not clear how to solve that, but that's a solid starting point into fixing this.

      This does have an additional issue where any case where run_init is used, a modification to pam needs to be made so the automatic transition is possible. I'm not clear on the general resolution of that.




            Unassigned Unassigned
            jowr eric gisse
            1 Vote for this issue
            4 Start watching this issue



              Zendesk Support