How to configure client side SSL trusted CA certificate ?

5,616 views
Skip to first unread message

Gang Yang

unread,
Feb 7, 2017, 6:08:50 PM2/7/17
to Django users
Hi,

I'm pretty new to Django and encountered some client side SSL issue. I'm trying to use django-cas-ng (CAS client) to do CAS authentication and the CAS server is using a self-signed server certificate. After obtaining the service ticket (ST), django-cas-ng tried to verify the ST by calling requests.get(...) and failed with CERTIFICATE_VERIFY_FAILED error. Following some suggestions on the internet, I've tried to modify django-cas-ng's code to call requests.get(..) with verify parameter, such as requests.get(..., verify=False) and requests.get(..., verify="CAS server cert"). Both workarounds worked, but I can't change third-party package code. I also tried to add the CAS server cert to the underlying OS (Windows 2008 and CentOS 6.7), but it did not help.

My question is where does SSL client code get the trusted CA certificates from, from Django, Python or the underlying OS? What configuration do I need in order for the SSL client to conduct the SSL handshake successfully?

Appreciate any help!

Gang

Pankaj Singh

unread,
Feb 8, 2017, 5:08:21 AM2/8/17
to Django users
I forgot to put c_rehash command in the example in my last reply. Here it goes:

mkdir -p /tmp/custom-certs
cp ~/Download/foo.example.com.cert /tmp/custom-certs
cp ~/Download/bar.example.com.cert /tmp/custom-certs
c_rehash /tmp/custom-certs
export REQUESTS_CA_BUNDLE='/tmp/custom-certs'

On Wed, Feb 8, 2017 at 12:23 PM, Pankaj Singh <psj...@gmail.com> wrote:
Hi,

My question is where does SSL client code get the trusted CA certificates from, from Django, Python or the underlying OS?


By default, Requests bundles a set of root CAs that it trusts, sourced from the Mozilla trust store. However, these are only updated once for each Requests version. This means that if you pin a Requests version your certificates can become extremely out of date.
 
From Requests version 2.4.0 onwards, Requests will attempt to use certificates from certifi if it is present on the system. This allows for users to update their trusted certificates without having to change the code that runs on their system.
 
For the sake of security we recommend upgrading certifi frequently!

You can read more about certifi on it's official docs page.

What configuration do I need in order for the SSL client to conduct the SSL handshake successfully?

You can set REQUESTS_CA_BUNDLE environment variable pointing to .cert file and it will pick it from there.

If you have just one `.crt` file which is self signed then you can do following

export REQUESTS_CA_BUNDLE='~/Download/bar.example.com.cert'

But if you have multiple certificates which are self signed then you can put them in a folder and set the folder path in environment variable. In case of a folder, make sure to run c_rehash command for folder.

mkdir -p /tmp/custom-certs
cp ~/Download/foo.example.com.cert /tmp/custom-certs
cp ~/Download/bar.example.com.cert /tmp/custom-certs
export REQUESTS_CA_BUNDLE='/tmp/custom-certs'



--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/f07875b8-f3b8-4bcb-b95f-2d936f5ece34%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Regards,
Pankaj Kumar Singh

Skype: psjinx



--

Regards,
Pankaj Kumar Singh

Skype: psjinx

Pankaj Singh

unread,
Feb 8, 2017, 5:08:44 AM2/8/17
to Django users
Hi,

My question is where does SSL client code get the trusted CA certificates from, from Django, Python or the underlying OS?


By default, Requests bundles a set of root CAs that it trusts, sourced from the Mozilla trust store. However, these are only updated once for each Requests version. This means that if you pin a Requests version your certificates can become extremely out of date.
 
From Requests version 2.4.0 onwards, Requests will attempt to use certificates from certifi if it is present on the system. This allows for users to update their trusted certificates without having to change the code that runs on their system.
 
For the sake of security we recommend upgrading certifi frequently!

You can read more about certifi on it's official docs page.

What configuration do I need in order for the SSL client to conduct the SSL handshake successfully?

You can set REQUESTS_CA_BUNDLE environment variable pointing to .cert file and it will pick it from there.

If you have just one `.crt` file which is self signed then you can do following

export REQUESTS_CA_BUNDLE='~/Download/bar.example.com.cert'

But if you have multiple certificates which are self signed then you can put them in a folder and set the folder path in environment variable. In case of a folder, make sure to run c_rehash command for folder.

mkdir -p /tmp/custom-certs
cp ~/Download/foo.example.com.cert /tmp/custom-certs
cp ~/Download/bar.example.com.cert /tmp/custom-certs
export REQUESTS_CA_BUNDLE='/tmp/custom-certs'


On Tue, Feb 7, 2017 at 10:30 PM, Gang Yang <gang...@gmail.com> wrote:

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/f07875b8-f3b8-4bcb-b95f-2d936f5ece34%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Gang Yang

unread,
Feb 8, 2017, 4:37:10 PM2/8/17
to Django users
Hi, Pankaj,

Thanks for the reply. The REQUESTS_CA_BUNDLE env var worked as long as I start the server manually. But I don't seem to be able to "export" this env var into the server daemon process, which is started from /etc/init.d. I'll keep digging on the daemon env var.

Gang
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.

Pankaj Singh

unread,
Feb 8, 2017, 10:03:04 PM2/8/17
to Django users
Hi,

You can put export commands in you daemon script. Look at this stackoverflow answers:

You can also find different ways to set environment variables for supervisord, uwsgi, apache mod_wsgi by Google Search.

I hope it helps solve your problem.

To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.

To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

For more options, visit https://groups.google.com/d/optout.

Gang Yang

unread,
Feb 9, 2017, 11:55:38 AM2/9/17
to Django users
Hi, Panjah,

Appreciate your help. I've tried all those options, but none worked. It turned out that the init script in init.d for the server (written by a different party) is using "su -" to start a new login shell clearing all env vars. Whatever that was set in the init script and /etc/default/... were thrown away. I had to export the REQUESTS_CA_BUNDLE in "-c". But now it works. The bottom line is REQUESTS_CA_BUNDLE env var is the way to go if you can't use the "verify" parameter in requests.get() code.

Thanks again.
Gang
Reply all
Reply to author
Forward
0 new messages