netbox-community / netbox

The premier source of truth powering network automation. Open source under Apache 2. Public demo: https://demo.netbox.dev
http://netboxlabs.com/oss/netbox/
Apache License 2.0
15.67k stars 2.53k forks source link

Add custom CA Certificate #16885

Open chaeynz opened 1 month ago

chaeynz commented 1 month ago

NetBox version

v4.0.2

Feature type

New functionality

Proposed functionality

As a user, I would like to add custom CA certificates to Netbox, so that outgoing Webhooks will not fail, if the HTTP Server serves a self-signed (self-signed CA) certificate.

Use case

Currently I just cat my.crt >> netbox/venv/python./certifi/cacert.pem The venv does not persist after an upgrade, so I have to do this after every update. It would be convenient to have a custom cert storage that persists.

Database changes

No response

External dependencies

No response

Vivida1 commented 1 month ago

What seems to work if you use Ubuntu (24.04) and docker-compose:

Install the CA into the OS:

vim /usr/local/share/ca-certificates/my-root-ca.crt
update-ca-certificates

Mount the bundle into the container and tell Python requests via env to use the bundle:

  netbox:
    image: docker.io/netboxcommunity/netbox:v4.0-2.9.1
    volumes:
    - /etc/ssl:/etc/ssl:ro
   # [...]
    environment:
      REQUESTS_CA_BUNDLE: "/etc/ssl/certs/ca-certificates.crt"
m2martin commented 1 month ago

What is the preferrable way to accomplish this in your opinion (from a user's perspective)?

Make it part of the upgrade.sh install/upgrade process? So, providing x509 certificates at a certain location, which will patch Certifi's cert store when running upgrade.sh?

Seems to be the only way of doing this as Certifi itself does not provide a way to do this programatically.

But this may also be a security risk because a fake trust may be implemented into the environment without further notice. So, I'd opt for user confirmation or sth. like that. This would make the process semi-automated.

EDIT: Maybe it is a way better idea to pass environment vars using systemd, so requests could handle them. This would not require any change for the Netbox project or any fancy unsupported or risky patches for Certifi.

Vivida1 commented 1 month ago

Interestingly enough, Certifi says it does not support modifying the trust store:

Addition/Removal of Certificates

Certifi does not support any addition/removal or other modification of the CA trust store content. This project is intended to provide a reliable and highly portable root of trust to python deployments. Look to upstream projects for methods to use alternate trust.

I would just give the user the option to define a custom CA trust store. If you don't want any changes to the netbox project, maybe documenting setting REQUESTS_CA_BUNDLE would already help a lot.

chaeynz commented 1 month ago

What is the preferrable way to accomplish this in your opinion (from a user's perspective)?

My first thought was adding this through the Settings of Netbox, maybe storing the certs in the PostgreSQL, maybe that is overkill?

What do you think about a directory instead, where each time upgrade.sh runs it will cat each cert in that dir and append it to the certifi cacert.pem ?

We're not using Docker, so I'm not sure if the Environment variable helps

m2martin commented 3 weeks ago

Two approaches should already be possible: