- Notifications
You must be signed in to change notification settings - Fork614
An ACME-based certificate authority, written in Go.
License
letsencrypt/boulder
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
This is an implementation of an ACME-based CA. TheACMEprotocol allows the CA toautomatically verify that an applicant for a certificate actually controls anidentifier, and allows domain holders to issue and revoke certificates fortheir domains. Boulder is the software that runsLet'sEncrypt.
Boulder is divided into the following main components:
- Web Front Ends (one per API version)
- Registration Authority
- Validation Authority
- Certificate Authority
- Storage Authority
- Publisher
- OCSP Responder
- CRL Updater
This component model lets us separate the function of the CA by securitycontext. The Web Front End, Validation Authority, OCSP Responder andPublisher need access to the Internet, which puts them at greater risk ofcompromise. The Registration Authority can live without Internetconnectivity, but still needs to talk to the Web Front End and ValidationAuthority. The Certificate Authority need only receive instructions from theRegistration Authority. All components talk to the SA for storage, so mostlines indicating SA RPCs are not shown here.
CA ---------> Publisher ^ | Subscriber -> WFE --> RA --> SA --> MariaDB | ^Subscriber server <- VA <----+ | | Browser -------------------> OCSP Responder
Internally, the logic of the system is based around five types of objects:accounts, authorizations, challenges, orders and certificates, mapping directlyto the resources of the same name in ACME. Requests from ACME clients result innew objects and changes to objects. The Storage Authority maintains persistentcopies of the current set of objects.
Boulder uses gRPC for inter-component communication. For components that youwant to be remote, it is necessary to instantiate a "client" and "server" forthat component. The client implements the component's Go interface, while theserver has the actual logic for the component. A high level overview for thiscommunication model can be found in thegRPCdocumentation.
The full details of how the various ACME operations happen in Boulder arelaid out inDESIGN.md.
Boulder has a Dockerfile and uses Docker Compose to make it easy to installand set up all its dependencies. This is how the maintainers work on Boulder,and is our main recommended way to run it for development/experimentation. Itis not suitable for use as a production environment.
While we aim to make Boulder easy to setup ACME client developers may findPebble, a miniature version ofBoulder, to be better suited for continuous integration and quickexperimentation.
We recommend setting git'sfsckObjectssettingbefore getting a copy of Boulder to have better integrity guarantees forupdates.
Clone the boulder repository:
git clone https://github.com/letsencrypt/boulder/cd boulder
Additionally, make sure you have Docker Engine 1.13.0+ and Docker Compose1.10.0+ installed. If you do not, you can follow Docker'sinstallationinstructions.
We recommend havingat least 2GB of RAM available on your Docker host. Inpractice using less RAM may result in the MariaDB container failing innon-obvious ways.
To start Boulder in a Docker container, run:
docker compose up
To run our standard battery of tests (lints, unit, integration):
docker compose run --use-aliases boulder ./test.sh
To run all unit tests:
docker compose run --use-aliases boulder ./test.sh --unit
To run specific unit tests (example is of the ./va directory):
docker compose run --use-aliases boulder ./test.sh --unit --filter=./va
To run all integration tests:
docker compose run --use-aliases boulder ./test.sh --integration
To run specific integration tests (example runs TestAkamaiPurgerDrainQueueFails and TestWFECORS):
docker compose run --use-aliases boulder ./test.sh --filter TestAkamaiPurgerDrainQueueFails/TestWFECORS
To get a list of available integration tests:
docker compose run --use-aliases boulder ./test.sh --list-integration-tests
The configuration in docker-compose.yml mounts your boulder checkout at/boulder so you can edit code on your host and it will be immediatelyreflected inside the Docker containers run withdocker compose
.
If you have problems with Docker, you may want to tryremoving allcontainers andvolumes.
By default, Boulder uses a fake DNS resolver that resolves all hostnames to127.0.0.1. This is suitable for running integration tests inside the Dockercontainer. If you want Boulder to be able to communicate with a clientrunning on your host instead, you should find your host's Docker IP with:
ifconfig docker0| grep"inet addr:"| cut -d: -f2| awk'{ print $1}'
And edit docker-compose.yml to change theFAKE_DNS
environment variable tomatch. This will cause Boulder's stubbed-out DNS resolver (sd-test-srv
) torespond to all A queries with the address inFAKE_DNS
.
If you use a host-based firewall (e.g.ufw
oriptables
) make sure you allowconnections from the Docker instance to your host on the required validationports to your ACME client.
Alternatively, you can override the docker-compose.yml default with anenvironmental variable using -e (replace 172.17.0.1 with the host IPv4address found in the command above)
docker compose run --use-aliases -e FAKE_DNS=172.17.0.1 --service-ports boulder ./start.py
Running tests without the./test.sh
wrapper:
Run all unit tests
docker compose run --use-aliases boulder gotest -p 1 ./...
Run unit tests for a specific directory:
docker compose run --use-aliases boulder gotest<DIRECTORY>
Run integration tests (omit--filter <REGEX>
to run all):
docker compose run --use-aliases boulder python3 test/integration-test.py --chisel --gotest --filter<REGEX>
Check out the Certbot client fromhttps://github.com/certbot/certbot andfollow their setup instructions. Once you've got the client set up, you'llprobably want to run it against your local Boulder. There are a number ofcommand line flags that are necessary to run the client against a localBoulder, and without root access. The simplest way to run the client locallyis to use a convenient alias for certbot (certbot_test
) with a customSERVER
environment variable:
SERVER=http://localhost:4001/directory certbot_test certonly --standalone -d test.example.com
Your local Boulder instance uses a fake DNS resolver that returns 127.0.0.1for any query, so you can use any value for the -d flag. To return an answerother than127.0.0.1
change the BoulderFAKE_DNS
environment variable toanother IP address.
Once you have followed the Boulder development environment instructions and havestarted the containers you will find the ACME endpoints exposed to your host atthe following URLs:
- ACME v2, HTTP:
http://localhost:4001/directory
- ACME v2, HTTPS:
https://localhost:4431/directory
To access the HTTPS versions of the endpoints you will need to configure yourACME client software to use a CA truststore that contains thetest/certs/ipki/minica.pem
CA certificate. Seetest/certs/README.md
for more information.
Your local Boulder instance uses a fake DNS resolver that returns 127.0.0.1for any query, allowing you to issue certificates for any domain as if itresolved to your localhost. To return an answer other than127.0.0.1
changethe BoulderFAKE_DNS
environment variable to another IP address.
Most often you will want to configureFAKE_DNS
to point to your hostmachine where you run an ACME client.
Boulder is custom built for Let's Encrypt and is intended only to support theWeb PKI and the CA/Browser forum's baseline requirements. In our experienceoften Boulder is not the right fit for organizations that are evaluating it forproduction usage. In most cases a centrally managed PKI that doesn't requiredomain-authorization with ACME is a better choice. For this environment werecommend evaluating a project other than Boulder.
We offer a briefdeployment and implementationguidethat describes some of the required work and security considerations involved inusing Boulder in a production environment. As-is the docker based Boulderdevelopment environment isnot suitable forproduction usage. It uses private key material that is publicly available,exposes debug ports and is brittle to component failure.
While we are supportive of other organization's deploying Boulder ina production setting we prioritize support and development work that favorsLet's Encrypt's mission. This means we may not be able to provide timely supportor accept pull-requests that deviate significantly from our first line goals. Ifyou've thoroughly evaluated the alternatives and Boulder is definitely the bestfit we're happy to answer questions to the best of our ability.
Please take a look atCONTRIBUTING.mdfor our guidelines on submitting patches, code review process, code of conduct,and various other tips related to working on the codebase.
The code of conduct for everyone participating in this community in any capacityis available for referenceon the community forum.
This project is licensed under the Mozilla Public License 2.0, the full textof which can be found in theLICENSE.txtfile.
About
An ACME-based certificate authority, written in Go.