Symantec Privileged Access Management

 View Only
  • 1.  How To bulk load, sync and update an admin account for linux

    Posted Feb 20, 2020 03:40 PM
    Edited by rafael diaz Feb 20, 2020 08:34 PM
    ​Hello,

    Looking for help on how to bulk load, sync and update an admin account for linux.

    • Over all goal is to managed a local linux account that has the permissions to manged root account.

    • This account is using key pair vs password.

    • we have a high number of servers we need to do this with and see what way do we go about this via bulk. (maybe CLI?)

    Any advise will be greatly appreciated.

    ------------------------------
    Rafael Diaz
    ------------------------------


  • 2.  RE: How To bulk load, sync and update an admin account for linux
    Best Answer

    Posted Feb 21, 2020 07:56 AM
    I used PAM API to onboard hundreds of linux devices, it was very helpful. Check within the training section for this course that instructs you on how to enable the Extenal API in PAM: "CA Privileged Access Manager r3.x: Use the External API 300​"

    If you are not familiar with web services and API calls you will need to learn how this works first.


  • 3.  RE: How To bulk load, sync and update an admin account for linux

    Posted Mar 17, 2020 11:39 PM
    Edited by Chris Scott Mar 18, 2020 12:32 AM
    Pedro,

    Curious, are you using curl from a remote machine?




  • 4.  RE: How To bulk load, sync and update an admin account for linux

    Broadcom Employee
    Posted Mar 18, 2020 02:12 AM
    Edited by Joseph Fry Mar 18, 2020 02:13 AM
    Below is a demo script, written in PowerShell, that creates a device, target application, and target account for linux/ssh.  I haven't used the API to create an account that uses keys, but the process should be similar.

    As Pedro says, you really need to be familiar with writing scripts/software and how to use API's if you want to perform bulk operations like you wish to do.  The built in API documentation is invaluable: https://techdocs.broadcom.com/content/broadcom/techdocs/us/en/ca-enterprise-software/layer7-privileged-access-management/privileged-access-manager/3-3-2/programming/external-api-for-integrating-applications/use-the-external-api-programmers.html

    # This is a simple demo of the PAM API
    #
    # The script will prompt you for your api key, and will add a device named "scriptDevice", create a linux/unix target application
    # named "scriptApp" for that device, and finally create a target account named "scriptAcct" for that target application.
    #
    # This is by no means a complete solution, however it will demonstrate the basics of creating a device, linux/unix target
    # application, and target account.  From here, you could expand to loop over the lines in a xls/csv file adding many devices.
    # Wherever possible, I left and commented out options that you could choose to use, but are not required.
    #
    # All of the properties set during the creation of the devices are easily obtained by creating a template device/app/acct and
    # querying it using the API to determine the appropriate settings to use.  Most settings can be left unset unless you
    # want to change the defaults.
    #
    # It is highly recommended that you become familar with the integrated PAM "API Doc" on your PAM settings menu (will need to
    # enable the api in the config first).  This "doc" is actually more of an interactive testing tool where you can run a single
    # api query and view the results... it's invaluable to any PAM API development project.
    #
    # NOTE: The script below is not suitable for Windows devices.  Unfortunately the devices.json/$deviceId/targetApplications API
    # only works with generic or Unix style target applications.  You would need to use the PAM Credential Management API (aka CLI)
    # to add a windows target application; a more complex procedure.
    
    
    $pamServer = "your.Pam.url.here"  # either FQDN or IP address
    $pamServer = "1.2.3.4"  # either FQDN or IP address
    
    #
    # This section is to prevent errors when connecting to a PAM system that uses a self signed certificate. If your system
    # uses a trusted certificate, then you may be able to delete this.
    # NOTE: the line with just "@ on it cannot be indented
    #
    if (-not ([System.Management.Automation.PSTypeName]"TrustEverything").Type) {
        Add-Type -TypeDefinition  @"
        using System.Net.Security;
        using System.Security.Cryptography.X509Certificates;
        public static class TrustEverything
        {
            private static bool ValidationCallback(object sender, X509Certificate certificate, X509Chain chain,
                SslPolicyErrors sslPolicyErrors) { return true; }
            public static void SetCallback() { System.Net.ServicePointManager.ServerCertificateValidationCallback = ValidationCallback; }
            public static void UnsetCallback() { System.Net.ServicePointManager.ServerCertificateValidationCallback = null; }
        }
    "@
    } [TrustEverything]::SetCallback()
    
    #
    # prompt for an API key
    #
    if (-not $apikey) {$apikey = Get-Credential -Message "Enter your API key"}
    
    #
    # run an API call to add a device
    #
    $newDevice = @{
            description = 'This device was added by a script'
            deviceName = 'ScriptDevice'
            domainName = '192.168.168.168'
            location = 'Imaginary'
            os = 'Linux'
            typePassword = 't'
            typeAccess = 't'
            deviceAccessMethods = @{
                arbitraryLabel = @{
                    type = 'SSH'
                    port = '22'
                    #taskProperty = 'x11Forwarding'
                    #customName = null
                }
            }
            #tags = FOR SOME REASON THIS DOESNT WORK
            #deviceGroupMembershipIds = null
            #deviceMonitors = null
            #deviceServiceIds = null
            #deviceTerminalData = null
            #deviceVPNServiceIds = null
            #isHostNamePreserved = null
            #overrideAddress = null
            #requestServerActive = null
            #requestServerDescription1 = null
            #requestServerDescription2 = null
            #targetServerDescription1 = null
            #targetServerDescription2 = null
            #transparentLoginType = null
            #transparentPrompts = null
            #typeA2A = null
    }
    $newDevice = ConvertTo-Json -InputObject $newDevice
    $deviceId = Invoke-RestMethod -Uri "https://$pamServer/api.php/v1/devices.json" -Method Post -Body $newDevice -Credential $apikey -ContentType 'application/json'
    write-host "device id $deviceId added"
    
    #
    # Run an API call to add a target application
    # Note: Unfortunately at this time this only works for generic and UnixII (linux) target applications
    # To add a windows or other type, you must use the credential management API (aka CLI).
    #
    
    $newApp = @{
            applicationName = 'scriptApp'
            applicationType = 'unixII'
            attributes = @{
                #changePasswordCommand = null
                #useVerifyScriptType = 'DEFAULT'
                #sshUseDefaultCompressionAlgorithms = 't'
                #useUpdateScriptType = 'DEFAULT'
                #sshUseDefaultCiphers = 't'
                #sshUseDefaultServerHostKeyAlgorithms = 't'
                #sshUseDefaultHashes = 't'
                #unixVariant = 'GENERIC'
                #sshStrictHostKeyCheckingEnabled = 'f'
                #extensionType = 'unixII'
                #sshUseDefaultKeyExchangeAlgorithms = 't'
                #patternMatchingCommand = null
                #changeFilePermissionsCommand = null
            }
            #description1 = null
            #description2 = null
            #passwordCompositionPolicyId = null  #should really set one of these, use the API to get the Id.
    }
    $newApp = ConvertTo-Json -InputObject $newApp
    $appId = Invoke-RestMethod -Uri "https://$pamServer/api.php/v1/devices.json/$deviceId/targetApplications" -Method Post -Body $newApp -Credential $apikey -ContentType 'application/json'
    write-host "Target Application id $appId added"
    
    
    #
    # Run an API call to add a target account
    #
    
    $newAcct = @{
            accountName = 'scriptAcct'
            password = '_generate_pass_'  #Add the acct with a random pw... or replace it with a known pw
            #passwordViewPolicyId = null  #should really set one of these, use the API to get the ID
            privileged = 't'
            synchronize = 'f'  #Set this to true to have it update the password on the remote system
            useAliasNameParameter = 'f'
            attributes = @{
                #verifyThroughOtherAccount = 'false'
                discoveryAllowed = 'f'
                protocol = 'SSH2_PASSWORD_AUTH'
                discoveryGlobal = 'f'
                extensionType = 'unixII'
                #descriptor1 = 
                #descriptor2 = 
                #privateKey = null
                #keyOptions = null
                #useOtherAccountToChangePassword = 't'  #This is where you would use a master account to change this password
                #otherAccount = '1122'  # you would need to query the API for the master account id to use here
                #passwordChangeMethod = 'USE_SUDO' # this is the equivilent to "use elevated priviliges"
              }
            #aliasNames = null
            #cacheBehavior = null
            #cacheDuration = null
            #description1 = null
            #description2 = null
    }
    $newAcct = ConvertTo-Json -InputObject $newAcct
    $acctId = Invoke-RestMethod -Uri "https://$pamServer/api.php/v1/devices.json/$deviceId/targetApplications/$appId/targetAccounts" -Method Post -Body $newAcct -Credential $apikey -ContentType 'application/json'
    write-host "Target Account id $acctId added"



  • 5.  RE: How To bulk load, sync and update an admin account for linux

    Posted Mar 18, 2020 08:11 AM
    Joseph

    This is valuable and excellent - thank you


  • 6.  RE: How To bulk load, sync and update an admin account for linux

    Posted Mar 19, 2020 09:11 AM
    Hi Joseph ,
    is there a demo script for REMOTE CLI also ? . I have to on-board 100's of linux root accounts to PAM , editing xml file for each of them is very time consuming . Just wondering , can we do it via a shell script also ?

    Regards
    Pankaj Kumar


  • 7.  RE: How To bulk load, sync and update an admin account for linux

    Broadcom Employee
    Posted Mar 19, 2020 09:57 AM
    Edited by Joseph Fry Mar 19, 2020 10:04 AM
    The script above is for Linux accounts, you don't really need to use the CLI for those since that functionality is built into the PAM API. 

    That said, the scripts below demonstrate how you can access the Credential Manager API (aka CLI) using a script.  The first is very basic, the second actually has some processing, but doesn't really do anything very useful.

    Both are written in powershell, but the process could be adapted to whatever language you choose.

    Refer to the documentation for the various CLI commands and their attributes: https://techdocs.broadcom.com/content/broadcom/techdocs/us/en/ca-enterprise-software/layer7-privileged-access-management/privileged-access-manager/3-3-2/programming/credential-manager-remote-cli-and-java-api/credential-manager-cli-commands.html

    Keep in mind that the CLI uses your PAM credentials, not an API key.  And the CLI always returns XML data that must be parsed, some languages make this easier than others, but it's never as easy as the PAM API is.

    # This is a simple demo of the PAM CLI
    
    $pamServer = "your.Pam.url.here"  # either FQDN or IP address
    
    # This section is to prevent errors when connecting to a PAM system that uses a self signed certificate.
    if (-not ([System.Management.Automation.PSTypeName]"TrustEverything").Type) {
        Add-Type -TypeDefinition  @"
        using System.Net.Security;
        using System.Security.Cryptography.X509Certificates;
        public static class TrustEverything
        {
            private static bool ValidationCallback(object sender, X509Certificate certificate, X509Chain chain,
                SslPolicyErrors sslPolicyErrors) { return true; }
            public static void SetCallback() { System.Net.ServicePointManager.ServerCertificateValidationCallback = ValidationCallback; }
            public static void UnsetCallback() { System.Net.ServicePointManager.ServerCertificateValidationCallback = null; }
        }
    "@
    } [TrustEverything]::SetCallback()
    
    
    # Create a request
    $request = @{
        "adminUserID" = '<PAM USER NAME NOT API KEY>'
        "adminPassword" = '<PASSWORD>'
        "authentication" = "CSPM"               
        "cmdName" = "verifyAccountPassword"    #see CLI documentation for a description of this command
        "TargetAccount.ID" = "<ID of account to verify>"   #this is an example of a parameter
    }
    
    #Run the api call
    $results = Invoke-RestMethod -Method Get -Uri "https://$pamServer/cspm/servlet/adminCLI" -Body $request -TimeoutSec 30
    
    #Parse the xml content from the results
    $xml = $results.'cw.appMessage'.content.'#cdata-section'
    
    #output the xml
    $xml


    # This script is not really useful, but it does give a good demonstration of using the PAM CLI commands in a script
    # This does not require the installation or use of the java command line tool as described in the documentation
    # as this script accesses the Credential Managment API (aka CLI) directly.  However this API is very different
    # than the PAM API in that it uses your PAM credential (not api key) and the responses are always in XML and somewhat
    # difficult to parse as you will see below.
    #
    # If you run this script unedited, it will change all of your target accounts that use the "Default" password view
    # policy, to use the "Default2" password view policy (must exist).  Not very useful, but its a good demo.
    
    $pamServer = "1.2.3.4"  # either FQDN or IP address
    $oldPVP = "Default" # name of the PVP to change from
    $newPVP = "Default2" # name of the PVP to change to
    
    # This section is to prevent errors when connecting to a PAM system that uses a self signed certificate.
    if (-not ([System.Management.Automation.PSTypeName]"TrustEverything").Type) {
        Add-Type -TypeDefinition  @"
        using System.Net.Security;
        using System.Security.Cryptography.X509Certificates;
        public static class TrustEverything
        {
            private static bool ValidationCallback(object sender, X509Certificate certificate, X509Chain chain,
                SslPolicyErrors sslPolicyErrors) { return true; }
            public static void SetCallback() { System.Net.ServicePointManager.ServerCertificateValidationCallback = ValidationCallback; }
            public static void UnsetCallback() { System.Net.ServicePointManager.ServerCertificateValidationCallback = null; }
        }
    "@
    } [TrustEverything]::SetCallback()
    
    # generate a credential object
    if (-not $CliCred) {
        $CliCred = Get-Credential -Message "Enter your PAM username and password (not an API key)"
    }
    
    # set the CLI url
    $Url = "https://$pamServer/cspm/servlet/adminCLI"
    
    Function getPvpId($pvpName) {
        
        # Create our request body as a hashtable
        $request = @{
            "adminUserID" = $CliCred.UserName
            "adminPassword" = $CliCred.GetNetworkCredential().Password
            "authentication" = "CSPM"               
            "cmdName" = "searchPasswordViewPolicy"
            "PasswordViewPolicy.name" = $pvpName
        }
    
        write-host "Retrieving the PVP id for $pvpName..."
    
        # Make the API call and store the XML results
        [xml]$results = Invoke-WebRequest -Uri $Url -Body $request -Method Get
    
        # The actual results are stored as XML data in a cdata section of the parent xml
        [xml]$results = $results.'cw.appMessage'.content.'#cdata-section'
    
        # The PVP's are nodes in the results
        $pvps = $results.SelectNodes('//PasswordViewPolicy')
    
        # Because the searchPasswordViewPolicy command returns all PVP's whose name contains the 
        # search string, we need to select the exact match from the results and return just it's ID
        return ($pvps | Where Name -eq $pvpName).ID 
    
    } # END getPvpId
    
    # Get the PVP IDs
    $oldPvpId = getPvpId($oldPVP)
    $newPvpId = getPvpId($newPVP)
    
    # Create a request body to grab a list of target accounts
    $request = @{
        "adminUserID" = $CliCred.UserName
        "adminPassword" = $CliCred.GetNetworkCredential().Password
        "authentication" = "CSPM"               
        "cmdName" = "searchTargetAccount"
    }
    
    write-host "Retrieving list of all target accounts..."
    
    # Make the API call and store the XML results
    [xml]$results = Invoke-WebRequest -Uri $Url -Body $request -Method Get
    
    # The actual results are stored as XML data in a cdata section of the parent xml
    [xml]$results = $results.'cw.appMessage'.content.'#cdata-section'
    
    # Create an array of target accounts that use the old PVP
    $toUpdate = $results.SelectNodes('//TargetAccount') | Where passwordViewPolicyID -eq $oldPvpId
    
    # Loop over the target accounts to update and change their PVP
    foreach($targetAccount in $toUpdate) {
        
        Write-Host "Updating target account $($targetAccount.ID) ($($targetAccount.userName))..." -NoNewline
        
        # Create a request body to update the target account
        $request = @{
            "adminUserID" = $CliCred.UserName
            "adminPassword" = $CliCred.GetNetworkCredential().Password
            "authentication" = "CSPM"               
            "cmdName" = "updateTargetAccount"
            "TargetAccount.ID" = $targetAccount.ID
            "TargetAccount.userName" = $targetAccount.userName
            "PasswordViewPolicy.ID" = $newPvpId
        }
    
        # Add any additional target account attributes to the request (for some reason they are required for updateTargetAccount even if they don't change)
        # On the left side of the pipe we grab any attribute from the target account that starts with 'Attribute.'
        # On the right side we loop over those attributes and add them to the request hashtable.
        ($targetAccount | select Attribute.*).psobject.properties | foreach {$request[$_.Name] = $_.Value}
    
        # Make the API call and store the XML results
        [xml]$results = Invoke-WebRequest -Uri $Url -Body $request -Method Get
    
        # Remove the password from the request data
        $request.adminPassword = "Removed for security"
    
        # Output completion message
        Write-Host $results.'cw.appMessage'.statusMessage
    
        # Write target account details to screen on error
        if ($results.'cw.appMessage'.statusMessage -ne "Success.") {
            Write-Host "FAILED Target account:"
            $targetAccount
            Write-Host "Request data:"
            $request
        }
    
    }



  • 8.  RE: How To bulk load, sync and update an admin account for linux

    Posted Mar 19, 2020 04:51 PM
    WOW - what can I say - very helpful for us struggling out here to to make good use of this tool.

    Thank you thank you thank you