From e371f2005f91b3db1904b3038c498c764ae15279 Mon Sep 17 00:00:00 2001 From: Rasmus Dahlberg Date: Mon, 8 Jan 2024 08:32:04 +0100 Subject: Bring introductory documentation up to speed --- README.md | 147 +++++++++++++++++++++++---------------------------- docs/introduction.md | 24 +++++---- 2 files changed, 80 insertions(+), 91 deletions(-) diff --git a/README.md b/README.md index 957fb9e..c554374 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,75 @@ # silent-ct -An implementation of a silent Certificate Transparency (CT) monitor. +An implementation of a silent Certificate Transparency monitor. -**Status:** work in progress, please do not use for anything serious. - -FIXME: update readme based on latest revision. +**Status:** drafty prototype, please do not use for anything serious. ## How it works -Each node that issues TLS certificates submit them to a self-hosted monitor. -This is what makes it possible for silent-ct to be _silent_: alerts are only -generated if a certificate found in the logs were not requested by the nodes. +A monitor downloads all certificates from Certificate Transparency logs. This +gives a concise view of which certificates have been issued for what domains. + +The monitor is configured to pull legitimately issued certificates from trusted +nodes. Each node packages its legitimate certificates as a single submission. +This submission is then made available for download on a URL via HTTP GET. + +To convince the monitor that a submission was generated by a trusted node, a +shared secret is established between the node and the monitor. The node creates +a message authentication code using the shared secret. The monitor verifies it. + +What makes this setup _silent_ is the fact that the monitor can compute the +difference between any discovered and legitimately issued certificates. If a +certificate is found that no node submitted, only then is an alert printed. + +## Quick start + +FIXME: the go install commands will not work until `rgdd.se` is configured +properly. Checkout the repository and go install from within the clone. -An overview is shown in the figure below. +### Setup a node - XXX: ASCII figure. +You will need the `silent-ctnode` tool to create submissions that the monitor +can pull. Install: -Each node establishes a secure channel to the monitor. Secure means end-to-end -encrypted communication where the node can authenticate the monitor. For the -monitor to authenticate each connecting node, HTTP Basic Authentication is used. + $ go install rgdd.se/silent-ct/cmd/silent-ctnode@latest -On a single-node system, the secure channel can be replaced by a UNIX socket. +Locate the node's certificates that are still valid (i.e., not expired) and +prepare a submission for them: -## Setting and threat model + $ silent-ctnode -n NAME -s SECRET /path/to/chain-1.pem /path/to/chain-2.pem ... - 1. Mis-issued certificates will only be used for MitM attacks against users - that connect from a set of fixed IP addresses. It is assumed that the - party who can detect certificate mis-issuance will never be targeted. This - is why each node needs to establish a secure channel with the monitor. - 2. The nodes issuing TLS certificates start in good states but may be - compromised sometime in the future. Detection of certificate mis-issuance - is then out of scope for all domains that the compromised node issued - certificates for. It is in-scope to not let such a compromise affect - detection of mis-issued certificates for other nodes' domains though. - 3. The platform running the monitor is not compromised by the attacker. - 4. An administrator notices alerts that the monitor outputs on stdout. The - integration with email, dashboards, or similar is out of scope. - 5. It is not always possible for nodes to reach the monitor. For example, the - monitor may be running on a workstation only powered on during work hours. +`NAME` is an arbitrary name of the node. -## Install +`SECRET` is a secret that will only be shared with the monitor. -Install the `silent-ct` software using Go's toolchain: +The output includes the node name, the computed message authentication code, and +the list of certificate chains that was specified. Use the `-o` option if you +prefer to save the output directly to a file rather than getting it on stdout. - $ go install rgdd.se/silent-ct@latest +Make the generated submission file available on a URL. Typically each node +already serves web content, in which case you can copy it into some directory. -If the monitor is not running on the same system as a single node, it is up to -you to configure an end-to-end encrypted channel where the monitor is -authenticated. The remainder of this README assumed use of a Tor onion service. -Note that the monitor will then punch any NAT and thus run without a public IP. +Finally, ensure that anytime the node requests a new certificate to be issued, +then a new submission is generated that replaces or extends the previous one. +For example, if `certbot` is run by `cron`, then that is a good place to hook. -## Configure the monitor +Repeat this setup if there are multiple nodes. -Create a configuration file specifying which nodes can issue what certificates. -You will also need to specify which domains the monitor should be looking for. +### Setup the monitor - $ cat config +Install on the system that will run the monitor: + + $ go install rgdd.se/silent-ct/cmd/silent-ctmoon@latest + +Create a monitor policy file in JSON format. Below is an example that looks for +all certificates related to `example.org`, expect for certificates that are +associated with `test.example.org`. You need at least one wildcard to match on. + + $ cat policy.json { "monitor": [ { + "bootstrap_at": "2024-01-01T00:00:00Z", "wildcard": "example.org", "excludes": [ "test" @@ -69,6 +80,7 @@ You will also need to specify which domains the monitor should be looking for. { "name": "NODE_NAME", "secret": "NODE_SECRET", + "url": "SUBMISSION_URL", "issues": [ "example.org", "www.example.org" @@ -77,55 +89,30 @@ You will also need to specify which domains the monitor should be looking for. ] } -Here, the monitor is looking for `example.com` and all its subdomains expect for -anything relating to `test.example.com`. There is a single node that is allowed -to issue certificates with the domain names `example.org` and `www.example.org`. - -## Start the monitor - -[Setup an onion service][] that routes through the below UNIX socket. - -Start the monitor: - - $ mkdir state - $ silent-ctmoon -c config.json -s state -l silent-ctmoon.sock - -The intended way to exit is by sending the SIGINT or SIGTERM signals. - -[Setup an onion service]: xxx - -## Node setup - -What makes `silent-ct` _silent_ is that all nodes report legitimately issued -certificates over a secure channel. For each such legitimate certificate, run: - - $ torify curl ... - -`NODE_NAME` is an arbitrary node name used for authentication. - -`NODE_SECRET` is an arbitrary node secret used for authentication. - -`ONION_ADDR` is the onion address where `silent-ct` listens for requests. +The `excludes` keyword is optional. The `bootstrap_at` keyword is required, and +should be set to the current time of adding the wildcard for monitoring. Any +certificate that expired before the specified bootstrap time will be ignored. -`CHAIN_PATH` is the path to a certificate chain that was issued legitimately. -It is safe to repeatedly submit the same certificate chain to `silent-ctmoon`. +Populate the list of nodes based on the names, secrets, and URLs selected during +your setup. Also add the domains each node is allowed to put into certificates. -You will need to add a cron job (or similar) that periodically submits the -issued certificates to `silent-ct`. See example that works for `certbot` -issuing certificates with Let's Encrypt in the [contrib/](./contrib) directory. +Bootstrap the monitor in a non-existent directory: -## Read monitoring alerts + $ silent-ctmoon --bootstrap -f policy.json -d /path/to/directory -v INFO + ... -All output is formatted as follows: +Leave the monitor running: - : + $ silent-ctmoon -f policy.json -d /path/to/directory -Only two keywords are expected by default: `fatal` and `alert`. +Any noteworthy events (like a potentially mis-issued certificate that no node +submitted) will be printed on stdout. If you prefer to get the monitor's output +in a file, use the `-o` option. Please note that it is your job to watch the +output, and/or to hook it up to a notification system like email or similar. -`fatal`: fatal errors were encountered, `silent-ct` is no longer running. +### Further documentation -`alert`: something that you want to know about has happened, such as a -certificate appearing in the logs that none of the trusted nodes submitted. + - A lengthier [introduction](./docs/introduction.md) to the overall design ## Contact diff --git a/docs/introduction.md b/docs/introduction.md index b0d7e71..0aab2cc 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -9,9 +9,6 @@ a specified list of domain names. The domain names that a node requests certificates for may overlap with the domain names of other nodes. For example, there may be two distinct nodes that request certificates for a given domain. - TODO: Add figure. - Figure 1: A few examples of how trusted nodes may be deployed. - The threat we are worried about is certificate mis-issuance. Due to considering a multi-node setting with overlapping domain names, no single node can be aware of all legitimately issued certificates for the domain names that it manages. @@ -65,28 +62,33 @@ from Certificate Transparency logs. The exact logs to download is automatically updated using a list that Google publishes in signed form. All historical updates to the list of logs is stored locally in case any issues are suspected. +(It is possible to get INFO output whenever logs are added and removed. The +default verbosity is however NOTICE, which aims to be as silent as possible.) + To filter out certificates that are not relevant, the monitor is configured with a list of domains to match on. Only matching certificates will be stored, which means there are nearly no storage requirements to run this type of monitor. -To get the property of _silence_, the monitor pulls the trusted nodes -periodically (HTTP GET) for legitimately issued certificates. The monitor will -use this feedback to filter the downloaded certificates that matched. If any -certificates are found that no node pushed to the monitor, an alert is created. +To get the property of _silence_, the monitor pulls the trusted nodes via HTTP +GET for legitimately issued certificates (periodic job). The monitor will use +this feedback to filter the downloaded certificates that matched. If any +certificates are found that no node pushed to the monitor, an alert is printed. The communication channel between the trusted nodes and the monitor can be tampered with. For example, it may be plain HTTP or an HTTPS connection that the attacker trivially hijacks by obtaining yet another mis-issued certificate. Owning that the communication channel is insecure helps avoid misconfiguration. -A pre-shared secret is used for each node to authenticate with the monitor. -That secret is never shown on the wire (an HMAC key is derived from it), which -means that all a man-in-the-middle attacker can do is replay and block messages. +A shared secret is used for each node to authenticate with the monitor. This +secret is never shown on the wire: an HMAC key is derived from it, which is used +to produce message authentication codes. All a machine-in-the-middle attacker +can do is replay or block integrity-protected submissions that a node generated. + "Replays" can happen either way because the monitor polls periodically, i.e., the monitor needs to account for the fact that it may poll the same thing twice. Blocking can not be solved by cryptography and would simply result in alerts. -## Further documentation +## Further reading docdoc -- cgit v1.2.3