-
Notifications
You must be signed in to change notification settings - Fork 787
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(server): add subjectAltName field into self signed certificate #1429
base: master
Are you sure you want to change the base?
Conversation
Current install script only fills CN field with PUBLIC_HOST value. When trying to access api and provide the self signed certificate to verify server certificate, the request will fail with SSL: CERTIFICATE_VERIFY_FAILED error. To prevent this error, the install script should add "subjectAltName = IP.1:${PUBLIC_HOST}" when generating self signed certificate. ```python import requests requests.get('https://${API_PREFIX}/access-keys',verify='shadowbox-selfsigned.crt') ```
This seems like a library limitation. What is this The big problem is the fact it's self-signed. We typically validate it with a certificate fingerprint. |
Found it: https://requests.readthedocs.io/en/latest/api/
Have you tried using the Python ssl library directly? Does it fail the same way? I think it may be a limitation of requests. I worry that by putting an IP there the certificate will become a lot more distinguishable and give away it's an Outline server. |
Sorry, I'm not a cryptography expert, so maybe I can't explain it accurately and clearly. From my limited knowledge, a self-signed certificate is not fundamentally different from a CA certificate. A CA Bundle is just a collection of many CA certificates. So passing in a self-signed certificate results in the certificate itself being treated as a CA. Prove its legitimacy by itself. Because it is a self-signed certificate, there is not a big difference between ignoring certificate verification or verifying the certificate as a CA. However because I want to do more key management through the API, I want to prevent MITM attacks through certificate verification. Finally, you mentioned that adding the SAN field may cause the server to be easily recognized as an Outline Server, which I haven't considered. It may be possible. |
Append the "-addext" option will add the following section after
|
When in doubt, read the RFC 🤓 https://datatracker.ietf.org/doc/html/rfc6125#section-4.1 says:
https://datatracker.ietf.org/doc/html/rfc9110#section-4.3.4-2 also covers some of that. So CN is deprecated, but still used. SAN is the recommended solution. This PR adds the IP to the SAN. There's one issue though. |
Use a regex to test whether input hostname is an IP address. If it's an IP address, use "IP" prefix. Otherwise, use "DNS".
This is great. I didn't realize that I should go through the RFC document.
If PUBLIC_HOSTNAME is not an IP address, we should put the hostname SAN field as DNS-ID.
Otherwise, use the IP address. Finally, I went through the Python requests source code even urllib3. The Python SSL module will handle the certificate verification, not requests or urllib3. This makes me think, the underlying libssl deprecates CN and uses SAN field to verify the server certificate. I also have made a quick test to verify that. If a FQDN domain is used, the install script should put it as SAN DNS-ID in the certificate. I pushed another commit to address this. |
Current install script only fills CN field with PUBLIC_HOST value. When trying to access api and provide the self signed certificate to verify server certificate, the request will fail with SSL: CERTIFICATE_VERIFY_FAILED error.
To prevent this error, the install script should add "subjectAltName = IP.1:${PUBLIC_HOST}" when generating self signed certificate.