Using sudo (instead of root) for running privileged tasks

Originally I was going to talk about how to use sudo for installing the cross platform agent. That turned out to be a bit tricky since the tasks in the MP are "Reserved" and required exporting, modifying, and re-importing the entire MP (and as it turned out, every MP up to the main Unix Library MP!). When it comes to things like diagnostics and remediations, the process is a little different and doesn't involve replacing the entire MP. Basically what you're going to do is use overrides on the existing MP for the privileged actions and then import new actions to replace them (not the entire MP). Overall, the process might actually be more involved than a "rip and replace" of the entire MP, but you leave yourself in a "more supported" position.

The other main difference here is that the process used for performing a remediation or recovery action is different than the process of installing an agent, specifically in that when installing the agent, you specify a user name and password as part of the task. In the diagnostic and recovery actions, it uses the specified account (privileged or non-privileged) to establish the connection, but you don't normally have a password into the command line. What does this mean? Well, if you use sudo, and your sudo configuration requires you to enter a password as part of the sudo command, or if the password is not cached, using sudo in an action will fail, unless you specifically add the password into the command line. Luckily, we have an OpsMgr variable we can insert to do that. If we assume that we're going to set the privileged user profile to be the one using sudo, then we'd use this variable: 
                          $RunAs[Name="Unix!Microsoft.Unix.PrivilegedAccount"]/Password$  
Alternatively, if your sudoers configuration specifies NOPASSWD for your account, you can do without all this variable wrangling and just use the sudo command.  You'll see later on how this fits in.

IMPORTANT:

The process described in this article involves disabling existing actions replacing them with your own (unsupported) actions. If you are not comfortable with this, then do not do it.

You should always test every MP change in a non-production environment to ensure it will work correctly in your specific situation. I have only done minimal testing in a limited environment that probably doesn’t come close to your own environment’s configuration.

Neither I nor Microsoft, nor any other person, animal, vegetable or mineral assumes responsibility for the process demonstrated here. USE AT YOUR OWN RISK!

 

  1. First, we start with a "blank" management pack. By blank I mean it has the bare essentials needed to be an importable management pack. What I typically do

  2. Open the Authoring Console and click on File > New and the New Management Pack wizard opens.

  3. Select Empty Management Pack and then type in a name for it like Linux.SLES10.Sudo. I used this to designate it's for SLES10 (since each OS has its own classes for doing agent installation). Click Next.

  4. Enter a display name for the MP, such as Sudo overrides for SLES 10 privileged actions. Click Create.

    You now have a "blank" management pack. Now you need to add references to the other libraries needed to support the task(s) we need to create.

  5. From the main menu, select File > Management Pack Properties.

  6. In the properties dialog, select the References tab and click Add Reference.

  7. Browse to the directory of the latest cross platform MPs (for CU2, it's C:\Program Files (x86)\System Center Management Packs\SCOMCrossPlatformCU2MP) and select Microsoft.Linux.SLES.10.mp and then click Open. This adds the MP to the reference list. We need this reference because our new actions are referencing the existing types in the SLES 10 MP. Also add the Microsoft.Unix.Library MP as a reference as shown below:

     image

  8. Now the easy, cut and paste part… Click File > Save and save your new MP. By default it will come up to the last directory you used, which was the CU2 MP directory. Use that if you like. Close the Authoring Console.

  9. Open the XML file in your favorite editor (mine is Visual Studio 2010!). You should see something like this:

     <ManagementPack ContentReadable="true" xmlns:xsd=https://www.w3.org/2001/XMLSchema 
    xmlns:xsl="https://www.w3.org/1999/XSL/Transform">
      <Manifest>
        <Identity>
          <ID>Linux.SLES10.Sudo</ID>
          <Version>1.0.0.0</Version>
        </Identity>
        <Name>Linux.SLES10.Sudo</Name>
        <References>
          <Reference Alias="SC">
            <ID>Microsoft.SystemCenter.Library</ID>
            <Version>6.1.7221.0</Version>
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
          </Reference>
          <Reference Alias="MicrosoftLinuxSLES10">
            <ID>Microsoft.Linux.SLES.10</ID>
            <Version>6.1.7000.273</Version>
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
          </Reference>
          <Reference Alias="MicrosoftUnixLibrary"> 
            <ID>Microsoft.Unix.Library</ID> 
            <Version>6.1.7000.273</Version> 
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken> 
          </Reference>
                <Reference Alias="Windows">
            <ID>Microsoft.Windows.Library</ID>
            <Version>6.1.7221.0</Version>
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
          </Reference>
          <Reference Alias="Health">
            <ID>System.Health.Library</ID>
            <Version>6.1.7221.0</Version>
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
          </Reference>
          <Reference Alias="System">
            <ID>System.Library</ID>
            <Version>6.1.7221.0</Version>
            <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
          </Reference>
        </References>
                    <LanguagePacks>
        <LanguagePack ID="ENU" IsDefault="true">
          <DisplayStrings>
            <DisplayString ElementID="Linux.SLES10.Sudo">
              <Name>Sudo overrides for SLES 10 privileged actions</Name>
              <Description />
            </DisplayString>
          </DisplayStrings>
        </LanguagePack>
      </LanguagePacks>
    </ManagementPack>
    
  10. Now, to provide a little "shorthand notation" to the SLES 10 reference (so it's not so long), change that reference alias as shown below:

     <Reference Alias="MicrosoftLinuxSLES10">
    
     becomes…
    
     <Reference Alias="SLES10">
    
  11. And, since the existing MP actions reference the "Unix" alias, we need to change our reference alias to match those:

     <Reference Alias="MicrosoftUnixLibrary">
    
     becomes…
    
     <Reference Alias="Unix">
    
  12. You'll  need to add a new Monitoring element between Manifest and LanguagePacks like this:

     </Manifest>
    
    <Monitoring>
    </Monitoring>
    
    <LanguagePacks>
    
  13. First, you export the existing MP. For the purposes of this article, I'll use the SLES 10 MP. There's a PowerShell command for exporting the MP, so open the Operations Manager Command Shell and type the following command:

    get-managementpack –name Microsoft.Linux.SLES.10 | export-managementpack –path C:\files    (put your own dir name here)

     image_thumb9 

  14. Looking in the existing MP for SLES 10, you'll need to find all the instances where the privileged account is used and copy those to the new MP, inside the Monitoring element.

    Note: I found it easier to just copy the entire Diagnostics and Recoveries sections from the existing MP to the new MP and then remove the diagnostics in the new MP that did not have the word "Privileged" in their TypeID. You should end up with 3 diagnostics and 7 recoveries.

  15. Next, to make the command work specifically for sudo, you need to change the command line string located in each of the <Input> elements of these actions. Like the previous article, we'll use "sudo -k; sudo" as a prefix to the command. We'll also need to add the password (since we're clearing the cache and need to account for instances where the password is required). And, since we're supplying the password in the command line, the sudo command needs to be changed to enable reading the password from stdin by making the command "sudo -S" (not "-s").  The final command prefix is:

    sudo -k; echo $RunAs[Name="Unix!Microsoft.Unix.PrivilegedAccount"]/Password$ | sudo -S <and then the rest of the command>

    Here is an example (it's hard to read, so I highlighted the added part:

     <Diagnostic ID="Microsoft.Linux.SLES.10.Process.Cron.Diagnostic" Accessibility="Public" 
    Enabled="true" Target="Microsoft.Linux.SLES.10.OperatingSystem" Monitor="Microsoft.Linux.SLES.10.Process.Cron.Monitor" 
    ExecuteOnState="Error" Remotable="true" Timeout="300">
      <Category>Maintenance</Category>
      <ProbeAction ID="ExecuteCommand" TypeID="Unix!Microsoft.Unix.WSMan.Invoke.Privileged.ProbeAction">
        <TargetSystem>$Target/Host/Property[Type="Unix!Microsoft.Unix.Computer"]/PrincipalName$</TargetSystem>
        <Uri>https://schemas.microsoft.com/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem?__cimnamespace=root/scx</Uri>
        <Selector />
        <InvokeAction>ExecuteCommand</InvokeAction>
        <Input>
    &lt;p:ExecuteCommand_INPUT xmlns:p="https://schemas.microsoft.com/wbem/wscim/1/cim-schema/2/SCX_OperatingSystem"&gt;
    &lt;p:command&gt;
    sudo -k; echo $RunAs[Name="Unix!Microsoft.Unix.PrivilegedAccount"]/Password$ | sudo -S service cron status
    &lt;/p:command&gt;
    &lt;p:timeout&gt;60&lt;/p:timeout&gt;
    &lt;/p:ExecuteCommand_INPUT&gt;
        </Input>
      </ProbeAction>
    </Diagnostic>
    

    Note: If your sudoers configuration specifies that a password is NOT required (NOPASSWD) for the user you're specifying for this command, then you can shorten the command to this: sudo -k; sudo 

  16. Repeat this for the other diagnostics and recoveries.

  17. Finally, since your new actions reference target classes in other management packs, you'll need to modify the Target name to show which MP these classes come from. This part is easy… just do a search for "Microsoft.Linux.SLES.10" and replace it with "SLES10!Microsoft.Linux.SLES.10". This uses the alias you created before. (note: I had 10 replacements in my MP).

    image 

  18. Do the same search and replace using the Monitor attribute:

    image 

  19. Finally, you'll to add the reference alias to any of the recoveries' "ExecuteOnDiagnostic" attributes that reference a diagnostic not in this MP. So, you'll need to add the SLES10 alias to the following:

    1. Microsoft.Linux.SLES.10.Process.ACPI.Diagnostic
    2. Microsoft.Linux.SLES.10.Process.Klog.Diagnostic
    3. Microsoft.Linux.SLES.10.Process.Udev.Diagnostic
    4. Microsoft.Linux.SLES.10.LogicalDisk.DiskHealth.Diagnostic

    Note: You do not want to add the alias to the front of your action ID attributes. You want these actions to have the exact same IDs as the ones they are replacing so that anything that interacts with them can still work without changing them.

  20. Save the XML file, then open your Operations Manager admin console.

    NOTE: Before importing the new MP, you will need to disable the existing agent install/upgrade tasks. If you don't already have an MP for overrides, you should create one (don't use the default MP for overrides).

  21. First you will need to disable the existing diagnostics and recoveries using overrides. In the admin console, go to the Authoring pane and select Management Pack Objects > Monitors.

  22. In the right pane, click Change Scope and type SUSE in the Look for box. This filters the list of MPs for you. Find the targets that begin with SUSE Linux Enterprise Server 10 and select them, then click OK.

  23. In the lower part of the Monitors pane, expand SUSE Linux Enterprise Server 10 Operating System > Entity Health > Availability. You should see 6 health status monitors for the system processes. You will need to disable some of the diagnostics and all of the recoveries for these.Use the following chart to determine the right actions to perform:

    Monitor

    Diagnostic

    Recovery

    Process Acpi  

    Disable

    Process Cron

    Disable

    Disable

    Process Klog  

    Disable

    Process SSH

    Disable

    Disable

    Process Syslog

    Disable

    Disable

    Process Udev  

    Disable

  24. Finally, expand SUSE Linux Enterprise Server 10 Logical Disk > Entity Health > Availability. You should see the Logical Disk Health monitor. You will need to disable the recovery for this monitor (not the diagnostic).

    Note: To double-check if you've disabled all of the right things, just go to Overrides (on the left) and then expand the items in the right pane. They should look like this:

    image

  25. Once all of these have been disabled, you can import the newly-created management pack. Once you do, you can go back into the monitors and see the new diagnostics and/or recoveries added to your existing health monitors. Here's an example of the ACPI monitor:

    image

    Note that your new one has the class name instead of a "nice" name (using the language pack settings). You can modify this if you want using the language pack string elements, or you can leave it like this. It kind of makes it easier to distinguish which ones are the ones you added.

 

Ok, one final caveat (and I expect to get some comments about this and be fixing the post)… In order to get this post out and answer some questions, I have not run the process through any real testing to make sure everything works perfectly – there are likely to be some bugs. If there are, feel free to post a comment or send me an email to let me know and I'll fix it.

I have posted two sample MPs - one requiring a password and one that doesn't need a password. Each MP will also have the overrides to the existing monitors built in. The files can be found on the SCX Community CodePlex Site in this changeset.