Hi,
I have an issue with Cybetark AIM credentials in AWX, We are able to use
CuberArk AIM credentials to pull passwords and it works fine, however when
we try to add an SSL Key and Cert to the call the process hangs and times
out.
ENVIRONMENT
- AWX version: 9.2
- AWX install method: docker on linux
- Ansible version: 2.9.3
- Operating System: Red-Hat 7.7
- Web Browser: Chrome
STEPS TO REPRODUCE
We have setup safe and App Id in CyberArk to test pulling passwords from a
CyberArk safe., The process is working fine with the Test
URL(https://[awxhost]/api/v2/credentials/XX/test/) weare able to pull a
test password. However, when l we configure to use a client key and
certificate to validate the client connection the process "hangs" and nginx
reports a timeout. Does anyone know where/which docker container we can
look at to find any debuging info for why the call with certs is timing out?
I'm not sure where I can pull any logs related to the API URL Test
URL(https://[awxhost]/api/v2/credentials/XX/test/). I've tried docker logs
on each container and I cant see anything related to the call.
I've located the module that handles AIM Creds in AWX :
/var/lib/awx/venv/awx/lib/python3.6/site-packages/awx/main/credential_plugins/aim.py
from .plugin import CredentialPlugin
from urllib.parse import quote, urlencode, urljoin
from django.utils.translation import ugettext_lazy as _
import requests
# AWX
from awx.main.utils import (
create_temporary_fifo,
)
aim_inputs = {
'fields': [{
'id': 'url',
'label': _('CyberArk AIM URL'),
'type': 'string',
'format': 'url',
}, {
'id': 'app_id',
'label': _('Application ID'),
'type': 'string',
'secret': True,
}, {
'id': 'client_key',
'label': _('Client Key'),
'type': 'string',
'secret': True,
'multiline': True,
}, {
'id': 'client_cert',
'label': _('Client Certificate'),
'type': 'string',
'secret': True,
'multiline': True,
}, {
'id': 'verify',
'label': _('Verify SSL Certificates'),
'type': 'boolean',
'default': True,
}],
'metadata': [{
'id': 'object_query',
'label': _('Object Query'),
'type': 'string',
'help_text': _('Lookup query for the object. Ex:
"Safe=TestSafe;Object=testAccountName123"'),
}, {
'id': 'object_query_format',
'label': _('Object Query Format'),
'type': 'string',
'default': 'Exact',
'choices': ['Exact', 'Regexp']
}, {
'id': 'reason',
'label': _('Reason'),
'type': 'string',
'help_text': _('Object request reason. This is only needed if it is
required by the object\'s policy.')
}],
'required': ['url', 'app_id', 'object_query'],
}
def aim_backend(**kwargs):
url = kwargs['url']
client_cert = kwargs.get('client_cert', None)
client_key = kwargs.get('client_key', None)
verify = kwargs['verify']
app_id = kwargs['app_id']
object_query = kwargs['object_query']
object_query_format = kwargs['object_query_format']
reason = kwargs.get('reason', None)
query_params = {
'AppId': app_id,
'Query': object_query,
'QueryFormat': object_query_format,
}
if reason:
query_params['reason'] = reason
request_qs = '?' + urlencode(query_params, quote_via=quote)
request_url = urljoin(url, '/'.join(['AIMWebService', 'api',
'Accounts']))
cert = None
if client_cert and client_key:
cert = (
create_temporary_fifo(client_cert.encode()),
create_temporary_fifo(client_key.encode())
)
elif client_cert:
cert = create_temporary_fifo(client_cert.encode())
res = requests.get(
request_url + request_qs,
timeout=30,
cert=cert,
verify=verify,
)
res.raise_for_status()
return res.json()['Content']
aim_plugin = CredentialPlugin(
'CyberArk AIM Central Credential Provider Lookup',
inputs=aim_inputs,
backend=aim_backend
)
I have tested the CyberArk call with Certs outside of AWX with a basic
Python Program and it works fine so I'm fairly certain that CyberArk is
properly configured to respond. Include the Python Code I'm using that
works :
#import http.client
import http.client
import json
import ssl
Defining certificate related stuff and host of endpoint
certificate_file = '/loc/cert.pem'
certificate_secret= ''
host = 'cyberarkhost'
Defining parts of the HTTP request
request_url='/AIMWebService/api/Accounts?AppID=APP_GSF_D_Ansible_Test&Safe=GSF_D_Ansible_Test&UserName=Ansible-User'
request_headers = {
'Content-Type': 'application/json'
}
request_body_dict={
"AppID": "APP_GSF_D_Ansible_Test",
"object_query": "Safe=GSF_D_Ansible_Test;UserName=Ansible-User",
"object_query_format": "Exact",
"reason":"sss"
}
Define the client certificate settings for https connection
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(certfile=certificate_file,
password=certificate_secret)
connection = http.client.HTTPSConnection(host, port=443, context=context)
Use connection to submit a HTTP POST request
connection.request(method="GET", url=request_url, headers=request_headers,
body=json.dumps(request_body_dict))
Print the HTTP response
response = connection.getresponse()
print(response.status, response.reason)
data = response.read()
print(data)
Thanks Matt