on 04-06-2023 01:03 AM - edited on 06-03-2023 10:27 PM by hslai
Contents
The official Cisco Platform Exchange Grid (pxGrid) account in GitHub, cisco-pxgrid, contains multiple repositories of example code to connect, discover, subcribe, and publish with pxGrid. There are two repositories that we will use in this tutorial with the Python programming language:
Repository | Description |
pxgrid-rest-ws | The official pxGrid client source code, available in Golang, Java , and Python |
python-advanced-examples | Contains the source code for a number of advanced pxGrid examples written in python that extend the examples found in pxgrid-rest-ws |
All of the examples in the tutorial assume that you have an ISE 3.x node and a Linux/Unix environment for running curl, git and other commands. Windows users should consider installing Windows Subsystem for Linux (WSL), a Linux VM, or Linux container (Podman / Docker).
These instructions provide the bare minimum requirements to enable ISE for doing pxGrid with a single internal test account. You may skip steps if you have already configured these options in your lab or production ISE deployment.
If you do not want to create individual network device entries for testing the fastest option is to use the Default Network Device Option.
ISEisC00L
(or your preferred shared secret)
You will want a simple test user account for generating RADIUS sessions with pxGrid if you do not already have one or more that you can use.
employee
ISEisC00L
(or your preferred test password)Employee
ISE requires one or more active Advanced licenses for pxGrid entitlement.
Virtual environments with Python allow you to create multiple development environments for your projects that will not conflict with each other. This allows you to clearly understand your dependencies and keep from bloating your workstation with random packages.
Create a project directory for playing with pxGrid and change directory (cd
) into it :
mkdir ISE_pxGrid_Tutorial
cd ISE_pxGrid_Tutorial
Create a Python environment with `pipenv` and install the necessary Python packages :
python -m ensurepip --upgrade
curl -sS https://bootstrap.pypa.io/get-pip.py | python3.10 # Install the latest
python3.10 -m pip --version # test the result
python3.10 -m pip install --upgrade pip # test upgrade
pip3 install pipenv # Install virtual environment utility pipenv install --python 3.11 # 3.8 or later should work pipenv install pxgrid-util # Install cisco-pxgrid/python-advanced-examples pipenv install requests # HTTP
pipenv install websockets # websockets pipenv shell # launch virtual environment
If you have any problems installing Python, see the Python Beginner's Guide.
You may verify your installed packages in your virtual environment :
pip list
Our ISE API examples will utilize the command line utility cURL. This is because cURL is the most universal and flexible choice for quickly doing HTTP/S-based REST calls.
To quickly test if curl
and your ISE APIs are working with your ISE node, try the following :
curl --insecure \
--header 'Accept: application/json' \
--user admin:ISEisC00L \
--request GET https://ise.securitydemo.net/api/v1/deployment/node
Be sure to use your ISE admin username and password or you will get a 401 error. ISE versions < 3.1 should use the REST endpoint /ers/config/node
instead of/api/v1/deployment/node
.
Your response should look something like this and you definitely want to see pxGrid as one of the services:
{
"response" : [ {
"hostname" : "ise",
"fqdn" : "ise.securitydemo.net",
"ipAddress" : "198.18.133.27",
"roles" : [ "Standalone" ],
"services" : [ "Session", "Profiler", "pxGrid" ],
"nodeStatus" : "Connected"
} ],
"version" : "1.0.0"
}
Frequently used command line options with curl:
cURL Option | Description |
-k, --insecure | Accept insecure connections. Useful if you are playing with a demo installation of ISE using a self-signed certificate. |
-H, --header {header} |
Header to include in the request. Use one per header. |
-i, --include | Include the HTTP result headers in the output. |
-s, --silent | Disable the progress bar output for clean output when piping the output to other utilities like xq |
-u, --user {username:password} | Specify the username & password to authenticate the API user |
-d, --data '{content}' | The data payload to send, as a string or file, typically with JSON or XML content. |
-X, --request <method> | Specify a custom HTTP request method. |
-L, --location | Follow the redirected URL in the location header. |
In the above example, we showed you the ISE admin username and password ISEisC00L in the clear on the command line. It is a bad security practice to do API work with your passwords to security applications like ISE exposed for anyone to see over your shoulder or in your command line history. For this reason, we will utilize environment variables in our command line work as a best practice with our ISE REST API usernames and passwords for all further examples. We will also use variables for our hostname (ISE_HOSTNAME) to generalize the scripts so you may copy and paste them to your command line.
The fastest to use environment variables in your command line scripts is to create temporary environment variables using the export command (or set command on Windows) in your terminal:
export ISE_HOSTNAME=ise.securitydemo.net # for small ISE deployments
export ISE_PAN=ise-ppan.example.com # large ISE deployments use the PAN node for ERS APIs
export ISE_MNT=ise-pmnt.example.com # large ISE deployments use the MNT node for MNT APIs
export ISE_PXG=ise-pxg1.example.com # large ISE deployments use the PXG node for pxGrid
export ISE_ERS_USERNAME=admin
export ISE_ERS_PASSWORD=ISEisC00L
export ISE_CERT_VERIFY=false
export PXGRID_CLIENT_USERNAME=pxgrid_demo_user
export PXGRID_CLIENT_PASSWORD=
You may also add the lines above to an ise.sh file in a .secrets folder in your home directory then, when you want to use them in your terminal session, run:
source ~/.secrets/ise.sh
You may view and verify your current environment variables using the following commands and access them in scripts or on the command line by prefixing them with a `$`:
env printenv ISE_ERS_USERNAME echo $ISE_ERS_USERNAME
The same example cURL command above using environment variables would look like this:
curl --insecure \
--header 'Accept: application/json' \
--user $ISE_ERS_USERNAME:$ISE_ERS_PASSWORD \
--request GET https://$ISE_HOSTNAME/api/v1/deployment/node
If you want to verify your environment variable values, use the echo command to help you troubleshoot!
> echo https://$ISE_HOSTNAME/api/v1/deployment/node
https://ise.securitydemo.net/api/v1/deployment/node
Many of the examples below will also utilize the command line utility jq to pretty-print the JSON output of the REST APIs. It may even be used to filter the output.
Pipe the output of curl into jq (" | jq"):
curl --insecure --silent \
--header 'Accept: application/json' \
--user $ISE_ERS_USERNAME:$ISE_ERS_PASSWORD \
--request GET https://$ISE_HOSTNAME/api/v1/deployment/node \
| jq -C .
To make an ISE ERS call, the ISE ERS API must be enabled under Administration > System > Settings > API Settings > API Service Settings. An example REST call with curl
is below to enable the basic user auth for pxGrid clients. You could also use Postman, Python, Ansible or some other mechanism to make the REST call.
curl \ --insecure --include \ --header 'Content-Type:application/json' \ --header 'Accept: application/json' \ --user $ISE_ERS_USERNAME:$ISE_ERS_PASSWORD \ --request PUT https://$ISE_HOSTNAME/ers/config/pxgridsettings/autoapprove \ --data ' { "PxgridSettings" : { "autoApproveCertBasedAccounts" : true, "allowPasswordBasedAccounts" : true } } '
Now that password-based authentication is enabled for pxGrid, you may create an account and password. Export an environment variable with your ISE pxGrid node’s name or IP address :
Submit a request for a nodeName (username) and retrieve a randomly generated password for your pxGrid client :
⚠ Do NOT include anyusername:password
credentials for theAccountCreate
request!
⚠ Allows <= 100 case-insensitive characters in thenodeName
:[a-z0-9_.-]
curl \ --include --insecure \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --request POST https://$ISE_PXG:8910/pxgrid/control/AccountCreate \ --data '{ "nodeName":"'$PXGRID_CLIENT_USERNAME'" }'
The REST response will show your pxGrid client username with a unique, random password:
HTTP/1.1 200
{"nodeName":"pxgrid_demo_user","password":"15ozVGARjkZJMCLN","userName":"pxgrid_demo_user"}
Update your PXGRID_CLIENT_PASSWORD environment variable with random password assigned to your account :
export PXGRID_CLIENT_PASSWORD='HjERBEHfkqqXWCpp'
In the ISE GUI, navigate to Administration > pxGrid Services > Client Management > Clients to see your pxGrid client registered the Initialized state. You must still activate and approve it.
Name | Description | Client Groups | Status |
pxgrid_demo_user | Initialized |
You have requested a pxGrid client account and now you must activate it :
curl \ --include --insecure \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \
--user $PXGRID_CLIENT_USERNAME:$PXGRID_CLIENT_PASSWORD \ --request POST https://$ISE_PXG:8910/pxgrid/control/AccountActivate \ --data '{ "description": "My pxGrid Client" }'
The response will show the accountState
as PENDING
:
{"accountState":"PENDING","version":"2.0"}
Refresh the pxGrid Clients table in the ISE GUI to see the updated Status and the Description you specified in the AccountActivate
body :
Name | Description | Client Groups | Status |
pxgrid_demo_user | My pxGrid Client | Pending |
Select the row for your pxgrid_demo_user
then select the
button above the table and you will see the Status change to Enabled
.
Name | Description | Client Groups | Status |
pxgrid_demo_user | My pxGrid Client | Enabled |
After being Approved in the ISE GUI, the same AccountActivate REST API request shows you are Enabled :
HTTP/1.1 200
{"accountState":"ENABLED","version":"2.0"}
If your request was declined in the ISE GUI, the AccountActivate REST API returns a 401 Unauthorized response :
HTTP/1.1 401
You may be authorized by the ISE Administrator to retrieve certain services but not others. Use the /pxgrid/control/Authorization REST endpoint to verify your capabilities.
Request:
curl \ --include --insecure \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --user $PXGRID_CLIENT_USERNAME:$PXGRID_CLIENT_PASSWORD \ --request POST https://$ISE_PXG:8910/pxgrid/control/Authorization \ --data ' { "requestNodeName":"'$PXGRID_CLIENT_USERNAME'", "serviceName":"com.cisco.ise.sessiondirectory", "serviceOperation":"gets" }'
Response:
HTTP/1.1 200
{"authorization":"PERMIT"}
There are many different services within ISE :
Request:
curl --silent --insecure \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ --user $PXGRID_CLIENT_USERNAME:$PXGRID_CLIENT_PASSWORD \ --request POST https://$ISE_PXG:8910/pxgrid/control/ServiceLookup \
--data '{ "name":"com.cisco.ise.session" }' \
| jq -C .
Response:
{
"services": [
{
"name": "com.cisco.ise.session",
"nodeName": "~ise-mnt-ise",
"properties": {
"sessionTopic": "/topic/com.cisco.ise.session",
"groupTopic": "/topic/com.cisco.ise.session.group",
"wsPubsubService": "com.cisco.ise.pubsub",
"restBaseURL": "https://ise.securitydemo.net:8910/pxgrid/mnt/sd",
"restBaseUrl": "https://ise.securitydemo.net:8910/pxgrid/mnt/sd"
}
}
]
}
Ue the nodeName from the ServiceLookup to get the AccessSecret for that service on that node.
curl --silent --insecure \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--user $PXGRID_CLIENT_USERNAME:$PXGRID_CLIENT_PASSWORD \
--request POST https://$ISE_PXG:8910/pxgrid/control/AccessSecret \
--data '{ "peerNodeName":"~ise-admin-ise" }' \
Response:
{
"secret": "8AF7vMB6hga2pdrq"
}
You may now perform REST API queries with that service.
This is an installable Python package (pip install pxgrid-util) that is hosted in the python-advanced-examples GitHub repository. The package has many tools for testing pxGrid but all of them may have examples here.
anc-policy
: Download ANC policies, endpoints with ANC policies applied, and apply ANC policycreate-new-pxgrid-account
: Create a simple password authentication pxGrid client if you have an ISE admin username and passwordmatrix-query-all
: Download all cells of the TrustSec policy matrixprofiles-query-all
: Download all ISE Profiler profilespx-subscribe
: General purpose utility to display details on multiple services and to allow subscriptions to topics of named servicessession-query-all
: Download all current sessionssession-query-by-ip
: Perform a query on the session topic using a given IP addresssgacls-query-all
: Download all current SG-ACL definitionssgts-query-all
: Download all SGT definitionssxp-query-bindings
: Download all SXP bindingssystem-query-all
: Download performance or health metrics from an ISE installationuser-groups-query
: Query for the groups associated with users authenticated to ISE
Downloads all current sessions
Request:
session-query-all \ --hostname $ISE_PXG \ --nodename $PXGRID_CLIENT_USERNAME \ --password $PXGRID_CLIENT_PASSWORD \ --insecure \ | jq -C .
Response:
{"sessions":[]}
Filtering responses with jq
Request:
session-query-all \
--hostname $ISE_PXG \
--nodename $PXGRID_CLIENT_USERNAME \
--password $PXGRID_CLIENT_PASSWORD \
--insecure \
| jq -C '[ .sessions[] | select(.state == "STARTED") | .macAddress ]'
Response:
[
"00:50:56:94:39:9F",
"00:50:56:94:6F:90",
"00:50:56:94:91:67",
"00:50:56:94:AA:9B",
"00:50:56:94:D8:7E",
"00:50:56:94:DF:7D",
"00:50:56:94:E4:31",
"00:50:56:94:E7:97"
]
Performs a query on the session topic using a given IP address.
session-query-by-ip
\
--hostname $ISE_PXG \
--nodename $PXGRID_CLIENT_USERNAME \
--password $PXGRID_CLIENT_PASSWORD \
--insecure
Run px-subscribe to connect to ISE with a websocket and observe any new RADIUS session updates :
px-subscribe \ --hostname $ISE_PXG \ --nodename $PXGRID_CLIENT_USERNAME \ --password $PXGRID_CLIENT_PASSWORD \ --insecure \ --service com.cisco.ise.session \ --topic sessionTopic \ | jq -C .
You may observe the px-subscribe websocket connection in the ISE GUI under Administration > pxGrid Services > Diagnostics > WebSocket Connection.
To see a new session, authenticate a user or endpoint to create a new RADIUS session which you should see in the px-subscribe output within ~5 seconds :
{
"sequence": 1,
"sessions": [
{
"adNormalizedUser": "thomas",
"authMethod": "dot1x",
"authProtocol": "PEAP (EAP-MSCHAPv2)",
"calledStationId": "2C-3F-0B-56-E3-6C:ISECorp",
"callingStationId": "56:5B:EE:FE:7C:34",
"ctsSecurityGroup": "Employees",
"endpointCheckResult": "none",
"endpointProfile": "Unknown",
"identitySourcePortEnd": 0,
"identitySourcePortFirst": 0,
"identitySourcePortStart": 0,
"ipAddresses": [
"10.80.60.151"
],
"macAddress": "56:5B:EE:FE:7C:34",
"mdmCompliant": false,
"mdmDiskEncrypted": false,
"mdmJailBroken": false,
"mdmPinLocked": false,
"mdmRegistered": false,
"nasIdentifier": "2C-3F-0B-56-E3-6C:vap1",
"nasIpAddress": "10.80.60.150",
"nasPortType": "Wireless - IEEE 802.11",
"networkDeviceProfileName": "Cisco",
"providers": [
"None"
],
"radiusFlowType": "Wireless802_1x",
"selectedAuthzProfiles": [
"PermitAccess"
],
"serviceType": "Framed",
"ssid": "2C-3F-0B-56-E3-6C:ISECorp",
"state": "STARTED",
"timestamp": "2022-03-22T03:44:12.445Z",
"userName": "thomas"
}
]
}
Disconnect the endpoint session and wait 5 seconds to see updated session information.
Download all cells of the TrustSec policy matrix.
matrix-query-all \ --hostname $ISE_PXG \ --nodename $PXGRID_CLIENT_USERNAME \ --password $PXGRID_CLIENT_PASSWORD \ --insecure
Response:
{
"deletedEgressPolicies": [],
"egressPolicies": [
{
"description": "Default egress rule",
"destinationSecurityGroupId": "92bb1950-8c01-11e6-996c-525400b48521",
"id": "92c1a900-8c01-11e6-996c-525400b48521",
"matrixId": "9fa3a33a-329e-43cb-a4cf-7bd38df16e7b",
"name": "ANY-ANY",
"sgaclIds": [
"92951ac0-8c01-11e6-996c-525400b48521"
],
"sourceSecurityGroupId": "92bb1950-8c01-11e6-996c-525400b48521",
"status": "ENABLED",
"timestamp": "2016-10-06T20:15:06.714861Z"
}
],
"totalCount": "1",
"version": "1.0.0"
}
Download all SGT definitions.
sgts-query-all \ --hostname $ISE_PXG \ --nodename $PXGRID_CLIENT_USERNAME \ --password $PXGRID_CLIENT_PASSWORD \ --insecure \ | jq -C .
Show the tag number and name :
sgts-query-all \ --hostname $ISE_PXG \ --nodename $PXGRID_CLIENT_USERNAME \ --password $PXGRID_CLIENT_PASSWORD \ --insecure \ | jq -C '[ .securityGroups[] | .tag, .name ]'
sgacls-query-all \ --hostname $ISE_PXG \ --nodename $PXGRID_CLIENT_USERNAME \ --password $PXGRID_CLIENT_PASSWORD \ --insecure \ | jq -C .
Download all SXP bindings.
sxp-query-bindings \ --hostname $ISE_PXG \ --nodename $PXGRID_CLIENT_USERNAME \ --password $PXGRID_CLIENT_PASSWORD \ --insecure \ | jq -C .
Response:
{
"bindings": []
}
user-groups-query \ --hostname $ISE_PXG \ --nodename $PXGRID_CLIENT_USERNAME \ --password $PXGRID_CLIENT_PASSWORD \ --insecure \ | jq -C .
Response:
{
"userGroups": [
{
"adUserQualifiedName": "thomas",
"adUserSamAccountName": "thomas",
"groups": [
{
"name": "null",
"type": "IDENTITY"
},
{
"name": "S-1-5-21-3064548688-3193819538-1298560677-513",
"type": "EXTERNAL"
},
{
"name": "dcloud.cisco.com/Users/Domain Users",
"type": "INTERESTING_ACTIVE_DIRECTORY"
}
],
"userName": "thomas"
}
]
}
Download ANC policies, endpoints with ANC policies applied, and apply ANC policies.
Get all defined ANC policies:
anc-policy \ --hostname $ISE_PXG \ --nodename $PXGRID_CLIENT_USERNAME \ --password $PXGRID_CLIENT_PASSWORD \ --insecure \ --get-anc-policies
Response:
{
"policies": [
{
"actions": [
"PORT_BOUNCE"
],
"name": "ANC-Destroy"
},
{
"actions": [
"SHUT_DOWN"
],
"name": "ANC-NukeFromOrbit"
},
{
"actions": [
"QUARANTINE"
],
"name": "pxGridQRadarQuarantine"
},
{
"actions": [
"SHUT_DOWN"
],
"name": "pxGridQRadarShutDown"
},
{
"actions": [
"PORT_BOUNCE"
],
"name": "pxGridQRadarPortBounce"
},
{
"actions": [
"QUARANTINE"
],
"name": "ANC-Investigate"
}
]
}
/path/to/12345678_cert/
Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: