Skip to content
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

https: New option to validate, CertSignature #50

Closed

Conversation

nuclearcat
Copy link
Contributor

This option validates signature of remote certificate.
It is always possible that malicious actor might put MITM
node and obtain his own certificate.
In fact such attack already happened, one of well documented cases:
https://notes.valdikss.org.ru/jabber.ru-mitm/
The only way to detect such malicious intent is by validating
certificate signature.

@nuclearcat
Copy link
Contributor Author

It seems signature will change on each renewal, i will see how to extract subject public key.

@nuclearcat nuclearcat force-pushed the add-certsignature-option branch 2 times, most recently from 6e12610 to b099458 Compare July 7, 2024 19:31
This option validates signature of remote certificate.
It is always possible that malicious actor might put MITM
node and obtain his own certificate.
In fact such attack already happened, one of well documented cases:
https://notes.valdikss.org.ru/jabber.ru-mitm/
The only way to detect such malicious intent is by validating
certificate public key.

Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
Signed-off-by: Denys Fedoryshchenko <denys.f@collabora.com>
@nuclearcat
Copy link
Contributor Author

nuclearcat commented Jul 7, 2024

I have also small program to retrieve public key of website and format properly, but it is python, it is permissible to add it in docs or maybe create some directory like tools?

#!/usr/bin/env python3
'''
Display remote server SSL certificate information (pubkey, for RSA - RSA(e,n)
'''

import sys
import socket
import ssl
import OpenSSL.crypto

def certinfo(cert):
    x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_ASN1, cert)
    pubkey = x509.get_pubkey()
    if pubkey.type() == OpenSSL.crypto.TYPE_RSA:
        key = pubkey.to_cryptography_key().public_numbers()
        print(f'RSA:{key.e:X}:{key.n:X}')

def getcert(host, port):
    context = ssl.create_default_context()
    with socket.create_connection((host, port)) as sock:
        with context.wrap_socket(sock, server_hostname=host) as ssock:
            cert = ssock.getpeercert(True)
            certinfo(cert)

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print(f'Usage: {sys.argv[0]} <host> [port]')
        sys.exit(1)
    host = sys.argv[1]
    port = int(sys.argv[2]) if len(sys.argv) > 2 else 443
    getcert(host, port)

@berthubert
Copy link
Owner

Does this actually work? Does this check if the final certificate is signed by the right key? Is that right key stable? I tries to think this one over earlier but did not figure it out.

@nuclearcat
Copy link
Contributor Author

The initial approach was unsuccessful, but I'm currently testing an alternative method on my own infrastructure with promising results. However, there are some caveats to consider.

I used your website as a reference point:

I noticed that the Subject Public Key Info is changing between renewals, which is bad for this monitoring. This behavior is also occurring on one of the project servers I manage, which is typical for default Certbot configurations.

In contrast, I maintain some servers with relatively static setups where the public key remains consistent across renewals:

After investigating, I discovered that Certbot generates a new key on each renewal by default. This behavior can be modified using the "reuse-key = True" option, which is beneficial for certificate pinning, DANE, and certain monitoring scenarios.

We now face two options for key monitoring:

  1. Disable new key generation on each renewal. While this is THEORETICALLY considered suboptimal from a security perspective, but it allows for effective monitoring, DANE implementation, and certificate pinning (which I utilize on embedded devices).

  2. Continue generating new certificates every few months. However, this approach might make it challenging to detect REAL attacks similar to the one I referenced earlier, as they could potentially blend in with routine renewals. And very real attacks.

Given these considerations, I'm still evaluating whether pursuing this option is worthwhile. Both approaches have their merits and drawbacks in terms of security and practicality.

@nuclearcat
Copy link
Contributor Author

It seems majority of solutions are changing key, so this feature unlikely will be useful :( Closing PR

@nuclearcat nuclearcat closed this Aug 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants