d-Rickyy-b / certstream-server-go

This project aims to be a drop-in replacement for the certstream server by Calidog. This tool aggregates, parses, and streams certificate data from multiple certificate transparency logs via websocket connections to the clients.
MIT License
88 stars 8 forks source link

Missing certificates #32

Closed cipisek9 closed 4 months ago

cipisek9 commented 9 months ago

Hello, I have started using your certstream server, but I have the problem. I have python script which is reading stream (endpoint domain-only) and looking for domains from my defined list. Unfortunately a lot of domains are missing in compare to list of catched domains from calidog certstream.

I have two solutions, but neither of them works:

First solution is the same script, as I am using for calidog certstream. With their stream works fine, with my own (your solution) not very well

import certstream

keywords = ["example_domain1", "example_domain2"]

def print_callback(message, context):
    logging.debug("Message -> {}".format(message))
    all_domains = message['data']['leaf_cert']['all_domains']

    for domain in all_domains:
        for k in keywords:
            if domain.find(k) != -1:
                print(f"Found certificate with domain {domain}")

logging.basicConfig(format='[%(levelname)s:%(name)s] %(asctime)s - %(message)s', level=logging.INFO)

certstream.listen_for_events(print_callback, url='wss://192.168.1.101/domains-only/')

Second solution - same results as with previous script, domains are missing

async def read_stream(uri):
    async with websockets.connect(uri) as websocket:
        while True:
            data = await websocket.recv()
            try:
                json_object = json.loads(data)
                all_domains = json_object['data']

                for domain in all_domains:
                    if domain == "example_domain":
                       print(f"Found certificate with domain {domain}")
            except Exception as e:
                print(e)

ws_uri = "wss://192.168.1.101/domains-only/"

asyncio.get_event_loop().run_until_complete(read_stream(ws_uri))

Could someone help me, how to find where is the problem, and how can I fix this? Thank you in advance.

d-Rickyy-b commented 9 months ago

Hi there, thanks for creating the issue.

The first thing I noticed is you use wss:// locally. Are you actually using certificates? Otherwise just use ws://


You seem to be using the domains-only endpoint (which is good when you only need domains).

certstream.listen_for_events(print_callback, url='wss://192.168.1.101/domains-only/')

But at the same time in your first example you try to fetch the certs from the json path data.leaf_cert.all_domains, which does not exist for domains-only! See here for the code that generates the domains-only json.

all_domains = message['data']['leaf_cert']['all_domains']

You can always fetch an example cert from certstream-server-go to inspect the json format by using http and appending /example.json to the endpoint's name. In your case it would be http://192.168.1.101/domains-only/example.json. Or for debugging you can also check on my hosted instance:

https://certstream.rico-j.de/domains-only/example.json (this hosted instance might go offline at any time. It is just there for debugging and testing purposes.)

The json looks like this:

{
    "data": [
        "*.oleksandrtsvietkov.direct.quickconnect.to",
        "oleksandrtsvietkov.direct.quickconnect.to"
    ],
    "message_type": "dns_entries"
}

So you should access the domains like this:

all_domains = message['data']


Also please check the server's log for indicators that your client is too slow. Python is quite a slow language and my server processes around 300-400 certificates per second (!). People noticed in other issues (https://github.com/d-Rickyy-b/certstream-server-go/issues/28) that their code was simply too slow to process all of the certificates (although they processed the whole certificates, not the domains only). I highly suggest using multiple threads.

Please let me know if any of this helped.

cipisek9 commented 8 months ago

Hi, thank you very much for your reply.

1.) Yes, I am using certificate.

2.) I am sorry, you are right. There is the mistake in code which I have posted here. However it happens, when I was writing examples of my code to this post. Actually in my code that line is correct, similar as in second example:

def print_callback(message, context):
    ....
    all_domains = message['data']
   ...

3.) I have attached log file from certstream server, where are last 150 lines. There are a lot of

GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body)

Maybe this could be reson? There is also sometimes bigger number in Queue length. I have seen 62 max. Unfortunately I have also discovered some lines with message "buffer is full", same as mentioned in another issue. :( I wil try to make my client faster.

certstram_logs.txt

Thank you for your any other hints :)

I just noticed there is also newer version (1.5.0), so I will also try to update.

cipisek9 commented 8 months ago

I have tought the update has sloved the problem with error messages, but I was wrong...

Jan 10 14:29:01 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:29:01 ct-watcher.go:238: Processed 383000 entries | Queue length: 0 Jan 10 14:29:06 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:29:06 ct-watcher.go:238: Processed 384000 entries | Queue length: 0 Jan 10 14:29:13 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:29:13 ct-watcher.go:238: Processed 385000 entries | Queue length: 3 Jan 10 14:29:22 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:29:22 ct-watcher.go:238: Processed 386000 entries | Queue length: 0 Jan 10 14:29:46 crt CERTSTREAM_SERVER[387211]: E0110 14:29:46.685359 387211 fetcher.go:292] https://oak.ct.letsencrypt.org/2024h1: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:29:48 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:29:48 ct-watcher.go:238: Processed 387000 entries | Queue length: 5 Jan 10 14:29:52 crt CERTSTREAM_SERVER[387211]: E0110 14:29:52.715965 387211 fetcher.go:292] https://yeti2025.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:30:12 crt CERTSTREAM_SERVER[387211]: E0110 14:30:12.522125 387211 fetcher.go:292] https://yeti2024.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:30:13 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:30:13 ct-watcher.go:238: Processed 388000 entries | Queue length: 4 Jan 10 14:30:22 crt CERTSTREAM_SERVER[387211]: E0110 14:30:22.716922 387211 fetcher.go:292] https://yeti2025.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:30:34 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:30:34 ct-watcher.go:238: Processed 389000 entries | Queue length: 0 Jan 10 14:30:42 crt CERTSTREAM_SERVER[387211]: E0110 14:30:42.523710 387211 fetcher.go:292] https://yeti2024.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:30:44 crt CERTSTREAM_SERVER[387211]: E0110 14:30:44.110960 387211 fetcher.go:292] https://oak.ct.letsencrypt.org/2024h1: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:30:46 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:30:46 ct-watcher.go:238: Processed 390000 entries | Queue length: 0 Jan 10 14:30:52 crt CERTSTREAM_SERVER[387211]: E0110 14:30:52.718161 387211 fetcher.go:292] https://yeti2025.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:30:58 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:30:58 ct-watcher.go:238: Processed 391000 entries | Queue length: 0 Jan 10 14:31:11 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:31:11 ct-watcher.go:238: Processed 392000 entries | Queue length: 0 Jan 10 14:31:12 crt CERTSTREAM_SERVER[387211]: E0110 14:31:12.524351 387211 fetcher.go:292] https://yeti2024.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:31:22 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:31:22 ct-watcher.go:238: Processed 393000 entries | Queue length: 0 Jan 10 14:31:22 crt CERTSTREAM_SERVER[387211]: E0110 14:31:22.718850 387211 fetcher.go:292] https://yeti2025.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:31:33 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:31:33 ct-watcher.go:238: Processed 394000 entries | Queue length: 0 Jan 10 14:31:42 crt CERTSTREAM_SERVER[387211]: E0110 14:31:42.525488 387211 fetcher.go:292] https://yeti2024.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:31:46 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:31:46 ct-watcher.go:238: Processed 395000 entries | Queue length: 0 Jan 10 14:31:52 crt CERTSTREAM_SERVER[387211]: E0110 14:31:52.719477 387211 fetcher.go:292] https://yeti2025.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:31:59 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:31:59 ct-watcher.go:238: Processed 396000 entries | Queue length: 0 Jan 10 14:32:09 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:32:09 ct-watcher.go:238: Processed 397000 entries | Queue length: 0 Jan 10 14:32:12 crt CERTSTREAM_SERVER[387211]: E0110 14:32:12.526065 387211 fetcher.go:292] https://yeti2024.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:32:18 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:32:18 ct-watcher.go:238: Processed 398000 entries | Queue length: 0 Jan 10 14:32:22 crt CERTSTREAM_SERVER[387211]: E0110 14:32:22.720408 387211 fetcher.go:292] https://yeti2025.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:32:31 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:32:31 ct-watcher.go:238: Processed 399000 entries | Queue length: 2 Jan 10 14:32:42 crt CERTSTREAM_SERVER[387211]: E0110 14:32:42.527962 387211 fetcher.go:292] https://yeti2024.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:32:43 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:32:43 ct-watcher.go:238: Processed 400000 entries | Queue length: 0 Jan 10 14:32:52 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:32:52 ct-watcher.go:238: Processed 401000 entries | Queue length: 0 Jan 10 14:32:52 crt CERTSTREAM_SERVER[387211]: E0110 14:32:52.721367 387211 fetcher.go:292] https://yeti2025.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:33:00 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:33:00 ct-watcher.go:238: Processed 402000 entries | Queue length: 12 Jan 10 14:33:12 crt CERTSTREAM_SERVER[387211]: E0110 14:33:12.528405 387211 fetcher.go:292] https://yeti2024.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body) Jan 10 14:33:15 crt CERTSTREAM_SERVER[387211]: 2024/01/10 14:33:15 ct-watcher.go:238: Processed 403000 entries | Queue length: 3 Jan 10 14:33:18 crt CERTSTREAM_SERVER[387211]: E0110 14:33:18.957504 387211 fetcher.go:292] https://oak.ct.letsencrypt.org/2024h1: GetRawEntries() failed: failed to read response body: context deadline exceeded (Client.Timeout or context cancellation while reading body)

cipisek9 commented 8 months ago

I think, update to latest version has solved problem with missing certs. I didn't even have to make client with using threads and I am using code from my first post. I will be testing few more days, and I will write the result.

cipisek9 commented 8 months ago

Ok, here is the result after few days testing... In compare to calidog certstream, still some certificates are missing. Calidog found 14 certificates, my stream found only 11.

I don't have buffer full errors in log anymore. However I found there only som

Internal server errors

Jan 15 06:30:34 crt CERTSTREAM_SERVER[387211]: E0115 06:30:34.624163 387211 fetcher.go:292] https://sabre.ct.comodo.com: GetRawEntries() failed: got HTTP Status "500 Internal Server Error"

408 Request Timeout

Jan 15 07:52:47 crt CERTSTREAM_SERVER[387211]: E0115 07:52:47.939214 387211 fetcher.go:292] https://sabre.ct.comodo.com: GetRawEntries() failed: got HTTP Status "408 Request Timeout"

Failed to read response body

Jan 15 07:53:16 crt CERTSTREAM_SERVER[387211]: E0115 07:53:16.124375 387211 fetcher.go:292] https://nessie2025.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: http2: server sent GOAWAY and closed the connection; LastStreamID=527, ErrCode=NO_ERROR, debug=""

Is there any chance that endpoint domains-only does not contain all domains?

d-Rickyy-b commented 8 months ago

Calidog found 14 certificates, my stream found only 11.

Are you definitely talking about unique certificates? Also could you please monitor on which ct-log the certificate was found?

Internal server errors

Jan 15 06:30:34 crt CERTSTREAM_SERVER[387211]: E0115 06:30:34.624163 387211 fetcher.go:292] https://sabre.ct.comodo.com: GetRawEntries() failed: got HTTP Status "500 Internal Server Error"

That is okay. Some ct logs sometimes don't answer, are broken or under maintenance. This is nothing we can fix. The log operator is responsible for this.

408 Request Timeout

Jan 15 07:52:47 crt CERTSTREAM_SERVER[387211]: E0115 07:52:47.939214 387211 fetcher.go:292] https://sabre.ct.comodo.com: GetRawEntries() failed: got HTTP Status "408 Request Timeout"

I will have a look at this, but the fact that it's again comodo - their logs are terrible imho - just makes me guess that it's again an issue with their log. The server closes the connection due to a timeout. certstream-server-go should automatically reconnect if that happens.

Failed to read response body

Jan 15 07:53:16 crt CERTSTREAM_SERVER[387211]: E0115 07:53:16.124375 387211 fetcher.go:292] https://nessie2025.ct.digicert.com/log: GetRawEntries() failed: failed to read response body: http2: server sent GOAWAY and closed the connection; LastStreamID=527, ErrCode=NO_ERROR, debug=""

Similar to the 408 error - the server closes the connection. This might be due to various reasons. certstream-server-go should automatically reconnect if that happens.

If these things only happen to certain logs, that's not a general issue but most likely an issue with their log or an issue with the connection to their server.

Is there any chance that endpoint domains-only does not contain all domains?

As long as your client does not skip any certificates, no certificate should be skipped by the certstream-server-go either. If your client is fast enough to process everything, you'll receive everything that the server receives from the ct logs.

d-Rickyy-b commented 4 months ago

Hi there, since I haven't heard back from you, I assume you're no longer needing assistance. Feel free to reopen or create another issue if you're still having problems.