github.com/letsencrypt/boulder@v0.20251208.0/README.md (about) 1 # Boulder - An ACME CA 2 3 [](https://github.com/letsencrypt/boulder/actions/workflows/boulder-ci.yml?query=branch%3Amain) 4 5 This is an implementation of an ACME-based CA. The [ACME 6 protocol](https://github.com/ietf-wg-acme/acme/) allows the CA to automatically 7 verify that an applicant for a certificate actually controls an identifier, and 8 allows subscribers to issue and revoke certificates for the identifiers they 9 control. Boulder is the software that runs [Let's 10 Encrypt](https://letsencrypt.org). 11 12 ## Contents 13 14 * [Overview](#overview) 15 * [Setting up Boulder](#setting-up-boulder) 16 * [Development](#development) 17 * [Working with Certbot](#working-with-certbot) 18 * [Working with another ACME Client](#working-with-another-acme-client) 19 * [Production](#production) 20 * [Contributing](#contributing) 21 * [License](#license) 22 23 ## Overview 24 25 Boulder is divided into the following main components: 26 27 1. Web Front Ends (one per API version) 28 2. Registration Authority 29 3. Validation Authority 30 4. Certificate Authority 31 5. Storage Authority 32 6. Publisher 33 7. CRL Updater 34 35 This component model lets us separate the function of the CA by security 36 context. The Web Front End, Validation Authority, CRL Storer, and 37 Publisher need access to the Internet, which puts them at greater risk of 38 compromise. The Registration Authority can live without Internet 39 connectivity, but still needs to talk to the Web Front End and Validation 40 Authority. The Certificate Authority need only receive instructions from the 41 Registration Authority. All components talk to the SA for storage, so most 42 lines indicating SA RPCs are not shown here. 43 44 ```text 45 CA ---------> Publisher 46 ^ 47 | 48 Subscriber -> WFE --> RA --> SA --> MariaDB 49 | ^ 50 Subscriber server <- VA <----+ | 51 | 52 Browser -----> S3 <----- CRL Storer/Updater 53 ``` 54 55 Internally, the logic of the system is based around five types of objects: 56 accounts, authorizations, challenges, orders and certificates, mapping directly 57 to the resources of the same name in ACME. Requests from ACME clients result in 58 new objects and changes to objects. The Storage Authority maintains persistent 59 copies of the current set of objects. 60 61 Boulder uses gRPC for inter-component communication. For components that you 62 want to be remote, it is necessary to instantiate a "client" and "server" for 63 that component. The client implements the component's Go interface, while the 64 server has the actual logic for the component. A high level overview for this 65 communication model can be found in the [gRPC 66 documentation](https://www.grpc.io/docs/). 67 68 The full details of how the various ACME operations happen in Boulder are 69 laid out in 70 [DESIGN.md](https://github.com/letsencrypt/boulder/blob/main/docs/DESIGN.md). 71 72 ## Setting up Boulder 73 74 ### Development 75 76 Boulder has a Dockerfile and uses Docker Compose to make it easy to install 77 and set up all its dependencies. This is how the maintainers work on Boulder, 78 and is our main recommended way to run it for development/experimentation. It 79 is not suitable for use as a production environment. 80 81 While we aim to make Boulder easy to setup ACME client developers may find 82 [Pebble](https://github.com/letsencrypt/pebble), a miniature version of 83 Boulder, to be better suited for continuous integration and quick 84 experimentation. 85 86 We recommend setting git's [fsckObjects 87 setting](https://groups.google.com/forum/#!topic/binary-transparency/f-BI4o8HZW0/discussion) 88 before getting a copy of Boulder to have better integrity guarantees for 89 updates. 90 91 Clone the boulder repository: 92 93 ```shell 94 git clone https://github.com/letsencrypt/boulder/ 95 cd boulder 96 ``` 97 98 Additionally, make sure you have Docker Engine 1.13.0+ and Docker Compose 99 1.10.0+ installed. If you do not, you can follow Docker's [installation 100 instructions](https://docs.docker.com/compose/install/). 101 102 We recommend having **at least 2GB of RAM** available on your Docker host. In 103 practice using less RAM may result in the MariaDB container failing in 104 non-obvious ways. 105 106 To start Boulder in a Docker container, run: 107 108 ```shell 109 docker compose up 110 ``` 111 112 To run our standard battery of tests (lints, unit, integration): 113 114 ```shell 115 ./t.sh 116 ``` 117 118 To run all unit tests: 119 120 ```shell 121 ./t.sh -u 122 ``` 123 124 To run specific unit tests (example is of the ./va directory): 125 126 ```shell 127 ./t.sh -u -p ./va 128 ``` 129 130 To run all integration tests: 131 132 ```shell 133 ./t.sh -i 134 ``` 135 136 To run unit tests and integration tests with coverage: 137 138 ```shell 139 ./t.sh -ui -c --coverage-dir=./test/coverage/mytestrun 140 ``` 141 142 To run specific integration tests (example runs TestGenerateValidity and TestWFECORS): 143 144 ```shell 145 ./t.sh -i -f TestGenerateValidity/TestWFECORS 146 ``` 147 148 To do any of the above, but using the "config-next" configuration, which 149 represents a likely future state (e.g. including new feature flags): 150 151 ```shell 152 ./tn.sh -your -options -here 153 ``` 154 155 The configuration in docker-compose.yml mounts your boulder checkout at 156 /boulder so you can edit code on your host and it will be immediately 157 reflected inside the Docker containers run with `docker compose`. 158 159 If you have problems with Docker, you may want to try [removing all 160 containers and 161 volumes](https://www.digitalocean.com/community/tutorials/how-to-remove-docker-images-containers-and-volumes). 162 163 By default, Boulder uses a fake DNS resolver that resolves all hostnames to 164 127.0.0.1. This is suitable for running integration tests inside the Docker 165 container. If you want Boulder to be able to communicate with a client 166 running on your host instead, you should find your host's Docker IP with: 167 168 ```shell 169 ifconfig docker0 | grep "inet addr:" | cut -d: -f2 | awk '{ print $1}' 170 ``` 171 172 And edit docker-compose.yml to change the `FAKE_DNS` environment variable to 173 match. This will cause Boulder's stubbed-out DNS resolver (`sd-test-srv`) to 174 respond to all A queries with the address in `FAKE_DNS`. 175 176 If you use a host-based firewall (e.g. `ufw` or `iptables`) make sure you allow 177 connections from the Docker instance to your host on the required validation 178 ports to your ACME client. 179 180 Alternatively, you can override the docker-compose.yml default with an 181 environmental variable using -e (replace 172.17.0.1 with the host IPv4 182 address found in the command above) 183 184 ```shell 185 docker compose run --use-aliases -e FAKE_DNS=172.17.0.1 --service-ports boulder ./start.py 186 ``` 187 188 Running tests without the `./test.sh` wrapper: 189 190 Run unit tests locally, without docker (only works for some directories): 191 192 ```shell 193 go test ./issuance/... 194 ``` 195 196 Run all unit tests: 197 198 ```shell 199 docker compose run --use-aliases boulder go test -p 1 ./... 200 ``` 201 202 Run unit tests for a specific directory: 203 204 ```shell 205 docker compose run --use-aliases boulder go test <DIRECTORY> 206 ``` 207 208 Run integration tests (omit `--filter <REGEX>` to run all): 209 210 ```shell 211 docker compose run --use-aliases boulder python3 test/integration-test.py --chisel --gotest --filter <REGEX> 212 ``` 213 214 ### Working with Certbot 215 216 Check out the Certbot client from https://github.com/certbot/certbot and 217 follow their setup instructions. Once you've got the client set up, you'll 218 probably want to run it against your local Boulder. There are a number of 219 command line flags that are necessary to run the client against a local 220 Boulder, and without root access. The simplest way to run the client locally 221 is to use a convenient alias for certbot (`certbot_test`) with a custom 222 `SERVER` environment variable: 223 224 ```shell 225 SERVER=http://localhost:4001/directory certbot_test certonly --standalone -d test.example.com 226 ``` 227 228 Your local Boulder instance uses a fake DNS resolver that returns 127.0.0.1 229 for any query, so you can use any value for the -d flag. To return an answer 230 other than `127.0.0.1` change the Boulder `FAKE_DNS` environment variable to 231 another IP address. 232 233 ### Working with another ACME Client 234 235 Once you have followed the Boulder development environment instructions and have 236 started the containers you will find the ACME endpoints exposed to your host at 237 the following URLs: 238 239 * ACME v2, HTTP: `http://localhost:4001/directory` 240 * ACME v2, HTTPS: `https://localhost:4431/directory` 241 242 To access the HTTPS versions of the endpoints you will need to configure your 243 ACME client software to use a CA truststore that contains the 244 `test/certs/ipki/minica.pem` CA certificate. See 245 [`test/certs/README.md`](https://github.com/letsencrypt/boulder/blob/main/test/certs/README.md) 246 for more information. 247 248 Your local Boulder instance uses a fake DNS resolver that returns 127.0.0.1 249 for any query, allowing you to issue certificates for any domain as if it 250 resolved to your localhost. To return an answer other than `127.0.0.1` change 251 the Boulder `FAKE_DNS` environment variable to another IP address. 252 253 Most often you will want to configure `FAKE_DNS` to point to your host 254 machine where you run an ACME client. 255 256 ### Production 257 258 Boulder is custom built for Let's Encrypt and is intended only to support the 259 Web PKI and the CA/Browser forum's baseline requirements. In our experience 260 often Boulder is not the right fit for organizations that are evaluating it for 261 production usage. In most cases a centrally managed PKI that doesn't require 262 domain-authorization with ACME is a better choice. For this environment we 263 recommend evaluating a project other than Boulder. 264 265 We offer a brief [deployment and implementation 266 guide](https://github.com/letsencrypt/boulder/wiki/Deployment-&-Implementation-Guide) 267 that describes some of the required work and security considerations involved in 268 using Boulder in a production environment. As-is the docker based Boulder 269 development environment is **not suitable for 270 production usage**. It uses private key material that is publicly available, 271 exposes debug ports and is brittle to component failure. 272 273 While we are supportive of other organization's deploying Boulder in 274 a production setting we prioritize support and development work that favors 275 Let's Encrypt's mission. This means we may not be able to provide timely support 276 or accept pull-requests that deviate significantly from our first line goals. If 277 you've thoroughly evaluated the alternatives and Boulder is definitely the best 278 fit we're happy to answer questions to the best of our ability. 279 280 ## Contributing 281 282 Please take a look at 283 [CONTRIBUTING.md](https://github.com/letsencrypt/boulder/blob/main/docs/CONTRIBUTING.md) 284 for our guidelines on submitting patches, code review process, code of conduct, 285 and various other tips related to working on the codebase. 286 287 ## Code of Conduct 288 289 The code of conduct for everyone participating in this community in any capacity 290 is available for reference 291 [on the community forum](https://community.letsencrypt.org/guidelines). 292 293 ## License 294 295 This project is licensed under the Mozilla Public License 2.0, the full text 296 of which can be found in the 297 [LICENSE.txt](https://github.com/letsencrypt/boulder/blob/main/LICENSE.txt) 298 file.