netbox-community / pynetbox

Python API client library for Netbox.
Apache License 2.0
577 stars 172 forks source link

verify=False being changed to verify=None #651

Closed toeknee2120 closed 3 weeks ago

toeknee2120 commented 3 weeks ago

pynetbox version

v7.4.1

NetBox version

v4.0.9

Python version

3.11

Steps to Reproduce

import pynetbox
import requests
session = requests.Session()
session.verify = False
nb = pynetbox.api(
    'https://localhost',
    token='<token>'
)
nb.http_session = session

nb.dcim.sites.get(name__ic='mysite')

Expected Behavior

I expected my unsecure request to go through

Observed Behavior

A requests.exceptions.SSLError occurs. '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate (_ssl.c:1006)'

It looks like after these lines, the request gets passed from pynextbox.core.query._make_call() -> requests.sessions.Session.get() -> requests.sessions.Session.request().

requests.sessions.Session.get() just passes on the kwargs it receives to requests.sessions.Session.request() which defaults verify=None. So it seems like pynextbox.core.query._make_call() needs to specify verify in the kwargs it passes to requests.sessions.Session.get().

toeknee2120 commented 3 weeks ago

I don't know the best way to do it, but adding verify=self.http_session.verify works.

 req = getattr(self.http_session, verb)(
            url_override or self.url, headers=headers, params=params, json=data, verify=self.http_session.verify
        )
markkuleinio commented 3 weeks ago

I'd first check something else: why do you get a certificate error even though your URL is http (not https)? Redirections in API calls may cause unexpected effects.

toeknee2120 commented 3 weeks ago

I'd first check something else: why do you get a certificate error even though your URL is http (not https)? Redirections in API calls may cause unexpected effects.

You're right. I forgot to update the url used. It is https.

markkuleinio commented 3 weeks ago

Unable to reproduce (warning message split for readability):

>>> import pynetbox
>>> import requests
>>> nb = pynetbox.api("https://netbox.example.com", token="123")
>>> session = requests.Session()
>>> session.verify = False
>>> nb.http_session = session
>>> nb.version
/home/markku/venv/lib/python3.11/site-packages/urllib3/connectionpool.py:1099: 
InsecureRequestWarning: Unverified HTTPS request is being made to host 'netbox.example.com'.
Adding certificate verification is strongly advised.
See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#tls-warnings
  warnings.warn(
'3.7'
>>> pynetbox.__version__
'7.4.1'
>>> 
toeknee2120 commented 3 weeks ago

@markkuleinio I appreciate you testing it out. I have exactly what you have with the url and token changed, of course, but I still receive the error. I can get to the url using curl, or requests by itself, just not when using pynetbox. I've uninstalled and reinstalled pynextbox in the same virtual environment. I've recreated the virtual environment in another directory and used that. Any ideas?

edit: When testing with just requests, including verify=False in the .get() works, but setting the .verify attribute does not. Maybe this is a requests issue.

# works
requests.get(url, verify=False)

# works
session = requests.Session()
session.get(url, verify=False)

# does not work
session = requests.Session()
session.verify = False
session.get(url)
toeknee2120 commented 3 weeks ago

It's the CURL_CA_BUNDLE environment variable. If it's set, it looks like requests ignores setting the .verify attribute to False. After running unset CURL_CA_BUNDLE and trying again, it works as expected.

toeknee2120 commented 3 weeks ago

For others in the future, it looks like there is a .trust_env attribute that can be set so you don't have to mess with CURL_CA_BUNDLE

session = requests.Session()
session.verify = False
session.trust_env = False
markkuleinio commented 3 weeks ago

Thanks for following up with the solution! Interesting to know about that option.