Typo fixes and grammar improvements, h/t Claude
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -29,8 +29,8 @@ audit the certificate logs themselves. The intent is that eventually clients wo
|
||||
certificates that do not appear in a log, effectively forcing CAs to add all issued certificates to
|
||||
the logs.
|
||||
|
||||
In the first two articles of this series, I explored [[Sunlight]({{< ref 2025-07-26-ctlog-1 >}})]
|
||||
and [[TesseraCT]({{< ref 2025-08-10-ctlog-2 >}})], two open source implementations of the Static CT
|
||||
In the first two articles of this series, I explored [[TesseraCT]({{< ref 2025-07-26-ctlog-1 >}})]
|
||||
and [[Sunlight]({{< ref 2025-08-10-ctlog-2 >}})], two open source implementations of the Static CT
|
||||
protocol. In this final article, I'll share the details on how I created the environment and
|
||||
production instances for four logs that IPng will be providing: Rennet and Lipase are two
|
||||
ingredients to make cheese and will serve as our staging/testing logs. Gouda and Halloumi are two
|
||||
@@ -74,7 +74,7 @@ ctlog1:~$ for log in lipase; do \
|
||||
```
|
||||
|
||||
The hypervisor will use PCI passthrough for the NVMe drives, and we'll handle ZFS directly on the
|
||||
VM. The first command creates a ZFS raidz2 pool using 4kB blocks, turns of _atime_ (which avoids one
|
||||
VM. The first command creates a ZFS raidz2 pool using 4kB blocks, turns off _atime_ (which avoids one
|
||||
metadata write for each read!), and turns on SSD trimming in ZFS, a very useful feature.
|
||||
|
||||
Then I'll create an encrypted volume for the configuration and key material. This way, if the
|
||||
@@ -87,12 +87,12 @@ _Rennet_ for the testing log and _Gouda_ for the production log.
|
||||
|
||||
{{< image width="10em" float="right" src="/assets/ctlog/sunlight-logo.png" alt="Sunlight logo" >}}
|
||||
|
||||
I set up Sunlight first. as its authors have extensive operational notes both in terms of the
|
||||
I set up Sunlight first, as its authors have extensive operational notes both in terms of the
|
||||
[[config](https://config.sunlight.geomys.org/)] of Geomys' _Tuscolo_ log, as well as on the
|
||||
[[Sunlight](https://sunlight.dev)] homepage. I really appreciate that Filippo added some
|
||||
[[Gists](https://gist.github.com/FiloSottile/989338e6ba8e03f2c699590ce83f537b)] and
|
||||
[[Doc](https://docs.google.com/document/d/1ID8dX5VuvvrgJrM0Re-jt6Wjhx1eZp-trbpSIYtOhRE/edit?tab=t.0#heading=h.y3yghdo4mdij)]
|
||||
with pretty much all I need to know to run one too. Our Rennet and Gouda logs use very similar
|
||||
with pretty much all I need to know to run one too. Our Rennet and Gouda logs use a very similar
|
||||
approach for their configuration, with one notable exception: the VMs do not have a public IP
|
||||
address, and are tucked away in a private network called IPng Site Local. I'll get back to that
|
||||
later.
|
||||
@@ -136,8 +136,8 @@ the automatic certificate renewals, and will handle SSL upstream. A few notes on
|
||||
|
||||
1. Most importantly, I will be using a common frontend pool with a wildcard certificate for
|
||||
`*.ct.ipng.ch`. I wrote about [[DNS-01]({{< ref 2023-03-24-lego-dns01 >}})] before, it's a very
|
||||
convenient way for IPng to do certificate pool management. I will be sharing certificate for all log
|
||||
types under this certificate.
|
||||
convenient way for IPng to do certificate pool management. I will be sharing a certificate for all log
|
||||
types.
|
||||
1. ACME/HTTP-01 could be made to work with a bit of effort; plumbing through the `/.well-known/`
|
||||
URIs on the frontend and pointing them to these instances. But then the cert would have to be copied
|
||||
from Sunlight back to the frontends.
|
||||
@@ -165,7 +165,7 @@ us going in a public `tesseract-posix` instance.
|
||||
|
||||
One thing I liked about Sunlight is its compact YAML file that described the pertinent bits of the
|
||||
system, and that I can serve any number of logs with the same process. On the other hand, TesseraCT
|
||||
can serve only one log per process. Both have pro's and con's, notably if any poisonous submission
|
||||
can serve only one log per process. Both have pros and cons, notably if any poisonous submission
|
||||
would be offered, Sunlight might take down all logs, while TesseraCT would only take down the log
|
||||
receiving the offensive submission. On the other hand, maintaining separate processes is cumbersome,
|
||||
and all log instances need to be meticulously configured.
|
||||
@@ -198,7 +198,7 @@ logs:
|
||||
EOF
|
||||
```
|
||||
|
||||
With this snippet, I have all the information I need. Here's the steps I take to construct the log
|
||||
With this snippet, I have all the information I need. Here are the steps I take to construct the log
|
||||
itself:
|
||||
|
||||
***1. Generate keys***
|
||||
@@ -245,7 +245,7 @@ Creating /ssd-vol0/logs/lipase2027h2/data/log.v3.json
|
||||
{{< image width="60%" src="/assets/ctlog/lipase.png" alt="TesseraCT Lipase Log" >}}
|
||||
|
||||
It's nice to see a familiar look-and-feel for these logs appear in those `index.html` (which all
|
||||
cross-link to each other within the logs specificied in `tesseract-staging.yaml`, which is dope.
|
||||
cross-link to each other within the logs specified in `tesseract-staging.yaml`, which is dope.
|
||||
|
||||
***3. Generate Roots***
|
||||
|
||||
@@ -347,7 +347,7 @@ read path. Filippo explained that the HTTP headers matter in the Static CT speci
|
||||
Issuers, and Checkpoint must all have specific caching and content type headers set. This is what
|
||||
makes Skylight such a gem - I get to read it (and the spec!) to see what I'm supposed to be serving.
|
||||
|
||||
And thus, `gen-nginx` command is born, and listens on port `:8080` for requests:
|
||||
And thus, the `gen-nginx` command is born, and listens on port `:8080` for requests:
|
||||
|
||||
```
|
||||
ctlog@ctlog1:/ssd-vol0/enc/tesseract$ tesseract-genconf -c tesseract-staging.yaml gen-nginx
|
||||
@@ -487,14 +487,14 @@ server {
|
||||
}
|
||||
```
|
||||
|
||||
Taking _Lipase_ shard 2025h2 as an example, The submission path (on `*.log.ct.ipng.ch`) will show
|
||||
Taking _Lipase_ shard 2025h2 as an example, the submission path (on `*.log.ct.ipng.ch`) will show
|
||||
the same `index.html` as the monitoring path (on `*.mon.ct.ipng.ch`), to provide some consistency
|
||||
with Sunlight logs. Otherwise, the `/metrics` endpoint is forwarded to the `otelcol` running on port
|
||||
`:9464`, and the rest (the `/ct/v1/` and so on) are sent to the first port `:16900` of the
|
||||
TesseraCT.
|
||||
|
||||
Then the read-path makes a special-case of the `/checkpoint` endpoint, which it does not cache. That
|
||||
request (as all others) are forwarded to port `:8080` which is where NGINX is running. Other
|
||||
request (as all others) is forwarded to port `:8080` which is where NGINX is running. Other
|
||||
requests (notably `/tile` and `/issuer`) are cacheable, so I'll cache these on the upstream NGINX
|
||||
servers, both for resilience as well as for performance. Having four of these NGINX upstream will
|
||||
allow the Static CT logs (regardless of being Sunlight or TesseraCT) to serve very high read-rates.
|
||||
|
||||
Reference in New Issue
Block a user