Securely creating fixlets to update OS user passwords

Hi all, I need to create a fixlet for updating OS user passwords (primarily Linux and Windows) and have been reading through this old thread: https://www.ibm.com/developerworks/community/forums/html/topic?id=77777777-0000-0000-0000-000014748508 .

While it does provide some options, im currently trying to do this fully through the API and all examples there seem to require manual input for the secure password feature to work.

Is there any other way to accomplish this? Can dashboard variables set to private be a secure alternative to this if they are accessible from fixlets?

If using the REST API, you can pass Secure Parameters in a Sourced Fixlet Action.

Here’s and example of running fixlet ID 4057 from the master action site

<?xml version="1.0" encoding="UTF-8"?> 
<BES xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BES.xsd"> 
<SourcedFixletAction> 
<SourceFixlet> 
<Sitename>ActionSite</Sitename> 
<FixletID>4057</FixletID> 
<Action>Action1</Action> 
</SourceFixlet> 
<Target> 
<ComputerID>15875486</ComputerID> 
</Target> 
<Parameter Name="username">user</Parameter>  
<SecureParameter Name="password">pass</SecureParameter>  
</SourcedFixletAction> 
</BES>
1 Like

I dont follow how this is the same as prior example if the password would end up stored in the fixlet which is not secure.

Im looking to do the following:

  1. Create a fixlet in a site that takes its password from somewhere else dynamically such as a variable or other secure means
  2. Execute that fixlet from the API against a set of machines and pass it the necessary password or update the variable before executing.

I know how to create fixlets but I dont understand what other calls to the API would allow for the rest or how to make use of the above example if it is secure.

[edit] I think I understand, is the above an action to be added through /api/actions ? If so wouldnt it be vulnerable to the same problem as the fixlet since getting the action would yield the original action/password or would it yield the action status instead?

Correct, you pass this as the payload to a http POST request. The IEM server detects that this action contains a secure parameter and “hides” it from the user. You’ll see the same behaviour is you manually execute a fixlet containing a secure parameter.

Sample java code:

   String actionXML = As above....

    HttpPost post = new HttpPost("https://yourserver:52311/api/actions"); 

    StringEntity entity = new StringEntity(actionXML); 
    entity.setContentType("application/xml"); 
    post.setEntity(entity);

    httpClient.execute(post,...)

If the action has been created as shown in @dominic example it is not possible to see the value of the parameter in the action.
It’s not visible if you retrieve the action via the REST API of if you looked at the action in the console.

This is definitely a good example. The server will encrypt the action immediately to the specific endpoint you are targeting it at. Not even the server can decrypt that answer after the action is made, only the endpoint can with its private key when the action is delivered to its mailbox site

In the above example, the target is using the id, but in the schema I see this:

<xs:complexType name="BESActionTarget">
<xs:choice>
  <xs:element name="ComputerName" type="xs:normalizedString" maxOccurs="unbounded" />
  <xs:element name="ComputerID" type="xs:nonNegativeInteger" maxOccurs="unbounded" />
  <xs:element name="CustomRelevance" type="xs:normalizedString" maxOccurs="1"/>
  <xs:element name="AllComputers" type="xs:boolean" maxOccurs="1" />
</xs:choice>

</xs:complexType>

Can we mix and match the element types (computer names with computer id’s or relevance) ? The console seems to organize this a bit differently so its hard to tell how it translates the selections.

You can only use secure parameters if targeting specific machines. This means you cannot use custom relevance, and I don’t think you can target All. I’m not sure if you can mix and match ComputerName & ComputerID. It might be one or the other.


These don’t perfectly fit what you are looking for, but are related and could be used as a template for what you are trying to accomplish:
http://bigfix.me/fixlet/details/3670
http://bigfix.me/fixlet/details/3673
http://bigfix.me/fixlet/details/3671

Thanks, I looked up the XSD definition, xs:choice is one or the other so it looks like mixing and matching isnt an option there. Good to know about the no relevance support there.

The reason you can’t use relevance is that when using a secure parameter, the action is encrypted separately with the public keys of all targeted endpoints and then delivered to the targets mailbox. This can only happen if the targeted endpoints are known at execution time on the server side. If using relevance, then which endpoints should get the action is determined by the endpoints themselves, not the root server. The root server cannot privately encrypt the action to every endpoint that should get it, because it has no way to know which endpoints those are.

A work around is to have an automatic group that collects all endpoints that need the task involving the secure parameter to be executed on them. Then have an action that periodically targets all members of this group specifically (using either computerName or computerID)

For instance, you could have an automatic group that has relevance to enjoin all endpoints with password age > 7 days, or similar.

Correct. You must target a specific endpoint(s) so the server can use the mailboxing feature. This is required for secured parameters as the parameter is encrypted to the endpoint. The SecuredParameter is kept encrypted in the fixlet on disk until it is used in the action.

This also means that only the endpoint(s) that should get this fixlet, get it. So not every endpoint you have gets the password in a fixlet (even if its encrypted).

1 Like

In the example fixlets on that original forum post above, they are using a windows specific MIMETYPE even though its running against a Linux server:

<ActionScript MIMEType="application/x-Fixlet-Windows-Shell">

Is there a Linux specific mimetype we should be using here? Although I suspect it might not matter since their examples were working for them, I just want to make sure the client/server doesnt do different backend processing based on this mimetype.

That MIMEtype is somewhat historical but it means the ActionScript type as compared to the sh script type etc.

It does not imply Windows functionality.

Cool, we have both the Linux and Windows version working but are now getting action failed status for both even though the password is being changed correctly. How does the ActionScript determine/check the exit code.

We did the following:

<DefaultAction ID="Action1">
  <Description>
<PreLink></PreLink>
<Link>Change</Link>
<PostLink><![CDATA[&nbsp;specified local user account password.]]></PostLink>
  </Description>
  <ActionScript MIMEType="application/x-Fixlet-Windows-Shell">
<![CDATA[wait sh -c "chpasswd <<< "{parameter "username" of action}:{parameter "password" of action}""]]>
  </ActionScript>
  <SuccessCriteria Option="CustomRelevance">exit code of action = 0</SuccessCriteria>
</DefaultAction>

The exit code isn’t available in the success criteria phase as “action” means the currently running action and that has ended by then.

You would need to fail the action in the ActionScript

I do it like the following in the upgrade fixlets so the download phase doesn’t get confused. The following example assumes that “0” means success

continue if {exists true whose (if true then (exit code of action = 0) else false)}

The native mailboxing approach to securing passwords does work, however it has several limitations. It is limited to specific, known, and existing machines. It isn’t applicable to groups, especially dynamic groups.

If targeting large numbers of machines, encrypting to unique keys for each client becomes an expensive and redundant operation from a server perspective.

Ideally an action, such as password change, would be a policy action targeted to a dynamic group which would remediate both current and future endpoints until the action is stopped. This way none are missed.

An alternative way of securing content, be it passwords or even files, is to take the original premise of the Local User Management site in Bigfix Labs that used OpenSSL and extend it a bit. The original process downloaded OpenSSL bits into a locked down subdirectory of the client, then generated a key pair. The public portion was pulled into an analysis on the server. This facilitated a way to encrypt data to a specific client. This was the basis for what has now become mailboxing.

Creating additional key pairs in OpenSSL and distributing them to groups of clients resolves several of the mailboxing short-comings. Similar to the Local User Management, the encrypted value is decrypted by OpenSSL commands in the action, then piped into a script or application.

Now static or dynamic groups can be targeted. That includes future machines which will eventually join a particular dynamic group. Now a local password action can target a dynamic group as a policy action so that new computers automatically get the update.

Different key pairs can be generated for different groups, sites, and/or operators. This is easy to automate and is cross-platform. The full feature set and options of OpenSSL is at one’s disposal.

Whole files can also be encrypted for distribution in addition to passwords.

IBM Feature Request: Offer an option to create a mailbox and unique key pair for any given group. Then allow that group to be targeted with the mailboxing approach.

A further enhancement would be to allow encryption of complete individual or multiple files to one or more group mailboxes. This could be a few extra options within the existing deployment wizard.

4 Likes

@AlanM, ty, ill give it a go.

@JonL even though it isnt applicable to groups since Im using the API Im working around it by dynamically generating the computer name list from a specific group and populating the Action XML via templating so its not much of a big deal. Im not much worried about how long it takes as long as it gets executed against the known list of servers at time of execution. As for those that are missed that can easily be monitored later through checking the last updated timestamp for account passwords. Due to the large volume of servers just getting it done in an automated fashion is more critical than how long it takes, but I get what you are saying.

2 Likes

Ive been able to get the above action working by importing through the console, but it does not work when I try to execute it through the api via POST /api/actions, I get an HTTP 500 error back from the server.

It also works if I then try to POST an export of the action from the console, but only if I dont use SecureParameter (the export is also not the same format as the original, it looks like the console modifies it). If I use SecureParameter with the exported version I get an HTTP 400 errror.

Anyone experience this while using the API?

This is an interesting point. I have never used a secure parameter through the API, so I have no idea if it is possible or how it would work.

The XML code and Java code I’ve posted have been used to insert an action. Make sure you are using Computer IDs and the order of the XML is important.

Can you post the failing XML here ?