Top Related Projects
Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.
🛡️ A private certificate authority (X.509 & SSH) & ACME server for secure automated certificate management, so you can use TLS everywhere & SSO for SSH.
A simple zero-config tool to make locally trusted development certificates with any names you'd like.
A pure Unix shell script implementing ACME client protocol
Quick Overview
Boulder is the ACME-based Certificate Authority (CA) software that powers Let's Encrypt. It's a Go implementation of an ACME server and is responsible for validating domain ownership, issuing certificates, and handling certificate revocations. Boulder is designed to be highly reliable, secure, and scalable to support the issuance of millions of certificates.
Pros
- Implements the ACME protocol, allowing for automated certificate issuance and management
- Highly scalable and reliable, capable of handling millions of certificate requests
- Open-source, allowing for community contributions and audits
- Supports various challenge types for domain validation
Cons
- Complex setup and configuration process
- Requires significant infrastructure to run at scale
- Limited documentation for advanced use cases
- Steep learning curve for those unfamiliar with PKI and ACME
Getting Started
To set up Boulder locally for development or testing:
-
Clone the repository:
git clone https://github.com/letsencrypt/boulder.git cd boulder
-
Install Docker and Docker Compose
-
Build and run Boulder:
docker-compose up
-
Access the Boulder instance at
http://localhost:4000/directory
Note: This is a simplified setup for local development. Production deployment requires additional configuration and infrastructure.
Competitor Comparisons
Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.
Pros of Certbot
- User-friendly command-line tool for obtaining and installing SSL/TLS certificates
- Supports a wide range of web servers and operating systems
- Provides automatic certificate renewal and configuration management
Cons of Certbot
- Limited to client-side operations, not suitable for large-scale certificate management
- Requires root access on the server, which may pose security concerns
- May have compatibility issues with some non-standard server configurations
Code Comparison
Boulder (Go):
func (ra *RegistrationAuthorityImpl) NewAuthorization(ctx context.Context, authz core.Authorization, regID int64) (core.Authorization, error) {
// Implementation details
}
Certbot (Python):
def obtain_and_enroll_certificate(self, domains, certname):
"""Obtain and enroll a certificate for domains."""
# Implementation details
Boulder is the ACME Certificate Authority (CA) server implementation used by Let's Encrypt, while Certbot is a client tool for obtaining and managing certificates. Boulder handles the server-side operations of certificate issuance and management, whereas Certbot focuses on simplifying the process for end-users to obtain and install certificates on their web servers.
🛡️ A private certificate authority (X.509 & SSH) & ACME server for secure automated certificate management, so you can use TLS everywhere & SSO for SSH.
Pros of Certificates
- More lightweight and easier to set up for smaller deployments
- Supports a wider range of certificate types, including SSH certificates
- Offers a simpler CLI interface for certificate management
Cons of Certificates
- Less battle-tested in large-scale production environments
- Smaller community and ecosystem compared to Boulder
- Fewer integrations with third-party services and tools
Code Comparison
Boulder (Go):
func (ra *RegistrationAuthorityImpl) NewAuthorization(ctx context.Context, request *rapb.NewAuthorizationRequest, registration *corepb.Registration) (*corepb.Authorization, error) {
// Implementation details
}
Certificates (Go):
func (a *Authority) Sign(req *SignRequest) (*X509Certificate, error) {
// Implementation details
}
Both projects use Go and follow similar coding patterns for their core functionality. Boulder's codebase is more extensive due to its broader scope and longer development history.
A simple zero-config tool to make locally trusted development certificates with any names you'd like.
Pros of mkcert
- Simpler to use for local development and testing
- Doesn't require external dependencies or network access
- Automatically installs the root CA in the system trust store
Cons of mkcert
- Not suitable for production use or public-facing websites
- Limited to generating certificates for local development
- Doesn't provide automated certificate renewal
Code Comparison
mkcert:
func makeCert(hosts []string) {
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
log.Fatal(err)
}
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{CommonName: hosts[0]},
NotBefore: time.Now(),
NotAfter: time.Now().Add(365 * 24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
DNSNames: hosts,
}
// ... (certificate creation code)
}
boulder:
func (ra *RegistrationAuthorityImpl) NewAuthorization(ctx context.Context, authz core.Authorization, regID int64) (core.Authorization, error) {
if !authz.IsValid() {
return core.Authorization{}, berrors.InternalServerError("invalid authorization")
}
if authz.Identifier.Type != identifier.DNS {
return core.Authorization{}, berrors.MalformedError("invalid identifier type")
}
// ... (authorization creation code)
}
The code snippets show that mkcert focuses on generating certificates locally, while boulder handles more complex tasks like authorization and validation for a full-fledged ACME CA.
A pure Unix shell script implementing ACME client protocol
Pros of acme.sh
- Lightweight and easy to use, with a simple shell script implementation
- Supports a wide range of DNS providers for domain validation
- Can be easily integrated into existing systems and automated workflows
Cons of acme.sh
- Limited to ACME protocol implementation, not a full-featured CA system
- May require more manual configuration for complex setups
- Less comprehensive documentation compared to Boulder
Code Comparison
Boulder (Go):
func (ra *RegistrationAuthorityImpl) NewAuthorization(ctx context.Context, request core.Authorization, regID int64) (core.Authorization, error) {
identifier := request.Identifier
if identifier.Type != core.IdentifierDNS {
return core.Authorization{}, berrors.MalformedError("invalid identifier type")
}
// ... (additional code)
}
acme.sh (Shell):
_send_signed_request() {
_debug "_send_signed_request"
url="$1"
payload="$2"
needbase64="$3"
# ... (additional code)
}
Boulder is a comprehensive ACME CA implementation written in Go, offering a full-featured certificate authority system. acme.sh, on the other hand, is a lightweight ACME client written in shell script, focusing on ease of use and integration. While Boulder provides a complete CA solution, acme.sh is more suitable for users who need a simple, flexible ACME client for certificate management.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Boulder - An ACME CA
This is an implementation of an ACME-based CA. The ACME protocol allows the CA to automatically verify that an applicant for a certificate actually controls an identifier, and allows domain holders to issue and revoke certificates for their domains. Boulder is the software that runs Let's Encrypt.
Contents
Overview
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 security context. The Web Front End, Validation Authority, OCSP Responder and Publisher need access to the Internet, which puts them at greater risk of compromise. The Registration Authority can live without Internet connectivity, but still needs to talk to the Web Front End and Validation Authority. The Certificate Authority need only receive instructions from the Registration Authority. All components talk to the SA for storage, so most lines 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 directly to the resources of the same name in ACME. Requests from ACME clients result in new objects and changes to objects. The Storage Authority maintains persistent copies of the current set of objects.
Boulder uses gRPC for inter-component communication. For components that you want to be remote, it is necessary to instantiate a "client" and "server" for that component. The client implements the component's Go interface, while the server has the actual logic for the component. A high level overview for this communication model can be found in the gRPC documentation.
The full details of how the various ACME operations happen in Boulder are laid out in DESIGN.md.
Setting up Boulder
Development
Boulder has a Dockerfile and uses Docker Compose to make it easy to install and 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. It is not suitable for use as a production environment.
While we aim to make Boulder easy to setup ACME client developers may find Pebble, a miniature version of Boulder, to be better suited for continuous integration and quick experimentation.
We recommend setting git's fsckObjects setting before getting a copy of Boulder to have better integrity guarantees for updates.
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 Compose 1.10.0+ installed. If you do not, you can follow Docker's installation instructions.
We recommend having at least 2GB of RAM available on your Docker host. In practice using less RAM may result in the MariaDB container failing in non-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 immediately
reflected inside the Docker containers run with docker compose
.
If you have problems with Docker, you may want to try removing all containers and volumes.
By default, Boulder uses a fake DNS resolver that resolves all hostnames to 127.0.0.1. This is suitable for running integration tests inside the Docker container. If you want Boulder to be able to communicate with a client running 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 the FAKE_DNS
environment variable to
match. This will cause Boulder's stubbed-out DNS resolver (sd-test-srv
) to
respond to all A queries with the address in FAKE_DNS
.
If you use a host-based firewall (e.g. ufw
or iptables
) make sure you allow
connections from the Docker instance to your host on the required validation
ports to your ACME client.
Alternatively, you can override the docker-compose.yml default with an environmental variable using -e (replace 172.17.0.1 with the host IPv4 address 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 go test -p 1 ./...
Run unit tests for a specific directory:
docker compose run --use-aliases boulder go test <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>
Working with Certbot
Check out the Certbot client from https://github.com/certbot/certbot and
follow their setup instructions. Once you've got the client set up, you'll
probably want to run it against your local Boulder. There are a number of
command line flags that are necessary to run the client against a local
Boulder, and without root access. The simplest way to run the client locally
is to use a convenient alias for certbot (certbot_test
) with a custom
SERVER
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.1
for any query, so you can use any value for the -d flag. To return an answer
other than 127.0.0.1
change the Boulder FAKE_DNS
environment variable to
another IP address.
Working with another ACME Client
Once you have followed the Boulder development environment instructions and have started the containers you will find the ACME endpoints exposed to your host at the 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 your
ACME client software to use a CA truststore that contains the
test/certs/ipki/minica.pem
CA certificate. See
test/certs/README.md
for more information.
Your local Boulder instance uses a fake DNS resolver that returns 127.0.0.1
for any query, allowing you to issue certificates for any domain as if it
resolved to your localhost. To return an answer other than 127.0.0.1
change
the Boulder FAKE_DNS
environment variable to another IP address.
Most often you will want to configure FAKE_DNS
to point to your host
machine where you run an ACME client.
Production
Boulder is custom built for Let's Encrypt and is intended only to support the Web PKI and the CA/Browser forum's baseline requirements. In our experience often Boulder is not the right fit for organizations that are evaluating it for production usage. In most cases a centrally managed PKI that doesn't require domain-authorization with ACME is a better choice. For this environment we recommend evaluating a project other than Boulder.
We offer a brief deployment and implementation guide that describes some of the required work and security considerations involved in using Boulder in a production environment. As-is the docker based Boulder development environment is not suitable for production 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 in a production setting we prioritize support and development work that favors Let's Encrypt's mission. This means we may not be able to provide timely support or accept pull-requests that deviate significantly from our first line goals. If you've thoroughly evaluated the alternatives and Boulder is definitely the best fit we're happy to answer questions to the best of our ability.
Contributing
Please take a look at CONTRIBUTING.md for our guidelines on submitting patches, code review process, code of conduct, and various other tips related to working on the codebase.
Code of Conduct
The code of conduct for everyone participating in this community in any capacity is available for reference on the community forum.
License
This project is licensed under the Mozilla Public License 2.0, the full text of which can be found in the LICENSE.txt file.
Top Related Projects
Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.
🛡️ A private certificate authority (X.509 & SSH) & ACME server for secure automated certificate management, so you can use TLS everywhere & SSO for SSH.
A simple zero-config tool to make locally trusted development certificates with any names you'd like.
A pure Unix shell script implementing ACME client protocol
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot