68 Commits

Author SHA1 Message Date
overcuriousity
b20bfd2e36 attempt bugfix 2025-09-26 23:34:06 +02:00
overcuriousity
c3534868ad try fix bug 2025-09-26 23:26:21 +02:00
36c0bcdc03 Merge pull request 'gradient-test' (#4) from gradient-test into main
Reviewed-on: mstoeck3/dnsrecon#4
2025-09-24 11:16:26 +00:00
overcuriousity
ceb2d2fffc redundancy removal 2025-09-24 12:13:06 +02:00
overcuriousity
60cd649961 adjust graph context menu 2025-09-24 12:02:42 +02:00
overcuriousity
64309c53b7 fixes to export manager 2025-09-24 12:01:33 +02:00
overcuriousity
50fc5176a6 fix graph not reloading on completion in some cases 2025-09-24 11:48:11 +02:00
overcuriousity
3951b9e521 fix correlation provider issues 2025-09-24 11:36:27 +02:00
overcuriousity
897bb80183 gradient 2025-09-24 09:30:42 +02:00
overcuriousity
571912218e renaming 2025-09-22 22:45:46 +02:00
overcuriousity
5d1d249910 fix for performance optimizations 2025-09-22 15:37:33 +02:00
overcuriousity
52ea7acf04 performance optimization 2025-09-22 15:34:35 +02:00
overcuriousity
513eff12ef test fix stale 2025-09-22 11:22:39 +02:00
overcuriousity
4c361c144d readme 2025-09-20 22:05:14 +02:00
overcuriousity
b2629de055 large entity real fix 2025-09-20 21:42:32 +02:00
overcuriousity
b2c5d2331c work on large entity extraction 2025-09-20 20:56:31 +02:00
overcuriousity
602739246f refinements for correlations running logic 2025-09-20 20:31:56 +02:00
overcuriousity
4a82c279ef fix running of correlations after stop 2025-09-20 20:16:23 +02:00
overcuriousity
71a05f5b32 run correlation after stop 2025-09-20 18:48:47 +02:00
overcuriousity
1b0c630667 fic run correlation after stop request 2025-09-20 18:23:47 +02:00
overcuriousity
bcd79ae2f5 some fixes for UX, correlation engine 2025-09-20 18:19:10 +02:00
3ee23c9d05 Merge pull request 'remove-large-entity-temporarily' (#3) from remove-large-entity-temporarily into main
Reviewed-on: mstoeck3/dnsrecon#3
2025-09-19 12:29:26 +00:00
overcuriousity
8d402ab4b1 postgres 2025-09-19 14:28:37 +02:00
overcuriousity
7472e6f416 fixes to hint for incomplete data 2025-09-19 12:35:28 +02:00
overcuriousity
eabb532557 almost fixed 2025-09-19 01:10:07 +02:00
overcuriousity
0a6d12de9a large entity recreation 2025-09-19 00:38:26 +02:00
overcuriousity
332805709d remove 2025-09-18 23:44:24 +02:00
overcuriousity
1558731c1c attempt fix large entity 2025-09-18 23:22:49 +02:00
overcuriousity
95cebbf935 bug fixes, improvements 2025-09-18 22:39:12 +02:00
overcuriousity
4c48917993 fixes for scheduler 2025-09-18 21:32:26 +02:00
overcuriousity
9d9afa6a08 fixes 2025-09-18 21:04:29 +02:00
overcuriousity
12f834bb65 correlation engine 2025-09-18 20:51:13 +02:00
overcuriousity
cbfd40ee98 adjustments to shodan & export manager 2025-09-18 19:22:58 +02:00
overcuriousity
d4081e1a32 export manager modularized 2025-09-18 17:42:39 +02:00
overcuriousity
15227b392d readme file & some ux improvements 2025-09-18 00:24:35 +02:00
overcuriousity
fdc26dcf15 executive summary 2025-09-18 00:13:37 +02:00
140ef54674 Merge pull request 'data-model' (#2) from data-model into main
Reviewed-on: mstoeck3/dnsrecon#2
2025-09-17 21:56:17 +00:00
overcuriousity
aae459446c update requirements, fix some bugs 2025-09-17 23:55:41 +02:00
overcuriousity
98e1b2280b new node types 2025-09-17 22:42:08 +02:00
overcuriousity
cd14198452 smaller css 2025-09-17 22:39:26 +02:00
overcuriousity
284660ab8c new node types 2025-09-17 22:09:39 +02:00
overcuriousity
ecfb27e02a new scheduling, removed many debug prints 2025-09-17 21:47:03 +02:00
overcuriousity
39b4242200 fix cli last task started 2025-09-17 21:35:54 +02:00
overcuriousity
a56755320c initial targets managed in backend 2025-09-17 21:29:18 +02:00
overcuriousity
b985f1e5f0 potential bugfix for the right click hiding 2025-09-17 21:15:52 +02:00
overcuriousity
8ae4fdbf80 UX improvements 2025-09-17 21:12:11 +02:00
overcuriousity
d0ee415f0d enhancements 2025-09-17 19:42:14 +02:00
overcuriousity
173c3dcf92 some adjustments for clarity 2025-09-17 17:10:11 +02:00
overcuriousity
ec755b17ad remove many unnecessary debug print, improve large entity handling 2025-09-17 13:31:35 +02:00
overcuriousity
469c133f1b fix session handling 2025-09-17 11:18:06 +02:00
overcuriousity
f775c61731 iterating on fixes 2025-09-17 11:08:50 +02:00
overcuriousity
b984189e08 scheduler fixes 2025-09-17 00:31:12 +02:00
overcuriousity
f2db739fa1 attempt to fix some logic 2025-09-17 00:05:48 +02:00
overcuriousity
47ce7ff883 format keys reduction 2025-09-16 23:17:23 +02:00
overcuriousity
229746e1ec improving the display 2025-09-16 22:25:46 +02:00
overcuriousity
733e1da640 new data model refinement 2025-09-16 21:23:02 +02:00
overcuriousity
97aa18f788 implement new data api 2025-09-16 20:21:08 +02:00
overcuriousity
15421dd4a5 update caching logic 2025-09-16 15:36:29 +02:00
overcuriousity
ad4086b156 fix root computation 2025-09-16 15:25:39 +02:00
overcuriousity
0e92ec6e9a readme 2025-09-16 01:00:21 +02:00
overcuriousity
baa57bfac2 update the shodan to use only ip 2025-09-16 00:57:24 +02:00
overcuriousity
f0f80be955 finalize pop-out 2025-09-16 00:32:46 +02:00
overcuriousity
ecc143ddbb extraction feature works 2025-09-16 00:08:27 +02:00
overcuriousity
2c48316477 extract from node feature 2025-09-16 00:01:24 +02:00
overcuriousity
fc098aed28 remove cache 2025-09-15 22:48:49 +02:00
9285226cbc Merge pull request 'new-scheduler' (#1) from new-scheduler into main
Reviewed-on: mstoeck3/dnsrecon#1
2025-09-15 20:45:47 +00:00
overcuriousity
350055fcec successfully implemented scheduler 2025-09-15 22:44:38 +02:00
overcuriousity
4a5ecf7a37 new highest-priority-first scheduler 2025-09-15 22:21:17 +02:00
112 changed files with 6985 additions and 6219 deletions

View File

@@ -1,5 +1,5 @@
# =============================================== # ===============================================
# DNSRecon Environment Variables # DNScope Environment Variables
# =============================================== # ===============================================
# Copy this file to .env and fill in your values. # Copy this file to .env and fill in your values.
@@ -25,10 +25,12 @@ DEFAULT_RECURSION_DEPTH=2
# Default timeout for provider API requests in seconds. # Default timeout for provider API requests in seconds.
DEFAULT_TIMEOUT=30 DEFAULT_TIMEOUT=30
# The number of concurrent provider requests to make. # The number of concurrent provider requests to make.
MAX_CONCURRENT_REQUESTS=5 MAX_CONCURRENT_REQUESTS=1
# The number of results from a provider that triggers the "large entity" grouping. # The number of results from a provider that triggers the "large entity" grouping.
LARGE_ENTITY_THRESHOLD=100 LARGE_ENTITY_THRESHOLD=100
# The number of times to retry a target if a provider fails. # The number of times to retry a target if a provider fails.
MAX_RETRIES_PER_TARGET=8 MAX_RETRIES_PER_TARGET=8
# How long cached provider responses are stored (in hours). # How long cached provider responses are stored (in hours).
CACHE_EXPIRY_HOURS=12 CACHE_TIMEOUT_HOURS=12
GRAPH_POLLING_NODE_THRESHOLD=100

1
.gitignore vendored
View File

@@ -169,3 +169,4 @@ cython_debug/
#.idea/ #.idea/
dump.rdb dump.rdb
cache/

366
README.md
View File

@@ -1,40 +1,102 @@
# DNSRecon - Passive Infrastructure Reconnaissance Tool # DNScope - Passive Infrastructure Reconnaissance Tool
DNSRecon is an interactive, passive reconnaissance tool designed to map adversary infrastructure. It operates on a "free-by-default" model, ensuring core functionality without subscriptions, while allowing power users to enhance its capabilities with paid API keys. DNScope is an interactive, passive reconnaissance tool designed to map adversary infrastructure. It operates on a "free-by-default" model, ensuring core functionality without subscriptions, while allowing power users to enhance its capabilities with paid API keys. It is aimed at cybersecurity researchers, pentesters, and administrators who want to understand the public footprint of a target domain.
**Current Status: Phase 2 Implementation** **Repo Link:** [https://github.com/overcuriousity/DNScope](https://github.com/overcuriousity/DNScope)
- ✅ Core infrastructure and graph engine -----
- ✅ Multi-provider support (crt.sh, DNS, Shodan)
- ✅ Session-based multi-user support ## Concept and Philosophy
- ✅ Real-time web interface with interactive visualization
- ✅ Forensic logging system and JSON export The core philosophy of DNScope is to provide a comprehensive and accurate map of a target's infrastructure using only **passive data sources** by default. This means that, out of the box, DNScope will not send any traffic to the target's servers. Instead, it queries public and historical data sources to build a picture of the target's online presence. This approach is ideal for researchers and pentesters who want to gather intelligence without alerting the target, and for administrators who want to see what information about their own infrastructure is publicly available.
For power users who require more in-depth information, DNScope can be configured to use API keys for services like Shodan, which provides a wealth of information about internet-connected devices. However, this is an optional feature, and the core functionality of the tool will always remain free and passive.
-----
-----
## Features ## Features
- **Passive Reconnaissance**: Gathers data without direct contact with target infrastructure. * **Passive Reconnaissance**: Gathers data without direct contact with target infrastructure.
- **In-Memory Graph Analysis**: Uses NetworkX for efficient relationship mapping. * **In-Memory Graph Analysis**: Uses NetworkX for efficient relationship mapping.
- **Real-Time Visualization**: The graph updates dynamically as the scan progresses. * **Real-Time Visualization**: The graph updates dynamically as the scan progresses.
- **Forensic Logging**: A complete audit trail of all reconnaissance activities is maintained. * **Forensic Logging**: A complete audit trail of all reconnaissance activities is maintained.
- **Confidence Scoring**: Relationships are weighted based on the reliability of the data source. * **Session Management**: Supports concurrent user sessions with isolated scanner instances.
- **Session Management**: Supports concurrent user sessions with isolated scanner instances. * **Extensible Provider Architecture**: Easily add new data sources to expand the tool's capabilities.
* **Web-Based UI**: An intuitive and interactive web interface for managing scans and visualizing results.
* **Export Options**: Export scan results to JSON, a list of targets to a text file, or an executive summary.
* **API Key Management**: Securely manage API keys for various providers through the web interface.
* **Provider Management**: Enable or disable providers for the current session.
## Installation -----
## Technical Architecture
DNScope is a web-based application built with a modern technology stack:
* **Backend**: The backend is a **Flask** application that provides a REST API for the frontend and manages the scanning process.
* **Scanning Engine**: The core scanning engine is a multi-threaded Python application that uses a provider-based architecture to query different data sources.
* **Session Management**: **Redis** is used for session management, allowing for concurrent user sessions with isolated scanner instances.
* **Data Storage**: The application uses an in-memory graph to store and analyze the relationships between different pieces of information. The graph is built using the **NetworkX** library.
* **Frontend**: The frontend is a single-page application that uses JavaScript to interact with the backend API and visualize the graph.
-----
## Data Sources
DNScope queries the following data sources:
* **DNS**: Standard DNS lookups (A, AAAA, CNAME, MX, NS, SOA, TXT).
* **crt.sh**: A certificate transparency log that provides information about SSL/TLS certificates.
* **Shodan**: A search engine for internet-connected devices (requires an API key).
-----
## Installation and Setup
### Prerequisites ### Prerequisites
- Python 3.8 or higher * Python 3.8 or higher
- A modern web browser with JavaScript enabled * A modern web browser with JavaScript enabled
- (Recommended) A Linux host for running the application and the optional DNS cache. * A Linux host for running the application
* Redis Server
### 1\. Clone the Project ### 1\. Install Redis
It is recommended to install Redis from the official repositories.
**On Debian/Ubuntu:**
```bash ```bash
git clone https://github.com/your-repo/dnsrecon.git sudo apt-get update
cd dnsrecon sudo apt-get install redis-server
``` ```
### 2\. Install Python Dependencies **On CentOS/RHEL:**
```bash
sudo yum install redis
sudo systemctl start redis
sudo systemctl enable redis
```
You can verify that Redis is running with the following command:
```bash
redis-cli ping
```
You should see `PONG` as the response.
### 2\. Clone the Project
```bash
git clone https://github.com/overcuriousity/DNScope
cd DNScope
```
### 3\. Install Python Dependencies
It is highly recommended to use a virtual environment: It is highly recommended to use a virtual environment:
@@ -44,181 +106,90 @@ source venv/bin/activate
pip install -r requirements.txt pip install -r requirements.txt
``` ```
### 3\. (Optional but Recommended) Set up a Local DNS Caching Resolver The `requirements.txt` file contains the following dependencies:
Running a local DNS caching resolver can significantly speed up DNS queries and reduce your network footprint. Heres how to set up `unbound` on a Debian-based Linux distribution (like Ubuntu). * Flask
* networkx
* requests
* python-dateutil
* Werkzeug
* urllib3
* dnspython
* gunicorn
* redis
* python-dotenv
* psycopg2-binary
**a. Install Unbound:** ### 4\. Configure the Application
DNScope is configured using a `.env` file. You can copy the provided example file and edit it to suit your needs:
```bash ```bash
sudo apt update cp .env.example .env
sudo apt install unbound -y
``` ```
**b. Configure Unbound:** The following environment variables are available for configuration:
Create a new configuration file for DNSRecon:
```bash | Variable | Description | Default |
sudo nano /etc/unbound/unbound.conf.d/dnsrecon.conf | :--- | :--- | :--- |
``` | `SHODAN_API_KEY` | Your Shodan API key. | |
| `FLASK_SECRET_KEY`| A strong, random secret key for session security. | `your-very-secret-and-random-key-here` |
| `FLASK_HOST` | The host address for the Flask application. | `127.0.0.1` |
| `FLASK_PORT` | The port for the Flask application. | `5000` |
| `FLASK_DEBUG` | Enable or disable Flask's debug mode. | `True` |
| `FLASK_PERMANENT_SESSION_LIFETIME_HOURS`| How long a user's session in the browser lasts (in hours). | `2` |
| `SESSION_TIMEOUT_MINUTES` | How long inactive scanner data is stored in Redis (in minutes). | `60` |
| `DEFAULT_RECURSION_DEPTH` | The default number of levels to recurse when scanning. | `2` |
| `DEFAULT_TIMEOUT` | Default timeout for provider API requests in seconds. | `30` |
| `MAX_CONCURRENT_REQUESTS`| The number of concurrent provider requests to make. | `5` |
| `LARGE_ENTITY_THRESHOLD`| The number of results from a provider that triggers the "large entity" grouping. | `100` |
| `MAX_RETRIES_PER_TARGET`| The number of times to retry a target if a provider fails. | `8` |
| `CACHE_EXPIRY_HOURS`| How long cached provider responses are stored (in hours). | `12` |
Add the following content to the file: -----
``` ## Running the Application
server:
# Listen on localhost for all users
interface: 127.0.0.1
access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.0/8 allow
# Enable prefetching of popular items For development, you can run the application using the following command:
prefetch: yes
```
**c. Restart Unbound and set it as the default resolver:**
```bash
sudo systemctl restart unbound
sudo systemctl enable unbound
```
To use this resolver for your system, you may need to update your network settings to point to `127.0.0.1` as your DNS server.
**d. Update DNSProvider to use the local resolver:**
In `dnsrecon/providers/dns_provider.py`, you can explicitly set the resolver's nameservers in the `__init__` method:
```python
# dnsrecon/providers/dns_provider.py
class DNSProvider(BaseProvider):
def __init__(self, session_config=None):
"""Initialize DNS provider with session-specific configuration."""
super().__init__(...)
# Configure DNS resolver
self.resolver = dns.resolver.Resolver()
self.resolver.nameservers = ['127.0.0.1'] # Use local caching resolver
self.resolver.timeout = 5
self.resolver.lifetime = 10
```
## Usage (Development)
### 1\. Start the Application
```bash ```bash
python app.py python app.py
``` ```
### 2\. Open Your Browser For production, it is recommended to use a more robust server, such as Gunicorn:
Navigate to `http://127.0.0.1:5000`.
### 3\. Basic Reconnaissance Workflow
1. **Enter Target Domain**: Input a domain like `example.com`.
2. **Select Recursion Depth**: Depth 2 is recommended for most investigations.
3. **Start Reconnaissance**: Click "Start Reconnaissance" to begin.
4. **Monitor Progress**: Watch the real-time graph build as relationships are discovered.
5. **Analyze and Export**: Interact with the graph and download the results when the scan is complete.
## Production Deployment
To deploy DNSRecon in a production environment, follow these steps:
### 1\. Use a Production WSGI Server
Do not use the built-in Flask development server for production. Use a WSGI server like **Gunicorn**:
```bash ```bash
pip install gunicorn
gunicorn --workers 4 --bind 0.0.0.0:5000 app:app gunicorn --workers 4 --bind 0.0.0.0:5000 app:app
``` ```
### 2\. Configure Environment Variables -----
Set the following environment variables for a secure and configurable deployment: ## Systemd Service
```bash To run DNScope as a service that starts automatically on boot, you can use `systemd`.
# Generate a strong, random secret key
export SECRET_KEY='your-super-secret-and-random-key'
# Set Flask to production mode
export FLASK_ENV='production'
export FLASK_DEBUG=False
# API keys (optional, but recommended for full functionality)
export SHODAN_API_KEY="your_shodan_key"
```
### 3\. Use a Reverse Proxy
Set up a reverse proxy like **Nginx** to sit in front of the Gunicorn server. This provides several benefits, including:
- **TLS/SSL Termination**: Securely handle HTTPS traffic.
- **Load Balancing**: Distribute traffic across multiple application instances.
- **Serving Static Files**: Efficiently serve CSS and JavaScript files.
**Example Nginx Configuration:**
```nginx
server {
listen 80;
server_name your_domain.com;
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name your_domain.com;
# SSL cert configuration
ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
alias /path/to/your/dnsrecon/static;
expires 30d;
}
}
```
## Autostart with systemd
To run DNSRecon as a service that starts automatically on boot, you can use `systemd`.
### 1\. Create a `.service` file ### 1\. Create a `.service` file
Create a new service file in `/etc/systemd/system/`: Create a new service file in `/etc/systemd/system/`:
```bash ```bash
sudo nano /etc/systemd/system/dnsrecon.service sudo nano /etc/systemd/system/DNScope.service
``` ```
### 2\. Add the Service Configuration ### 2\. Add the Service Configuration
Paste the following configuration into the file. **Remember to replace `/path/to/your/dnsrecon` and `your_user` with your actual project path and username.** Paste the following configuration into the file. **Remember to replace `/path/to/your/DNScope` and `your_user` with your actual project path and username.**
```ini ```ini
[Unit] [Unit]
Description=DNSRecon Application Description=DNScope Application
After=network.target After=network.target
[Service] [Service]
User=your_user User=your_user
Group=your_user Group=your_user
WorkingDirectory=/path/to/your/dnsrecon WorkingDirectory=/path/to/your/DNScope
ExecStart=/path/to/your/dnsrecon/venv/bin/gunicorn --workers 4 --bind 0.0.0.0:5000 app:app ExecStart=/path/to/your/DNScope/venv/bin/gunicorn --workers 4 --bind 0.0.0.0:5000 app:app
Restart=always Restart=always
Environment="SECRET_KEY=your-super-secret-and-random-key" Environment="SECRET_KEY=your-super-secret-and-random-key"
Environment="FLASK_ENV=production" Environment="FLASK_ENV=production"
@@ -235,22 +206,87 @@ Reload the `systemd` daemon, enable the service to start on boot, and then start
```bash ```bash
sudo systemctl daemon-reload sudo systemctl daemon-reload
sudo systemctl enable dnsrecon.service sudo systemctl enable DNScope.service
sudo systemctl start dnsrecon.service sudo systemctl start DNScope.service
``` ```
You can check the status of the service at any time with: You can check the status of the service at any time with:
```bash ```bash
sudo systemctl status dnsrecon.service sudo systemctl status DNScope.service
``` ```
## Security Considerations -----
- **API Keys**: API keys are stored in memory for the duration of a user session and are not written to disk. ## Updating the Application
- **Rate Limiting**: DNSRecon includes built-in rate limiting to be respectful to data sources.
- **Local Use**: The application is designed for local or trusted network use and does not have built-in authentication. **Do not expose it directly to the internet without proper security controls.** To update the application, you should first pull the latest changes from the git repository. Then, you will need to wipe the Redis database and the local cache to ensure that you are using the latest data.
### 1\. Update the Code
```bash
git pull
```
### 2\. Wipe the Redis Database
```bash
redis-cli FLUSHALL
```
### 3\. Wipe the Local Cache
```bash
rm -rf cache/*
```
### 4\. Restart the Service
```bash
sudo systemctl restart DNScope.service
```
-----
## Extensibility
DNScope is designed to be extensible, and adding new providers is a straightforward process. To add a new provider, you will need to create a new Python file in the `providers` directory that inherits from the `BaseProvider` class. The new provider will need to implement the following methods:
* `get_name()`: Return the name of the provider.
* `get_display_name()`: Return a display-friendly name for the provider.
* `requires_api_key()`: Return `True` if the provider requires an API key.
* `get_eligibility()`: Return a dictionary indicating whether the provider can query domains and/or IPs.
* `is_available()`: Return `True` if the provider is available (e.g., if an API key is configured).
* `query_domain(domain)`: Query the provider for information about a domain.
* `query_ip(ip)`: Query the provider for information about an IP address.
-----
## Unique Capabilities and Limitations
### Unique Capabilities
* **Graph-Based Analysis**: The use of a graph-based data model allows for a more intuitive and powerful analysis of the relationships between different pieces of information.
* **Real-Time Visualization**: The real-time visualization of the graph provides immediate feedback and allows for a more interactive and engaging analysis experience.
* **Session Management**: The session management feature allows multiple users to use the application concurrently without interfering with each other's work.
### Limitations
* **Passive-Only by Default**: While the passive-only approach is a key feature of the tool, it also means that the information it can gather is limited to what is publicly available.
* **No Active Scanning**: The tool does not perform any active scanning, such as port scanning or vulnerability scanning.
-----
## License ## License
This project is licensed under the terms of the license agreement found in the `LICENSE` file. This project is licensed under the terms of the **BSD-3-Clause** license.
Copyright (c) 2025 mstoeck3.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

548
app.py
View File

@@ -1,8 +1,9 @@
# dnsrecon-reduced/app.py # DNScope-reduced/app.py
""" """
Flask application entry point for DNSRecon web interface. Flask application entry point for DNScope web interface.
Provides REST API endpoints and serves the web interface with user session support. Provides REST API endpoints and serves the web interface with user session support.
UPDATED: Added /api/config endpoint for graph polling optimization settings.
""" """
import json import json
@@ -10,60 +11,69 @@ import traceback
from flask import Flask, render_template, request, jsonify, send_file, session from flask import Flask, render_template, request, jsonify, send_file, session
from datetime import datetime, timezone, timedelta from datetime import datetime, timezone, timedelta
import io import io
import os
from core.session_manager import session_manager from core.session_manager import session_manager
from config import config from config import config
from core.graph_manager import NodeType from core.graph_manager import NodeType
from utils.helpers import is_valid_target from utils.helpers import is_valid_target
from utils.export_manager import export_manager
from decimal import Decimal
app = Flask(__name__) app = Flask(__name__)
# Use centralized configuration for Flask settings
app.config['SECRET_KEY'] = config.flask_secret_key app.config['SECRET_KEY'] = config.flask_secret_key
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=config.flask_permanent_session_lifetime_hours) app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=config.flask_permanent_session_lifetime_hours)
def get_user_scanner(): def get_user_scanner():
""" """
Retrieves the scanner for the current session, or creates a new Retrieves the scanner for the current session, or creates a new one if none exists.
session and scanner if one doesn't exist.
""" """
# Get current Flask session info for debugging current_flask_session_id = session.get('DNScope_session_id')
current_flask_session_id = session.get('dnsrecon_session_id')
# Try to get existing session
if current_flask_session_id: if current_flask_session_id:
existing_scanner = session_manager.get_session(current_flask_session_id) existing_scanner = session_manager.get_session(current_flask_session_id)
if existing_scanner: if existing_scanner:
return current_flask_session_id, existing_scanner return current_flask_session_id, existing_scanner
# Create new session if none exists
print("Creating new session as none was found...")
new_session_id = session_manager.create_session() new_session_id = session_manager.create_session()
new_scanner = session_manager.get_session(new_session_id) new_scanner = session_manager.get_session(new_session_id)
if not new_scanner: if not new_scanner:
raise Exception("Failed to create new scanner session") raise Exception("Failed to create new scanner session")
# Store in Flask session session['DNScope_session_id'] = new_session_id
session['dnsrecon_session_id'] = new_session_id
session.permanent = True session.permanent = True
return new_session_id, new_scanner return new_session_id, new_scanner
@app.route('/') @app.route('/')
def index(): def index():
"""Serve the main web interface.""" """Serve the main web interface."""
return render_template('index.html') return render_template('index.html')
@app.route('/api/config', methods=['GET'])
def get_config():
"""Get configuration settings for frontend."""
try:
return jsonify({
'success': True,
'config': {
'graph_polling_node_threshold': config.graph_polling_node_threshold
}
})
except Exception as e:
traceback.print_exc()
return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500
@app.route('/api/scan/start', methods=['POST']) @app.route('/api/scan/start', methods=['POST'])
def start_scan(): def start_scan():
""" """
Start a new reconnaissance scan. Creates a new isolated scanner if Starts a new reconnaissance scan.
clear_graph is true, otherwise adds to the existing one.
""" """
print("=== API: /api/scan/start called ===")
try: try:
data = request.get_json() data = request.get_json()
if not data or 'target' not in data: if not data or 'target' not in data:
@@ -72,47 +82,28 @@ def start_scan():
target = data['target'].strip() target = data['target'].strip()
max_depth = data.get('max_depth', config.default_recursion_depth) max_depth = data.get('max_depth', config.default_recursion_depth)
clear_graph = data.get('clear_graph', True) clear_graph = data.get('clear_graph', True)
force_rescan_target = data.get('force_rescan_target', None) # **FIX**: Get the new parameter force_rescan_target = data.get('force_rescan_target', None)
print(f"Parsed - target: '{target}', max_depth: {max_depth}, clear_graph: {clear_graph}, force_rescan: {force_rescan_target}")
# Validation
if not target: if not target:
return jsonify({'success': False, 'error': 'Target cannot be empty'}), 400 return jsonify({'success': False, 'error': 'Target cannot be empty'}), 400
if not is_valid_target(target): if not is_valid_target(target):
return jsonify({'success': False, 'error': 'Invalid target format. Please enter a valid domain or IP address.'}), 400 return jsonify({'success': False, 'error': 'Invalid target format.'}), 400
if not isinstance(max_depth, int) or not 1 <= max_depth <= 5: if not isinstance(max_depth, int) or not 1 <= max_depth <= 5:
return jsonify({'success': False, 'error': 'Max depth must be an integer between 1 and 5'}), 400 return jsonify({'success': False, 'error': 'Max depth must be an integer between 1 and 5'}), 400
user_session_id, scanner = None, None
if clear_graph:
print("Clear graph requested: Creating a new, isolated scanner session.")
old_session_id = session.get('dnsrecon_session_id')
if old_session_id:
session_manager.terminate_session(old_session_id)
user_session_id = session_manager.create_session()
session['dnsrecon_session_id'] = user_session_id
session.permanent = True
scanner = session_manager.get_session(user_session_id)
else:
print("Adding to existing graph: Reusing the current scanner session.")
user_session_id, scanner = get_user_scanner() user_session_id, scanner = get_user_scanner()
if not scanner: if not scanner:
return jsonify({'success': False, 'error': 'Failed to get or create a scanner instance.'}), 500 return jsonify({'success': False, 'error': 'Failed to get scanner instance.'}), 500
print(f"Using scanner {id(scanner)} in session {user_session_id}") success = scanner.start_scan(target, max_depth, clear_graph=clear_graph, force_rescan_target=force_rescan_target)
success = scanner.start_scan(target, max_depth, clear_graph=clear_graph, force_rescan_target=force_rescan_target) # **FIX**: Pass the new parameter
if success: if success:
return jsonify({ return jsonify({
'success': True, 'success': True,
'message': 'Scan started successfully', 'message': 'Reconnaissance scan started successfully',
'scan_id': scanner.logger.session_id, 'scan_id': scanner.logger.session_id,
'user_session_id': user_session_id, 'user_session_id': user_session_id
}) })
else: else:
return jsonify({ return jsonify({
@@ -121,171 +112,176 @@ def start_scan():
}), 409 }), 409
except Exception as e: except Exception as e:
print(f"ERROR: Exception in start_scan endpoint: {e}")
traceback.print_exc() traceback.print_exc()
return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500 return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500
@app.route('/api/scan/stop', methods=['POST']) @app.route('/api/scan/stop', methods=['POST'])
def stop_scan(): def stop_scan():
"""Stop the current scan with immediate GUI feedback.""" """Stop the current scan."""
print("=== API: /api/scan/stop called ===")
try: try:
# Get user-specific scanner
user_session_id, scanner = get_user_scanner() user_session_id, scanner = get_user_scanner()
print(f"Stopping scan for session: {user_session_id}")
if not scanner: if not scanner:
return jsonify({ return jsonify({'success': False, 'error': 'No scanner found for session'}), 404
'success': False,
'error': 'No scanner found for session'
}), 404
# Ensure session ID is set
if not scanner.session_id: if not scanner.session_id:
scanner.session_id = user_session_id scanner.session_id = user_session_id
# Use the stop mechanism scanner.stop_scan()
success = scanner.stop_scan()
# Also set the Redis stop signal directly for extra reliability
session_manager.set_stop_signal(user_session_id) session_manager.set_stop_signal(user_session_id)
# Force immediate status update
session_manager.update_scanner_status(user_session_id, 'stopped') session_manager.update_scanner_status(user_session_id, 'stopped')
# Update the full scanner state
session_manager.update_session_scanner(user_session_id, scanner) session_manager.update_session_scanner(user_session_id, scanner)
print(f"Stop scan completed. Success: {success}, Scanner status: {scanner.status}")
return jsonify({ return jsonify({
'success': True, 'success': True,
'message': 'Scan stop requested - termination initiated', 'message': 'Scan stop requested',
'user_session_id': user_session_id, 'user_session_id': user_session_id
'scanner_status': scanner.status,
'stop_method': 'cross_process'
}) })
except Exception as e: except Exception as e:
print(f"ERROR: Exception in stop_scan endpoint: {e}")
traceback.print_exc() traceback.print_exc()
return jsonify({ return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500
'success': False,
'error': f'Internal server error: {str(e)}'
}), 500
@app.route('/api/scan/status', methods=['GET']) @app.route('/api/scan/status', methods=['GET'])
def get_scan_status(): def get_scan_status():
"""Get current scan status with error handling.""" """Get current scan status."""
try: try:
# Get user-specific scanner
user_session_id, scanner = get_user_scanner() user_session_id, scanner = get_user_scanner()
if not scanner: if not scanner:
# Return default idle status if no scanner
return jsonify({ return jsonify({
'success': True, 'success': True,
'status': { 'status': {
'status': 'idle', 'status': 'idle', 'target_domain': None, 'current_depth': 0,
'target_domain': None, 'max_depth': 0, 'progress_percentage': 0.0,
'current_depth': 0,
'max_depth': 0,
'current_indicator': '',
'total_indicators_found': 0,
'indicators_processed': 0,
'progress_percentage': 0.0,
'enabled_providers': [],
'graph_statistics': {},
'user_session_id': user_session_id 'user_session_id': user_session_id
} }
}) })
# Ensure session ID is set
if not scanner.session_id: if not scanner.session_id:
scanner.session_id = user_session_id scanner.session_id = user_session_id
status = scanner.get_scan_status() status = scanner.get_scan_status()
status['user_session_id'] = user_session_id status['user_session_id'] = user_session_id
# Additional debug info return jsonify({'success': True, 'status': status})
status['debug_info'] = {
'scanner_object_id': id(scanner),
'session_id_set': bool(scanner.session_id),
'has_scan_thread': bool(scanner.scan_thread and scanner.scan_thread.is_alive())
}
return jsonify({
'success': True,
'status': status
})
except Exception as e: except Exception as e:
print(f"ERROR: Exception in get_scan_status endpoint: {e}")
traceback.print_exc() traceback.print_exc()
return jsonify({ return jsonify({
'success': False, 'success': False, 'error': f'Internal server error: {str(e)}',
'error': f'Internal server error: {str(e)}', 'fallback_status': {'status': 'error', 'progress_percentage': 0.0}
'fallback_status': {
'status': 'error',
'target_domain': None,
'current_depth': 0,
'max_depth': 0,
'progress_percentage': 0.0
}
}), 500 }), 500
@app.route('/api/graph', methods=['GET']) @app.route('/api/graph', methods=['GET'])
def get_graph_data(): def get_graph_data():
"""Get current graph data with error handling.""" """Get current graph data."""
try: try:
# Get user-specific scanner
user_session_id, scanner = get_user_scanner() user_session_id, scanner = get_user_scanner()
if not scanner: empty_graph = {
# Return empty graph if no scanner 'nodes': [], 'edges': [],
return jsonify({ 'statistics': {'node_count': 0, 'edge_count': 0}
'success': True,
'graph': {
'nodes': [],
'edges': [],
'statistics': {
'node_count': 0,
'edge_count': 0,
'creation_time': datetime.now(timezone.utc).isoformat(),
'last_modified': datetime.now(timezone.utc).isoformat()
} }
},
'user_session_id': user_session_id
})
graph_data = scanner.get_graph_data() if not scanner:
return jsonify({ return jsonify({'success': True, 'graph': empty_graph, 'user_session_id': user_session_id})
'success': True,
'graph': graph_data, graph_data = scanner.get_graph_data() or empty_graph
'user_session_id': user_session_id
}) return jsonify({'success': True, 'graph': graph_data, 'user_session_id': user_session_id})
except Exception as e: except Exception as e:
print(f"ERROR: Exception in get_graph_data endpoint: {e}") traceback.print_exc()
return jsonify({
'success': False, 'error': f'Internal server error: {str(e)}',
'fallback_graph': {'nodes': [], 'edges': [], 'statistics': {}}
}), 500
@app.route('/api/graph/large-entity/extract', methods=['POST'])
def extract_from_large_entity():
"""
FIXED: Extract a node from a large entity with proper error handling.
"""
try:
data = request.get_json()
large_entity_id = data.get('large_entity_id')
node_id = data.get('node_id')
if not large_entity_id or not node_id:
return jsonify({'success': False, 'error': 'Missing required parameters'}), 400
user_session_id, scanner = get_user_scanner()
if not scanner:
return jsonify({'success': False, 'error': 'No active session found'}), 404
# FIXED: Check if node exists and provide better error messages
if not scanner.graph.graph.has_node(node_id):
return jsonify({
'success': False,
'error': f'Node {node_id} not found in graph'
}), 404
# FIXED: Check if node is actually part of the large entity
node_data = scanner.graph.graph.nodes[node_id]
metadata = node_data.get('metadata', {})
current_large_entity = metadata.get('large_entity_id')
if not current_large_entity:
return jsonify({
'success': False,
'error': f'Node {node_id} is not part of any large entity'
}), 400
if current_large_entity != large_entity_id:
return jsonify({
'success': False,
'error': f'Node {node_id} belongs to large entity {current_large_entity}, not {large_entity_id}'
}), 400
# FIXED: Check if large entity exists
if not scanner.graph.graph.has_node(large_entity_id):
return jsonify({
'success': False,
'error': f'Large entity {large_entity_id} not found'
}), 404
# Perform the extraction
success = scanner.extract_node_from_large_entity(large_entity_id, node_id)
if success:
# Force immediate session state update
session_manager.update_session_scanner(user_session_id, scanner)
return jsonify({
'success': True,
'message': f'Node {node_id} extracted successfully from {large_entity_id}.',
'extracted_node': node_id,
'large_entity': large_entity_id
})
else:
# This should not happen with the improved checks above, but handle it gracefully
return jsonify({
'success': False,
'error': f'Failed to extract node {node_id} from {large_entity_id}. Node may have already been extracted.'
}), 409
except json.JSONDecodeError:
return jsonify({'success': False, 'error': 'Invalid JSON in request body'}), 400
except Exception as e:
traceback.print_exc() traceback.print_exc()
return jsonify({ return jsonify({
'success': False, 'success': False,
'error': f'Internal server error: {str(e)}', 'error': f'Internal server error: {str(e)}',
'fallback_graph': { 'error_type': type(e).__name__
'nodes': [],
'edges': [],
'statistics': {'node_count': 0, 'edge_count': 0}
}
}), 500 }), 500
@app.route('/api/graph/node/<node_id>', methods=['DELETE']) @app.route('/api/graph/node/<node_id>', methods=['DELETE'])
def delete_graph_node(node_id): def delete_graph_node(node_id):
"""Delete a node from the graph for the current user session.""" """Delete a node from the graph."""
try: try:
user_session_id, scanner = get_user_scanner() user_session_id, scanner = get_user_scanner()
if not scanner: if not scanner:
@@ -294,14 +290,12 @@ def delete_graph_node(node_id):
success = scanner.graph.remove_node(node_id) success = scanner.graph.remove_node(node_id)
if success: if success:
# Persist the change
session_manager.update_session_scanner(user_session_id, scanner) session_manager.update_session_scanner(user_session_id, scanner)
return jsonify({'success': True, 'message': f'Node {node_id} deleted successfully.'}) return jsonify({'success': True, 'message': f'Node {node_id} deleted successfully.'})
else: else:
return jsonify({'success': False, 'error': f'Node {node_id} not found in graph.'}), 404 return jsonify({'success': False, 'error': f'Node {node_id} not found.'}), 404
except Exception as e: except Exception as e:
print(f"ERROR: Exception in delete_graph_node endpoint: {e}")
traceback.print_exc() traceback.print_exc()
return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500 return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500
@@ -322,7 +316,6 @@ def revert_graph_action():
action_data = data['data'] action_data = data['data']
if action_type == 'delete': if action_type == 'delete':
# Re-add the node
node_to_add = action_data.get('node') node_to_add = action_data.get('node')
if node_to_add: if node_to_add:
scanner.graph.add_node( scanner.graph.add_node(
@@ -333,56 +326,61 @@ def revert_graph_action():
metadata=node_to_add.get('metadata') metadata=node_to_add.get('metadata')
) )
# Re-add the edges
edges_to_add = action_data.get('edges', []) edges_to_add = action_data.get('edges', [])
for edge in edges_to_add: for edge in edges_to_add:
# Add edge only if both nodes exist to prevent errors
if scanner.graph.graph.has_node(edge['from']) and scanner.graph.graph.has_node(edge['to']): if scanner.graph.graph.has_node(edge['from']) and scanner.graph.graph.has_node(edge['to']):
scanner.graph.add_edge( scanner.graph.add_edge(
source_id=edge['from'], source_id=edge['from'], target_id=edge['to'],
target_id=edge['to'],
relationship_type=edge['metadata']['relationship_type'], relationship_type=edge['metadata']['relationship_type'],
confidence_score=edge['metadata']['confidence_score'],
source_provider=edge['metadata']['source_provider'], source_provider=edge['metadata']['source_provider'],
raw_data=edge.get('raw_data', {}) raw_data=edge.get('raw_data', {})
) )
# Persist the change
session_manager.update_session_scanner(user_session_id, scanner) session_manager.update_session_scanner(user_session_id, scanner)
return jsonify({'success': True, 'message': 'Delete action reverted successfully.'}) return jsonify({'success': True, 'message': 'Delete action reverted successfully.'})
return jsonify({'success': False, 'error': f'Unknown revert action type: {action_type}'}), 400 return jsonify({'success': False, 'error': f'Unknown revert action type: {action_type}'}), 400
except Exception as e: except Exception as e:
print(f"ERROR: Exception in revert_graph_action endpoint: {e}")
traceback.print_exc() traceback.print_exc()
return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500 return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500
@app.route('/api/export', methods=['GET']) @app.route('/api/export', methods=['GET'])
def export_results(): def export_results():
"""Export complete scan results as downloadable JSON for the user session.""" """Export scan results as a JSON file with improved error handling."""
try: try:
# Get user-specific scanner
user_session_id, scanner = get_user_scanner() user_session_id, scanner = get_user_scanner()
# Get complete results if not scanner:
results = scanner.export_results() return jsonify({'success': False, 'error': 'No active scanner session found'}), 404
# Add session information to export # Get export data using the new export manager
results['export_metadata'] = { try:
'user_session_id': user_session_id, results = export_manager.export_scan_results(scanner)
'export_timestamp': datetime.now(timezone.utc).isoformat(), except Exception as e:
'export_type': 'user_session_results' return jsonify({'success': False, 'error': f'Failed to gather export data: {str(e)}'}), 500
}
# Create filename with timestamp # Add user session metadata
timestamp = datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S') results['export_metadata']['user_session_id'] = user_session_id
target = scanner.current_target or 'unknown' results['export_metadata']['forensic_integrity'] = 'maintained'
filename = f"dnsrecon_{target}_{timestamp}_{user_session_id[:8]}.json"
# Create in-memory file # Generate filename
json_data = json.dumps(results, indent=2, ensure_ascii=False) filename = export_manager.generate_filename(
target=scanner.current_target or 'unknown',
export_type='json'
)
# Serialize with export manager
try:
json_data = export_manager.serialize_to_json(results)
except Exception as e:
return jsonify({
'success': False,
'error': f'JSON serialization failed: {str(e)}'
}), 500
# Create file object
file_obj = io.BytesIO(json_data.encode('utf-8')) file_obj = io.BytesIO(json_data.encode('utf-8'))
return send_file( return send_file(
@@ -393,70 +391,86 @@ def export_results():
) )
except Exception as e: except Exception as e:
print(f"ERROR: Exception in export_results endpoint: {e}")
traceback.print_exc() traceback.print_exc()
return jsonify({ return jsonify({
'success': False, 'success': False,
'error': f'Export failed: {str(e)}' 'error': f'Export failed: {str(e)}',
'error_type': type(e).__name__
}), 500 }), 500
@app.route('/api/export/targets', methods=['GET'])
@app.route('/api/providers', methods=['GET']) def export_targets():
def get_providers(): """Export all discovered targets as a TXT file."""
"""Get information about available providers for the user session."""
try: try:
# Get user-specific scanner
user_session_id, scanner = get_user_scanner() user_session_id, scanner = get_user_scanner()
if not scanner:
return jsonify({'success': False, 'error': 'No active scanner session found'}), 404
if scanner: # Use export manager for targets export
completed_tasks = scanner.indicators_completed targets_txt = export_manager.export_targets_list(scanner)
enqueued_tasks = len(scanner.task_queue)
print(f"DEBUG: Tasks - Completed: {completed_tasks}, Enqueued: {enqueued_tasks}")
else:
print("DEBUG: No active scanner session found.")
provider_info = scanner.get_provider_info() # Generate filename using export manager
filename = export_manager.generate_filename(
target=scanner.current_target or 'unknown',
export_type='targets'
)
return jsonify({ file_obj = io.BytesIO(targets_txt.encode('utf-8'))
'success': True,
'providers': provider_info,
'user_session_id': user_session_id
})
return send_file(
file_obj,
as_attachment=True,
download_name=filename,
mimetype='text/plain'
)
except Exception as e: except Exception as e:
print(f"ERROR: Exception in get_providers endpoint: {e}")
traceback.print_exc() traceback.print_exc()
return jsonify({ return jsonify({'success': False, 'error': f'Export failed: {str(e)}'}), 500
'success': False,
'error': f'Internal server error: {str(e)}'
}), 500
@app.route('/api/export/summary', methods=['GET'])
def export_summary():
"""Export an executive summary as a TXT file."""
try:
user_session_id, scanner = get_user_scanner()
if not scanner:
return jsonify({'success': False, 'error': 'No active scanner session found'}), 404
# Use export manager for summary generation
summary_txt = export_manager.generate_executive_summary(scanner)
# Generate filename using export manager
filename = export_manager.generate_filename(
target=scanner.current_target or 'unknown',
export_type='summary'
)
file_obj = io.BytesIO(summary_txt.encode('utf-8'))
return send_file(
file_obj,
as_attachment=True,
download_name=filename,
mimetype='text/plain'
)
except Exception as e:
traceback.print_exc()
return jsonify({'success': False, 'error': f'Export failed: {str(e)}'}), 500
@app.route('/api/config/api-keys', methods=['POST']) @app.route('/api/config/api-keys', methods=['POST'])
def set_api_keys(): def set_api_keys():
""" """Set API keys for the current session."""
Set API keys for providers for the user session only.
"""
try: try:
data = request.get_json() data = request.get_json()
if data is None: if data is None:
return jsonify({ return jsonify({'success': False, 'error': 'No API keys provided'}), 400
'success': False,
'error': 'No API keys provided'
}), 400
# Get user-specific scanner and config
user_session_id, scanner = get_user_scanner() user_session_id, scanner = get_user_scanner()
session_config = scanner.config session_config = scanner.config
updated_providers = [] updated_providers = []
# Iterate over the API keys provided in the request data
for provider_name, api_key in data.items(): for provider_name, api_key in data.items():
# This allows us to both set and clear keys. The config
# handles enabling/disabling based on if the key is empty.
api_key_value = str(api_key or '').strip() api_key_value = str(api_key or '').strip()
success = session_config.set_api_key(provider_name.lower(), api_key_value) success = session_config.set_api_key(provider_name.lower(), api_key_value)
@@ -464,60 +478,136 @@ def set_api_keys():
updated_providers.append(provider_name) updated_providers.append(provider_name)
if updated_providers: if updated_providers:
# Reinitialize scanner providers to apply the new keys
scanner._initialize_providers() scanner._initialize_providers()
# Persist the updated scanner object back to the user's session
session_manager.update_session_scanner(user_session_id, scanner) session_manager.update_session_scanner(user_session_id, scanner)
return jsonify({ return jsonify({
'success': True, 'success': True,
'message': f'API keys updated for session {user_session_id}: {", ".join(updated_providers)}', 'message': f'API keys updated for: {", ".join(updated_providers)}',
'updated_providers': updated_providers,
'user_session_id': user_session_id 'user_session_id': user_session_id
}) })
else: else:
return jsonify({ return jsonify({'success': False, 'error': 'No valid API keys were provided.'}), 400
'success': False,
'error': 'No valid API keys were provided or provider names were incorrect.'
}), 400
except Exception as e: except Exception as e:
print(f"ERROR: Exception in set_api_keys endpoint: {e}")
traceback.print_exc() traceback.print_exc()
return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500
@app.route('/api/providers', methods=['GET'])
def get_providers():
"""Get enhanced information about available providers including API key sources."""
try:
user_session_id, scanner = get_user_scanner()
base_provider_info = scanner.get_provider_info()
# Enhance provider info with API key source information
enhanced_provider_info = {}
for provider_name, info in base_provider_info.items():
enhanced_info = dict(info) # Copy base info
if info['requires_api_key']:
# Determine API key source and configuration status
api_key = scanner.config.get_api_key(provider_name)
backend_api_key = os.getenv(f'{provider_name.upper()}_API_KEY')
if backend_api_key:
# API key configured via backend/environment
enhanced_info.update({
'api_key_configured': True,
'api_key_source': 'backend',
'api_key_help': f'API key configured via environment variable {provider_name.upper()}_API_KEY'
})
elif api_key:
# API key configured via web interface
enhanced_info.update({
'api_key_configured': True,
'api_key_source': 'frontend',
'api_key_help': f'API key set via web interface (session-only)'
})
else:
# No API key configured
enhanced_info.update({
'api_key_configured': False,
'api_key_source': None,
'api_key_help': f'Requires API key to enable {info["display_name"]} integration'
})
else:
# Provider doesn't require API key
enhanced_info.update({
'api_key_configured': True, # Always "configured" for non-API providers
'api_key_source': None,
'api_key_help': None
})
enhanced_provider_info[provider_name] = enhanced_info
return jsonify({ return jsonify({
'success': False, 'success': True,
'error': f'Internal server error: {str(e)}' 'providers': enhanced_provider_info,
}), 500 'user_session_id': user_session_id
})
except Exception as e:
traceback.print_exc()
return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500
@app.route('/api/config/providers', methods=['POST'])
def configure_providers():
"""Configure provider settings (enable/disable)."""
try:
data = request.get_json()
if data is None:
return jsonify({'success': False, 'error': 'No provider settings provided'}), 400
user_session_id, scanner = get_user_scanner()
session_config = scanner.config
updated_providers = []
for provider_name, settings in data.items():
provider_name_clean = provider_name.lower().strip()
if 'enabled' in settings:
# Update the enabled state in session config
session_config.enabled_providers[provider_name_clean] = settings['enabled']
updated_providers.append(provider_name_clean)
if updated_providers:
# Reinitialize providers with new settings
scanner._initialize_providers()
session_manager.update_session_scanner(user_session_id, scanner)
return jsonify({
'success': True,
'message': f'Provider settings updated for: {", ".join(updated_providers)}',
'user_session_id': user_session_id
})
else:
return jsonify({'success': False, 'error': 'No valid provider settings were provided.'}), 400
except Exception as e:
traceback.print_exc()
return jsonify({'success': False, 'error': f'Internal server error: {str(e)}'}), 500
@app.errorhandler(404) @app.errorhandler(404)
def not_found(error): def not_found(error):
"""Handle 404 errors.""" """Handle 404 errors."""
return jsonify({ return jsonify({'success': False, 'error': 'Endpoint not found'}), 404
'success': False,
'error': 'Endpoint not found'
}), 404
@app.errorhandler(500) @app.errorhandler(500)
def internal_error(error): def internal_error(error):
"""Handle 500 errors.""" """Handle 500 errors."""
print(f"ERROR: 500 Internal Server Error: {error}")
traceback.print_exc() traceback.print_exc()
return jsonify({ return jsonify({'success': False, 'error': 'Internal server error'}), 500
'success': False,
'error': 'Internal server error'
}), 500
if __name__ == '__main__': if __name__ == '__main__':
print("Starting DNSRecon Flask application with user session support...")
# Load configuration from environment
config.load_from_env() config.load_from_env()
# Start Flask application
print(f"Starting server on {config.flask_host}:{config.flask_port}")
app.run( app.run(
host=config.flask_host, host=config.flask_host,
port=config.flask_port, port=config.flask_port,

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"api.piped.mikoshi.de","first_cached":"2025-09-14T22:39:13.556737+00:00","last_upstream_query":"2025-09-15T15:40:40.243081+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":20189195635,"entry_timestamp":"2025-08-08T00:03:32.697","not_before":"2025-08-07T23:05:02","not_after":"2025-11-05T23:05:01","serial_number":"057a2344f2f0cff0a83bba587eb7326b4145","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":20189195721,"entry_timestamp":"2025-08-08T00:03:32.49","not_before":"2025-08-07T23:05:02","not_after":"2025-11-05T23:05:01","serial_number":"057a2344f2f0cff0a83bba587eb7326b4145","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":20060635277,"entry_timestamp":"2025-08-02T00:01:30.128","not_before":"2025-08-01T23:02:57","not_after":"2025-10-30T23:02:56","serial_number":"05a33355cd549118b90ec6c7219b2e283059","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":20060633958,"entry_timestamp":"2025-08-02T00:01:27.809","not_before":"2025-08-01T23:02:57","not_after":"2025-10-30T23:02:56","serial_number":"05a33355cd549118b90ec6c7219b2e283059","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":19929361217,"entry_timestamp":"2025-07-27T00:01:57.423","not_before":"2025-07-26T23:03:27","not_after":"2025-10-24T23:03:26","serial_number":"068f68538c5e6483213c6bdff93070960e6a","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":19929361084,"entry_timestamp":"2025-07-27T00:01:57.128","not_before":"2025-07-26T23:03:27","not_after":"2025-10-24T23:03:26","serial_number":"068f68538c5e6483213c6bdff93070960e6a","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":19803755935,"entry_timestamp":"2025-07-21T00:00:47.697","not_before":"2025-07-20T23:02:17","not_after":"2025-10-18T23:02:16","serial_number":"054cc0b2449a9ce1ce82324d844a1d4795f5","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":19803753732,"entry_timestamp":"2025-07-21T00:00:47.407","not_before":"2025-07-20T23:02:17","not_after":"2025-10-18T23:02:16","serial_number":"054cc0b2449a9ce1ce82324d844a1d4795f5","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":19668414027,"entry_timestamp":"2025-07-15T00:00:49.06","not_before":"2025-07-14T23:02:16","not_after":"2025-10-12T23:02:15","serial_number":"06ee7d4154b5a296e1cbefe4df2f6bfeba81","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":19668413763,"entry_timestamp":"2025-07-15T00:00:46.299","not_before":"2025-07-14T23:02:16","not_after":"2025-10-12T23:02:15","serial_number":"06ee7d4154b5a296e1cbefe4df2f6bfeba81","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":19523855233,"entry_timestamp":"2025-07-08T06:30:53.184","not_before":"2025-07-08T05:32:22","not_after":"2025-10-06T05:32:21","serial_number":"05956787611c0bc853c699866a6bc839eb89","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"api.piped.mikoshi.de","name_value":"api.piped.mikoshi.de","id":19523854846,"entry_timestamp":"2025-07-08T06:30:52.835","not_before":"2025-07-08T05:32:22","not_after":"2025-10-06T05:32:21","serial_number":"05956787611c0bc853c699866a6bc839eb89","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"app.fleischkombinat-ost.de","first_cached":"2025-09-14T21:11:17.304989+00:00","last_upstream_query":"2025-09-15T09:15:09.273000+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"app.fleischkombinat-ost.de","name_value":"app.fleischkombinat-ost.de","id":19374493240,"entry_timestamp":"2025-07-01T14:09:36.354","not_before":"2025-07-01T13:11:00","not_after":"2025-09-29T13:10:59","serial_number":"0693231ff5e3212cabc2588e38b5d8337528","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"app.fleischkombinat-ost.de","name_value":"app.fleischkombinat-ost.de","id":19374489847,"entry_timestamp":"2025-07-01T14:09:30.117","not_before":"2025-07-01T13:11:00","not_after":"2025-09-29T13:10:59","serial_number":"0693231ff5e3212cabc2588e38b5d8337528","result_count":2}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"c210lb.kasserver.com","first_cached":"2025-09-15T11:49:15.879325+00:00","last_upstream_query":"2025-09-15T11:49:15.879328+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"test.c210lb.kasserver.com","name_value":"test.c210lb.kasserver.com\nwww.test.c210lb.kasserver.com","id":16080758209,"entry_timestamp":"2024-12-12T09:28:08.296","not_before":"2024-12-12T08:29:37","not_after":"2025-03-12T08:29:36","serial_number":"04d8425c5834ecd8914f58bb80e86bcae4a4","result_count":3},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"test.c210lb.kasserver.com","name_value":"test.c210lb.kasserver.com\nwww.test.c210lb.kasserver.com","id":15724227115,"entry_timestamp":"2024-12-12T09:28:07.974","not_before":"2024-12-12T08:29:37","not_after":"2025-03-12T08:29:36","serial_number":"04d8425c5834ecd8914f58bb80e86bcae4a4","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"c214lb.kasserver.com","first_cached":"2025-09-15T11:50:40.061642+00:00","last_upstream_query":"2025-09-15T11:50:40.061644+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"test.c214lb.kasserver.com","name_value":"test.c214lb.kasserver.com\nwww.test.c214lb.kasserver.com","id":16070500096,"entry_timestamp":"2024-12-11T14:25:06.88","not_before":"2024-12-11T13:26:36","not_after":"2025-03-11T13:26:35","serial_number":"047e10af0f4b68375cc37572f400322f1339","result_count":3},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"test.c214lb.kasserver.com","name_value":"test.c214lb.kasserver.com\nwww.test.c214lb.kasserver.com","id":15713437449,"entry_timestamp":"2024-12-11T14:25:06.342","not_before":"2024-12-11T13:26:36","not_after":"2025-03-11T13:26:35","serial_number":"047e10af0f4b68375cc37572f400322f1339","result_count":3}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"cc24.mikoshi.de","first_cached":"2025-09-15T15:35:01.674879+00:00","last_upstream_query":"2025-09-15T15:35:01.674884+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":20275888640,"entry_timestamp":"2025-08-12T00:10:43.67","not_before":"2025-08-11T23:12:11","not_after":"2025-11-09T23:12:10","serial_number":"062bf40cddf77b5bb2efcc8d4394466e2f1b","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":20275882615,"entry_timestamp":"2025-08-12T00:10:41.383","not_before":"2025-08-11T23:12:11","not_after":"2025-11-09T23:12:10","serial_number":"062bf40cddf77b5bb2efcc8d4394466e2f1b","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":18987170126,"entry_timestamp":"2025-06-13T00:07:54.264","not_before":"2025-06-12T23:09:23","not_after":"2025-09-10T23:09:22","serial_number":"06146db771c214ec7474cb203b6ab75c21ae","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":18987169887,"entry_timestamp":"2025-06-13T00:07:53.982","not_before":"2025-06-12T23:09:23","not_after":"2025-09-10T23:09:22","serial_number":"06146db771c214ec7474cb203b6ab75c21ae","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":17831548102,"entry_timestamp":"2025-04-14T00:19:47.297","not_before":"2025-04-13T23:21:14","not_after":"2025-07-12T23:21:13","serial_number":"05d1504b6ed3a888b7577090d0f45a5e1f6e","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":17831584469,"entry_timestamp":"2025-04-14T00:19:45.047","not_before":"2025-04-13T23:21:14","not_after":"2025-07-12T23:21:13","serial_number":"05d1504b6ed3a888b7577090d0f45a5e1f6e","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":17170817151,"entry_timestamp":"2025-02-13T00:02:39.94","not_before":"2025-02-12T23:04:09","not_after":"2025-05-13T23:04:08","serial_number":"03b5b2d8ad135f1cf98224c917b797d0d844","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":16704121260,"entry_timestamp":"2025-02-13T00:02:39.313","not_before":"2025-02-12T23:04:09","not_after":"2025-05-13T23:04:08","serial_number":"03b5b2d8ad135f1cf98224c917b797d0d844","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":16672548148,"entry_timestamp":"2025-02-11T11:09:43.173","not_before":"2025-02-11T10:11:12","not_after":"2025-05-12T10:11:11","serial_number":"035ed55d94e5d12e255be2412e4035be70c9","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cc24.mikoshi.de","name_value":"cc24.mikoshi.de","id":16672548664,"entry_timestamp":"2025-02-11T11:09:42.207","not_before":"2025-02-11T10:11:12","not_after":"2025-05-12T10:11:11","serial_number":"035ed55d94e5d12e255be2412e4035be70c9","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"cloud.aibkurpark.de","first_cached":"2025-09-14T22:46:40.289218+00:00","last_upstream_query":"2025-09-15T15:41:52.573914+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":20275873234,"entry_timestamp":"2025-08-12T00:10:04.8","not_before":"2025-08-11T23:11:34","not_after":"2025-11-09T23:11:33","serial_number":"0502f324ff45ca5c652de0f798011836a079","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":20275861222,"entry_timestamp":"2025-08-12T00:10:04.577","not_before":"2025-08-11T23:11:34","not_after":"2025-11-09T23:11:33","serial_number":"0502f324ff45ca5c652de0f798011836a079","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":18987158394,"entry_timestamp":"2025-06-13T00:07:19.317","not_before":"2025-06-12T23:08:44","not_after":"2025-09-10T23:08:43","serial_number":"051a486ebf950f3ccc46e6da6bc68a6477cc","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":18987157465,"entry_timestamp":"2025-06-13T00:07:15.025","not_before":"2025-06-12T23:08:44","not_after":"2025-09-10T23:08:43","serial_number":"051a486ebf950f3ccc46e6da6bc68a6477cc","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":17831539356,"entry_timestamp":"2025-04-14T00:19:09.511","not_before":"2025-04-13T23:20:39","not_after":"2025-07-12T23:20:38","serial_number":"05d6f819ef2fc26e17ae6bdc186dc1f83610","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":17831579073,"entry_timestamp":"2025-04-14T00:19:09.182","not_before":"2025-04-13T23:20:39","not_after":"2025-07-12T23:20:38","serial_number":"05d6f819ef2fc26e17ae6bdc186dc1f83610","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":17170816053,"entry_timestamp":"2025-02-13T00:02:33.08","not_before":"2025-02-12T23:04:01","not_after":"2025-05-13T23:04:00","serial_number":"0457fefa87af5335359d49883ebe4b6c2f22","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":16704122042,"entry_timestamp":"2025-02-13T00:02:31.914","not_before":"2025-02-12T23:04:01","not_after":"2025-05-13T23:04:00","serial_number":"0457fefa87af5335359d49883ebe4b6c2f22","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":17122421412,"entry_timestamp":"2025-02-09T15:23:02.809","not_before":"2025-02-09T14:24:32","not_after":"2025-05-10T14:24:31","serial_number":"0338963c04daad7c5c311c00a3b6c8999e36","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":16635575756,"entry_timestamp":"2025-02-09T15:23:02.704","not_before":"2025-02-09T14:24:32","not_after":"2025-05-10T14:24:31","serial_number":"0338963c04daad7c5c311c00a3b6c8999e36","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":11633733632,"entry_timestamp":"2024-01-03T19:39:23.66","not_before":"2024-01-03T18:39:23","not_after":"2024-04-02T18:39:22","serial_number":"040656c602c0e9460d045b95c5972319d195","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":11610236633,"entry_timestamp":"2024-01-03T19:39:23.48","not_before":"2024-01-03T18:39:23","not_after":"2024-04-02T18:39:22","serial_number":"040656c602c0e9460d045b95c5972319d195","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":10998276570,"entry_timestamp":"2023-11-04T20:08:52.9","not_before":"2023-11-04T19:08:52","not_after":"2024-02-02T19:08:51","serial_number":"03d6d33fb298a3b24e240893175dc0606f11","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"cloud.aibkurpark.de","name_value":"cloud.aibkurpark.de","id":10998275332,"entry_timestamp":"2023-11-04T20:08:52.78","not_before":"2023-11-04T19:08:52","not_after":"2024-02-02T19:08:51","serial_number":"03d6d33fb298a3b24e240893175dc0606f11","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"cloud.cc24.dev","first_cached":"2025-09-14T21:36:46.109884+00:00","last_upstream_query":"2025-09-14T21:36:46.109891+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":20275852221,"entry_timestamp":"2025-08-12T00:08:47.671","not_before":"2025-08-11T23:10:16","not_after":"2025-11-09T23:10:15","serial_number":"0531b80da7039a455eb889201f8e62ba8cc9","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":20275837420,"entry_timestamp":"2025-08-12T00:08:47.014","not_before":"2025-08-11T23:10:16","not_after":"2025-11-09T23:10:15","serial_number":"0531b80da7039a455eb889201f8e62ba8cc9","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":18987132752,"entry_timestamp":"2025-06-13T00:06:00.445","not_before":"2025-06-12T23:07:30","not_after":"2025-09-10T23:07:29","serial_number":"066841f1e247045c3bb244d599955addbc66","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":18987133145,"entry_timestamp":"2025-06-13T00:06:00.158","not_before":"2025-06-12T23:07:30","not_after":"2025-09-10T23:07:29","serial_number":"066841f1e247045c3bb244d599955addbc66","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":17831462233,"entry_timestamp":"2025-04-14T00:17:56.109","not_before":"2025-04-13T23:19:24","not_after":"2025-07-12T23:19:23","serial_number":"051efd08e5e21db1fe47698ba7cb273c05b7","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":17831396685,"entry_timestamp":"2025-04-14T00:17:54.708","not_before":"2025-04-13T23:19:24","not_after":"2025-07-12T23:19:23","serial_number":"051efd08e5e21db1fe47698ba7cb273c05b7","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":17170810540,"entry_timestamp":"2025-02-13T00:02:07.841","not_before":"2025-02-12T23:03:37","not_after":"2025-05-13T23:03:36","serial_number":"03fe022033cd38b75215385397375a1a3741","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":16704105434,"entry_timestamp":"2025-02-13T00:02:07.708","not_before":"2025-02-12T23:03:37","not_after":"2025-05-13T23:03:36","serial_number":"03fe022033cd38b75215385397375a1a3741","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":17122390503,"entry_timestamp":"2025-02-09T15:21:20.386","not_before":"2025-02-09T14:22:49","not_after":"2025-05-10T14:22:48","serial_number":"031fcf4e1368ddbc276836806c2d3df6c376","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"cloud.cc24.dev","name_value":"cloud.cc24.dev","id":16635540435,"entry_timestamp":"2025-02-09T15:21:19.831","not_before":"2025-02-09T14:22:49","not_after":"2025-05-10T14:22:48","serial_number":"031fcf4e1368ddbc276836806c2d3df6c376","result_count":2}]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"console.s3.cc24.dev","first_cached":"2025-09-14T21:33:25.149502+00:00","last_upstream_query":"2025-09-14T21:33:25.149505+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"console.s3.cc24.dev","name_value":"console.s3.cc24.dev","id":20287575466,"entry_timestamp":"2025-08-12T12:55:37.077","not_before":"2025-08-12T11:57:05","not_after":"2025-11-10T11:57:04","serial_number":"066bdfa83088f8d7e67284da94dd5d122ed6","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"console.s3.cc24.dev","name_value":"console.s3.cc24.dev","id":20287575457,"entry_timestamp":"2025-08-12T12:55:36.75","not_before":"2025-08-12T11:57:05","not_after":"2025-11-10T11:57:04","serial_number":"066bdfa83088f8d7e67284da94dd5d122ed6","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"coturn.mikoshi.de","first_cached":"2025-09-14T22:37:33.747891+00:00","last_upstream_query":"2025-09-15T15:40:16.119867+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"coturn.mikoshi.de","name_value":"coturn.mikoshi.de","id":19208664152,"entry_timestamp":"2025-06-23T18:46:24.952","not_before":"2025-06-23T17:47:50","not_after":"2025-09-21T17:47:49","serial_number":"06d2bfd2d049388cf81d75548de9029700a8","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"coturn.mikoshi.de","name_value":"coturn.mikoshi.de","id":19208662980,"entry_timestamp":"2025-06-23T18:46:20.96","not_before":"2025-06-23T17:47:50","not_after":"2025-09-21T17:47:49","serial_number":"06d2bfd2d049388cf81d75548de9029700a8","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"coturn.mikoshi.de","name_value":"coturn.mikoshi.de","id":17345025382,"entry_timestamp":"2025-03-23T14:41:31.643","not_before":"2025-03-23T13:43:01","not_after":"2025-06-21T13:43:00","serial_number":"06245dcee4d40047ccbe0b4eac028e25edbe","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"coturn.mikoshi.de","name_value":"coturn.mikoshi.de","id":17345311273,"entry_timestamp":"2025-03-23T14:41:31.261","not_before":"2025-03-23T13:43:01","not_after":"2025-06-21T13:43:00","serial_number":"06245dcee4d40047ccbe0b4eac028e25edbe","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"coturn.ms-it-services.de","first_cached":"2025-09-14T21:03:44.169328+00:00","last_upstream_query":"2025-09-15T19:08:39.390556+00:00","upstream_query_count":3,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"coturn.ms-it-services.de","name_value":"coturn.ms-it-services.de","id":14781803935,"entry_timestamp":"2024-10-03T09:53:12.473","not_before":"2024-10-03T08:54:42","not_after":"2025-01-01T08:54:41","serial_number":"0395c04e522a2715eebcb7fc4ffb3da1fdba","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"coturn.ms-it-services.de","name_value":"coturn.ms-it-services.de","id":14781794097,"entry_timestamp":"2024-10-03T09:53:12.142","not_before":"2024-10-03T08:54:42","not_after":"2025-01-01T08:54:41","serial_number":"0395c04e522a2715eebcb7fc4ffb3da1fdba","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"coturn.ms-it-services.de","name_value":"coturn.ms-it-services.de","id":14773518990,"entry_timestamp":"2024-10-02T19:20:49.687","not_before":"2024-10-02T18:22:19","not_after":"2024-12-31T18:22:18","serial_number":"04f26242ac1b2ac659ac2e19ae2522ce3274","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"coturn.ms-it-services.de","name_value":"coturn.ms-it-services.de","id":14773501988,"entry_timestamp":"2024-10-02T19:20:49.356","not_before":"2024-10-02T18:22:19","not_after":"2024-12-31T18:22:18","serial_number":"04f26242ac1b2ac659ac2e19ae2522ce3274","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"dd10032.kasserver.com","first_cached":"2025-09-15T11:49:39.835993+00:00","last_upstream_query":"2025-09-15T11:49:39.835996+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"wernertest.dd10032.kasserver.com","name_value":"wernertest.dd10032.kasserver.com\nwww.wernertest.dd10032.kasserver.com","id":19900983152,"entry_timestamp":"2025-07-25T15:08:27.328","not_before":"2025-07-25T14:09:55","not_after":"2025-10-23T14:09:54","serial_number":"053bbb3a5a38ad78a0298a2d7de184471db7","result_count":3},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"wernertest.dd10032.kasserver.com","name_value":"wernertest.dd10032.kasserver.com\nwww.wernertest.dd10032.kasserver.com","id":19900983133,"entry_timestamp":"2025-07-25T15:08:25.843","not_before":"2025-07-25T14:09:55","not_after":"2025-10-23T14:09:54","serial_number":"053bbb3a5a38ad78a0298a2d7de184471db7","result_count":3},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"wernertest.dd10032.kasserver.com","name_value":"wernertest.dd10032.kasserver.com\nwww.wernertest.dd10032.kasserver.com","id":18625008970,"entry_timestamp":"2025-05-26T02:06:09.384","not_before":"2025-05-26T01:07:39","not_after":"2025-08-24T01:07:38","serial_number":"05b1920c57feb37d80ab28e0a745fd4e5711","result_count":3},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"wernertest.dd10032.kasserver.com","name_value":"wernertest.dd10032.kasserver.com\nwww.wernertest.dd10032.kasserver.com","id":18625008687,"entry_timestamp":"2025-05-26T02:06:09.149","not_before":"2025-05-26T01:07:39","not_after":"2025-08-24T01:07:38","serial_number":"05b1920c57feb37d80ab28e0a745fd4e5711","result_count":3},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"wernertest.dd10032.kasserver.com","name_value":"wernertest.dd10032.kasserver.com\nwww.wernertest.dd10032.kasserver.com","id":17676635727,"entry_timestamp":"2025-03-18T15:24:41.197","not_before":"2025-03-18T14:26:10","not_after":"2025-06-16T14:26:09","serial_number":"05f4a3810f24e3916e04d2b092c864e92b04","result_count":3},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"wernertest.dd10032.kasserver.com","name_value":"wernertest.dd10032.kasserver.com\nwww.wernertest.dd10032.kasserver.com","id":17214728959,"entry_timestamp":"2025-03-18T15:24:40.996","not_before":"2025-03-18T14:26:10","not_after":"2025-06-16T14:26:09","serial_number":"05f4a3810f24e3916e04d2b092c864e92b04","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd15000.kasserver.com","first_cached":"2025-09-15T11:49:51.832307+00:00","last_upstream_query":"2025-09-15T11:49:51.832313+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"litera.dd15000.kasserver.com","name_value":"litera.dd15000.kasserver.com\nwww.litera.dd15000.kasserver.com","id":17806830,"entry_timestamp":"2016-05-03T09:27:49.724","not_before":"2016-05-03T08:28:00","not_after":"2016-08-01T08:28:00","serial_number":"030cb7992941a2b2860858446a989170f2db","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd17120.kasserver.com","first_cached":"2025-09-15T11:50:52.134823+00:00","last_upstream_query":"2025-09-15T11:50:52.134826+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"letest.dd17120.kasserver.com","name_value":"letest.dd17120.kasserver.com\nwww.letest.dd17120.kasserver.com","id":3820560694,"entry_timestamp":"2020-12-23T15:35:32.403","not_before":"2020-12-23T14:35:32","not_after":"2021-03-23T14:35:32","serial_number":"04c92961dbb2d095ce5690f41ab75431abed","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"letest.dd17120.kasserver.com","name_value":"letest.dd17120.kasserver.com\nwww.letest.dd17120.kasserver.com","id":3820561611,"entry_timestamp":"2020-12-23T15:35:32.275","not_before":"2020-12-23T14:35:32","not_after":"2021-03-23T14:35:32","serial_number":"04c92961dbb2d095ce5690f41ab75431abed","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"letest.dd17120.kasserver.com","name_value":"letest.dd17120.kasserver.com\nwww.letest.dd17120.kasserver.com","id":3820541026,"entry_timestamp":"2020-12-23T15:29:20.032","not_before":"2020-12-23T14:29:19","not_after":"2021-03-23T14:29:19","serial_number":"03446bb8f1a87b4f0cb40fd1030125240eed","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"letest.dd17120.kasserver.com","name_value":"letest.dd17120.kasserver.com\nwww.letest.dd17120.kasserver.com","id":3820541140,"entry_timestamp":"2020-12-23T15:29:19.847","not_before":"2020-12-23T14:29:19","not_after":"2021-03-23T14:29:19","serial_number":"03446bb8f1a87b4f0cb40fd1030125240eed","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"letest.dd17120.kasserver.com","name_value":"letest.dd17120.kasserver.com\nwww.letest.dd17120.kasserver.com","id":3820538580,"entry_timestamp":"2020-12-23T15:28:46.532","not_before":"2020-12-23T14:28:46","not_after":"2021-03-23T14:28:46","serial_number":"03c3eb90d764b2c2a0ac04beed2e876f03e1","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"letest.dd17120.kasserver.com","name_value":"letest.dd17120.kasserver.com\nwww.letest.dd17120.kasserver.com","id":3820538531,"entry_timestamp":"2020-12-23T15:28:46.312","not_before":"2020-12-23T14:28:46","not_after":"2021-03-23T14:28:46","serial_number":"03c3eb90d764b2c2a0ac04beed2e876f03e1","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"letest.dd17120.kasserver.com","name_value":"letest.dd17120.kasserver.com\nwww.letest.dd17120.kasserver.com","id":3820537101,"entry_timestamp":"2020-12-23T15:28:12.742","not_before":"2020-12-23T14:28:12","not_after":"2021-03-23T14:28:12","serial_number":"034cd7432ae3dba0e76509de60666d58f1e4","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"letest.dd17120.kasserver.com","name_value":"letest.dd17120.kasserver.com\nwww.letest.dd17120.kasserver.com","id":3820537306,"entry_timestamp":"2020-12-23T15:28:12.459","not_before":"2020-12-23T14:28:12","not_after":"2021-03-23T14:28:12","serial_number":"034cd7432ae3dba0e76509de60666d58f1e4","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd18904.kasserver.com","first_cached":"2025-09-15T11:49:03.689534+00:00","last_upstream_query":"2025-09-15T11:49:03.689540+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"thomas.dd18904.kasserver.com","name_value":"thomas.dd18904.kasserver.com\nwww.thomas.dd18904.kasserver.com","id":6766495494,"entry_timestamp":"2022-05-20T07:44:34.589","not_before":"2022-05-20T06:44:34","not_after":"2022-08-18T06:44:33","serial_number":"046fc2606fb3d5e6438be8586ff20e296e8e","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"thomas.dd18904.kasserver.com","name_value":"thomas.dd18904.kasserver.com\nwww.thomas.dd18904.kasserver.com","id":6766489032,"entry_timestamp":"2022-05-20T07:44:34.335","not_before":"2022-05-20T06:44:34","not_after":"2022-08-18T06:44:33","serial_number":"046fc2606fb3d5e6438be8586ff20e296e8e","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"thomas.dd18904.kasserver.com","name_value":"thomas.dd18904.kasserver.com\nwww.thomas.dd18904.kasserver.com","id":6766485621,"entry_timestamp":"2022-05-20T07:42:24.52","not_before":"2022-05-20T06:42:24","not_after":"2022-08-18T06:42:23","serial_number":"03a52deebc041d7b6b4246ec8fc0455345a8","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"thomas.dd18904.kasserver.com","name_value":"thomas.dd18904.kasserver.com\nwww.thomas.dd18904.kasserver.com","id":6766485609,"entry_timestamp":"2022-05-20T07:42:24.413","not_before":"2022-05-20T06:42:24","not_after":"2022-08-18T06:42:23","serial_number":"03a52deebc041d7b6b4246ec8fc0455345a8","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd19536.kasserver.com","first_cached":"2025-09-15T11:47:57.902219+00:00","last_upstream_query":"2025-09-15T11:47:57.902224+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"login.jitsi.dd19536.kasserver.com","name_value":"login.jitsi.dd19536.kasserver.com\nwww.login.jitsi.dd19536.kasserver.com","id":14154546767,"entry_timestamp":"2024-08-12T05:52:06.917","not_before":"2024-08-12T04:53:36","not_after":"2024-11-10T04:53:35","serial_number":"04fca7ec58a44a09702875c5d2c6c9d6401b","result_count":3},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"login.jitsi.dd19536.kasserver.com","name_value":"login.jitsi.dd19536.kasserver.com\nwww.login.jitsi.dd19536.kasserver.com","id":14108590090,"entry_timestamp":"2024-08-12T05:52:06.531","not_before":"2024-08-12T04:53:36","not_after":"2024-11-10T04:53:35","serial_number":"04fca7ec58a44a09702875c5d2c6c9d6401b","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd24432.kasserver.com","first_cached":"2025-09-15T11:51:28.290098+00:00","last_upstream_query":"2025-09-15T11:51:28.290102+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"test1.dd24432.kasserver.com","name_value":"test1.dd24432.kasserver.com\nwww.test1.dd24432.kasserver.com","id":157863863,"entry_timestamp":"2017-06-20T11:17:00.314","not_before":"2017-06-20T10:17:00","not_after":"2017-09-18T10:17:00","serial_number":"03c833715204594e6946b183652f0be2055e","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd27030.kasserver.com","first_cached":"2025-09-15T11:48:39.556778+00:00","last_upstream_query":"2025-09-15T11:48:39.556783+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"wernertest.dd27030.kasserver.com","name_value":"wernertest.dd27030.kasserver.com\nwww.wernertest.dd27030.kasserver.com","id":17324952949,"entry_timestamp":"2025-03-19T12:30:16.583","not_before":"2025-03-19T11:31:44","not_after":"2025-06-17T11:31:43","serial_number":"0686091c483d6c1a55f241d41c29523fc3f0","result_count":3},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"wernertest.dd27030.kasserver.com","name_value":"wernertest.dd27030.kasserver.com\nwww.wernertest.dd27030.kasserver.com","id":17314228622,"entry_timestamp":"2025-03-19T12:30:14.317","not_before":"2025-03-19T11:31:44","not_after":"2025-06-17T11:31:43","serial_number":"0686091c483d6c1a55f241d41c29523fc3f0","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd27120.kasserver.com","first_cached":"2025-09-15T11:47:51.800693+00:00","last_upstream_query":"2025-09-15T11:47:51.800697+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"otrs2.dd27120.kasserver.com","name_value":"otrs2.dd27120.kasserver.com\nwww.otrs2.dd27120.kasserver.com","id":1476617768,"entry_timestamp":"2019-05-09T10:40:20.848","not_before":"2019-05-09T09:40:19","not_after":"2019-08-07T09:40:19","serial_number":"0342616d062ef6933a703e4de279da4e38b6","result_count":3},{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"otrs2.dd27120.kasserver.com","name_value":"otrs2.dd27120.kasserver.com\nwww.otrs2.dd27120.kasserver.com","id":1458597695,"entry_timestamp":"2019-05-09T10:40:20.006","not_before":"2019-05-09T09:40:19","not_after":"2019-08-07T09:40:19","serial_number":"0342616d062ef6933a703e4de279da4e38b6","result_count":3},{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"otrs2.dd27120.kasserver.com","name_value":"otrs2.dd27120.kasserver.com\nwww.otrs2.dd27120.kasserver.com","id":1476589088,"entry_timestamp":"2019-05-09T10:17:27.514","not_before":"2019-05-09T09:17:26","not_after":"2019-08-07T09:17:26","serial_number":"0398319827847d1df54260d7273cd5ea6d5c","result_count":3},{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"otrs2.dd27120.kasserver.com","name_value":"otrs2.dd27120.kasserver.com\nwww.otrs2.dd27120.kasserver.com","id":1457806572,"entry_timestamp":"2019-05-09T10:17:26.68","not_before":"2019-05-09T09:17:26","not_after":"2019-08-07T09:17:26","serial_number":"0398319827847d1df54260d7273cd5ea6d5c","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd27932.kasserver.com","first_cached":"2025-09-15T11:48:51.718464+00:00","last_upstream_query":"2025-09-15T11:48:51.718468+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"switest.dd27932.kasserver.com","name_value":"switest.dd27932.kasserver.com\nwww.switest.dd27932.kasserver.com","id":99317583,"entry_timestamp":"2017-03-05T01:00:32.21","not_before":"2017-03-05T00:01:00","not_after":"2017-06-03T00:01:00","serial_number":"03e0f1fb8ff2a8a742ee45c2da39e4bd68ed","result_count":3},{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"switest.dd27932.kasserver.com","name_value":"switest.dd27932.kasserver.com\nwww.switest.dd27932.kasserver.com","id":69451932,"entry_timestamp":"2016-12-21T10:01:06.051","not_before":"2016-12-21T09:01:00","not_after":"2017-03-21T09:01:00","serial_number":"03a4f79d5ed3c6661f6f2c430a1a1546e0d8","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd28826.kasserver.com","first_cached":"2025-09-15T11:50:28.011163+00:00","last_upstream_query":"2025-09-15T11:50:28.011167+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"161gs86116.dd28826.kasserver.com","name_value":"161gs86116.dd28826.kasserver.com\nwww.161gs86116.dd28826.kasserver.com","id":138535930,"entry_timestamp":"2017-05-15T11:15:13.509","not_before":"2017-05-15T10:15:00","not_after":"2017-08-13T10:15:00","serial_number":"03bca24f2de29889f514c04523a1f8945136","result_count":3},{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"161gs86116.dd28826.kasserver.com","name_value":"161gs86116.dd28826.kasserver.com\nwww.161gs86116.dd28826.kasserver.com","id":40903630,"entry_timestamp":"2016-10-07T12:00:36.009","not_before":"2016-10-07T11:01:00","not_after":"2017-01-05T11:01:00","serial_number":"0385d74f0a39572de61c2b7765c94d848c82","result_count":3},{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"161gs86116.dd28826.kasserver.com","name_value":"161gs86116.dd28826.kasserver.com\nwww.161gs86116.dd28826.kasserver.com","id":40901166,"entry_timestamp":"2016-10-07T11:54:34.702","not_before":"2016-10-07T10:55:00","not_after":"2017-01-05T10:55:00","serial_number":"039ef12598cb7aaf33c04d4c90983b0829fe","result_count":3}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"dd39314.kasserver.com","first_cached":"2025-09-15T11:47:59.899335+00:00","last_upstream_query":"2025-09-15T11:47:59.899339+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"http2.dd39314.kasserver.com","name_value":"http2.dd39314.kasserver.com\nwww.http2.dd39314.kasserver.com","id":35834556,"entry_timestamp":"2016-09-27T11:27:08.538","not_before":"2016-09-27T10:27:00","not_after":"2016-12-26T10:27:00","serial_number":"03024be246b9452e3e5e7dbed7e502a1ee16","result_count":3}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"dd44624.kasserver.com","first_cached":"2025-09-15T11:50:16.030946+00:00","last_upstream_query":"2025-09-15T11:50:16.030952+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"aitest.dd44624.kasserver.com","name_value":"aitest.dd44624.kasserver.com\nwww.aitest.dd44624.kasserver.com","id":2366400329,"entry_timestamp":"2020-01-21T09:28:49.996","not_before":"2020-01-21T08:28:49","not_after":"2020-04-20T08:28:49","serial_number":"0319ee129ecf09b2a08a98d6cd7d92062efe","result_count":3},{"issuer_ca_id":16418,"issuer_name":"C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3","common_name":"aitest.dd44624.kasserver.com","name_value":"aitest.dd44624.kasserver.com\nwww.aitest.dd44624.kasserver.com","id":2355073809,"entry_timestamp":"2020-01-21T09:28:49.389","not_before":"2020-01-21T08:28:49","not_after":"2020-04-20T08:28:49","serial_number":"0319ee129ecf09b2a08a98d6cd7d92062efe","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd46900.kasserver.com","first_cached":"2025-09-15T11:49:27.811675+00:00","last_upstream_query":"2025-09-15T11:49:27.811679+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"wernertest.dd46900.kasserver.com","name_value":"wernertest.dd46900.kasserver.com\nwww.wernertest.dd46900.kasserver.com","id":19891708696,"entry_timestamp":"2025-07-25T04:48:43.91","not_before":"2025-07-25T03:50:12","not_after":"2025-10-23T03:50:11","serial_number":"06ab9c27b7c779ee95cb82b66f985d87601c","result_count":3},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"wernertest.dd46900.kasserver.com","name_value":"wernertest.dd46900.kasserver.com\nwww.wernertest.dd46900.kasserver.com","id":19891706706,"entry_timestamp":"2025-07-25T04:48:42.387","not_before":"2025-07-25T03:50:12","not_after":"2025-10-23T03:50:11","serial_number":"06ab9c27b7c779ee95cb82b66f985d87601c","result_count":3},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"wernertest.dd46900.kasserver.com","name_value":"wernertest.dd46900.kasserver.com\nwww.wernertest.dd46900.kasserver.com","id":18618700336,"entry_timestamp":"2025-05-25T17:22:29.664","not_before":"2025-05-25T16:23:59","not_after":"2025-08-23T16:23:58","serial_number":"05abb39369b76694a079e1109a93e616bf18","result_count":3},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"wernertest.dd46900.kasserver.com","name_value":"wernertest.dd46900.kasserver.com\nwww.wernertest.dd46900.kasserver.com","id":18618704556,"entry_timestamp":"2025-05-25T17:22:29.449","not_before":"2025-05-25T16:23:59","not_after":"2025-08-23T16:23:58","serial_number":"05abb39369b76694a079e1109a93e616bf18","result_count":3},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"wernertest.dd46900.kasserver.com","name_value":"wernertest.dd46900.kasserver.com\nwww.wernertest.dd46900.kasserver.com","id":17676537327,"entry_timestamp":"2025-03-18T15:18:10.621","not_before":"2025-03-18T14:19:39","not_after":"2025-06-16T14:19:38","serial_number":"0610cb215ef16b2619af24f76349e349939c","result_count":3},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"wernertest.dd46900.kasserver.com","name_value":"wernertest.dd46900.kasserver.com\nwww.wernertest.dd46900.kasserver.com","id":17230420365,"entry_timestamp":"2025-03-18T15:18:09.941","not_before":"2025-03-18T14:19:39","not_after":"2025-06-16T14:19:38","serial_number":"0610cb215ef16b2619af24f76349e349939c","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"dd55600.kasserver.com","first_cached":"2025-09-15T11:47:55.878914+00:00","last_upstream_query":"2025-09-15T11:47:55.878918+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"letest.dd55600.kasserver.com","name_value":"letest.dd55600.kasserver.com\nwww.letest.dd55600.kasserver.com","id":20031222371,"entry_timestamp":"2025-07-31T13:43:52.442","not_before":"2025-07-31T12:45:20","not_after":"2025-10-29T12:45:19","serial_number":"06eb0a6229e52eabee01d67ad7a999665794","result_count":3},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"letest.dd55600.kasserver.com","name_value":"letest.dd55600.kasserver.com\nwww.letest.dd55600.kasserver.com","id":20031228125,"entry_timestamp":"2025-07-31T13:43:50.126","not_before":"2025-07-31T12:45:20","not_after":"2025-10-29T12:45:19","serial_number":"06eb0a6229e52eabee01d67ad7a999665794","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"deck0.mikoshi.de","first_cached":"2025-09-15T15:38:47.110406+00:00","last_upstream_query":"2025-09-15T15:38:47.110410+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":20275849021,"entry_timestamp":"2025-08-12T00:08:09.613","not_before":"2025-08-11T23:09:39","not_after":"2025-11-09T23:09:38","serial_number":"05785ec3742887857667078bfa75b21eda78","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":20275847401,"entry_timestamp":"2025-08-12T00:08:09.412","not_before":"2025-08-11T23:09:39","not_after":"2025-11-09T23:09:38","serial_number":"05785ec3742887857667078bfa75b21eda78","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":18987122782,"entry_timestamp":"2025-06-13T00:05:25.356","not_before":"2025-06-12T23:06:50","not_after":"2025-09-10T23:06:49","serial_number":"051c77c6054cfd6720e600ff7f5a9a42b40f","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":18987120711,"entry_timestamp":"2025-06-13T00:05:21.025","not_before":"2025-06-12T23:06:50","not_after":"2025-09-10T23:06:49","serial_number":"051c77c6054cfd6720e600ff7f5a9a42b40f","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":17831463793,"entry_timestamp":"2025-04-14T00:17:17.936","not_before":"2025-04-13T23:18:47","not_after":"2025-07-12T23:18:46","serial_number":"0652fad83eb95b52eb2a47457872b0408fef","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":17831393060,"entry_timestamp":"2025-04-14T00:17:17.692","not_before":"2025-04-13T23:18:47","not_after":"2025-07-12T23:18:46","serial_number":"0652fad83eb95b52eb2a47457872b0408fef","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":16704809501,"entry_timestamp":"2025-02-13T00:02:01.475","not_before":"2025-02-12T23:03:29","not_after":"2025-05-13T23:03:28","serial_number":"03336511cc977e31ed4534ee782a8b856e03","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":16704111156,"entry_timestamp":"2025-02-13T00:01:59.346","not_before":"2025-02-12T23:03:29","not_after":"2025-05-13T23:03:28","serial_number":"03336511cc977e31ed4534ee782a8b856e03","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":17122385653,"entry_timestamp":"2025-02-09T15:20:45.345","not_before":"2025-02-09T14:22:14","not_after":"2025-05-10T14:22:13","serial_number":"04b3ee603f5f877a0acbb32ff5e68570fc4e","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck0.mikoshi.de","name_value":"deck0.mikoshi.de","id":16636455622,"entry_timestamp":"2025-02-09T15:20:45.058","not_before":"2025-02-09T14:22:14","not_after":"2025-05-10T14:22:13","serial_number":"04b3ee603f5f877a0acbb32ff5e68570fc4e","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"deck.mikoshi.de","first_cached":"2025-09-15T15:37:15.209223+00:00","last_upstream_query":"2025-09-15T15:37:15.209226+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":20296619407,"entry_timestamp":"2025-08-13T00:04:28.809","not_before":"2025-08-12T23:05:56","not_after":"2025-11-10T23:05:55","serial_number":"068288286ab2af41b51f2a6f0e4c6d6343ed","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":20296618002,"entry_timestamp":"2025-08-13T00:04:26.633","not_before":"2025-08-12T23:05:56","not_after":"2025-11-10T23:05:55","serial_number":"068288286ab2af41b51f2a6f0e4c6d6343ed","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":19007501639,"entry_timestamp":"2025-06-14T00:02:02.957","not_before":"2025-06-13T23:03:32","not_after":"2025-09-11T23:03:31","serial_number":"065d212df70f76cc2d2e5fb1cd3372785d45","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":19007529630,"entry_timestamp":"2025-06-14T00:02:02.71","not_before":"2025-06-13T23:03:32","not_after":"2025-09-11T23:03:31","serial_number":"065d212df70f76cc2d2e5fb1cd3372785d45","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":17831396750,"entry_timestamp":"2025-04-14T00:16:41.797","not_before":"2025-04-13T23:18:10","not_after":"2025-07-12T23:18:09","serial_number":"063db5541056907cd7d1a6dd6b90337970cf","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":17831377445,"entry_timestamp":"2025-04-14T00:16:41.02","not_before":"2025-04-13T23:18:10","not_after":"2025-07-12T23:18:09","serial_number":"063db5541056907cd7d1a6dd6b90337970cf","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":16704809458,"entry_timestamp":"2025-02-13T00:01:53.117","not_before":"2025-02-12T23:03:22","not_after":"2025-05-13T23:03:21","serial_number":"04dd85a6d9cafec66b0b7ca3753191d347fa","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":16704110323,"entry_timestamp":"2025-02-13T00:01:52.905","not_before":"2025-02-12T23:03:22","not_after":"2025-05-13T23:03:21","serial_number":"04dd85a6d9cafec66b0b7ca3753191d347fa","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":16636696795,"entry_timestamp":"2025-02-09T15:20:11.318","not_before":"2025-02-09T14:21:40","not_after":"2025-05-10T14:21:39","serial_number":"043f12b3e0be22dd52133924bbb5c1ded954","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"deck.mikoshi.de","name_value":"deck.mikoshi.de","id":16635534286,"entry_timestamp":"2025-02-09T15:20:10.545","not_before":"2025-02-09T14:21:40","not_after":"2025-05-10T14:21:39","serial_number":"043f12b3e0be22dd52133924bbb5c1ded954","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"dev.mikoshi.de","first_cached":"2025-09-15T15:39:15.810886+00:00","last_upstream_query":"2025-09-15T15:39:15.810888+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":20275786291,"entry_timestamp":"2025-08-12T00:05:23.212","not_before":"2025-08-11T23:06:52","not_after":"2025-11-09T23:06:51","serial_number":"062b3368dce240f65370e3fcf5b868f3cb16","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":20275788995,"entry_timestamp":"2025-08-12T00:05:22.899","not_before":"2025-08-11T23:06:52","not_after":"2025-11-09T23:06:51","serial_number":"062b3368dce240f65370e3fcf5b868f3cb16","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":18987037224,"entry_timestamp":"2025-06-13T00:03:00.049","not_before":"2025-06-12T23:04:25","not_after":"2025-09-10T23:04:24","serial_number":"05dac28fc29cc4ffa07ebb5d652b5d3c220d","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":18987083431,"entry_timestamp":"2025-06-13T00:02:56.025","not_before":"2025-06-12T23:04:25","not_after":"2025-09-10T23:04:24","serial_number":"05dac28fc29cc4ffa07ebb5d652b5d3c220d","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":17831380009,"entry_timestamp":"2025-04-14T00:13:37.609","not_before":"2025-04-13T23:15:06","not_after":"2025-07-12T23:15:05","serial_number":"05acf9ab2ed9a117ef386d05d6cfae3ed258","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":17831368386,"entry_timestamp":"2025-04-14T00:13:36.704","not_before":"2025-04-13T23:15:06","not_after":"2025-07-12T23:15:05","serial_number":"05acf9ab2ed9a117ef386d05d6cfae3ed258","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":17170799512,"entry_timestamp":"2025-02-13T00:01:03.867","not_before":"2025-02-12T23:02:33","not_after":"2025-05-13T23:02:32","serial_number":"04324a24cab88153022dd4a82cd03a1d5bec","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":16705238915,"entry_timestamp":"2025-02-13T00:01:03.58","not_before":"2025-02-12T23:02:33","not_after":"2025-05-13T23:02:32","serial_number":"04324a24cab88153022dd4a82cd03a1d5bec","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":16635493913,"entry_timestamp":"2025-02-09T15:16:09.908","not_before":"2025-02-09T14:17:39","not_after":"2025-05-10T14:17:38","serial_number":"03567895f69539097a4621b1b2f68c04f75c","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"dev.mikoshi.de","name_value":"dev.mikoshi.de","id":16635494768,"entry_timestamp":"2025-02-09T15:16:09.457","not_before":"2025-02-09T14:17:39","not_after":"2025-05-10T14:17:38","serial_number":"03567895f69539097a4621b1b2f68c04f75c","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"dnsrecon.cc24.dev","first_cached":"2025-09-14T21:33:58.773156+00:00","last_upstream_query":"2025-09-14T21:33:58.773159+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295809,"issuer_name":"C=US, O=Let's Encrypt, CN=E8","common_name":"dnsrecon.cc24.dev","name_value":"dnsrecon.cc24.dev","id":20965278266,"entry_timestamp":"2025-09-12T09:49:23.247","not_before":"2025-09-12T08:50:53","not_after":"2025-12-11T08:50:52","serial_number":"060fbe619a364febd85aebccb1c6fcf7153f","result_count":2},{"issuer_ca_id":295809,"issuer_name":"C=US, O=Let's Encrypt, CN=E8","common_name":"dnsrecon.cc24.dev","name_value":"dnsrecon.cc24.dev","id":20965277886,"entry_timestamp":"2025-09-12T09:49:23.039","not_before":"2025-09-12T08:50:53","not_after":"2025-12-11T08:50:52","serial_number":"060fbe619a364febd85aebccb1c6fcf7153f","result_count":2}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"electrum.mikoshi.de","first_cached":"2025-09-15T15:35:50.844792+00:00","last_upstream_query":"2025-09-15T15:35:50.844796+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":20275738086,"entry_timestamp":"2025-08-12T00:01:00.455","not_before":"2025-08-11T23:02:29","not_after":"2025-11-09T23:02:28","serial_number":"0607acd92d2e4ed2c21a0fd8879b4fcc1da6","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":20275720683,"entry_timestamp":"2025-08-12T00:01:00.121","not_before":"2025-08-11T23:02:29","not_after":"2025-11-09T23:02:28","serial_number":"0607acd92d2e4ed2c21a0fd8879b4fcc1da6","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":18987049091,"entry_timestamp":"2025-06-13T00:00:34.9","not_before":"2025-06-12T23:02:04","not_after":"2025-09-10T23:02:03","serial_number":"05b5b53d270451a0c1287c9aad800bf21a5b","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":18987049255,"entry_timestamp":"2025-06-13T00:00:34.45","not_before":"2025-06-12T23:02:04","not_after":"2025-09-10T23:02:03","serial_number":"05b5b53d270451a0c1287c9aad800bf21a5b","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":17831223577,"entry_timestamp":"2025-04-14T00:03:09.379","not_before":"2025-04-13T23:04:37","not_after":"2025-07-12T23:04:36","serial_number":"06f83ec1efdf5ec3387c8f241234448b1618","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":17831306766,"entry_timestamp":"2025-04-14T00:03:07.489","not_before":"2025-04-13T23:04:37","not_after":"2025-07-12T23:04:36","serial_number":"06f83ec1efdf5ec3387c8f241234448b1618","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":17170790341,"entry_timestamp":"2025-02-13T00:00:15.841","not_before":"2025-02-12T23:01:45","not_after":"2025-05-13T23:01:44","serial_number":"0400d022ec8e2ded90606b9276eef71a1664","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":16704088726,"entry_timestamp":"2025-02-13T00:00:15.527","not_before":"2025-02-12T23:01:45","not_after":"2025-05-13T23:01:44","serial_number":"0400d022ec8e2ded90606b9276eef71a1664","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":16635426761,"entry_timestamp":"2025-02-09T15:12:05.797","not_before":"2025-02-09T14:13:35","not_after":"2025-05-10T14:13:34","serial_number":"045de320229498cb69676d307ec9467fa83e","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"electrum.mikoshi.de","name_value":"electrum.mikoshi.de","id":16635425561,"entry_timestamp":"2025-02-09T15:12:05.539","not_before":"2025-02-09T14:13:35","not_after":"2025-05-10T14:13:34","serial_number":"045de320229498cb69676d307ec9467fa83e","result_count":2}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"fleischkombinat-ost.de","first_cached":"2025-09-14T21:11:00.028593+00:00","last_upstream_query":"2025-09-15T09:15:04.796648+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"app.fleischkombinat-ost.de","name_value":"app.fleischkombinat-ost.de","id":19374493240,"entry_timestamp":"2025-07-01T14:09:36.354","not_before":"2025-07-01T13:11:00","not_after":"2025-09-29T13:10:59","serial_number":"0693231ff5e3212cabc2588e38b5d8337528","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"app.fleischkombinat-ost.de","name_value":"app.fleischkombinat-ost.de","id":19374489847,"entry_timestamp":"2025-07-01T14:09:30.117","not_before":"2025-07-01T13:11:00","not_after":"2025-09-29T13:10:59","serial_number":"0693231ff5e3212cabc2588e38b5d8337528","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"fleischkombinat-ost.de","name_value":"fleischkombinat-ost.de","id":19374378473,"entry_timestamp":"2025-07-01T14:01:50.593","not_before":"2025-07-01T13:03:20","not_after":"2025-09-29T13:03:19","serial_number":"06315dfed8c93d1497c26b21c448857b6f2c","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"fleischkombinat-ost.de","name_value":"fleischkombinat-ost.de","id":19374376791,"entry_timestamp":"2025-07-01T14:01:50.385","not_before":"2025-07-01T13:03:20","not_after":"2025-09-29T13:03:19","serial_number":"06315dfed8c93d1497c26b21c448857b6f2c","result_count":2},{"issuer_ca_id":158800,"issuer_name":"C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA","common_name":"*.fleischkombinat-ost.de","name_value":"*.fleischkombinat-ost.de\nfleischkombinat-ost.de","id":19369530786,"entry_timestamp":"2025-07-01T09:12:02.496","not_before":"2025-07-01T00:00:00","not_after":"2025-09-29T23:59:59","serial_number":"07c51a2c164b3a6c5769b0e03a9f4085","result_count":3},{"issuer_ca_id":158800,"issuer_name":"C=AT, O=ZeroSSL, CN=ZeroSSL RSA Domain Secure Site CA","common_name":"*.fleischkombinat-ost.de","name_value":"*.fleischkombinat-ost.de\nfleischkombinat-ost.de","id":19369530780,"entry_timestamp":"2025-07-01T09:12:01.04","not_before":"2025-07-01T00:00:00","not_after":"2025-09-29T23:59:59","serial_number":"07c51a2c164b3a6c5769b0e03a9f4085","result_count":3}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"forum.cc24.dev","first_cached":"2025-09-14T21:37:55.208070+00:00","last_upstream_query":"2025-09-14T21:37:55.208073+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":20275855672,"entry_timestamp":"2025-08-12T00:09:25.872","not_before":"2025-08-11T23:10:53","not_after":"2025-11-09T23:10:52","serial_number":"05e7fa80df3e45a7ecec44d25dafad0904e5","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":20275850214,"entry_timestamp":"2025-08-12T00:09:23.776","not_before":"2025-08-11T23:10:53","not_after":"2025-11-09T23:10:52","serial_number":"05e7fa80df3e45a7ecec44d25dafad0904e5","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":18987146858,"entry_timestamp":"2025-06-13T00:06:40.302","not_before":"2025-06-12T23:08:03","not_after":"2025-09-10T23:08:02","serial_number":"055efe65125ee83f14545a2f5d99590e635f","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":18987145127,"entry_timestamp":"2025-06-13T00:06:34.097","not_before":"2025-06-12T23:08:03","not_after":"2025-09-10T23:08:02","serial_number":"055efe65125ee83f14545a2f5d99590e635f","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":17831472866,"entry_timestamp":"2025-04-14T00:18:33.004","not_before":"2025-04-13T23:20:02","not_after":"2025-07-12T23:20:01","serial_number":"064fefe879ff5e732ce6c6a63f1e911db568","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":17831402949,"entry_timestamp":"2025-04-14T00:18:32.224","not_before":"2025-04-13T23:20:02","not_after":"2025-07-12T23:20:01","serial_number":"064fefe879ff5e732ce6c6a63f1e911db568","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":17170813968,"entry_timestamp":"2025-02-13T00:02:16.332","not_before":"2025-02-12T23:03:44","not_after":"2025-05-13T23:03:43","serial_number":"036e8e11288b54228648cab399477ea43c56","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":16705244862,"entry_timestamp":"2025-02-13T00:02:14.119","not_before":"2025-02-12T23:03:44","not_after":"2025-05-13T23:03:43","serial_number":"036e8e11288b54228648cab399477ea43c56","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":17122401304,"entry_timestamp":"2025-02-09T15:21:53.869","not_before":"2025-02-09T14:23:23","not_after":"2025-05-10T14:23:22","serial_number":"03e0928358e7636b3cc59a7dbc3b188bd7ca","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"forum.cc24.dev","name_value":"forum.cc24.dev","id":16636457115,"entry_timestamp":"2025-02-09T15:21:53.738","not_before":"2025-02-09T14:23:23","not_after":"2025-05-10T14:23:22","serial_number":"03e0928358e7636b3cc59a7dbc3b188bd7ca","result_count":2}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"git.mikoshi.de","first_cached":"2025-09-14T22:41:53.620008+00:00","last_upstream_query":"2025-09-15T15:34:53.671880+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295817,"issuer_name":"C=US, O=Let's Encrypt, CN=R13","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":20885174925,"entry_timestamp":"2025-09-09T00:00:36.192","not_before":"2025-09-08T23:02:04","not_after":"2025-12-07T23:02:03","serial_number":"0615e6baefd21c126c2cdddf6dcb2507d56f","result_count":2},{"issuer_ca_id":295817,"issuer_name":"C=US, O=Let's Encrypt, CN=R13","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":20885174361,"entry_timestamp":"2025-09-09T00:00:34.086","not_before":"2025-09-08T23:02:04","not_after":"2025-12-07T23:02:03","serial_number":"0615e6baefd21c126c2cdddf6dcb2507d56f","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":19559742374,"entry_timestamp":"2025-07-10T00:00:34.37","not_before":"2025-07-09T23:02:04","not_after":"2025-10-07T23:02:03","serial_number":"06d9b4e5782769647aa336db245fff31f620","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":19559742305,"entry_timestamp":"2025-07-10T00:00:34.165","not_before":"2025-07-09T23:02:04","not_after":"2025-10-07T23:02:03","serial_number":"06d9b4e5782769647aa336db245fff31f620","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":18325953073,"entry_timestamp":"2025-05-10T12:59:59.883","not_before":"2025-05-10T12:01:29","not_after":"2025-08-08T12:01:28","serial_number":"06b8ea37731e6560b6c67edbefbacfd4105c","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":18325952875,"entry_timestamp":"2025-05-10T12:59:59.504","not_before":"2025-05-10T12:01:29","not_after":"2025-08-08T12:01:28","serial_number":"06b8ea37731e6560b6c67edbefbacfd4105c","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":17831317349,"entry_timestamp":"2025-04-14T00:13:00.421","not_before":"2025-04-13T23:14:28","not_after":"2025-07-12T23:14:27","serial_number":"056bf6f5e9efb81381e56fbd6e28c32f4f90","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":17831304428,"entry_timestamp":"2025-04-14T00:12:58.339","not_before":"2025-04-13T23:14:28","not_after":"2025-07-12T23:14:27","serial_number":"056bf6f5e9efb81381e56fbd6e28c32f4f90","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":17170797746,"entry_timestamp":"2025-02-13T00:00:56.931","not_before":"2025-02-12T23:02:26","not_after":"2025-05-13T23:02:25","serial_number":"03b7b4c4c6233e74e3ad23a7bb2e455fcc3f","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":16705238631,"entry_timestamp":"2025-02-13T00:00:56.689","not_before":"2025-02-12T23:02:26","not_after":"2025-05-13T23:02:25","serial_number":"03b7b4c4c6233e74e3ad23a7bb2e455fcc3f","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":17122277510,"entry_timestamp":"2025-02-09T15:15:36.076","not_before":"2025-02-09T14:17:05","not_after":"2025-05-10T14:17:04","serial_number":"0404f208620f990403046876d32991e8f320","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"git.mikoshi.de","name_value":"git.mikoshi.de","id":16635498764,"entry_timestamp":"2025-02-09T15:15:35.493","not_before":"2025-02-09T14:17:05","not_after":"2025-05-10T14:17:04","serial_number":"0404f208620f990403046876d32991e8f320","result_count":2}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"hoarder.cc24.dev","first_cached":"2025-09-14T21:33:21.961821+00:00","last_upstream_query":"2025-09-14T21:33:21.961824+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"hoarder.cc24.dev","name_value":"hoarder.cc24.dev","id":17651896110,"entry_timestamp":"2025-04-03T19:39:13.874","not_before":"2025-04-03T18:40:43","not_after":"2025-07-02T18:40:42","serial_number":"062e2d17ef9c31ca560ab40299e0e00701c0","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"hoarder.cc24.dev","name_value":"hoarder.cc24.dev","id":17610697718,"entry_timestamp":"2025-04-03T19:39:13.522","not_before":"2025-04-03T18:40:43","not_after":"2025-07-02T18:40:42","serial_number":"062e2d17ef9c31ca560ab40299e0e00701c0","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"hub.cc24.dev","first_cached":"2025-09-14T21:33:48.364903+00:00","last_upstream_query":"2025-09-14T21:33:48.364908+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":20317572962,"entry_timestamp":"2025-08-14T00:02:25.791","not_before":"2025-08-13T23:03:55","not_after":"2025-11-11T23:03:54","serial_number":"05ee38e8ae7bff4c5c414784e2c64d933b7a","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":20317572564,"entry_timestamp":"2025-08-14T00:02:25.581","not_before":"2025-08-13T23:03:55","not_after":"2025-11-11T23:03:54","serial_number":"05ee38e8ae7bff4c5c414784e2c64d933b7a","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":20189230503,"entry_timestamp":"2025-08-08T00:05:51.4","not_before":"2025-08-07T23:07:21","not_after":"2025-11-05T23:07:20","serial_number":"0502ddbfff49d3df12f3a15ba33ad895ccf1","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":20189230585,"entry_timestamp":"2025-08-08T00:05:51.234","not_before":"2025-08-07T23:07:21","not_after":"2025-11-05T23:07:20","serial_number":"0502ddbfff49d3df12f3a15ba33ad895ccf1","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":20060643580,"entry_timestamp":"2025-08-02T00:02:15.895","not_before":"2025-08-01T23:03:45","not_after":"2025-10-30T23:03:44","serial_number":"05c750b95573daa27e1a55a8803a2e6d21ad","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":20060643807,"entry_timestamp":"2025-08-02T00:02:15.683","not_before":"2025-08-01T23:03:45","not_after":"2025-10-30T23:03:44","serial_number":"05c750b95573daa27e1a55a8803a2e6d21ad","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":19929376671,"entry_timestamp":"2025-07-27T00:02:55.144","not_before":"2025-07-26T23:04:22","not_after":"2025-10-24T23:04:21","serial_number":"052c4fe632cf76d0306310cfb9faecc224ba","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":19929375724,"entry_timestamp":"2025-07-27T00:02:52.759","not_before":"2025-07-26T23:04:22","not_after":"2025-10-24T23:04:21","serial_number":"052c4fe632cf76d0306310cfb9faecc224ba","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":19803769083,"entry_timestamp":"2025-07-21T00:01:15.171","not_before":"2025-07-20T23:02:40","not_after":"2025-10-18T23:02:39","serial_number":"05e9927e9ea80c233e8a9502f11e4958cd06","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":19803778513,"entry_timestamp":"2025-07-21T00:01:10.987","not_before":"2025-07-20T23:02:40","not_after":"2025-10-18T23:02:39","serial_number":"05e9927e9ea80c233e8a9502f11e4958cd06","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":19665369127,"entry_timestamp":"2025-07-14T21:15:11.092","not_before":"2025-07-14T20:16:38","not_after":"2025-10-12T20:16:37","serial_number":"069e06aa4855496ab6b766889d6b45135d4e","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"hub.cc24.dev","name_value":"hub.cc24.dev","id":19665373526,"entry_timestamp":"2025-07-14T21:15:08.866","not_before":"2025-07-14T20:16:38","not_after":"2025-10-12T20:16:37","serial_number":"069e06aa4855496ab6b766889d6b45135d4e","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"ip.mikoshi.de","first_cached":"2025-09-15T15:35:38.687945+00:00","last_upstream_query":"2025-09-15T15:35:38.687948+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":20275799673,"entry_timestamp":"2025-08-12T00:06:09.895","not_before":"2025-08-11T23:07:39","not_after":"2025-11-09T23:07:38","serial_number":"05abe97c54f28c570ed093f2c2064d2bd909","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":20275798755,"entry_timestamp":"2025-08-12T00:06:09.726","not_before":"2025-08-11T23:07:39","not_after":"2025-11-09T23:07:38","serial_number":"05abe97c54f28c570ed093f2c2064d2bd909","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":18987090979,"entry_timestamp":"2025-06-13T00:03:33.968","not_before":"2025-06-12T23:05:03","not_after":"2025-09-10T23:05:02","serial_number":"05861ba42c1b941a781e56836a1286805486","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":18987090443,"entry_timestamp":"2025-06-13T00:03:33.547","not_before":"2025-06-12T23:05:03","not_after":"2025-09-10T23:05:02","serial_number":"05861ba42c1b941a781e56836a1286805486","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":17831378289,"entry_timestamp":"2025-04-14T00:14:14.055","not_before":"2025-04-13T23:15:43","not_after":"2025-07-12T23:15:42","serial_number":"05e8a5d6c84779035ff19c804b3eb98d997a","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":17831323161,"entry_timestamp":"2025-04-14T00:14:13.821","not_before":"2025-04-13T23:15:43","not_after":"2025-07-12T23:15:42","serial_number":"05e8a5d6c84779035ff19c804b3eb98d997a","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":17170801048,"entry_timestamp":"2025-02-13T00:01:10.43","not_before":"2025-02-12T23:02:40","not_after":"2025-05-13T23:02:39","serial_number":"03af85f30dcc4dbca816456437ccc8760356","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":16704107826,"entry_timestamp":"2025-02-13T00:01:10.264","not_before":"2025-02-12T23:02:40","not_after":"2025-05-13T23:02:39","serial_number":"03af85f30dcc4dbca816456437ccc8760356","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":17122289078,"entry_timestamp":"2025-02-09T15:16:43.147","not_before":"2025-02-09T14:18:12","not_after":"2025-05-10T14:18:11","serial_number":"03ef24688a55744de221b025bac45c4898c5","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"ip.mikoshi.de","name_value":"ip.mikoshi.de","id":16635485733,"entry_timestamp":"2025-02-09T15:16:43.019","not_before":"2025-02-09T14:18:12","not_after":"2025-05-10T14:18:11","serial_number":"03ef24688a55744de221b025bac45c4898c5","result_count":2}]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"kvmtest2.kasserver.com","first_cached":"2025-09-15T11:48:15.510962+00:00","last_upstream_query":"2025-09-15T11:48:15.510965+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmtest2.kasserver.com","name_value":"nextcloud.kvmtest2.kasserver.com\nwww.nextcloud.kvmtest2.kasserver.com","id":11872742578,"entry_timestamp":"2024-01-26T08:07:49.508","not_before":"2024-01-26T07:07:49","not_after":"2024-04-25T07:07:48","serial_number":"033a4ebc78836fabf49336d55237d61606b1","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmtest2.kasserver.com","name_value":"nextcloud.kvmtest2.kasserver.com\nwww.nextcloud.kvmtest2.kasserver.com","id":11872748114,"entry_timestamp":"2024-01-26T08:07:49.316","not_before":"2024-01-26T07:07:49","not_after":"2024-04-25T07:07:48","serial_number":"033a4ebc78836fabf49336d55237d61606b1","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmtest2.kasserver.com","name_value":"nextcloud.kvmtest2.kasserver.com\nwww.nextcloud.kvmtest2.kasserver.com","id":11867647719,"entry_timestamp":"2024-01-25T21:52:18.981","not_before":"2024-01-25T20:52:18","not_after":"2024-04-24T20:52:17","serial_number":"03e7aa261a2cd46d7de1f7a140b4a798eb21","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmtest2.kasserver.com","name_value":"nextcloud.kvmtest2.kasserver.com\nwww.nextcloud.kvmtest2.kasserver.com","id":11867647704,"entry_timestamp":"2024-01-25T21:52:18.671","not_before":"2024-01-25T20:52:18","not_after":"2024-04-24T20:52:17","serial_number":"03e7aa261a2cd46d7de1f7a140b4a798eb21","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmtest2.kasserver.com","name_value":"nextcloud.kvmtest2.kasserver.com\nwww.nextcloud.kvmtest2.kasserver.com","id":11864252076,"entry_timestamp":"2024-01-25T14:44:38.589","not_before":"2024-01-25T13:44:38","not_after":"2024-04-24T13:44:37","serial_number":"03542eac1a93d9a614ab26535b70ea26a6a5","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmtest2.kasserver.com","name_value":"nextcloud.kvmtest2.kasserver.com\nwww.nextcloud.kvmtest2.kasserver.com","id":11864248841,"entry_timestamp":"2024-01-25T14:44:38.505","not_before":"2024-01-25T13:44:38","not_after":"2024-04-24T13:44:37","serial_number":"03542eac1a93d9a614ab26535b70ea26a6a5","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmtest2.kasserver.com","name_value":"nextcloud.kvmtest2.kasserver.com\nwww.nextcloud.kvmtest2.kasserver.com","id":11853852174,"entry_timestamp":"2024-01-24T14:39:08.051","not_before":"2024-01-24T13:39:06","not_after":"2024-04-23T13:39:05","serial_number":"047335e6361f4c5477b088ff8cd2719d4d9a","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmtest2.kasserver.com","name_value":"nextcloud.kvmtest2.kasserver.com\nwww.nextcloud.kvmtest2.kasserver.com","id":11853852409,"entry_timestamp":"2024-01-24T14:39:07.46","not_before":"2024-01-24T13:39:06","not_after":"2024-04-23T13:39:05","serial_number":"047335e6361f4c5477b088ff8cd2719d4d9a","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"kvmthkr.kasserver.com","first_cached":"2025-09-15T11:50:03.952251+00:00","last_upstream_query":"2025-09-15T11:50:03.952256+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":105484,"issuer_name":"C=GB, ST=Greater Manchester, L=Salford, O=Sectigo Limited, CN=Sectigo ECC Domain Validation Secure Server CA","common_name":"ec.kvmthkr.kasserver.com","name_value":"ec.kvmthkr.kasserver.com\nwww.ec.kvmthkr.kasserver.com","id":14939726486,"entry_timestamp":"2024-10-15T07:02:39.33","not_before":"2024-10-15T00:00:00","not_after":"2024-11-14T23:59:59","serial_number":"6827c362ad3905799d6a865b0f1f60f8","result_count":3},{"issuer_ca_id":105484,"issuer_name":"C=GB, ST=Greater Manchester, L=Salford, O=Sectigo Limited, CN=Sectigo ECC Domain Validation Secure Server CA","common_name":"ec.kvmthkr.kasserver.com","name_value":"ec.kvmthkr.kasserver.com\nwww.ec.kvmthkr.kasserver.com","id":14939726540,"entry_timestamp":"2024-10-15T07:02:38.057","not_before":"2024-10-15T00:00:00","not_after":"2024-11-14T23:59:59","serial_number":"6827c362ad3905799d6a865b0f1f60f8","result_count":3}]}

View File

@@ -1 +0,0 @@
{"domain":"kvmu12s1.kasserver.com","first_cached":"2025-09-15T11:51:04.220452+00:00","last_upstream_query":"2025-09-15T11:51:04.220456+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmu12s1.kasserver.com","name_value":"nextcloud.kvmu12s1.kasserver.com\nwww.nextcloud.kvmu12s1.kasserver.com","id":10586150052,"entry_timestamp":"2023-09-15T10:36:49.311","not_before":"2023-09-15T09:36:48","not_after":"2023-12-14T09:36:47","serial_number":"045dedd31035da18a73d26fe8a4f963f6eef","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmu12s1.kasserver.com","name_value":"nextcloud.kvmu12s1.kasserver.com\nwww.nextcloud.kvmu12s1.kasserver.com","id":10577792024,"entry_timestamp":"2023-09-15T10:36:49.018","not_before":"2023-09-15T09:36:48","not_after":"2023-12-14T09:36:47","serial_number":"045dedd31035da18a73d26fe8a4f963f6eef","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmu12s1.kasserver.com","name_value":"nextcloud.kvmu12s1.kasserver.com\nwww.nextcloud.kvmu12s1.kasserver.com","id":9948906308,"entry_timestamp":"2023-07-14T08:26:39.958","not_before":"2023-07-14T07:26:39","not_after":"2023-10-12T07:26:38","serial_number":"035e2fe150728c3a351990f06dab0a9b29b7","result_count":3},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"nextcloud.kvmu12s1.kasserver.com","name_value":"nextcloud.kvmu12s1.kasserver.com\nwww.nextcloud.kvmu12s1.kasserver.com","id":9905731790,"entry_timestamp":"2023-07-14T08:26:39.811","not_before":"2023-07-14T07:26:39","not_after":"2023-10-12T07:26:38","serial_number":"035e2fe150728c3a351990f06dab0a9b29b7","result_count":3}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"llm.mikoshi.de","first_cached":"2025-09-15T15:40:09.181904+00:00","last_upstream_query":"2025-09-15T15:40:09.181907+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"llm.mikoshi.de","name_value":"llm.mikoshi.de","id":19995849024,"entry_timestamp":"2025-07-30T00:02:19.725","not_before":"2025-07-29T23:03:47","not_after":"2025-10-27T23:03:46","serial_number":"05335d7df5f076bd039bf6148fe11ebfd86d","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"llm.mikoshi.de","name_value":"llm.mikoshi.de","id":19995848373,"entry_timestamp":"2025-07-30T00:02:17.527","not_before":"2025-07-29T23:03:47","not_after":"2025-10-27T23:03:46","serial_number":"05335d7df5f076bd039bf6148fe11ebfd86d","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"llm.mikoshi.de","name_value":"llm.mikoshi.de","id":18720891589,"entry_timestamp":"2025-05-31T00:01:22.576","not_before":"2025-05-30T23:02:49","not_after":"2025-08-28T23:02:48","serial_number":"064967b3c615cbb4a7f8690b4ee7ed3ab2c2","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"llm.mikoshi.de","name_value":"llm.mikoshi.de","id":18720891502,"entry_timestamp":"2025-05-31T00:01:20.192","not_before":"2025-05-30T23:02:49","not_after":"2025-08-28T23:02:48","serial_number":"064967b3c615cbb4a7f8690b4ee7ed3ab2c2","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"llm.mikoshi.de","name_value":"llm.mikoshi.de","id":17870870943,"entry_timestamp":"2025-03-31T19:43:16.66","not_before":"2025-03-31T18:44:46","not_after":"2025-06-29T18:44:45","serial_number":"05da28c4ebc6a250cb83e37fa4bc54b85508","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"llm.mikoshi.de","name_value":"llm.mikoshi.de","id":17539939653,"entry_timestamp":"2025-03-31T19:43:16.406","not_before":"2025-03-31T18:44:46","not_after":"2025-06-29T18:44:45","serial_number":"05da28c4ebc6a250cb83e37fa4bc54b85508","result_count":2}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"matrix.mikoshi.de","first_cached":"2025-09-15T15:40:28.068782+00:00","last_upstream_query":"2025-09-15T15:40:28.068785+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"matrix.mikoshi.de","name_value":"matrix.mikoshi.de","id":17170805427,"entry_timestamp":"2025-02-13T00:01:24.095","not_before":"2025-02-12T23:02:53","not_after":"2025-05-13T23:02:52","serial_number":"0340c3ca26c1ab1678dd4c8885208ac93818","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"matrix.mikoshi.de","name_value":"matrix.mikoshi.de","id":16704107881,"entry_timestamp":"2025-02-13T00:01:23.078","not_before":"2025-02-12T23:02:53","not_after":"2025-05-13T23:02:52","serial_number":"0340c3ca26c1ab1678dd4c8885208ac93818","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"matrix.mikoshi.de","name_value":"matrix.mikoshi.de","id":17122315423,"entry_timestamp":"2025-02-09T15:17:51.214","not_before":"2025-02-09T14:19:20","not_after":"2025-05-10T14:19:19","serial_number":"03e088e499d2b5e10132f28674a00990313a","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"matrix.mikoshi.de","name_value":"matrix.mikoshi.de","id":16635517598,"entry_timestamp":"2025-02-09T15:17:50.818","not_before":"2025-02-09T14:19:20","not_after":"2025-05-10T14:19:19","serial_number":"03e088e499d2b5e10132f28674a00990313a","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"mempool.mikoshi.de","first_cached":"2025-09-15T15:37:03.196760+00:00","last_upstream_query":"2025-09-15T15:37:03.196764+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":20275766421,"entry_timestamp":"2025-08-12T00:03:06.545","not_before":"2025-08-11T23:04:33","not_after":"2025-11-09T23:04:32","serial_number":"05db41917aa6146ca29cc3a918e57bfa2dcf","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":20275769957,"entry_timestamp":"2025-08-12T00:03:04.069","not_before":"2025-08-11T23:04:33","not_after":"2025-11-09T23:04:32","serial_number":"05db41917aa6146ca29cc3a918e57bfa2dcf","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":18986859548,"entry_timestamp":"2025-06-13T00:01:16.577","not_before":"2025-06-12T23:02:40","not_after":"2025-09-10T23:02:39","serial_number":"05b7e05db409b0791e0b480cfb8f3116b44f","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":18987057144,"entry_timestamp":"2025-06-13T00:01:10.626","not_before":"2025-06-12T23:02:40","not_after":"2025-09-10T23:02:39","serial_number":"05b7e05db409b0791e0b480cfb8f3116b44f","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":17831239624,"entry_timestamp":"2025-04-14T00:05:10.579","not_before":"2025-04-13T23:06:40","not_after":"2025-07-12T23:06:39","serial_number":"0573b6923c8539ab353225bf023b7fd6b465","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":17831349460,"entry_timestamp":"2025-04-14T00:05:10.362","not_before":"2025-04-13T23:06:40","not_after":"2025-07-12T23:06:39","serial_number":"0573b6923c8539ab353225bf023b7fd6b465","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":17170793138,"entry_timestamp":"2025-02-13T00:00:22.884","not_before":"2025-02-12T23:01:52","not_after":"2025-05-13T23:01:51","serial_number":"048ddc03e0d19d586ef5508bb636fa2ba81b","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":16704095754,"entry_timestamp":"2025-02-13T00:00:22.634","not_before":"2025-02-12T23:01:52","not_after":"2025-05-13T23:01:51","serial_number":"048ddc03e0d19d586ef5508bb636fa2ba81b","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":16636671204,"entry_timestamp":"2025-02-09T15:12:41.443","not_before":"2025-02-09T14:14:11","not_after":"2025-05-10T14:14:10","serial_number":"03a2ba996fd26f676c53edec5725f7442c90","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"mempool.mikoshi.de","name_value":"mempool.mikoshi.de","id":16635433368,"entry_timestamp":"2025-02-09T15:12:41.328","not_before":"2025-02-09T14:14:11","not_after":"2025-05-10T14:14:10","serial_number":"03a2ba996fd26f676c53edec5725f7442c90","result_count":2}]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"misp.mikoshi.de","first_cached":"2025-09-14T22:38:25.627275+00:00","last_upstream_query":"2025-09-15T15:37:51.293899+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"misp.mikoshi.de","name_value":"misp.mikoshi.de","id":17353605244,"entry_timestamp":"2025-02-25T00:29:30.385","not_before":"2025-02-24T23:30:59","not_after":"2025-05-25T23:30:58","serial_number":"03b9fa625fe61e6c16d14916613ca1f46d04","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"misp.mikoshi.de","name_value":"misp.mikoshi.de","id":16895667572,"entry_timestamp":"2025-02-25T00:29:29.913","not_before":"2025-02-24T23:30:59","not_after":"2025-05-25T23:30:58","serial_number":"03b9fa625fe61e6c16d14916613ca1f46d04","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"mx00.ionos.de","first_cached":"2025-09-14T21:05:21.043082+00:00","last_upstream_query":"2025-09-15T15:34:57.508633+00:00","upstream_query_count":3,"certificates":[{"issuer_ca_id":245439,"issuer_name":"C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":17921174855,"entry_timestamp":"2025-04-18T11:32:56.685","not_before":"2024-05-14T10:13:42","not_after":"2025-05-18T23:59:59","serial_number":"01f21195d95cb3f63712c59f40b2f75c","result_count":1},{"issuer_ca_id":245439,"issuer_name":"C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":17755974719,"entry_timestamp":"2025-04-10T06:20:35.546","not_before":"2025-04-10T06:20:33","not_after":"2026-04-14T23:59:59","serial_number":"27efd5b7b17610e4ae86d40dea979ad7","result_count":1},{"issuer_ca_id":245439,"issuer_name":"C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":13038507917,"entry_timestamp":"2024-05-14T10:13:43.64","not_before":"2024-05-14T10:13:42","not_after":"2025-05-18T23:59:59","serial_number":"01f21195d95cb3f63712c59f40b2f75c","result_count":1},{"issuer_ca_id":245439,"issuer_name":"C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":9700366741,"entry_timestamp":"2023-06-20T11:08:14.981","not_before":"2023-06-20T11:08:11","not_after":"2024-06-24T23:59:59","serial_number":"153f3cd769500d3eebec07c90476d817","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":7107715703,"entry_timestamp":"2022-07-12T10:00:03.026","not_before":"2022-07-12T10:00:01","not_after":"2023-07-16T23:59:59","serial_number":"210a3739eb290b28d1199f6a9c04d294","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":4981516894,"entry_timestamp":"2021-08-04T08:35:13.1","not_before":"2021-08-04T08:35:11","not_after":"2022-08-08T23:59:59","serial_number":"11ae5449f5d5cc2a5ec198105748f927","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":2864694015,"entry_timestamp":"2020-05-28T07:54:38.37","not_before":"2020-05-28T07:54:37","not_after":"2022-06-02T23:59:59","serial_number":"325b678601aae53e99926c1834988786","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":2857249553,"entry_timestamp":"2020-05-26T09:01:33.944","not_before":"2020-05-26T09:01:33","not_after":"2022-05-31T23:59:59","serial_number":"0ceee698ba17a744881fbb3998c05748","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":2857204010,"entry_timestamp":"2020-05-26T08:46:52.8","not_before":"2020-05-26T08:46:52","not_after":"2022-05-31T23:59:59","serial_number":"0ac520de92fde640943c1d2c0eb2f6e8","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx00.ionos.de","id":2856876813,"entry_timestamp":"2020-05-26T06:58:49.881","not_before":"2020-05-26T06:58:49","not_after":"2022-05-31T23:59:59","serial_number":"2f9201af62a3408df1579b8a39c0f7b6","result_count":1}]}

View File

@@ -1,188 +0,0 @@
{
"domain": "mx00.kundenserver.de",
"first_cached": "2025-09-15T19:23:52.908544+00:00",
"last_upstream_query": "2025-09-15T19:23:52.908548+00:00",
"upstream_query_count": 1,
"certificates": [
{
"issuer_ca_id": 245439,
"issuer_name": "C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 17921174855,
"entry_timestamp": "2025-04-18T11:32:56.685",
"not_before": "2024-05-14T10:13:42",
"not_after": "2025-05-18T23:59:59",
"serial_number": "01f21195d95cb3f63712c59f40b2f75c",
"result_count": 1
},
{
"issuer_ca_id": 245439,
"issuer_name": "C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 17755974719,
"entry_timestamp": "2025-04-10T06:20:35.546",
"not_before": "2025-04-10T06:20:33",
"not_after": "2026-04-14T23:59:59",
"serial_number": "27efd5b7b17610e4ae86d40dea979ad7",
"result_count": 1
},
{
"issuer_ca_id": 245439,
"issuer_name": "C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 13038507917,
"entry_timestamp": "2024-05-14T10:13:43.64",
"not_before": "2024-05-14T10:13:42",
"not_after": "2025-05-18T23:59:59",
"serial_number": "01f21195d95cb3f63712c59f40b2f75c",
"result_count": 1
},
{
"issuer_ca_id": 245439,
"issuer_name": "C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 9700366741,
"entry_timestamp": "2023-06-20T11:08:14.981",
"not_before": "2023-06-20T11:08:11",
"not_after": "2024-06-24T23:59:59",
"serial_number": "153f3cd769500d3eebec07c90476d817",
"result_count": 1
},
{
"issuer_ca_id": 6069,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 7107715703,
"entry_timestamp": "2022-07-12T10:00:03.026",
"not_before": "2022-07-12T10:00:01",
"not_after": "2023-07-16T23:59:59",
"serial_number": "210a3739eb290b28d1199f6a9c04d294",
"result_count": 1
},
{
"issuer_ca_id": 6069,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 4981516894,
"entry_timestamp": "2021-08-04T08:35:13.1",
"not_before": "2021-08-04T08:35:11",
"not_after": "2022-08-08T23:59:59",
"serial_number": "11ae5449f5d5cc2a5ec198105748f927",
"result_count": 1
},
{
"issuer_ca_id": 6069,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 2864694015,
"entry_timestamp": "2020-05-28T07:54:38.37",
"not_before": "2020-05-28T07:54:37",
"not_after": "2022-06-02T23:59:59",
"serial_number": "325b678601aae53e99926c1834988786",
"result_count": 1
},
{
"issuer_ca_id": 6069,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 2857249553,
"entry_timestamp": "2020-05-26T09:01:33.944",
"not_before": "2020-05-26T09:01:33",
"not_after": "2022-05-31T23:59:59",
"serial_number": "0ceee698ba17a744881fbb3998c05748",
"result_count": 1
},
{
"issuer_ca_id": 6069,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 2857204010,
"entry_timestamp": "2020-05-26T08:46:52.8",
"not_before": "2020-05-26T08:46:52",
"not_after": "2022-05-31T23:59:59",
"serial_number": "0ac520de92fde640943c1d2c0eb2f6e8",
"result_count": 1
},
{
"issuer_ca_id": 6069,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 2856876813,
"entry_timestamp": "2020-05-26T06:58:49.881",
"not_before": "2020-05-26T06:58:49",
"not_after": "2022-05-31T23:59:59",
"serial_number": "2f9201af62a3408df1579b8a39c0f7b6",
"result_count": 1
},
{
"issuer_ca_id": 6069,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 1351991065,
"entry_timestamp": "2019-04-05T05:26:06.601",
"not_before": "2019-02-18T09:14:39",
"not_after": "2021-02-23T23:59:59",
"serial_number": "2c12501e6e490dd60bfb87d85edad1d1",
"result_count": 1
},
{
"issuer_ca_id": 6069,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 1213296236,
"entry_timestamp": "2019-02-18T09:14:39.61",
"not_before": "2019-02-18T09:14:39",
"not_after": "2021-02-23T23:59:59",
"serial_number": "2c12501e6e490dd60bfb87d85edad1d1",
"result_count": 1
},
{
"issuer_ca_id": 1375,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=NRW, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass DE-1",
"common_name": "mx00.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 370285812,
"entry_timestamp": "2018-03-30T01:09:17.252",
"not_before": "2013-08-06T15:49:56",
"not_after": "2014-08-11T23:59:59",
"serial_number": "00f17c74ae3d6e7a5c",
"result_count": 2
},
{
"issuer_ca_id": 1477,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass DE-2",
"common_name": "mx.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 307747879,
"entry_timestamp": "2018-01-19T09:01:19.72",
"not_before": "2017-03-22T10:21:38",
"not_after": "2019-03-27T23:59:59",
"serial_number": "00bf95dcc292d7bf01",
"result_count": 1
},
{
"issuer_ca_id": 1477,
"issuer_name": "C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass DE-2",
"common_name": "mx00.kundenserver.de",
"name_value": "mx00.kundenserver.de",
"id": 14627870,
"entry_timestamp": "2016-03-08T11:54:51.83",
"not_before": "2014-07-22T11:15:15",
"not_after": "2017-07-27T23:59:59",
"serial_number": "20e14d5c7f18e199",
"result_count": 2
}
]
}

View File

@@ -1 +0,0 @@
{"domain":"mx01.ionos.de","first_cached":"2025-09-14T21:05:58.567956+00:00","last_upstream_query":"2025-09-15T15:34:59.570960+00:00","upstream_query_count":3,"certificates":[{"issuer_ca_id":245439,"issuer_name":"C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":17921174855,"entry_timestamp":"2025-04-18T11:32:56.685","not_before":"2024-05-14T10:13:42","not_after":"2025-05-18T23:59:59","serial_number":"01f21195d95cb3f63712c59f40b2f75c","result_count":1},{"issuer_ca_id":245439,"issuer_name":"C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":17755974719,"entry_timestamp":"2025-04-10T06:20:35.546","not_before":"2025-04-10T06:20:33","not_after":"2026-04-14T23:59:59","serial_number":"27efd5b7b17610e4ae86d40dea979ad7","result_count":1},{"issuer_ca_id":245439,"issuer_name":"C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":13038507917,"entry_timestamp":"2024-05-14T10:13:43.64","not_before":"2024-05-14T10:13:42","not_after":"2025-05-18T23:59:59","serial_number":"01f21195d95cb3f63712c59f40b2f75c","result_count":1},{"issuer_ca_id":245439,"issuer_name":"C=DE, O=Deutsche Telekom Security GmbH, CN=Telekom Security ServerID OV Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":9700366741,"entry_timestamp":"2023-06-20T11:08:14.981","not_before":"2023-06-20T11:08:11","not_after":"2024-06-24T23:59:59","serial_number":"153f3cd769500d3eebec07c90476d817","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":7107715703,"entry_timestamp":"2022-07-12T10:00:03.026","not_before":"2022-07-12T10:00:01","not_after":"2023-07-16T23:59:59","serial_number":"210a3739eb290b28d1199f6a9c04d294","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":4981516894,"entry_timestamp":"2021-08-04T08:35:13.1","not_before":"2021-08-04T08:35:11","not_after":"2022-08-08T23:59:59","serial_number":"11ae5449f5d5cc2a5ec198105748f927","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":2864694015,"entry_timestamp":"2020-05-28T07:54:38.37","not_before":"2020-05-28T07:54:37","not_after":"2022-06-02T23:59:59","serial_number":"325b678601aae53e99926c1834988786","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":2857249553,"entry_timestamp":"2020-05-26T09:01:33.944","not_before":"2020-05-26T09:01:33","not_after":"2022-05-31T23:59:59","serial_number":"0ceee698ba17a744881fbb3998c05748","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":2857204010,"entry_timestamp":"2020-05-26T08:46:52.8","not_before":"2020-05-26T08:46:52","not_after":"2022-05-31T23:59:59","serial_number":"0ac520de92fde640943c1d2c0eb2f6e8","result_count":1},{"issuer_ca_id":6069,"issuer_name":"C=DE, O=T-Systems International GmbH, OU=T-Systems Trust Center, ST=Nordrhein Westfalen, postalCode=57250, L=Netphen, street=Untere Industriestr. 20, CN=TeleSec ServerPass Class 2 CA","common_name":"mx.kundenserver.de","name_value":"mx01.ionos.de","id":2856876813,"entry_timestamp":"2020-05-26T06:58:49.881","not_before":"2020-05-26T06:58:49","not_after":"2022-05-31T23:59:59","serial_number":"2f9201af62a3408df1579b8a39c0f7b6","result_count":1}]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"nostr.mikoshi.de","first_cached":"2025-09-14T22:44:55.522098+00:00","last_upstream_query":"2025-09-15T15:39:39.928858+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295809,"issuer_name":"C=US, O=Let's Encrypt, CN=E8","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":20839972270,"entry_timestamp":"2025-09-07T00:01:25.998","not_before":"2025-09-06T23:02:55","not_after":"2025-12-05T23:02:54","serial_number":"05c5c3ab0353acb84d7adc05e78d6d6fe276","result_count":2},{"issuer_ca_id":295809,"issuer_name":"C=US, O=Let's Encrypt, CN=E8","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":20839069128,"entry_timestamp":"2025-09-07T00:01:25.786","not_before":"2025-09-06T23:02:55","not_after":"2025-12-05T23:02:54","serial_number":"05c5c3ab0353acb84d7adc05e78d6d6fe276","result_count":2},{"issuer_ca_id":295813,"issuer_name":"C=US, O=Let's Encrypt, CN=E7","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":20641626677,"entry_timestamp":"2025-08-29T00:03:39.504","not_before":"2025-08-28T23:05:09","not_after":"2025-11-26T23:05:08","serial_number":"059eab3e56a39c431f4cb961af259f45f550","result_count":2},{"issuer_ca_id":295813,"issuer_name":"C=US, O=Let's Encrypt, CN=E7","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":20641627201,"entry_timestamp":"2025-08-29T00:03:39.306","not_before":"2025-08-28T23:05:09","not_after":"2025-11-26T23:05:08","serial_number":"059eab3e56a39c431f4cb961af259f45f550","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":20446505609,"entry_timestamp":"2025-08-19T20:58:17.951","not_before":"2025-08-19T19:59:45","not_after":"2025-11-17T19:59:44","serial_number":"06e00b2fda8f18091bb0be67f6809f87a889","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":20441143198,"entry_timestamp":"2025-08-19T20:58:15.697","not_before":"2025-08-19T19:59:45","not_after":"2025-11-17T19:59:44","serial_number":"06e00b2fda8f18091bb0be67f6809f87a889","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":17170798515,"entry_timestamp":"2025-02-13T00:00:50.437","not_before":"2025-02-12T23:02:19","not_after":"2025-05-13T23:02:18","serial_number":"04b641da285b3701db3e199cc49b87a023c7","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":16705237488,"entry_timestamp":"2025-02-13T00:00:50.226","not_before":"2025-02-12T23:02:19","not_after":"2025-05-13T23:02:18","serial_number":"04b641da285b3701db3e199cc49b87a023c7","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":17122272223,"entry_timestamp":"2025-02-09T15:15:01.538","not_before":"2025-02-09T14:16:30","not_after":"2025-05-10T14:16:29","serial_number":"04f78d3955d454fb6d004d08cfadb198d2be","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"nostr.mikoshi.de","name_value":"nostr.mikoshi.de","id":16636445173,"entry_timestamp":"2025-02-09T15:15:01.221","not_before":"2025-02-09T14:16:30","not_after":"2025-05-10T14:16:29","serial_number":"04f78d3955d454fb6d004d08cfadb198d2be","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"notes.mikoshi.de","first_cached":"2025-09-15T15:37:27.243670+00:00","last_upstream_query":"2025-09-15T15:37:27.243675+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"notes.mikoshi.de","name_value":"notes.mikoshi.de","id":17831397265,"entry_timestamp":"2025-04-14T00:15:27.018","not_before":"2025-04-13T23:16:56","not_after":"2025-07-12T23:16:55","serial_number":"0604f6b0149b4afe45efbe46a5493c1ec3fd","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"notes.mikoshi.de","name_value":"notes.mikoshi.de","id":17831343922,"entry_timestamp":"2025-04-14T00:15:26.683","not_before":"2025-04-13T23:16:56","not_after":"2025-07-12T23:16:55","serial_number":"0604f6b0149b4afe45efbe46a5493c1ec3fd","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"notes.mikoshi.de","name_value":"notes.mikoshi.de","id":17170808839,"entry_timestamp":"2025-02-13T00:01:30.661","not_before":"2025-02-12T23:03:00","not_after":"2025-05-13T23:02:59","serial_number":"032b2779b00fd8c25fb56ccab4a5eccf7b1a","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"notes.mikoshi.de","name_value":"notes.mikoshi.de","id":16704108124,"entry_timestamp":"2025-02-13T00:01:30.468","not_before":"2025-02-12T23:03:00","not_after":"2025-05-13T23:02:59","serial_number":"032b2779b00fd8c25fb56ccab4a5eccf7b1a","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"notes.mikoshi.de","name_value":"notes.mikoshi.de","id":17122334548,"entry_timestamp":"2025-02-09T15:18:27.206","not_before":"2025-02-09T14:19:56","not_after":"2025-05-10T14:19:55","serial_number":"042257f7bcc91c0994e9c3c76da6ee700a03","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"notes.mikoshi.de","name_value":"notes.mikoshi.de","id":16636453516,"entry_timestamp":"2025-02-09T15:18:26.537","not_before":"2025-02-09T14:19:56","not_after":"2025-05-10T14:19:55","serial_number":"042257f7bcc91c0994e9c3c76da6ee700a03","result_count":2}]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"office.mikoshi.de","first_cached":"2025-09-15T15:38:27.549467+00:00","last_upstream_query":"2025-09-15T15:38:27.549473+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":20275820856,"entry_timestamp":"2025-08-12T00:07:33.018","not_before":"2025-08-11T23:09:02","not_after":"2025-11-09T23:09:01","serial_number":"05c2c936c2f12251f76b59d3ad2854f50f78","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":20275819318,"entry_timestamp":"2025-08-12T00:07:32.912","not_before":"2025-08-11T23:09:02","not_after":"2025-11-09T23:09:01","serial_number":"05c2c936c2f12251f76b59d3ad2854f50f78","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":18987110425,"entry_timestamp":"2025-06-13T00:04:44.238","not_before":"2025-06-12T23:06:13","not_after":"2025-09-10T23:06:12","serial_number":"051acaa08d5d89e6f4063edabca209961196","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":18987111139,"entry_timestamp":"2025-06-13T00:04:43.915","not_before":"2025-06-12T23:06:13","not_after":"2025-09-10T23:06:12","serial_number":"051acaa08d5d89e6f4063edabca209961196","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":17831462745,"entry_timestamp":"2025-04-14T00:16:05.147","not_before":"2025-04-13T23:17:32","not_after":"2025-07-12T23:17:31","serial_number":"054ddaf61e4b9f57e8d56a9497df9149c395","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":17831369811,"entry_timestamp":"2025-04-14T00:16:03.009","not_before":"2025-04-13T23:17:32","not_after":"2025-07-12T23:17:31","serial_number":"054ddaf61e4b9f57e8d56a9497df9149c395","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":17170808669,"entry_timestamp":"2025-02-13T00:01:46.473","not_before":"2025-02-12T23:03:15","not_after":"2025-05-13T23:03:14","serial_number":"03deb0895b1825adbbbaf9addcd01dd92799","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":16720296902,"entry_timestamp":"2025-02-13T00:01:45.743","not_before":"2025-02-12T23:03:15","not_after":"2025-05-13T23:03:14","serial_number":"03deb0895b1825adbbbaf9addcd01dd92799","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":17122359365,"entry_timestamp":"2025-02-09T15:19:36.715","not_before":"2025-02-09T14:21:06","not_after":"2025-05-10T14:21:05","serial_number":"04610182dee49a266a3d43aadacfd0b41e27","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"office.mikoshi.de","name_value":"office.mikoshi.de","id":16635528699,"entry_timestamp":"2025-02-09T15:19:36.337","not_before":"2025-02-09T14:21:06","not_after":"2025-05-10T14:21:05","serial_number":"04610182dee49a266a3d43aadacfd0b41e27","result_count":2}]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"proxy.piped.mikoshi.de","first_cached":"2025-09-14T22:45:40.325331+00:00","last_upstream_query":"2025-09-15T15:38:51.713680+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":20189220475,"entry_timestamp":"2025-08-08T00:05:07.009","not_before":"2025-08-07T23:06:36","not_after":"2025-11-05T23:06:35","serial_number":"05c0d9d7f7cae49c673abcdb28c4412d78d6","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":20189220702,"entry_timestamp":"2025-08-08T00:05:06.824","not_before":"2025-08-07T23:06:36","not_after":"2025-11-05T23:06:35","serial_number":"05c0d9d7f7cae49c673abcdb28c4412d78d6","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":20060639877,"entry_timestamp":"2025-08-02T00:01:52.165","not_before":"2025-08-01T23:03:21","not_after":"2025-10-30T23:03:20","serial_number":"05cb1fd70bdfe7e07c8a952b4e089c39d1da","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":20060638194,"entry_timestamp":"2025-08-02T00:01:51.846","not_before":"2025-08-01T23:03:21","not_after":"2025-10-30T23:03:20","serial_number":"05cb1fd70bdfe7e07c8a952b4e089c39d1da","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":19929369417,"entry_timestamp":"2025-07-27T00:02:26.4","not_before":"2025-07-26T23:03:54","not_after":"2025-10-24T23:03:53","serial_number":"063f8984c7c967816e258a7216ecd1959f34","result_count":2},{"issuer_ca_id":295810,"issuer_name":"C=US, O=Let's Encrypt, CN=E5","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":19929369596,"entry_timestamp":"2025-07-27T00:02:24.492","not_before":"2025-07-26T23:03:54","not_after":"2025-10-24T23:03:53","serial_number":"063f8984c7c967816e258a7216ecd1959f34","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":19803763772,"entry_timestamp":"2025-07-21T00:00:57.2","not_before":"2025-07-20T23:02:26","not_after":"2025-10-18T23:02:25","serial_number":"0572a8c3609d51428351eb07244bcd441072","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":19803763758,"entry_timestamp":"2025-07-21T00:00:56.856","not_before":"2025-07-20T23:02:26","not_after":"2025-10-18T23:02:25","serial_number":"0572a8c3609d51428351eb07244bcd441072","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":19668416256,"entry_timestamp":"2025-07-15T00:00:58.486","not_before":"2025-07-14T23:02:28","not_after":"2025-10-12T23:02:27","serial_number":"06664191409b60fb8f1241b999cd884247cb","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":19668412981,"entry_timestamp":"2025-07-15T00:00:58.222","not_before":"2025-07-14T23:02:28","not_after":"2025-10-12T23:02:27","serial_number":"06664191409b60fb8f1241b999cd884247cb","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":19523857935,"entry_timestamp":"2025-07-08T06:31:01.3","not_before":"2025-07-08T05:32:26","not_after":"2025-10-06T05:32:25","serial_number":"05def41b49262bc3c90ceef09a3c53fdb897","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"proxy.piped.mikoshi.de","name_value":"proxy.piped.mikoshi.de","id":19523855448,"entry_timestamp":"2025-07-08T06:30:56.952","not_before":"2025-07-08T05:32:26","not_after":"2025-10-06T05:32:25","serial_number":"05def41b49262bc3c90ceef09a3c53fdb897","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"push.mikoshi.de","first_cached":"2025-09-15T15:36:51.090852+00:00","last_upstream_query":"2025-09-15T15:36:51.090855+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":20275820653,"entry_timestamp":"2025-08-12T00:06:47.342","not_before":"2025-08-11T23:08:16","not_after":"2025-11-09T23:08:15","serial_number":"052026f4f3142d63bd9ca3feae317ece4ee9","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":20275820169,"entry_timestamp":"2025-08-12T00:06:47.109","not_before":"2025-08-11T23:08:16","not_after":"2025-11-09T23:08:15","serial_number":"052026f4f3142d63bd9ca3feae317ece4ee9","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":18987077850,"entry_timestamp":"2025-06-13T00:04:10.192","not_before":"2025-06-12T23:05:37","not_after":"2025-09-10T23:05:36","serial_number":"0546092d0c32d96eb7fcf0ce30e5e65ea3e1","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":18987099791,"entry_timestamp":"2025-06-13T00:04:07.918","not_before":"2025-06-12T23:05:37","not_after":"2025-09-10T23:05:36","serial_number":"0546092d0c32d96eb7fcf0ce30e5e65ea3e1","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":17831474873,"entry_timestamp":"2025-04-14T00:14:50.26","not_before":"2025-04-13T23:16:19","not_after":"2025-07-12T23:16:18","serial_number":"0513fd56736b1233441a3275762b03fc9eb0","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":17831474384,"entry_timestamp":"2025-04-14T00:14:50.004","not_before":"2025-04-13T23:16:19","not_after":"2025-07-12T23:16:18","serial_number":"0513fd56736b1233441a3275762b03fc9eb0","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":17170801795,"entry_timestamp":"2025-02-13T00:01:17.002","not_before":"2025-02-12T23:02:46","not_after":"2025-05-13T23:02:45","serial_number":"03487570ab1eaa62f8f4c3b61a8b90eda732","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":16715026255,"entry_timestamp":"2025-02-13T00:01:16.729","not_before":"2025-02-12T23:02:46","not_after":"2025-05-13T23:02:45","serial_number":"03487570ab1eaa62f8f4c3b61a8b90eda732","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":17122309940,"entry_timestamp":"2025-02-09T15:17:17.076","not_before":"2025-02-09T14:18:46","not_after":"2025-05-10T14:18:45","serial_number":"047ea82614cb4449bda99fc1ba86eb49b5c8","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"push.mikoshi.de","name_value":"push.mikoshi.de","id":16635500733,"entry_timestamp":"2025-02-09T15:17:16.594","not_before":"2025-02-09T14:18:46","not_after":"2025-05-10T14:18:45","serial_number":"047ea82614cb4449bda99fc1ba86eb49b5c8","result_count":2}]}

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"s3.cc24.dev","first_cached":"2025-09-14T21:38:35.568153+00:00","last_upstream_query":"2025-09-14T21:38:35.568155+00:00","upstream_query_count":1,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"console.s3.cc24.dev","name_value":"console.s3.cc24.dev","id":20287575466,"entry_timestamp":"2025-08-12T12:55:37.077","not_before":"2025-08-12T11:57:05","not_after":"2025-11-10T11:57:04","serial_number":"066bdfa83088f8d7e67284da94dd5d122ed6","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"console.s3.cc24.dev","name_value":"console.s3.cc24.dev","id":20287575457,"entry_timestamp":"2025-08-12T12:55:36.75","not_before":"2025-08-12T11:57:05","not_after":"2025-11-10T11:57:04","serial_number":"066bdfa83088f8d7e67284da94dd5d122ed6","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"s3.cc24.dev","name_value":"s3.cc24.dev","id":20285693027,"entry_timestamp":"2025-08-12T10:58:41.611","not_before":"2025-08-12T10:00:11","not_after":"2025-11-10T10:00:10","serial_number":"06f0f73404258136977fdbfe4cf51db786a7","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"s3.cc24.dev","name_value":"s3.cc24.dev","id":20285693495,"entry_timestamp":"2025-08-12T10:58:41.366","not_before":"2025-08-12T10:00:11","not_after":"2025-11-10T10:00:10","serial_number":"06f0f73404258136977fdbfe4cf51db786a7","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"se.mikoshi.de","first_cached":"2025-09-14T22:37:29.207379+00:00","last_upstream_query":"2025-09-15T15:40:52.328157+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":20296592765,"entry_timestamp":"2025-08-13T00:02:43.765","not_before":"2025-08-12T23:04:13","not_after":"2025-11-10T23:04:12","serial_number":"05688b90444fda4afff5208583d9b4c6b453","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":20296592676,"entry_timestamp":"2025-08-13T00:02:43.253","not_before":"2025-08-12T23:04:13","not_after":"2025-11-10T23:04:12","serial_number":"05688b90444fda4afff5208583d9b4c6b453","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":19007481148,"entry_timestamp":"2025-06-14T00:01:17.383","not_before":"2025-06-13T23:02:46","not_after":"2025-09-11T23:02:45","serial_number":"057f456b58a7ea34177d50585ea3b4561e6b","result_count":2},{"issuer_ca_id":295814,"issuer_name":"C=US, O=Let's Encrypt, CN=R10","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":19007493221,"entry_timestamp":"2025-06-14T00:01:17.049","not_before":"2025-06-13T23:02:46","not_after":"2025-09-11T23:02:45","serial_number":"057f456b58a7ea34177d50585ea3b4561e6b","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":17850961291,"entry_timestamp":"2025-04-15T00:00:37.293","not_before":"2025-04-14T23:02:02","not_after":"2025-07-13T23:02:01","serial_number":"052c5b098d5fa135547d9e3d7f7496b63af6","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":17850962036,"entry_timestamp":"2025-04-15T00:00:32.962","not_before":"2025-04-14T23:02:02","not_after":"2025-07-13T23:02:01","serial_number":"052c5b098d5fa135547d9e3d7f7496b63af6","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":17170796076,"entry_timestamp":"2025-02-13T00:00:29.982","not_before":"2025-02-12T23:01:59","not_after":"2025-05-13T23:01:58","serial_number":"04ecdefe30d1b5ce4d3ebb91bbbb2257bd15","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":16704095774,"entry_timestamp":"2025-02-13T00:00:29.674","not_before":"2025-02-12T23:01:59","not_after":"2025-05-13T23:01:58","serial_number":"04ecdefe30d1b5ce4d3ebb91bbbb2257bd15","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":17122261002,"entry_timestamp":"2025-02-09T15:13:15.78","not_before":"2025-02-09T14:14:45","not_after":"2025-05-10T14:14:44","serial_number":"03972d789d00e59045e4f37eae917438e10a","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":16635473126,"entry_timestamp":"2025-02-09T15:13:15.412","not_before":"2025-02-09T14:14:45","not_after":"2025-05-10T14:14:44","serial_number":"03972d789d00e59045e4f37eae917438e10a","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":11490113222,"entry_timestamp":"2023-12-16T00:55:58.472","not_before":"2023-12-15T23:55:57","not_after":"2024-03-14T23:55:56","serial_number":"0386fd7fd921ad63f4805ad4f593819aa238","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"se.mikoshi.de","name_value":"se.mikoshi.de","id":11422214995,"entry_timestamp":"2023-12-16T00:55:57.647","not_before":"2023-12-15T23:55:57","not_after":"2024-03-14T23:55:56","serial_number":"0386fd7fd921ad63f4805ad4f593819aa238","result_count":2}]}

View File

@@ -1 +0,0 @@
{"domain":"signaling.mikoshi.de","first_cached":"2025-09-14T21:05:14.189157+00:00","last_upstream_query":"2025-09-15T15:36:14.904100+00:00","upstream_query_count":3,"certificates":[{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":19208276669,"entry_timestamp":"2025-06-23T18:21:11.885","not_before":"2025-06-23T17:22:40","not_after":"2025-09-21T17:22:39","serial_number":"0542fce9cb99bb1c1d18e5e452c90d850936","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":19208276557,"entry_timestamp":"2025-06-23T18:21:11.215","not_before":"2025-06-23T17:22:40","not_after":"2025-09-21T17:22:39","serial_number":"0542fce9cb99bb1c1d18e5e452c90d850936","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":19208272013,"entry_timestamp":"2025-06-23T18:20:29.619","not_before":"2025-06-23T17:21:56","not_after":"2025-09-21T17:21:55","serial_number":"0540be6c8cb99dcaa5492af7b934f40466f9","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":19208263539,"entry_timestamp":"2025-06-23T18:20:26.82","not_before":"2025-06-23T17:21:56","not_after":"2025-09-21T17:21:55","serial_number":"0540be6c8cb99dcaa5492af7b934f40466f9","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":17428224909,"entry_timestamp":"2025-03-23T15:21:03.771","not_before":"2025-03-23T14:22:33","not_after":"2025-06-21T14:22:32","serial_number":"0537513d69487cead5f018b5322aa54fb52e","result_count":2},{"issuer_ca_id":295819,"issuer_name":"C=US, O=Let's Encrypt, CN=E6","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":17346408492,"entry_timestamp":"2025-03-23T15:21:03.617","not_before":"2025-03-23T14:22:33","not_after":"2025-06-21T14:22:32","serial_number":"0537513d69487cead5f018b5322aa54fb52e","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":17170806575,"entry_timestamp":"2025-02-13T00:01:39.507","not_before":"2025-02-12T23:03:07","not_after":"2025-05-13T23:03:06","serial_number":"04a3141d80551d2287647211445f32131b19","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":16704105641,"entry_timestamp":"2025-02-13T00:01:37.463","not_before":"2025-02-12T23:03:07","not_after":"2025-05-13T23:03:06","serial_number":"04a3141d80551d2287647211445f32131b19","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":17122350772,"entry_timestamp":"2025-02-09T15:19:01.645","not_before":"2025-02-09T14:20:31","not_after":"2025-05-10T14:20:30","serial_number":"0456c53707eac4c8e79109b09eb9257674ef","result_count":2},{"issuer_ca_id":295815,"issuer_name":"C=US, O=Let's Encrypt, CN=R11","common_name":"signaling.mikoshi.de","name_value":"signaling.mikoshi.de","id":16635514012,"entry_timestamp":"2025-02-09T15:19:01.438","not_before":"2025-02-09T14:20:31","not_after":"2025-05-10T14:20:30","serial_number":"0456c53707eac4c8e79109b09eb9257674ef","result_count":2}]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
{"domain":"test.mikoshi.de","first_cached":"2025-09-14T22:38:58.849950+00:00","last_upstream_query":"2025-09-15T15:34:55.551888+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"test.mikoshi.de","name_value":"test.mikoshi.de","id":11527598498,"entry_timestamp":"2023-12-19T19:30:11.511","not_before":"2023-12-19T18:30:10","not_after":"2024-03-18T18:30:09","serial_number":"0460a2ce513e2971556b911e64d3c06c876d","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"test.mikoshi.de","name_value":"test.mikoshi.de","id":11448041639,"entry_timestamp":"2023-12-19T19:30:10.729","not_before":"2023-12-19T18:30:10","not_after":"2024-03-18T18:30:09","serial_number":"0460a2ce513e2971556b911e64d3c06c876d","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"test.mikoshi.de","name_value":"test.mikoshi.de","id":11487822748,"entry_timestamp":"2023-12-15T22:27:24.154","not_before":"2023-12-15T21:27:23","not_after":"2024-03-14T21:27:22","serial_number":"03524dd265a8db8b1d3b8ae9236457b06564","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"test.mikoshi.de","name_value":"test.mikoshi.de","id":11420685419,"entry_timestamp":"2023-12-15T22:27:23.743","not_before":"2023-12-15T21:27:23","not_after":"2024-03-14T21:27:22","serial_number":"03524dd265a8db8b1d3b8ae9236457b06564","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"test.mikoshi.de","name_value":"test.mikoshi.de","id":10845362810,"entry_timestamp":"2023-10-20T20:03:11.855","not_before":"2023-10-20T19:03:11","not_after":"2024-01-18T19:03:10","serial_number":"04fb05ec64b2614143f419dfe3c1e058a6f8","result_count":2},{"issuer_ca_id":183267,"issuer_name":"C=US, O=Let's Encrypt, CN=R3","common_name":"test.mikoshi.de","name_value":"test.mikoshi.de","id":10845356148,"entry_timestamp":"2023-10-20T20:03:11.585","not_before":"2023-10-20T19:03:11","not_after":"2024-01-18T19:03:10","serial_number":"04fb05ec64b2614143f419dfe3c1e058a6f8","result_count":2}]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,32 +0,0 @@
{
"domain": "www.overcuriousity.org",
"first_cached": "2025-09-14T21:16:24.041839+00:00",
"last_upstream_query": "2025-09-15T19:08:25.160183+00:00",
"upstream_query_count": 3,
"certificates": [
{
"issuer_ca_id": 295819,
"issuer_name": "C=US, O=Let's Encrypt, CN=E6",
"common_name": "signaling.mikoshi.de",
"name_value": "www.overcuriousity.org",
"id": 19208272013,
"entry_timestamp": "2025-06-23T18:20:29.619",
"not_before": "2025-06-23T17:21:56",
"not_after": "2025-09-21T17:21:55",
"serial_number": "0540be6c8cb99dcaa5492af7b934f40466f9",
"result_count": 1
},
{
"issuer_ca_id": 295819,
"issuer_name": "C=US, O=Let's Encrypt, CN=E6",
"common_name": "signaling.mikoshi.de",
"name_value": "www.overcuriousity.org",
"id": 19208263539,
"entry_timestamp": "2025-06-23T18:20:26.82",
"not_before": "2025-06-23T17:21:56",
"not_after": "2025-09-21T17:21:55",
"serial_number": "0540be6c8cb99dcaa5492af7b934f40466f9",
"result_count": 1
}
]
}

View File

@@ -1 +0,0 @@
{"domain":"zap.mikoshi.de","first_cached":"2025-09-14T22:37:56.901178+00:00","last_upstream_query":"2025-09-15T15:36:02.901638+00:00","upstream_query_count":2,"certificates":[{"issuer_ca_id":295813,"issuer_name":"C=US, O=Let's Encrypt, CN=E7","common_name":"zap.mikoshi.de","name_value":"zap.mikoshi.de","id":20979146330,"entry_timestamp":"2025-09-13T00:01:36.857","not_before":"2025-09-12T23:03:06","not_after":"2025-12-11T23:03:05","serial_number":"060330123144270f9c8614ee282e43b5b676","result_count":2},{"issuer_ca_id":295813,"issuer_name":"C=US, O=Let's Encrypt, CN=E7","common_name":"zap.mikoshi.de","name_value":"zap.mikoshi.de","id":20979146321,"entry_timestamp":"2025-09-13T00:01:36.705","not_before":"2025-09-12T23:03:06","not_after":"2025-12-11T23:03:05","serial_number":"060330123144270f9c8614ee282e43b5b676","result_count":2},{"issuer_ca_id":295809,"issuer_name":"C=US, O=Let's Encrypt, CN=E8","common_name":"zap.mikoshi.de","name_value":"zap.mikoshi.de","id":20955786867,"entry_timestamp":"2025-09-12T00:00:06.78","not_before":"2025-09-11T23:01:36","not_after":"2025-12-10T23:01:35","serial_number":"069fdbfcf2023341872c23d4eadf03dbd600","result_count":2},{"issuer_ca_id":295809,"issuer_name":"C=US, O=Let's Encrypt, CN=E8","common_name":"zap.mikoshi.de","name_value":"zap.mikoshi.de","id":20955786725,"entry_timestamp":"2025-09-12T00:00:06.615","not_before":"2025-09-11T23:01:36","not_after":"2025-12-10T23:01:35","serial_number":"069fdbfcf2023341872c23d4eadf03dbd600","result_count":2},{"issuer_ca_id":295809,"issuer_name":"C=US, O=Let's Encrypt, CN=E8","common_name":"zap.mikoshi.de","name_value":"zap.mikoshi.de","id":20754243960,"entry_timestamp":"2025-09-03T00:01:13.766","not_before":"2025-09-02T23:02:41","not_after":"2025-12-01T23:02:40","serial_number":"05c8fbc52b5d8c0ca2089679fd1574503cf0","result_count":2},{"issuer_ca_id":295809,"issuer_name":"C=US, O=Let's Encrypt, CN=E8","common_name":"zap.mikoshi.de","name_value":"zap.mikoshi.de","id":20754243261,"entry_timestamp":"2025-09-03T00:01:11.505","not_before":"2025-09-02T23:02:41","not_after":"2025-12-01T23:02:40","serial_number":"05c8fbc52b5d8c0ca2089679fd1574503cf0","result_count":2},{"issuer_ca_id":295813,"issuer_name":"C=US, O=Let's Encrypt, CN=E7","common_name":"zap.mikoshi.de","name_value":"zap.mikoshi.de","id":20539947210,"entry_timestamp":"2025-08-24T10:34:58.674","not_before":"2025-08-24T09:36:27","not_after":"2025-11-22T09:36:26","serial_number":"062deaf87750f6cf54f0027bbf6f9617447b","result_count":2},{"issuer_ca_id":295813,"issuer_name":"C=US, O=Let's Encrypt, CN=E7","common_name":"zap.mikoshi.de","name_value":"zap.mikoshi.de","id":20539914846,"entry_timestamp":"2025-08-24T10:34:58.16","not_before":"2025-08-24T09:36:27","not_after":"2025-11-22T09:36:26","serial_number":"062deaf87750f6cf54f0027bbf6f9617447b","result_count":2}]}

View File

@@ -1,5 +1,7 @@
# DNScope-reduced/config.py
""" """
Configuration management for DNSRecon tool. Configuration management for DNScope tool.
Handles API key storage, rate limiting, and default settings. Handles API key storage, rate limiting, and default settings.
""" """
@@ -11,7 +13,7 @@ from dotenv import load_dotenv
load_dotenv() load_dotenv()
class Config: class Config:
"""Configuration manager for DNSRecon application.""" """Configuration manager for DNScope application."""
def __init__(self): def __init__(self):
"""Initialize configuration with default values.""" """Initialize configuration with default values."""
@@ -19,27 +21,31 @@ class Config:
# --- General Settings --- # --- General Settings ---
self.default_recursion_depth = 2 self.default_recursion_depth = 2
self.default_timeout = 30 self.default_timeout = 60
self.max_concurrent_requests = 5 self.max_concurrent_requests = 1
self.large_entity_threshold = 100 self.large_entity_threshold = 100
self.max_retries_per_target = 8 self.max_retries_per_target = 8
self.cache_expiry_hours = 12
# --- Graph Polling Performance Settings ---
self.graph_polling_node_threshold = 100 # Stop graph auto-polling above this many nodes
# --- Provider Caching Settings --- # --- Provider Caching Settings ---
self.cache_timeout_hours = 6 # Provider-specific cache timeout self.cache_timeout_hours = 6 # Provider-specific cache timeout
# --- Rate Limiting (requests per minute) --- # --- Rate Limiting (requests per minute) ---
self.rate_limits = { self.rate_limits = {
'crtsh': 30, 'crtsh': 5,
'shodan': 60, 'shodan': 60,
'dns': 100 'dns': 100,
'correlation': 0 # Set to 0 to make sure correlations run last
} }
# --- Provider Settings --- # --- Provider Settings ---
self.enabled_providers = { self.enabled_providers = {
'crtsh': True, 'crtsh': True,
'dns': True, 'dns': True,
'shodan': False 'shodan': False,
'correlation': True # Enable the new provider by default
} }
# --- Logging --- # --- Logging ---
@@ -67,9 +73,11 @@ class Config:
self.max_concurrent_requests = int(os.getenv('MAX_CONCURRENT_REQUESTS', self.max_concurrent_requests)) self.max_concurrent_requests = int(os.getenv('MAX_CONCURRENT_REQUESTS', self.max_concurrent_requests))
self.large_entity_threshold = int(os.getenv('LARGE_ENTITY_THRESHOLD', self.large_entity_threshold)) self.large_entity_threshold = int(os.getenv('LARGE_ENTITY_THRESHOLD', self.large_entity_threshold))
self.max_retries_per_target = int(os.getenv('MAX_RETRIES_PER_TARGET', self.max_retries_per_target)) self.max_retries_per_target = int(os.getenv('MAX_RETRIES_PER_TARGET', self.max_retries_per_target))
self.cache_expiry_hours = int(os.getenv('CACHE_EXPIRY_HOURS', self.cache_expiry_hours))
self.cache_timeout_hours = int(os.getenv('CACHE_TIMEOUT_HOURS', self.cache_timeout_hours)) self.cache_timeout_hours = int(os.getenv('CACHE_TIMEOUT_HOURS', self.cache_timeout_hours))
# Override graph polling threshold from environment
self.graph_polling_node_threshold = int(os.getenv('GRAPH_POLLING_NODE_THRESHOLD', self.graph_polling_node_threshold))
# Override Flask and session settings # Override Flask and session settings
self.flask_host = os.getenv('FLASK_HOST', self.flask_host) self.flask_host = os.getenv('FLASK_HOST', self.flask_host)
self.flask_port = int(os.getenv('FLASK_PORT', self.flask_port)) self.flask_port = int(os.getenv('FLASK_PORT', self.flask_port))
@@ -85,6 +93,60 @@ class Config:
self.enabled_providers[provider] = True self.enabled_providers[provider] = True
return True return True
def set_provider_enabled(self, provider: str, enabled: bool) -> bool:
"""
Set provider enabled status for the session.
Args:
provider: Provider name
enabled: Whether the provider should be enabled
Returns:
True if the setting was applied successfully
"""
provider_key = provider.lower()
self.enabled_providers[provider_key] = enabled
return True
def get_provider_enabled(self, provider: str) -> bool:
"""
Get provider enabled status.
Args:
provider: Provider name
Returns:
True if the provider is enabled
"""
provider_key = provider.lower()
return self.enabled_providers.get(provider_key, True) # Default to enabled
def bulk_set_provider_settings(self, provider_settings: dict) -> dict:
"""
Set multiple provider settings at once.
Args:
provider_settings: Dict of provider_name -> {'enabled': bool, ...}
Returns:
Dict with results for each provider
"""
results = {}
for provider_name, settings in provider_settings.items():
provider_key = provider_name.lower()
try:
if 'enabled' in settings:
self.enabled_providers[provider_key] = settings['enabled']
results[provider_key] = {'success': True, 'enabled': settings['enabled']}
else:
results[provider_key] = {'success': False, 'error': 'No enabled setting provided'}
except Exception as e:
results[provider_key] = {'success': False, 'error': str(e)}
return results
def get_api_key(self, provider: str) -> Optional[str]: def get_api_key(self, provider: str) -> Optional[str]:
"""Get API key for a provider.""" """Get API key for a provider."""
return self.api_keys.get(provider) return self.api_keys.get(provider)

View File

@@ -1,5 +1,5 @@
""" """
Core modules for DNSRecon passive reconnaissance tool. Core modules for DNScope passive reconnaissance tool.
Contains graph management, scanning orchestration, and forensic logging. Contains graph management, scanning orchestration, and forensic logging.
""" """

View File

@@ -1,8 +1,11 @@
# core/graph_manager.py # DNScope-reduced/core/graph_manager.py
""" """
Graph data model for DNSRecon using NetworkX. Graph data model for DNScope using NetworkX.
Manages in-memory graph storage with confidence scoring and forensic metadata. Manages in-memory graph storage with forensic metadata.
Now fully compatible with the unified ProviderResult data model.
UPDATED: Fixed correlation exclusion keys to match actual attribute names.
UPDATED: Removed export_json() method - now handled by ExportManager.
""" """
import re import re
from datetime import datetime, timezone from datetime import datetime, timezone
@@ -16,7 +19,8 @@ class NodeType(Enum):
"""Enumeration of supported node types.""" """Enumeration of supported node types."""
DOMAIN = "domain" DOMAIN = "domain"
IP = "ip" IP = "ip"
ASN = "asn" ISP = "isp"
CA = "ca"
LARGE_ENTITY = "large_entity" LARGE_ENTITY = "large_entity"
CORRELATION_OBJECT = "correlation_object" CORRELATION_OBJECT = "correlation_object"
@@ -26,8 +30,9 @@ class NodeType(Enum):
class GraphManager: class GraphManager:
""" """
Thread-safe graph manager for DNSRecon infrastructure mapping. Thread-safe graph manager for DNScope infrastructure mapping.
Uses NetworkX for in-memory graph storage with confidence scoring. Uses NetworkX for in-memory graph storage.
Compatible with unified ProviderResult data model.
""" """
def __init__(self): def __init__(self):
@@ -35,178 +40,37 @@ class GraphManager:
self.graph = nx.DiGraph() self.graph = nx.DiGraph()
self.creation_time = datetime.now(timezone.utc).isoformat() self.creation_time = datetime.now(timezone.utc).isoformat()
self.last_modified = self.creation_time self.last_modified = self.creation_time
self.correlation_index = {}
# Compile regex for date filtering for efficiency
self.date_pattern = re.compile(r'^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}')
def __getstate__(self): def add_node(self, node_id: str, node_type: NodeType, attributes: Optional[List[Dict[str, Any]]] = None,
"""Prepare GraphManager for pickling, excluding compiled regex."""
state = self.__dict__.copy()
# Compiled regex patterns are not always picklable
if 'date_pattern' in state:
del state['date_pattern']
return state
def __setstate__(self, state):
"""Restore GraphManager state and recompile regex."""
self.__dict__.update(state)
self.date_pattern = re.compile(r'^\d{4}-\d{2}-\d{2}[ T]\d{2}:\d{2}:\d{2}')
def _update_correlation_index(self, node_id: str, data: Any, path: List[str] = [], parent_attr: str = ""):
"""Recursively traverse metadata and add hashable values to the index with better path tracking."""
if path is None:
path = []
if isinstance(data, dict):
for key, value in data.items():
self._update_correlation_index(node_id, value, path + [key], key)
elif isinstance(data, list):
for i, item in enumerate(data):
# Instead of just using [i], include the parent attribute context
list_path_component = f"[{i}]" if not parent_attr else f"{parent_attr}[{i}]"
self._update_correlation_index(node_id, item, path + [list_path_component], parent_attr)
else:
self._add_to_correlation_index(node_id, data, ".".join(path), parent_attr)
def _add_to_correlation_index(self, node_id: str, value: Any, path_str: str, parent_attr: str = ""):
"""Add a hashable value to the correlation index, filtering out noise."""
if not isinstance(value, (str, int, float, bool)) or value is None:
return
# Ignore certain paths that contain noisy, non-unique identifiers
if any(keyword in path_str.lower() for keyword in ['count', 'total', 'timestamp', 'date']):
return
# Filter out common low-entropy values and date-like strings
if isinstance(value, str):
# FIXED: Prevent correlation on date/time strings.
if self.date_pattern.match(value):
return
if len(value) < 4 or value.lower() in ['true', 'false', 'unknown', 'none', 'crt.sh']:
return
elif isinstance(value, int) and (abs(value) < 1024 or abs(value) > 65535):
return # Ignore small integers and common port numbers
elif isinstance(value, bool):
return # Ignore boolean values
# Add the valuable correlation data to the index
if value not in self.correlation_index:
self.correlation_index[value] = {}
if node_id not in self.correlation_index[value]:
self.correlation_index[value][node_id] = []
# Store both the full path and the parent attribute for better edge labeling
correlation_entry = {
'path': path_str,
'parent_attr': parent_attr,
'meaningful_attr': self._extract_meaningful_attribute(path_str, parent_attr)
}
if correlation_entry not in self.correlation_index[value][node_id]:
self.correlation_index[value][node_id].append(correlation_entry)
def _extract_meaningful_attribute(self, path_str: str, parent_attr: str = "") -> str:
"""Extract the most meaningful attribute name from a path string."""
if not path_str:
return "unknown"
path_parts = path_str.split('.')
# Look for the last non-array-index part
for part in reversed(path_parts):
# Skip array indices like [0], [1], etc.
if not (part.startswith('[') and part.endswith(']') and part[1:-1].isdigit()):
# Clean up compound names like "hostnames[0]" to just "hostnames"
clean_part = re.sub(r'\[\d+\]$', '', part)
if clean_part:
return clean_part
# Fallback to parent attribute if available
if parent_attr:
return parent_attr
# Last resort - use the first meaningful part
for part in path_parts:
if not (part.startswith('[') and part.endswith(']') and part[1:-1].isdigit()):
clean_part = re.sub(r'\[\d+\]$', '', part)
if clean_part:
return clean_part
return "correlation"
def _check_for_correlations(self, new_node_id: str, data: Any, path: List[str] = [], parent_attr: str = "") -> List[Dict]:
"""Recursively traverse metadata to find correlations with existing data."""
if path is None:
path = []
all_correlations = []
if isinstance(data, dict):
for key, value in data.items():
if key == 'source': # Avoid correlating on the provider name
continue
all_correlations.extend(self._check_for_correlations(new_node_id, value, path + [key], key))
elif isinstance(data, list):
for i, item in enumerate(data):
list_path_component = f"[{i}]" if not parent_attr else f"{parent_attr}[{i}]"
all_correlations.extend(self._check_for_correlations(new_node_id, item, path + [list_path_component], parent_attr))
else:
value = data
if value in self.correlation_index:
existing_nodes_with_paths = self.correlation_index[value]
unique_nodes = set(existing_nodes_with_paths.keys())
unique_nodes.add(new_node_id)
if len(unique_nodes) < 2:
return all_correlations # Correlation must involve at least two distinct nodes
new_source = {
'node_id': new_node_id,
'path': ".".join(path),
'parent_attr': parent_attr,
'meaningful_attr': self._extract_meaningful_attribute(".".join(path), parent_attr)
}
all_sources = [new_source]
for node_id, path_entries in existing_nodes_with_paths.items():
for entry in path_entries:
if isinstance(entry, dict):
all_sources.append({
'node_id': node_id,
'path': entry['path'],
'parent_attr': entry.get('parent_attr', ''),
'meaningful_attr': entry.get('meaningful_attr', self._extract_meaningful_attribute(entry['path'], entry.get('parent_attr', '')))
})
else:
# Handle legacy string-only entries
all_sources.append({
'node_id': node_id,
'path': str(entry),
'parent_attr': '',
'meaningful_attr': self._extract_meaningful_attribute(str(entry))
})
all_correlations.append({
'value': value,
'sources': all_sources,
'nodes': list(unique_nodes)
})
return all_correlations
def add_node(self, node_id: str, node_type: NodeType, attributes: Optional[Dict[str, Any]] = None,
description: str = "", metadata: Optional[Dict[str, Any]] = None) -> bool: description: str = "", metadata: Optional[Dict[str, Any]] = None) -> bool:
"""Add a node to the graph, update attributes, and process correlations.""" """
Add a node to the graph, update attributes, and process correlations.
Now compatible with unified data model - attributes are dictionaries from converted StandardAttribute objects.
"""
is_new_node = not self.graph.has_node(node_id) is_new_node = not self.graph.has_node(node_id)
if is_new_node: if is_new_node:
self.graph.add_node(node_id, type=node_type.value, self.graph.add_node(node_id, type=node_type.value,
added_timestamp=datetime.now(timezone.utc).isoformat(), added_timestamp=datetime.now(timezone.utc).isoformat(),
attributes=attributes or {}, attributes=attributes or [], # Store as a list from the start
description=description, description=description,
metadata=metadata or {}) metadata=metadata or {})
else: else:
# Safely merge new attributes into existing attributes # Safely merge new attributes into the existing list of attributes
if attributes: if attributes:
existing_attributes = self.graph.nodes[node_id].get('attributes', {}) existing_attributes = self.graph.nodes[node_id].get('attributes', [])
existing_attributes.update(attributes)
# Handle cases where old data might still be in dictionary format
if not isinstance(existing_attributes, list):
existing_attributes = []
# Create a set of existing attribute names for efficient duplicate checking
existing_attr_names = {attr['name'] for attr in existing_attributes}
for new_attr in attributes:
if new_attr['name'] not in existing_attr_names:
existing_attributes.append(new_attr)
existing_attr_names.add(new_attr['name'])
self.graph.nodes[node_id]['attributes'] = existing_attributes self.graph.nodes[node_id]['attributes'] = existing_attributes
if description: if description:
self.graph.nodes[node_id]['description'] = description self.graph.nodes[node_id]['description'] = description
@@ -215,199 +79,25 @@ class GraphManager:
existing_metadata.update(metadata) existing_metadata.update(metadata)
self.graph.nodes[node_id]['metadata'] = existing_metadata self.graph.nodes[node_id]['metadata'] = existing_metadata
if attributes and node_type != NodeType.CORRELATION_OBJECT:
correlations = self._check_for_correlations(node_id, attributes)
for corr in correlations:
value = corr['value']
# STEP 1: Substring check against all existing nodes
if self._correlation_value_matches_existing_node(value):
# Skip creating correlation node - would be redundant
continue
eligible_nodes = set(corr['nodes'])
if len(eligible_nodes) < 2:
# Need at least 2 nodes to create a correlation
continue
# STEP 3: Check for existing correlation node with same connection pattern
correlation_nodes_with_pattern = self._find_correlation_nodes_with_same_pattern(eligible_nodes)
if correlation_nodes_with_pattern:
# STEP 4: Merge with existing correlation node
target_correlation_node = correlation_nodes_with_pattern[0]
self._merge_correlation_values(target_correlation_node, value, corr)
else:
# STEP 5: Create new correlation node for eligible nodes only
correlation_node_id = f"corr_{abs(hash(str(sorted(eligible_nodes))))}"
self.add_node(correlation_node_id, NodeType.CORRELATION_OBJECT,
metadata={'values': [value], 'sources': corr['sources'],
'correlated_nodes': list(eligible_nodes)})
# Create edges from eligible nodes to this correlation node with better labeling
for c_node_id in eligible_nodes:
if self.graph.has_node(c_node_id):
# Find the best attribute name for this node
meaningful_attr = self._find_best_attribute_name_for_node(c_node_id, corr['sources'])
relationship_type = f"c_{meaningful_attr}"
self.add_edge(c_node_id, correlation_node_id, relationship_type, confidence_score=0.9)
self._update_correlation_index(node_id, attributes)
self.last_modified = datetime.now(timezone.utc).isoformat() self.last_modified = datetime.now(timezone.utc).isoformat()
return is_new_node return is_new_node
def _find_best_attribute_name_for_node(self, node_id: str, sources: List[Dict]) -> str:
"""Find the best attribute name for a correlation edge by looking at the sources."""
node_sources = [s for s in sources if s['node_id'] == node_id]
if not node_sources:
return "correlation"
# Use the meaningful_attr if available
for source in node_sources:
meaningful_attr = source.get('meaningful_attr')
if meaningful_attr and meaningful_attr != "unknown":
return meaningful_attr
# Fallback to parent_attr
for source in node_sources:
parent_attr = source.get('parent_attr')
if parent_attr:
return parent_attr
# Last resort - extract from path
for source in node_sources:
path = source.get('path', '')
if path:
extracted = self._extract_meaningful_attribute(path)
if extracted != "unknown":
return extracted
return "correlation"
def _has_direct_edge_bidirectional(self, node_a: str, node_b: str) -> bool:
"""
Check if there's a direct edge between two nodes in either direction.
Returns True if node_a→node_b OR node_b→node_a exists.
"""
return (self.graph.has_edge(node_a, node_b) or
self.graph.has_edge(node_b, node_a))
def _correlation_value_matches_existing_node(self, correlation_value: str) -> bool:
"""
Check if correlation value contains any existing node ID as substring.
Returns True if match found (correlation node should NOT be created).
"""
correlation_str = str(correlation_value).lower()
# Check against all existing nodes
for existing_node_id in self.graph.nodes():
if existing_node_id.lower() in correlation_str:
return True
return False
def _find_correlation_nodes_with_same_pattern(self, node_set: set) -> List[str]:
"""
Find existing correlation nodes that have the exact same pattern of connected nodes.
Returns list of correlation node IDs with matching patterns.
"""
correlation_nodes = self.get_nodes_by_type(NodeType.CORRELATION_OBJECT)
matching_nodes = []
for corr_node_id in correlation_nodes:
# Get all nodes connected to this correlation node
connected_nodes = set()
# Add all predecessors (nodes pointing TO the correlation node)
connected_nodes.update(self.graph.predecessors(corr_node_id))
# Add all successors (nodes pointed TO by the correlation node)
connected_nodes.update(self.graph.successors(corr_node_id))
# Check if the pattern matches exactly
if connected_nodes == node_set:
matching_nodes.append(corr_node_id)
return matching_nodes
def _merge_correlation_values(self, target_node_id: str, new_value: Any, corr_data: Dict) -> None:
"""
Merge a new correlation value into an existing correlation node.
Uses same logic as large entity merging.
"""
if not self.graph.has_node(target_node_id):
return
target_metadata = self.graph.nodes[target_node_id]['metadata']
# Get existing values (ensure it's a list)
existing_values = target_metadata.get('values', [])
if not isinstance(existing_values, list):
existing_values = [existing_values]
# Add new value if not already present
if new_value not in existing_values:
existing_values.append(new_value)
# Merge sources
existing_sources = target_metadata.get('sources', [])
new_sources = corr_data.get('sources', [])
# Create set of unique sources based on (node_id, path) tuples
source_set = set()
for source in existing_sources + new_sources:
source_tuple = (source['node_id'], source.get('path', ''))
source_set.add(source_tuple)
# Convert back to list of dictionaries
merged_sources = [{'node_id': nid, 'path': path} for nid, path in source_set]
# Update metadata
target_metadata.update({
'values': existing_values,
'sources': merged_sources,
'correlated_nodes': list(set(target_metadata.get('correlated_nodes', []) + corr_data.get('nodes', []))),
'merge_count': len(existing_values),
'last_merge_timestamp': datetime.now(timezone.utc).isoformat()
})
# Update description to reflect merged nature
value_count = len(existing_values)
node_count = len(target_metadata['correlated_nodes'])
self.graph.nodes[target_node_id]['description'] = (
f"Correlation container with {value_count} merged values "
f"across {node_count} nodes"
)
def add_edge(self, source_id: str, target_id: str, relationship_type: str, def add_edge(self, source_id: str, target_id: str, relationship_type: str,
confidence_score: float = 0.5, source_provider: str = "unknown", source_provider: str = "unknown",
raw_data: Optional[Dict[str, Any]] = None) -> bool: raw_data: Optional[Dict[str, Any]] = None) -> bool:
"""Add or update an edge between two nodes, ensuring nodes exist.""" """
UPDATED: Add or update an edge between two nodes with raw relationship labels.
"""
if not self.graph.has_node(source_id) or not self.graph.has_node(target_id): if not self.graph.has_node(source_id) or not self.graph.has_node(target_id):
return False return False
new_confidence = confidence_score
if relationship_type.startswith("c_"): # UPDATED: Use raw relationship type - no formatting
edge_label = relationship_type edge_label = relationship_type
else:
edge_label = f"{source_provider}_{relationship_type}"
if self.graph.has_edge(source_id, target_id): # Add a new edge with raw attributes
# If edge exists, update confidence if the new score is higher.
if new_confidence > self.graph.edges[source_id, target_id].get('confidence_score', 0):
self.graph.edges[source_id, target_id]['confidence_score'] = new_confidence
self.graph.edges[source_id, target_id]['updated_timestamp'] = datetime.now(timezone.utc).isoformat()
self.graph.edges[source_id, target_id]['updated_by'] = source_provider
return False
# Add a new edge with all attributes.
self.graph.add_edge(source_id, target_id, self.graph.add_edge(source_id, target_id,
relationship_type=edge_label, relationship_type=edge_label,
confidence_score=new_confidence,
source_provider=source_provider, source_provider=source_provider,
discovery_timestamp=datetime.now(timezone.utc).isoformat(), discovery_timestamp=datetime.now(timezone.utc).isoformat(),
raw_data=raw_data or {}) raw_data=raw_data or {})
@@ -422,18 +112,6 @@ class GraphManager:
# Remove node from the graph (NetworkX handles removing connected edges) # Remove node from the graph (NetworkX handles removing connected edges)
self.graph.remove_node(node_id) self.graph.remove_node(node_id)
# Clean up the correlation index
keys_to_delete = []
for value, nodes in self.correlation_index.items():
if node_id in nodes:
del nodes[node_id]
if not nodes: # If no other nodes are associated with this value, remove it
keys_to_delete.append(value)
for key in keys_to_delete:
if key in self.correlation_index:
del self.correlation_index[key]
self.last_modified = datetime.now(timezone.utc).isoformat() self.last_modified = datetime.now(timezone.utc).isoformat()
return True return True
@@ -449,102 +127,92 @@ class GraphManager:
"""Get all nodes of a specific type.""" """Get all nodes of a specific type."""
return [n for n, d in self.graph.nodes(data=True) if d.get('type') == node_type.value] return [n for n, d in self.graph.nodes(data=True) if d.get('type') == node_type.value]
def get_neighbors(self, node_id: str) -> List[str]:
"""Get all unique neighbors (predecessors and successors) for a node."""
if not self.graph.has_node(node_id):
return []
return list(set(self.graph.predecessors(node_id)) | set(self.graph.successors(node_id)))
def get_high_confidence_edges(self, min_confidence: float = 0.8) -> List[Tuple[str, str, Dict]]:
"""Get edges with confidence score above a given threshold."""
return [(u, v, d) for u, v, d in self.graph.edges(data=True)
if d.get('confidence_score', 0) >= min_confidence]
def get_graph_data(self) -> Dict[str, Any]: def get_graph_data(self) -> Dict[str, Any]:
"""Export graph data formatted for frontend visualization.""" """
Export graph data formatted for frontend visualization.
SIMPLIFIED: No certificate styling - frontend handles all visual styling.
"""
nodes = [] nodes = []
for node_id, attrs in self.graph.nodes(data=True): for node_id, attrs in self.graph.nodes(data=True):
node_data = {'id': node_id, 'label': node_id, 'type': attrs.get('type', 'unknown'), node_data = {
'attributes': attrs.get('attributes', {}), 'id': node_id,
'label': node_id,
'type': attrs.get('type', 'unknown'),
'attributes': attrs.get('attributes', []), # Raw attributes list
'description': attrs.get('description', ''), 'description': attrs.get('description', ''),
'metadata': attrs.get('metadata', {}), 'metadata': attrs.get('metadata', {}),
'added_timestamp': attrs.get('added_timestamp')} 'added_timestamp': attrs.get('added_timestamp'),
# Customize node appearance based on type and attributes 'max_depth_reached': attrs.get('metadata', {}).get('max_depth_reached', False)
node_type = node_data['type'] }
attributes = node_data['attributes']
if node_type == 'domain' and attributes.get('certificates', {}).get('has_valid_cert') is False:
node_data['color'] = {'background': '#c7c7c7', 'border': '#999'} # Gray for invalid cert
# Add incoming and outgoing edges to node data # Add incoming and outgoing edges to node data
if self.graph.has_node(node_id): if self.graph.has_node(node_id):
node_data['incoming_edges'] = [{'from': u, 'data': d} for u, _, d in self.graph.in_edges(node_id, data=True)] node_data['incoming_edges'] = [
node_data['outgoing_edges'] = [{'to': v, 'data': d} for _, v, d in self.graph.out_edges(node_id, data=True)] {'from': u, 'data': d} for u, _, d in self.graph.in_edges(node_id, data=True)
]
node_data['outgoing_edges'] = [
{'to': v, 'data': d} for _, v, d in self.graph.out_edges(node_id, data=True)
]
nodes.append(node_data) nodes.append(node_data)
edges = [] edges = []
for source, target, attrs in self.graph.edges(data=True): for source, target, attrs in self.graph.edges(data=True):
edges.append({'from': source, 'to': target, edges.append({
'from': source,
'to': target,
'label': attrs.get('relationship_type', ''), 'label': attrs.get('relationship_type', ''),
'confidence_score': attrs.get('confidence_score', 0),
'source_provider': attrs.get('source_provider', ''), 'source_provider': attrs.get('source_provider', ''),
'discovery_timestamp': attrs.get('discovery_timestamp')}) 'discovery_timestamp': attrs.get('discovery_timestamp'),
'raw_data': attrs.get('raw_data', {})
})
return { return {
'nodes': nodes, 'edges': edges, 'nodes': nodes,
'edges': edges,
'statistics': self.get_statistics()['basic_metrics'] 'statistics': self.get_statistics()['basic_metrics']
} }
def export_json(self) -> Dict[str, Any]: def get_statistics(self) -> Dict[str, Any]:
"""Export complete graph data as a JSON-serializable dictionary.""" """Get comprehensive statistics about the graph with proper empty graph handling."""
graph_data = nx.node_link_data(self.graph) # Use NetworkX's built-in robust serializer
return { # FIXED: Handle empty graph case properly
'export_metadata': { node_count = self.get_node_count()
'export_timestamp': datetime.now(timezone.utc).isoformat(), edge_count = self.get_edge_count()
'graph_creation_time': self.creation_time,
'last_modified': self.last_modified, stats = {
'total_nodes': self.get_node_count(), 'basic_metrics': {
'total_edges': self.get_edge_count(), 'total_nodes': node_count,
'graph_format': 'dnsrecon_v1_nodeling' 'total_edges': edge_count,
'creation_time': self.creation_time,
'last_modified': self.last_modified
}, },
'graph': graph_data, 'node_type_distribution': {},
'statistics': self.get_statistics() 'relationship_type_distribution': {},
'provider_distribution': {}
} }
def _get_confidence_distribution(self) -> Dict[str, int]: # FIXED: Only calculate distributions if we have data
"""Get distribution of edge confidence scores.""" if node_count > 0:
distribution = {'high': 0, 'medium': 0, 'low': 0} # Calculate node type distributions
for _, _, data in self.graph.edges(data=True):
confidence = data.get('confidence_score', 0)
if confidence >= 0.8:
distribution['high'] += 1
elif confidence >= 0.6:
distribution['medium'] += 1
else:
distribution['low'] += 1
return distribution
def get_statistics(self) -> Dict[str, Any]:
"""Get comprehensive statistics about the graph."""
stats = {'basic_metrics': {'total_nodes': self.get_node_count(),
'total_edges': self.get_edge_count(),
'creation_time': self.creation_time,
'last_modified': self.last_modified},
'node_type_distribution': {}, 'relationship_type_distribution': {},
'confidence_distribution': self._get_confidence_distribution(),
'provider_distribution': {}}
# Calculate distributions
for node_type in NodeType: for node_type in NodeType:
stats['node_type_distribution'][node_type.value] = self.get_nodes_by_type(node_type).__len__() count = len(self.get_nodes_by_type(node_type))
if count > 0: # Only include types that exist
stats['node_type_distribution'][node_type.value] = count
if edge_count > 0:
# Calculate edge distributions
for _, _, data in self.graph.edges(data=True): for _, _, data in self.graph.edges(data=True):
rel_type = data.get('relationship_type', 'unknown') rel_type = data.get('relationship_type', 'unknown')
stats['relationship_type_distribution'][rel_type] = stats['relationship_type_distribution'].get(rel_type, 0) + 1 stats['relationship_type_distribution'][rel_type] = stats['relationship_type_distribution'].get(rel_type, 0) + 1
provider = data.get('source_provider', 'unknown') provider = data.get('source_provider', 'unknown')
stats['provider_distribution'][provider] = stats['provider_distribution'].get(provider, 0) + 1 stats['provider_distribution'][provider] = stats['provider_distribution'].get(provider, 0) + 1
return stats return stats
def clear(self) -> None: def clear(self) -> None:
"""Clear all nodes, edges, and indices from the graph.""" """Clear all nodes and edges from the graph."""
self.graph.clear() self.graph.clear()
self.correlation_index.clear()
self.creation_time = datetime.now(timezone.utc).isoformat() self.creation_time = datetime.now(timezone.utc).isoformat()
self.last_modified = self.creation_time self.last_modified = self.creation_time

View File

@@ -1,4 +1,4 @@
# dnsrecon/core/logger.py # DNScope/core/logger.py
import logging import logging
import threading import threading
@@ -30,7 +30,6 @@ class RelationshipDiscovery:
source_node: str source_node: str
target_node: str target_node: str
relationship_type: str relationship_type: str
confidence_score: float
provider: str provider: str
raw_data: Dict[str, Any] raw_data: Dict[str, Any]
discovery_method: str discovery_method: str
@@ -38,7 +37,7 @@ class RelationshipDiscovery:
class ForensicLogger: class ForensicLogger:
""" """
Thread-safe forensic logging system for DNSRecon. Thread-safe forensic logging system for DNScope.
Maintains detailed audit trail of all reconnaissance activities. Maintains detailed audit trail of all reconnaissance activities.
""" """
@@ -50,7 +49,7 @@ class ForensicLogger:
session_id: Unique identifier for this reconnaissance session session_id: Unique identifier for this reconnaissance session
""" """
self.session_id = session_id or self._generate_session_id() self.session_id = session_id or self._generate_session_id()
#self.lock = threading.Lock() self.lock = threading.Lock()
# Initialize audit trail storage # Initialize audit trail storage
self.api_requests: List[APIRequest] = [] self.api_requests: List[APIRequest] = []
@@ -66,7 +65,7 @@ class ForensicLogger:
} }
# Configure standard logger # Configure standard logger
self.logger = logging.getLogger(f'dnsrecon.{self.session_id}') self.logger = logging.getLogger(f'DNScope.{self.session_id}')
self.logger.setLevel(logging.INFO) self.logger.setLevel(logging.INFO)
# Create formatter for structured logging # Create formatter for structured logging
@@ -86,13 +85,15 @@ class ForensicLogger:
# Remove the unpickleable 'logger' attribute # Remove the unpickleable 'logger' attribute
if 'logger' in state: if 'logger' in state:
del state['logger'] del state['logger']
if 'lock' in state:
del state['lock']
return state return state
def __setstate__(self, state): def __setstate__(self, state):
"""Restore ForensicLogger after unpickling by reconstructing logger.""" """Restore ForensicLogger after unpickling by reconstructing logger."""
self.__dict__.update(state) self.__dict__.update(state)
# Re-initialize the 'logger' attribute # Re-initialize the 'logger' attribute
self.logger = logging.getLogger(f'dnsrecon.{self.session_id}') self.logger = logging.getLogger(f'DNScope.{self.session_id}')
self.logger.setLevel(logging.INFO) self.logger.setLevel(logging.INFO)
formatter = logging.Formatter( formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s' '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
@@ -101,10 +102,11 @@ class ForensicLogger:
console_handler = logging.StreamHandler() console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter) console_handler.setFormatter(formatter)
self.logger.addHandler(console_handler) self.logger.addHandler(console_handler)
self.lock = threading.Lock()
def _generate_session_id(self) -> str: def _generate_session_id(self) -> str:
"""Generate unique session identifier.""" """Generate unique session identifier."""
return f"dnsrecon_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}" return f"DNScope_{datetime.now(timezone.utc).strftime('%Y%m%d_%H%M%S')}"
def log_api_request(self, provider: str, url: str, method: str = "GET", def log_api_request(self, provider: str, url: str, method: str = "GET",
status_code: Optional[int] = None, status_code: Optional[int] = None,
@@ -149,12 +151,12 @@ class ForensicLogger:
# Log to standard logger # Log to standard logger
if error: if error:
self.logger.error(f"API Request Failed - {provider}: {url} - {error}") self.logger.error(f"API Request Failed.")
else: else:
self.logger.info(f"API Request - {provider}: {url} - Status: {status_code}") self.logger.info(f"API Request - {provider}: {url} - Status: {status_code}")
def log_relationship_discovery(self, source_node: str, target_node: str, def log_relationship_discovery(self, source_node: str, target_node: str,
relationship_type: str, confidence_score: float, relationship_type: str,
provider: str, raw_data: Dict[str, Any], provider: str, raw_data: Dict[str, Any],
discovery_method: str) -> None: discovery_method: str) -> None:
""" """
@@ -164,7 +166,6 @@ class ForensicLogger:
source_node: Source node identifier source_node: Source node identifier
target_node: Target node identifier target_node: Target node identifier
relationship_type: Type of relationship (e.g., 'SAN', 'A_Record') relationship_type: Type of relationship (e.g., 'SAN', 'A_Record')
confidence_score: Confidence score (0.0 to 1.0)
provider: Provider that discovered this relationship provider: Provider that discovered this relationship
raw_data: Raw data from provider response raw_data: Raw data from provider response
discovery_method: Method used to discover relationship discovery_method: Method used to discover relationship
@@ -174,7 +175,6 @@ class ForensicLogger:
source_node=source_node, source_node=source_node,
target_node=target_node, target_node=target_node,
relationship_type=relationship_type, relationship_type=relationship_type,
confidence_score=confidence_score,
provider=provider, provider=provider,
raw_data=raw_data, raw_data=raw_data,
discovery_method=discovery_method discovery_method=discovery_method
@@ -185,7 +185,7 @@ class ForensicLogger:
self.logger.info( self.logger.info(
f"Relationship Discovered - {source_node} -> {target_node} " f"Relationship Discovered - {source_node} -> {target_node} "
f"({relationship_type}) - Confidence: {confidence_score:.2f} - Provider: {provider}" f"({relationship_type}) - Provider: {provider}"
) )
def log_scan_start(self, target_domain: str, recursion_depth: int, def log_scan_start(self, target_domain: str, recursion_depth: int,
@@ -199,8 +199,6 @@ class ForensicLogger:
def log_scan_complete(self) -> None: def log_scan_complete(self) -> None:
"""Log the completion of a reconnaissance scan.""" """Log the completion of a reconnaissance scan."""
self.session_metadata['end_time'] = datetime.now(timezone.utc).isoformat() self.session_metadata['end_time'] = datetime.now(timezone.utc).isoformat()
self.session_metadata['providers_used'] = list(self.session_metadata['providers_used'])
self.session_metadata['target_domains'] = list(self.session_metadata['target_domains'])
self.logger.info(f"Scan Complete - Session: {self.session_id}") self.logger.info(f"Scan Complete - Session: {self.session_id}")
@@ -211,8 +209,12 @@ class ForensicLogger:
Returns: Returns:
Dictionary containing complete session audit trail Dictionary containing complete session audit trail
""" """
session_metadata_export = self.session_metadata.copy()
session_metadata_export['providers_used'] = list(session_metadata_export['providers_used'])
session_metadata_export['target_domains'] = list(session_metadata_export['target_domains'])
return { return {
'session_metadata': self.session_metadata.copy(), 'session_metadata': session_metadata_export,
'api_requests': [asdict(req) for req in self.api_requests], 'api_requests': [asdict(req) for req in self.api_requests],
'relationships': [asdict(rel) for rel in self.relationships], 'relationships': [asdict(rel) for rel in self.relationships],
'export_timestamp': datetime.now(timezone.utc).isoformat() 'export_timestamp': datetime.now(timezone.utc).isoformat()
@@ -235,7 +237,6 @@ class ForensicLogger:
'successful_requests': len([req for req in provider_requests if req.error is None]), 'successful_requests': len([req for req in provider_requests if req.error is None]),
'failed_requests': len([req for req in provider_requests if req.error is not None]), 'failed_requests': len([req for req in provider_requests if req.error is not None]),
'relationships_discovered': len(provider_relationships), 'relationships_discovered': len(provider_relationships),
'avg_confidence': sum(rel.confidence_score for rel in provider_relationships) / len(provider_relationships) if provider_relationships else 0
} }
return { return {

89
core/provider_result.py Normal file
View File

@@ -0,0 +1,89 @@
# DNScope-reduced/core/provider_result.py
"""
Unified data model for DNScope passive reconnaissance.
Standardizes the data structure across all providers to ensure consistent processing.
"""
from typing import Any, Optional, List, Dict
from dataclasses import dataclass, field
from datetime import datetime, timezone
@dataclass
class StandardAttribute:
"""A unified data structure for a single piece of information about a node."""
target_node: str
name: str
value: Any
type: str
provider: str
timestamp: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
metadata: Optional[Dict[str, Any]] = field(default_factory=dict)
@dataclass
class Relationship:
"""A unified data structure for a directional link between two nodes."""
source_node: str
target_node: str
relationship_type: str
provider: str
timestamp: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
raw_data: Optional[Dict[str, Any]] = field(default_factory=dict)
@dataclass
class ProviderResult:
"""A container for all data returned by a provider from a single query."""
attributes: List[StandardAttribute] = field(default_factory=list)
relationships: List[Relationship] = field(default_factory=list)
def add_attribute(self, target_node: str, name: str, value: Any, attr_type: str,
provider: str, metadata: Optional[Dict[str, Any]] = None) -> None:
"""Helper method to add an attribute to the result."""
self.attributes.append(StandardAttribute(
target_node=target_node,
name=name,
value=value,
type=attr_type,
provider=provider,
metadata=metadata or {}
))
def add_relationship(self, source_node: str, target_node: str, relationship_type: str,
provider: str, raw_data: Optional[Dict[str, Any]] = None) -> None:
"""Helper method to add a relationship to the result."""
self.relationships.append(Relationship(
source_node=source_node,
target_node=target_node,
relationship_type=relationship_type,
provider=provider,
raw_data=raw_data or {}
))
def get_discovered_nodes(self) -> set:
"""Get all unique node identifiers discovered in this result."""
nodes = set()
# Add nodes from relationships
for rel in self.relationships:
nodes.add(rel.source_node)
nodes.add(rel.target_node)
# Add nodes from attributes
for attr in self.attributes:
nodes.add(attr.target_node)
return nodes
def get_relationship_count(self) -> int:
"""Get the total number of relationships in this result."""
return len(self.relationships)
def get_attribute_count(self) -> int:
"""Get the total number of attributes in this result."""
return len(self.attributes)
##TODO
#def is_large_entity(self, threshold: int) -> bool:
# """Check if this result qualifies as a large entity based on relationship count."""
# return self.get_relationship_count() > threshold

145
core/rate_limiter.py Normal file
View File

@@ -0,0 +1,145 @@
# DNScope-reduced/core/rate_limiter.py
import time
import logging
class GlobalRateLimiter:
"""
FIXED: Improved rate limiter with better cleanup and error handling.
Prevents accumulation of stale entries that cause infinite retry loops.
"""
def __init__(self, redis_client):
self.redis = redis_client
self.logger = logging.getLogger('DNScope.rate_limiter')
# Track last cleanup times to avoid excessive Redis operations
self._last_cleanup = {}
def is_rate_limited(self, key, limit, period):
"""
FIXED: Check if a key is rate-limited with improved cleanup and error handling.
Args:
key: Rate limit key (e.g., provider name)
limit: Maximum requests allowed
period: Time period in seconds (60 for per-minute)
Returns:
bool: True if rate limited, False otherwise
"""
if limit <= 0:
# Rate limit of 0 or negative means no limiting
return False
now = time.time()
rate_key = f"rate_limit:{key}"
try:
# FIXED: More aggressive cleanup to prevent accumulation
# Only clean up if we haven't cleaned recently (every 10 seconds max)
should_cleanup = (
rate_key not in self._last_cleanup or
now - self._last_cleanup.get(rate_key, 0) > 10
)
if should_cleanup:
# Remove entries older than the period
removed_count = self.redis.zremrangebyscore(rate_key, 0, now - period)
self._last_cleanup[rate_key] = now
if removed_count > 0:
self.logger.debug(f"Rate limiter cleaned up {removed_count} old entries for {key}")
# Get current count
current_count = self.redis.zcard(rate_key)
if current_count >= limit:
self.logger.debug(f"Rate limited: {key} has {current_count}/{limit} requests in period")
return True
# Add new timestamp with error handling
try:
# Use pipeline for atomic operations
pipe = self.redis.pipeline()
pipe.zadd(rate_key, {str(now): now})
pipe.expire(rate_key, int(period * 2)) # Set TTL to 2x period for safety
pipe.execute()
except Exception as e:
self.logger.warning(f"Failed to record rate limit entry for {key}: {e}")
# Don't block the request if we can't record it
return False
return False
except Exception as e:
self.logger.error(f"Rate limiter error for {key}: {e}")
# FIXED: On Redis errors, don't block requests to avoid infinite loops
return False
def get_rate_limit_status(self, key, limit, period):
"""
Get detailed rate limit status for debugging.
Returns:
dict: Status information including current count, limit, and time to reset
"""
now = time.time()
rate_key = f"rate_limit:{key}"
try:
current_count = self.redis.zcard(rate_key)
# Get oldest entry to calculate reset time
oldest_entries = self.redis.zrange(rate_key, 0, 0, withscores=True)
time_to_reset = 0
if oldest_entries:
oldest_time = oldest_entries[0][1]
time_to_reset = max(0, period - (now - oldest_time))
return {
'key': key,
'current_count': current_count,
'limit': limit,
'period': period,
'is_limited': current_count >= limit,
'time_to_reset': time_to_reset
}
except Exception as e:
self.logger.error(f"Failed to get rate limit status for {key}: {e}")
return {
'key': key,
'current_count': 0,
'limit': limit,
'period': period,
'is_limited': False,
'time_to_reset': 0,
'error': str(e)
}
def reset_rate_limit(self, key):
"""
ADDED: Reset rate limit for a specific key (useful for debugging).
"""
rate_key = f"rate_limit:{key}"
try:
deleted = self.redis.delete(rate_key)
self.logger.info(f"Reset rate limit for {key} (deleted: {deleted})")
return True
except Exception as e:
self.logger.error(f"Failed to reset rate limit for {key}: {e}")
return False
def cleanup_all_rate_limits(self):
"""
ADDED: Clean up all rate limit entries (useful for maintenance).
"""
try:
keys = self.redis.keys("rate_limit:*")
if keys:
deleted = self.redis.delete(*keys)
self.logger.info(f"Cleaned up {deleted} rate limit keys")
return deleted
return 0
except Exception as e:
self.logger.error(f"Failed to cleanup rate limits: {e}")
return 0

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
""" """
Per-session configuration management for DNSRecon. Per-session configuration management for DNScope.
Provides isolated configuration instances for each user session. Provides isolated configuration instances for each user session.
""" """

View File

@@ -1,22 +1,19 @@
# dnsrecon/core/session_manager.py # DNScope/core/session_manager.py
import threading import threading
import time import time
import uuid import uuid
import redis import redis
import pickle import pickle
from typing import Dict, Optional, Any, List from typing import Dict, Optional, Any
from core.scanner import Scanner from core.scanner import Scanner
from config import config from config import config
# WARNING: Using pickle can be a security risk if the data source is not trusted.
# In this case, we are only serializing/deserializing our own trusted Scanner objects,
# which is generally safe. Do not unpickle data from untrusted sources.
class SessionManager: class SessionManager:
""" """
Manages multiple scanner instances for concurrent user sessions using Redis. FIXED: Manages multiple scanner instances for concurrent user sessions using Redis.
Now more conservative about session creation to preserve API keys and configuration.
""" """
def __init__(self, session_timeout_minutes: int = 0): def __init__(self, session_timeout_minutes: int = 0):
@@ -28,7 +25,10 @@ class SessionManager:
self.redis_client = redis.StrictRedis(db=0, decode_responses=False) self.redis_client = redis.StrictRedis(db=0, decode_responses=False)
self.session_timeout = session_timeout_minutes * 60 # Convert to seconds self.session_timeout = session_timeout_minutes * 60 # Convert to seconds
self.lock = threading.Lock() # Lock for local operations, Redis handles atomic ops self.lock = threading.Lock()
# FIXED: Add a creation lock to prevent race conditions
self.creation_lock = threading.Lock()
# Start cleanup thread # Start cleanup thread
self.cleanup_thread = threading.Thread(target=self._cleanup_loop, daemon=True) self.cleanup_thread = threading.Thread(target=self._cleanup_loop, daemon=True)
@@ -40,7 +40,7 @@ class SessionManager:
"""Prepare SessionManager for pickling.""" """Prepare SessionManager for pickling."""
state = self.__dict__.copy() state = self.__dict__.copy()
# Exclude unpickleable attributes - Redis client and threading objects # Exclude unpickleable attributes - Redis client and threading objects
unpicklable_attrs = ['lock', 'cleanup_thread', 'redis_client'] unpicklable_attrs = ['lock', 'cleanup_thread', 'redis_client', 'creation_lock']
for attr in unpicklable_attrs: for attr in unpicklable_attrs:
if attr in state: if attr in state:
del state[attr] del state[attr]
@@ -50,24 +50,26 @@ class SessionManager:
"""Restore SessionManager after unpickling.""" """Restore SessionManager after unpickling."""
self.__dict__.update(state) self.__dict__.update(state)
# Re-initialize unpickleable attributes # Re-initialize unpickleable attributes
import redis
self.redis_client = redis.StrictRedis(db=0, decode_responses=False) self.redis_client = redis.StrictRedis(db=0, decode_responses=False)
self.lock = threading.Lock() self.lock = threading.Lock()
self.creation_lock = threading.Lock()
self.cleanup_thread = threading.Thread(target=self._cleanup_loop, daemon=True) self.cleanup_thread = threading.Thread(target=self._cleanup_loop, daemon=True)
self.cleanup_thread.start() self.cleanup_thread.start()
def _get_session_key(self, session_id: str) -> str: def _get_session_key(self, session_id: str) -> str:
"""Generates the Redis key for a session.""" """Generates the Redis key for a session."""
return f"dnsrecon:session:{session_id}" return f"DNScope:session:{session_id}"
def _get_stop_signal_key(self, session_id: str) -> str: def _get_stop_signal_key(self, session_id: str) -> str:
"""Generates the Redis key for a session's stop signal.""" """Generates the Redis key for a session's stop signal."""
return f"dnsrecon:stop:{session_id}" return f"DNScope:stop:{session_id}"
def create_session(self) -> str: def create_session(self) -> str:
""" """
Create a new user session and store it in Redis. FIXED: Create a new user session with thread-safe creation to prevent duplicates.
""" """
# FIXED: Use creation lock to prevent race conditions
with self.creation_lock:
session_id = str(uuid.uuid4()) session_id = str(uuid.uuid4())
print(f"=== CREATING SESSION {session_id} IN REDIS ===") print(f"=== CREATING SESSION {session_id} IN REDIS ===")
@@ -99,6 +101,7 @@ class SessionManager:
self.redis_client.setex(stop_key, self.session_timeout, b'0') self.redis_client.setex(stop_key, self.session_timeout, b'0')
print(f"Session {session_id} stored in Redis with stop signal initialized") print(f"Session {session_id} stored in Redis with stop signal initialized")
print(f"Session has {len(scanner_instance.providers)} providers: {[p.get_name() for p in scanner_instance.providers]}")
return session_id return session_id
except Exception as e: except Exception as e:
@@ -212,7 +215,14 @@ class SessionManager:
# Immediately save to Redis for GUI updates # Immediately save to Redis for GUI updates
success = self._save_session_data(session_id, session_data) success = self._save_session_data(session_id, session_data)
if success: if success:
print(f"Scanner state updated for session {session_id} (status: {scanner.status})") # Only log occasionally to reduce noise
if hasattr(self, '_last_update_log'):
if time.time() - self._last_update_log > 5: # Log every 5 seconds max
#print(f"Scanner state updated for session {session_id} (status: {scanner.status})")
self._last_update_log = time.time()
else:
#print(f"Scanner state updated for session {session_id} (status: {scanner.status})")
self._last_update_log = time.time()
else: else:
print(f"WARNING: Failed to save scanner state for session {session_id}") print(f"WARNING: Failed to save scanner state for session {session_id}")
return success return success
@@ -343,7 +353,7 @@ class SessionManager:
while True: while True:
try: try:
# Clean up orphaned stop signals # Clean up orphaned stop signals
stop_keys = self.redis_client.keys("dnsrecon:stop:*") stop_keys = self.redis_client.keys("DNScope:stop:*")
for stop_key in stop_keys: for stop_key in stop_keys:
# Extract session ID from stop key # Extract session ID from stop key
session_id = stop_key.decode('utf-8').split(':')[-1] session_id = stop_key.decode('utf-8').split(':')[-1]
@@ -362,8 +372,8 @@ class SessionManager:
def get_statistics(self) -> Dict[str, Any]: def get_statistics(self) -> Dict[str, Any]:
"""Get session manager statistics.""" """Get session manager statistics."""
try: try:
session_keys = self.redis_client.keys("dnsrecon:session:*") session_keys = self.redis_client.keys("DNScope:session:*")
stop_keys = self.redis_client.keys("dnsrecon:stop:*") stop_keys = self.redis_client.keys("DNScope:stop:*")
active_sessions = len(session_keys) active_sessions = len(session_keys)
running_scans = 0 running_scans = 0

View File

@@ -1,19 +1,22 @@
""" """
Data provider modules for DNSRecon. Data provider modules for DNScope.
Contains implementations for various reconnaissance data sources. Contains implementations for various reconnaissance data sources.
""" """
from .base_provider import BaseProvider, RateLimiter from .base_provider import BaseProvider
from .crtsh_provider import CrtShProvider from .crtsh_provider import CrtShProvider
from .dns_provider import DNSProvider from .dns_provider import DNSProvider
from .shodan_provider import ShodanProvider from .shodan_provider import ShodanProvider
from .correlation_provider import CorrelationProvider
from core.rate_limiter import GlobalRateLimiter
__all__ = [ __all__ = [
'BaseProvider', 'BaseProvider',
'RateLimiter', 'GlobalRateLimiter',
'CrtShProvider', 'CrtShProvider',
'DNSProvider', 'DNSProvider',
'ShodanProvider' 'ShodanProvider',
'CorrelationProvider'
] ]
__version__ = "0.0.0-rc" __version__ = "0.0.0-rc"

View File

@@ -1,52 +1,20 @@
# dnsrecon/providers/base_provider.py # DNScope/providers/base_provider.py
import time import time
import requests import requests
import threading import threading
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import List, Dict, Any, Optional, Tuple from typing import Dict, Any, Optional
from core.logger import get_forensic_logger from core.logger import get_forensic_logger # Ensure this import is present
from core.rate_limiter import GlobalRateLimiter
from core.provider_result import ProviderResult
class RateLimiter:
"""Simple rate limiter for API calls."""
def __init__(self, requests_per_minute: int):
"""
Initialize rate limiter.
Args:
requests_per_minute: Maximum requests allowed per minute
"""
self.requests_per_minute = requests_per_minute
self.min_interval = 60.0 / requests_per_minute
self.last_request_time = 0
def __getstate__(self):
"""RateLimiter is fully picklable, return full state."""
return self.__dict__.copy()
def __setstate__(self, state):
"""Restore RateLimiter state."""
self.__dict__.update(state)
def wait_if_needed(self) -> None:
"""Wait if necessary to respect rate limits."""
current_time = time.time()
time_since_last = current_time - self.last_request_time
if time_since_last < self.min_interval:
sleep_time = self.min_interval - time_since_last
time.sleep(sleep_time)
self.last_request_time = time.time()
class BaseProvider(ABC): class BaseProvider(ABC):
""" """
Abstract base class for all DNSRecon data providers. Abstract base class for all DNScope data providers.
Now supports session-specific configuration. Now supports session-specific configuration and returns standardized ProviderResult objects.
""" """
def __init__(self, name: str, rate_limit: int = 60, timeout: int = 30, session_config=None): def __init__(self, name: str, rate_limit: int = 60, timeout: int = 30, session_config=None):
@@ -68,14 +36,11 @@ class BaseProvider(ABC):
# Fallback to global config for backwards compatibility # Fallback to global config for backwards compatibility
from config import config as global_config from config import config as global_config
self.config = global_config self.config = global_config
actual_rate_limit = rate_limit
actual_timeout = timeout actual_timeout = timeout
self.name = name self.name = name
self.rate_limiter = RateLimiter(actual_rate_limit)
self.timeout = actual_timeout self.timeout = actual_timeout
self._local = threading.local() self._local = threading.local()
self.logger = get_forensic_logger()
self._stop_event = None self._stop_event = None
# Statistics (per provider instance) # Statistics (per provider instance)
@@ -106,10 +71,15 @@ class BaseProvider(ABC):
if not hasattr(self._local, 'session'): if not hasattr(self._local, 'session'):
self._local.session = requests.Session() self._local.session = requests.Session()
self._local.session.headers.update({ self._local.session.headers.update({
'User-Agent': 'DNSRecon/1.0 (Passive Reconnaissance Tool)' 'User-Agent': 'DNScope/1.0 (Passive Reconnaissance Tool)'
}) })
return self._local.session return self._local.session
@property
def logger(self):
"""Get the current forensic logger instance."""
return get_forensic_logger()
@abstractmethod @abstractmethod
def get_name(self) -> str: def get_name(self) -> str:
"""Return the provider name.""" """Return the provider name."""
@@ -136,7 +106,7 @@ class BaseProvider(ABC):
pass pass
@abstractmethod @abstractmethod
def query_domain(self, domain: str) -> List[Tuple[str, str, str, float, Dict[str, Any]]]: def query_domain(self, domain: str) -> ProviderResult:
""" """
Query the provider for information about a domain. Query the provider for information about a domain.
@@ -144,12 +114,12 @@ class BaseProvider(ABC):
domain: Domain to investigate domain: Domain to investigate
Returns: Returns:
List of tuples: (source_node, target_node, relationship_type, confidence, raw_data) ProviderResult containing standardized attributes and relationships
""" """
pass pass
@abstractmethod @abstractmethod
def query_ip(self, ip: str) -> List[Tuple[str, str, str, float, Dict[str, Any]]]: def query_ip(self, ip: str) -> ProviderResult:
""" """
Query the provider for information about an IP address. Query the provider for information about an IP address.
@@ -157,7 +127,7 @@ class BaseProvider(ABC):
ip: IP address to investigate ip: IP address to investigate
Returns: Returns:
List of tuples: (source_node, target_node, relationship_type, confidence, raw_data) ProviderResult containing standardized attributes and relationships
""" """
pass pass
@@ -167,13 +137,13 @@ class BaseProvider(ABC):
target_indicator: str = "") -> Optional[requests.Response]: target_indicator: str = "") -> Optional[requests.Response]:
""" """
Make a rate-limited HTTP request. Make a rate-limited HTTP request.
FIXED: Returns response without automatically raising HTTPError exceptions.
Individual providers should handle status codes appropriately.
""" """
if self._is_stop_requested(): if self._is_stop_requested():
print(f"Request cancelled before start: {url}") print(f"Request cancelled before start: {url}")
return None return None
self.rate_limiter.wait_if_needed()
start_time = time.time() start_time = time.time()
response = None response = None
error = None error = None
@@ -205,8 +175,14 @@ class BaseProvider(ABC):
raise ValueError(f"Unsupported HTTP method: {method}") raise ValueError(f"Unsupported HTTP method: {method}")
print(f"Response status: {response.status_code}") print(f"Response status: {response.status_code}")
response.raise_for_status()
# FIXED: Don't automatically raise for HTTP error status codes
# Let individual providers handle status codes appropriately
# Only count 2xx responses as successful
if 200 <= response.status_code < 300:
self.successful_requests += 1 self.successful_requests += 1
else:
self.failed_requests += 1
duration_ms = (time.time() - start_time) * 1000 duration_ms = (time.time() - start_time) * 1000
self.logger.log_api_request( self.logger.log_api_request(
@@ -257,7 +233,6 @@ class BaseProvider(ABC):
def log_relationship_discovery(self, source_node: str, target_node: str, def log_relationship_discovery(self, source_node: str, target_node: str,
relationship_type: str, relationship_type: str,
confidence_score: float,
raw_data: Dict[str, Any], raw_data: Dict[str, Any],
discovery_method: str) -> None: discovery_method: str) -> None:
""" """
@@ -267,7 +242,6 @@ class BaseProvider(ABC):
source_node: Source node identifier source_node: Source node identifier
target_node: Target node identifier target_node: Target node identifier
relationship_type: Type of relationship relationship_type: Type of relationship
confidence_score: Confidence score
raw_data: Raw data from provider raw_data: Raw data from provider
discovery_method: Method used for discovery discovery_method: Method used for discovery
""" """
@@ -277,7 +251,6 @@ class BaseProvider(ABC):
source_node=source_node, source_node=source_node,
target_node=target_node, target_node=target_node,
relationship_type=relationship_type, relationship_type=relationship_type,
confidence_score=confidence_score,
provider=self.name, provider=self.name,
raw_data=raw_data, raw_data=raw_data,
discovery_method=discovery_method discovery_method=discovery_method
@@ -297,5 +270,5 @@ class BaseProvider(ABC):
'failed_requests': self.failed_requests, 'failed_requests': self.failed_requests,
'success_rate': (self.successful_requests / self.total_requests * 100) if self.total_requests > 0 else 0, 'success_rate': (self.successful_requests / self.total_requests * 100) if self.total_requests > 0 else 0,
'relationships_found': self.total_relationships_found, 'relationships_found': self.total_relationships_found,
'rate_limit': self.rate_limiter.requests_per_minute 'rate_limit': self.config.get_rate_limit(self.name)
} }

Some files were not shown because too many files have changed in this diff Show More