github.com/letsencrypt/boulder@v0.20251208.0/README.md (about)

     1  # Boulder - An ACME CA
     2  
     3  [![Build Status](https://github.com/letsencrypt/boulder/actions/workflows/boulder-ci.yml/badge.svg?branch=main)](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.