Using python-oracledb / cx_oracle to connect to AWS RDS Oracle with TLS / mutual TLS · oracle/python-oracledb · Discussion #34 (original) (raw)
I'm trying to use the Python oracledb library to connect from AWS Lambda to RDS Oracle using TLS. I may want to do mutual TLS, but even one-way TLS would be fine. I could use some help. I'm technical and have plenty of experience, but both Python and Oracle are outside my core skillset - I'm good with Java and I'm full time AWS architect.
What I can do:
- I can connect to RDS Oracle using TLS with SQL Developer on my local PC. I had to add the AWS RDS 2019 root cert to the Java Keystore. I didn't have to use an Oracle wallet. The direct link to the AWS self signed root cert is here.
- I can connect unencrypted from Lambda Python 3.9 to Oracle RDS using python-oracledb in thin mode
- I can connect unencrypted from Python on my PC to Oracle RDS using python-oracledb in thin mode
Noting that this is not a firewall issue, I have opened up the correct ports in AWS.
Code
Here's the basics of the code for one way TLS, which is very similar to the Oracle example.
import oracledb
import sys
import boto3
# When creating the Lambda function, ensure the following setting for LD_LIBRARY_PATH
def lambda_handler(event, context):
ssm_parameter = boto3.client('ssm')
# Unencrypted connection works fine
# oracleDSN = "dbname.accountstring.ap-southeast-2.rds.amazonaws.com:2484/servicename"
oracleDSN = '''(description= (retry_count=3)(retry_delay=1)(address=(protocol=tcps)
(port=2484)(host=dbname.accountstring.ap-southeast-2.rds.amazonaws.com))(connect_data=(service_name=servicename))
(security=(ssl_server_cert_dn="C=US,ST=Washington,L=Seattle,O=Amazon.com,OU=RDS,CN=dbname.accountstring.ap-southeast-2.rds.amazonaws.com")))'''
connRds = oracledb.connect(user=database_user, password=database_password, dsn=oracleDSN)
Errors
Here's the error message output from lambda (# replaces sensitive information)
Response
{
"errorMessage": "DPY-6005: cannot connect to database. Connection failed with \"[SSL] internal error (_ssl.c:2633)\"",
"errorType": "OperationalError",
"requestId": "",
"stackTrace": [
" File \"/var/lang/lib/python3.9/importlib/__init__.py\", line 127, in import_module\n return _bootstrap._gcd_import(name[level:], package, level)\n",
" File \"<frozen importlib._bootstrap>\", line 1030, in _gcd_import\n",
" File \"<frozen importlib._bootstrap>\", line 1007, in _find_and_load\n",
" File \"<frozen importlib._bootstrap>\", line 986, in _find_and_load_unlocked\n",
" File \"<frozen importlib._bootstrap>\", line 680, in _load_unlocked\n",
" File \"<frozen importlib._bootstrap_external>\", line 850, in exec_module\n",
" File \"<frozen importlib._bootstrap>\", line 228, in _call_with_frames_removed\n",
" File \"/var/task/TableDailyCount.py\", line 50, in <module>\n connRds = oracledb.connect(user=database_user, password=database_password, dsn=oracleDSN)\n",
" File \"/opt/python/oracledb/connection.py\", line 1000, in connect\n return conn_class(dsn=dsn, pool=pool, params=params, **kwargs)\n",
" File \"/opt/python/oracledb/connection.py\", line 128, in __init__\n impl.connect(params_impl)\n",
" File \"src/oracledb/impl/thin/connection.pyx\", line 345, in oracledb.thin_impl.ThinConnImpl.connect\n",
" File \"src/oracledb/impl/thin/connection.pyx\", line 163, in oracledb.thin_impl.ThinConnImpl._connect_with_params\n",
" File \"src/oracledb/impl/thin/connection.pyx\", line 129, in oracledb.thin_impl.ThinConnImpl._connect_with_description\n",
" File \"src/oracledb/impl/thin/connection.pyx\", line 247, in oracledb.thin_impl.ThinConnImpl._connect_with_address\n",
" File \"/opt/python/oracledb/errors.py\", line 103, in _raise_err\n raise exc_type(_Error(message)) from cause\n"
]
}
What I've tried
- Reading all the docs. The answers are probably there, but because I'm fairly new to Python and Oracle I may not understand it fully.
- I've tried using orapki to create a wallet to use with the oracledb thin driver with the RDS root cert, including creating the oracle keystore as p12 and converting to ewallet.pem - that didn't work. I tried the create_pem.py script from this page and OpenSSL.
- Copying the RDS pem root certificate into the deployment package and referencing that as the keystore - that didn't work
- I've added the RDS CA Certs to three different cacerts files within the python39 folder ( C:\Users\Tim\AppData\Roaming\Python\Python39) as described on this page (you need to register for a free account to see the page)
- I've read everything I can find on the internet about this that seems relevant
- Noting the AWS certs page, ap-southeast-2-bundle.pem.
Question
- How would I get single direction TLS working?
- How do you create the ewallet.pem in the format that's required for mTls, from the AWS RDS Sydney root certificates?