colinstubbs/compactlog

By colinstubbs

•Updated 8 months ago

compactlog CT log server

Image
Security
Developer tools
Web servers
0

2.2K

colinstubbs/compactlog repository overview

Current fork of compact_log/compactlog in: https://github.com/colin-stubbs/compact_log⁠

You should consider volume mounts to the following paths if you desire persistence or customisation of data.

  • /tmp/ct-log-storage - if you want to expose/persist compact_log/compactlog's CT log data and you're using the default configuration.
  • /compactlog/keys/ - location for private/public key for compact_log/compactlog's CT log
  • /compactlog/trusted_roots/ - custom trusted roots
  • /compactlog/monitor_json/ - location for monitor.json files
  • /var/log/ - location for log files

Individual files that you might want to make inject via volume mounts in order to customise compact_log/compactlog and disable the default configuration being applied.

  • ./Config.toml:/compactlog/Config.toml - non-default compact_log/compactlog configuration file
  • /compactlog/monitor_json//monitor-rfc6962.json
  • /compactlog/monitor_json//monitor-static.json
  • /compactlog/monitor_json//monitor-combined.json
  • /compactlog/Caddyfile - alternatively adjust ${CADDY_CONFIG_FILE}

Example minimal compose file for a simple default dev/test Itko instance.

services:
  compactlog:
    image: colinstubbs/compactlog:latest
    restart: unless-stopped
    environment:
      # set to true to load test certs from testdata/
      - LOAD_TEST_DATA=true
      # set to 1+ to auto-generate certificates, NOTE: this is dependent upon LOAD_TEST_DATA being true and will not occur if LOAD_TEST_DATA is false.
      - GEN_TEST_CERTS=300
    ports:
      - "80:80"
    healthcheck:
      test: curl --silent --fail http://localhost:${CADDY_LISTEN_PORT:-80}/ct/v1/get-sth | grep '"tree_size":' || exit 1
      interval: 30s
      timeout: 10s
      retries: 3

Example container output,

olin.stubbs@office-monitor-left tmp % docker compose -f ./compose.yml up
[+] Running 2/2
 āœ” Network tmp_default         Created                                                                                                                                                                  0.2s 
 āœ” Container tmp-compactlog-1  Created                                                                                                                                                                  0.1s 
Attaching to compactlog-1
compactlog-1  | ### Creating 300 additional test leaf certificates...
compactlog-1  | ### Adding test CA certificate to trusted roots...
compactlog-1  | '/compactlog/testdata/generated/test-ca.crt' -> '/compactlog/trusted_roots//test-ca.pem'
compactlog-1  | ### Creating test subleaf 1 certificate...
%{BREVITY}%
compactlog-1  | ### Creating test subleaf 300 certificate...
compactlog-1  | ### Waiting for compact_log to start and respond to HTTP requests.......OK!
compactlog-1  | ### Adding 300 additional test leaf certificates...
compactlog-1  | ### Creating test subleaf 1 certificate chain...
%{BREVITY}%
compactlog-1  | ### Adding test subleaf 300 certificate chain...OK!
compactlog-1  | {"level":"info","ts":1761813545.6017065,"msg":"maxprocs: Leaving GOMAXPROCS=8: CPU quota undefined"}
compactlog-1  | {"level":"info","ts":1761813545.6018078,"msg":"GOMEMLIMIT is updated","package":"github.com/KimMachineGun/automemlimit/memlimit","GOMEMLIMIT":11276856115,"previous":9223372036854775807}
compactlog-1  | {"level":"info","ts":1761813545.601852,"msg":"using config from file","file":"/compactlog/Caddyfile"}
compactlog-1  | {"level":"info","ts":1761813545.603064,"msg":"adapted config to JSON","adapter":"caddyfile"}
compactlog-1  | {"level":"info","ts":1761813545.6035395,"msg":"redirected default logger","from":"stderr","to":"/var/log/caddy.log"}
compactlog-1  | {"level":"info","ts":1761813545.612392,"msg":"serving initial configuration"}

You'll have the RFC6962 API endpoints and static tiled CT log files available via http://localhost/⁠

user@box tmp % curl -v http://localhost/ct/v1/get-sth | jq  
* Host localhost:80 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying [::1]:80...
* Connected to localhost (::1) port 80
> GET /ct/v1/get-sth HTTP/1.1
> Host: localhost
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Thu, 30 Oct 2025 08:43:04 GMT
< Vary: accept-encoding
< Via: 1.1 Caddy
< Transfer-Encoding: chunked
< 
{ [240 bytes data]
100   234    0   234    0     0  52881      0 --:--:-- --:--:-- --:--:-- 58500
* Connection #0 to host localhost left intact
{
  "tree_size": 300,
  "timestamp": 1761813784327,
  "sha256_root_hash": "IBcWpUumSOuDUqa1qXIacZT5fi3FdifWXRrKf3gAalU=",
  "tree_head_signature": "BAMARzBFAiEA4fREhiycE5BH0OjGVVDd3h6Aft+4g84r+VIgpjOxqgsCIHskjfyGVeOCMykk11rBvMtU1teQOdEXn4RoPyTUruhR"
}
user@box tmp % 
user@box tmp % curl -v http://localhost/ct/v1/get-roots | jq | head -n 3
* Host localhost:80 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying [::1]:80...
* Connected to localhost (::1) port 80
> GET /ct/v1/get-roots HTTP/1.1
> Host: localhost
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Thu, 30 Oct 2025 08:43:16 GMT
< Vary: accept-encoding
< Via: 1.1 Caddy
< Transfer-Encoding: chunked
< 
{ [14232 bytes data]
100  508k    0  508k    0     0  26.6M      0 --:--:-- --:--:-- --:--:-- 27.6M
* Connection #0 to host localhost left intact
{
  "certificates": [
    "MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj",
user@box tmp % 

user@box tmp % curl -v http://localhost/checkpoint                      
* Host localhost:80 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
*   Trying [::1]:80...
* Connected to localhost (::1) port 80
> GET /checkpoint HTTP/1.1
> Host: localhost
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< Cache-Control: max-age=5, must-revalidate
< Content-Type: text/plain; charset=utf-8
< Date: Thu, 30 Oct 2025 08:43:51 GMT
< Vary: accept-encoding
< Via: 1.1 Caddy
< Transfer-Encoding: chunked
< 
localhost:8080
300
IBcWpUumSOuDUqa1qXIacZT5fi3FdifWXRrKf3gAalU=

— localhost:8080 zeURFQAAAZo0SZ+GBAMARzBFAiEA+HErBAbjqm8YwpMeJZqO6GMnQvSflWFWkIoefGn+GPwCIGw3tSwgXNcY6bAEdHSghtXw2MWmwT/TabnJQFNJ6BjJ
* Connection #0 to host localhost left intact
user@box tmp % 

monitor.json files are available via http://localhost/monitor-*.json⁠ ,e.g.

user@box tmp % curl -s http://localhost/monitor-rfc6962.json | jq
{
  "is_all_logs": false,
  "version": "1.0.0",
  "log_list_timestamp": "2025-10-30T08:39:05Z",
  "name": "testing",
  "operators": [
    {
      "name": "testing",
      "email": [
        "[email protected]"
      ],
      "logs": [
        {
          "description": "compactlog",
          "log_id": "AiAO4/ZKRZthY/WgVhwrYM5GluR+5rl/yreyYNnsQ9Y=",
          "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc8HQfN6Ey1iFpdI8gCCCixypxr4Nn7vLzwxhnAya4JaRvKpvsU/m2lqG7jhDjUvmGJkE+ELjDM62fNvbrX9hBw==",
          "url": "",
          "mmd": 86400,
          "state": {
            "usable": {
              "timestamp": "2025-10-30T08:39:05Z"
            }
          },
          "temporal_interval": {
            "start_inclusive": "2000-01-01T00:00:00Z",
            "end_exclusive": "2000-01-01T00:00:00Z"
          }
        }
      ],
      "tiled_logs": []
    }
  ]
}
user@box tmp % curl -s http://localhost/monitor-static.json | jq
{
  "is_all_logs": false,
  "version": "1.0.0",
  "log_list_timestamp": "2025-10-30T08:39:05Z",
  "name": "testing",
  "operators": [
    {
      "name": "testing",
      "email": [
        "[email protected]"
      ],
      "logs": [],
      "tiled_logs": [
        {
          "description": "compactlog",
          "log_id": "AiAO4/ZKRZthY/WgVhwrYM5GluR+5rl/yreyYNnsQ9Y=",
          "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc8HQfN6Ey1iFpdI8gCCCixypxr4Nn7vLzwxhnAya4JaRvKpvsU/m2lqG7jhDjUvmGJkE+ELjDM62fNvbrX9hBw==",
          "monitoring_url": "",
          "submission_url": "",
          "mmd": 60,
          "state": {
            "usable": {
              "timestamp": "2025-10-30T08:39:05Z"
            }
          },
          "temporal_interval": {
            "start_inclusive": "2000-01-01T00:00:00Z",
            "end_exclusive": "2000-01-01T00:00:00Z"
          }
        }
      ]
    }
  ]
}
user@box tmp % curl -s http://localhost/monitor-combined.json | jq
{
  "is_all_logs": false,
  "version": "1.0.0",
  "log_list_timestamp": "2025-10-30T08:39:05Z",
  "name": "testing",
  "operators": [
    {
      "name": "testing",
      "email": [
        "[email protected]"
      ],
      "logs": [
        {
          "description": "compactlog",
          "log_id": "AiAO4/ZKRZthY/WgVhwrYM5GluR+5rl/yreyYNnsQ9Y=",
          "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc8HQfN6Ey1iFpdI8gCCCixypxr4Nn7vLzwxhnAya4JaRvKpvsU/m2lqG7jhDjUvmGJkE+ELjDM62fNvbrX9hBw==",
          "url": "",
          "mmd": 86400,
          "state": {
            "usable": {
              "timestamp": "2025-10-30T08:39:05Z"
            }
          },
          "temporal_interval": {
            "start_inclusive": "2000-01-01T00:00:00Z",
            "end_exclusive": "2000-01-01T00:00:00Z"
          }
        }
      ],
      "tiled_logs": [
        {
          "description": "compactlog",
          "log_id": "AiAO4/ZKRZthY/WgVhwrYM5GluR+5rl/yreyYNnsQ9Y=",
          "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEc8HQfN6Ey1iFpdI8gCCCixypxr4Nn7vLzwxhnAya4JaRvKpvsU/m2lqG7jhDjUvmGJkE+ELjDM62fNvbrX9hBw==",
          "monitoring_url": "",
          "submission_url": "",
          "mmd": 60,
          "state": {
            "usable": {
              "timestamp": "2025-10-30T08:39:05Z"
            }
          },
          "temporal_interval": {
            "start_inclusive": "2000-01-01T00:00:00Z",
            "end_exclusive": "2000-01-01T00:00:00Z"
          }
        }
      ]
    }
  ]
}
user@box tmp % 

Tag summary

Content type

Image

Digest

sha256:7fea6d5a6…

Size

972.6 MB

Last updated

8 months ago

docker pull colinstubbs/compactlog