Git Product home page Git Product logo

boulder's Introduction

Azure Pipelines CI status

EFF Certbot Logo

Certbot is part of EFF’s effort to encrypt the entire Internet. Secure communication over the Web relies on HTTPS, which requires the use of a digital certificate that lets browsers verify the identity of web servers (e.g., is that really google.com?). Web servers obtain their certificates from trusted third parties called certificate authorities (CAs). Certbot is an easy-to-use client that fetches a certificate from Let’s Encrypt—an open certificate authority launched by the EFF, Mozilla, and others—and deploys it to a web server.

Anyone who has gone through the trouble of setting up a secure website knows what a hassle getting and maintaining a certificate is. Certbot and Let’s Encrypt can automate away the pain and let you turn on and manage HTTPS with simple commands. Using Certbot and Let's Encrypt is free.

Getting Started

The best way to get started is to use our interactive guide. It generates instructions based on your configuration settings. In most cases, you’ll need root or administrator access to your web server to run Certbot.

Certbot is meant to be run directly on your web server on the command line, not on your personal computer. If you’re using a hosted service and don’t have direct access to your web server, you might not be able to use Certbot. Check with your hosting provider for documentation about uploading certificates or using certificates issued by Let’s Encrypt.

Contributing

If you'd like to contribute to this project please read Developer Guide.

This project is governed by EFF's Public Projects Code of Conduct.

Documentation: https://certbot.eff.org/docs

Software project: https://github.com/certbot/certbot

Changelog: https://github.com/certbot/certbot/blob/master/certbot/CHANGELOG.md

For Contributors: https://certbot.eff.org/docs/contributing.html

For Users: https://certbot.eff.org/docs/using.html

Main Website: https://certbot.eff.org

Let's Encrypt Website: https://letsencrypt.org

Community: https://community.letsencrypt.org

ACME spec: RFC 8555

ACME working area in github (archived): https://github.com/ietf-wg-acme/acme

Current Features

  • Supports multiple web servers:
    • Apache 2.4+
    • nginx/0.8.48+
    • webroot (adds files to webroot directories in order to prove control of domains and obtain certificates)
    • standalone (runs its own simple webserver to prove you control a domain)
    • other server software via third party plugins
  • The private key is generated locally on your system.
  • Can talk to the Let's Encrypt CA or optionally to other ACME compliant services.
  • Can get domain-validated (DV) certificates.
  • Can revoke certificates.
  • Supports ECDSA (default) and RSA certificate private keys.
  • Can optionally install a http -> https redirect, so your site effectively runs https only.
  • Fully automated.
  • Configuration changes are logged and can be reverted.

boulder's People

Contributors

4a6f656c avatar aarongable avatar alexzorin avatar andygabby avatar beautifulentropy avatar benileo avatar bifurcation avatar bmw avatar briansmith avatar cpu avatar dependabot[bot] avatar duesee avatar hlandau avatar ibukanov avatar jcjones avatar jessfraz avatar jgillula avatar jmhodges avatar jsha avatar klebervirgilio avatar kuba avatar mcpherrinm avatar mvdan avatar pde avatar pgporada avatar r0ro avatar riking avatar rolandshoemaker avatar tomclegg avatar weppos avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

boulder's Issues

Log consistently using Syslog over TCP

For central logging we will want to reduce the use of stdout / stderr and prefer RFC 5424 syslogging over TCP. Logging should follow a consistent format so that we can write a Logstash grok rule to decode important details.

The remote logging server should be specified by hostname via the command line.

It appears that the Go syslog package supports syslog over UDP and TCP.

Don't ignore random number generation errors

In

func RandomString(byteLength int) string {
:

func RandomString(byteLength int) string {
    b := make([]byte, byteLength)
    rand.Read(b) // NOTE: Ignoring errors
    return B64enc(b)
}

An error in rand.Read might indicate that the system RNG is failing. You probably want to make sure callers hard-fail if there is an error here so that tokens, keys, etc. don't end up with too little entropy.

From https://golang.org/pkg/crypto/rand/#Read:

 On return, n == len(b) if and only if err == nil. 

Send Heartbeats from Activity Monitor

If the Activity Monitor is down, it means we are no longer logging all activity and need to cease operations.

The Activity Monitor should send frequent (1s?) heartbeat messages to AMQP, and each component (but especially the Web Frontend) should consume them. If there is is a pause in Activity Monitor heartbeats, the components should pause their own operations until the Activity Monitor resumes. The Web Frontend should start serving 500s until then.

Google Certificate Transparency (CT) support

Chrome is not currently supporting a hard CT requirement for EV or DV certs, and hasn't announced when it plans to do so. We can and should participate in CT, but clients won't get any obvious indication of its absence. We should make a public statement that ever certificate we issue will be submitted to a CT log, and third-party monitors can collect certs from the Internet and check logs to keep us honest.

Subscribers that want to provide a CT proof can do so with the OCSP Stapling technique (recommended) or the TLS Extension technique. I haven't yet investigated whether we can bundle the CT proof with the regular OCSP responses we send.

To implement CT, we can use a polling component that exists outside of our firewall. This component will continuously query Let's Encrypt's certificate repository for new certificates, and submit those certificates to the appropriate logs.

To do this we'll need to update the certificate repository code in Boulder so that it can be used to query for new certificates. One simple way to do this: In addition to querying by serial numbers (implemented), we could allow querying by the sequential part of the serial number. This would return all certificates with serial numbers greater than the sequential part queried and less than the next increment of the sequential part. Assuming everything is functioning correctly, that should be exactly one certificate. The CT poller would fetch and store each certificate until gets a 404, then poll that number until it resolves, and so on.

Whitelist values to copy from CSR

CSR is a powerful format and allows specifying arbitrary extensions. Since the user fully controls CSR input, we want to strictly whitelist which values from the CSR can be copied into the certificate. It probably makes sense to implement this in CFSSL rather than Boulder. CFSSL issue cloudflare/cfssl#156 has some of the discussion.

Wildcard Certificate Support

According to a presentation by Seth Schoen and according to brief inspection of the CA source code, Let's Encrypt is planning on not issuing wildcard certificates. IIRC, the reason given by Schoen was the lack of a method of checking that the ACME client really speaks for the whole domain subspace. Furthermore, it was observed that being able to quickly meant non-wildcard certificates for a particular host names in an automated fashion without payment makes wildcard certificates less necessary.

This doesn't address the wildcard use case that Sandstorm (https://sandstorm.io/) has: Minting randomly-generated host names all the time in order to generate new unguessable origins. In order for newly-minted origins to work immediately, it doesn't make sense to wait even for fast automatic certificate issuance. Also, I would imagine that as long as the Baseline Requirements don't exempt short-lived certificates from revocation infrastructure requirements, Let's Encrypt might not be too keen to have servers generate certs for throw-away hostnames all the time.

To address this use case, I suggest that Let's Encrypt issues a wildcard certificate when the ACME client can demonstrate that it speaks for several hostnames that are randomly generated by the Registration Authority. For some reasonable value for "several", the RA should be able to convince itself that there exists a DNS wildcard that makes hostnames that would match the requested wildcard certificates point to the server running the ACME client.

Audit Logging

All of the following are identified as audit log entries that must be produced by Boulder. These must be written with the AuditLogger.Audit() function from PR #61.
These are valid as of CPS draft 2.1, updates for 4/1/2015.

All Certificate requests – Date and time of request, type of event, and request information are automatically logged by the application. This includes Issuance, renewal, and re-key requests as well as sender/requester DN, Certificate serial number, initial application, method of request (online, in-person), source of verification, name of document presented for identity proofing, all fields verified in the application, Certificate common name, new validity period dates, date and time of response and success or failure indication are automatically logged by the application, and all associated error messages and codes. Manual interactions with participants such as telephone or in person inquiries and results of verification calls will be logged manually in a logbook or in a computer-based recording/tracking system and include date/time, description of interaction and identity provided.

All Certificate Revocation requests – Date and time of Revocation request, sender/requester DN, Certificate serial number, subject DN of Certificate to revoke, Subscriber’s common name, Revocation reason, date and time of response and success or failure indication are automatically logged by the application; manual interactions with requestors such as telephone or in person inquiries and requests for Revocation are logged manually in a logbook or in a computer-based recording/tracking system. The date/time, description of interaction and identity provided are also recorded.

The approval or rejection of a Certificate status change request – Identity of equipment operator who initiated the request, message contents, message source, destination, and success or failure indication are automatically logged by the application.

Any security-relevant changes to the configuration of a component – Date and time of modification, name of modifier, description of modification, build information (i.e. size, version number) of any modified files and the reason for modification are manually logged during change management processes.

All Certificate compromise notification requests – Date and time of notification, identity of person making the notification, identification of entity compromised, and a description of the compromise are logged manually by the personnel who receive the notification (e.g. Help Desk, RA Operators, etc.) and by RA/RA Operators’ system processing logs.

Software error conditions – Date and time of event, and description of event are automatically logged by the application reporting the event or by the operating system.

Software check integrity failures – Date and time of event, and description of event are automatically logged by the application reporting the event or by the operating system.

Receipt of improper messages – Date and time of event, and description of event are automatically logged by the application reporting the event or by the operating system.

Misrouted messages – Date and time of event, and description of event are automatically logged by the application reporting the event or by the operating system.

Client certificates

Will it be possible to use a Let's Encrypt certificate to sign client certificates yourself, or will it be possible to request client certificates from Let's Encrypt?

Handle SIGTERM gracefully

When receiving SIGTERM, Boulder instances should:

  1. Immediately stop reading any messages on the AMQP interface
  2. Finish processing any outstanding messages
  3. Close

This lets us do rolling restarts without data loss.

Catching SIGTERM seems well-understood with the os/signal package. Just look for syscall.SIGTERM and set appropriate flags in motion.

Noteworthy StackOverflow:
http://stackoverflow.com/questions/11268943/golang-is-it-possible-to-capture-a-ctrlc-signal-and-run-a-cleanup-function-in

Config parser's errors are eclipsed

In the event that config.json has an error, such as a trailing comma, the following log is emitted;

Unable to connect to AMQP server: AMQP scheme must be either 'amqp://' or 'amqps://'

This error is (potentially) spurious; the AMQP string may be valid. Likely the JSON parser 's error(s) are being discarded.

Rate limiting

The WFE should be able to do rate limiting by:

  • Client IP address
  • Account key
  • 2LD (i.e. the first label after a public suffix)
  • global account count (for beta deployment)
  • global validated domain count (for beta deployment)
  • global cert count (for beta deployment)

These rate limits should be readily adjustable with a config file, and should be overridable for specific values of each rate limit key.

Update README for initial setup

Now when I try to start up Boulder, I get this error:

$ ./bin/boulder-start monolithic
amqp://guest:guest@localhost:5672
localhost:8888


2015/03/12 17:49:36 [DEBUG] validating configuration
2015/03/12 17:49:36 [DEBUG] validate remote profile
2015/03/12 17:49:36 [DEBUG] invalid remote profile: no remote signer specified
2015/03/12 17:49:36 [DEBUG] default profile is invalid
Unable to create CA: {"code":5200,"message":"Invalid or unknown policy"}

I'm guessing this is because I need to be running a cfssl instance locally. Could you please add instructions to the README, @bifurcation?

Content-type: application/json missing

The content-type header is currently sent as 'content-type': 'text/plain; charset=utf-8'
All of the messages besides the certificate should set the Header to application/json.

Quickstart doesn't fully work

In the Quickstart section there's installation instructions that might not work, depending on your gopath. If you go get github.com/letsencrypt/anvil you don't fetch dependencies for anvil-start, so github.com/codegangsta/cli will be missing.

As anvil-start requires the anvil pkg, changing the go build in the instructions to go get makes sure this dependency is installed, along with whatever the go get of the anvil pkg does.

I'm preparing a pull request.

Potential timing attack in challenge authentication

https://github.com/letsencrypt/boulder/blob/master/validation-authority.go#L85

This looks like a straightforward classic timing attack. I think you want either http://golang.org/pkg/crypto/subtle/ (ConstantTimeCompare), or some higher-level crypto API, or to make Challenge that higher-level API (implemented with crypto.subtle).

Another approach is to bytes.Compare a randomized form of the tokens (randomized in a way the attacker cannot predict). But since crypto.subtle is there, it seems straightforward to just use that as a drop-in replacement to the current code.

Note that the return values for bytes.Compare and crypto.subtle.ConstantTimeCompare return different values when the arrays are equal. :]

if crypto.subtle.ConstantTimeCompare(body, []byte(challenge.Token)) == 1 {
challenge.Status = StatusValid
return
}

Issue without CN

The current logic in IssueCertificate only includes the CommonName in subjectAlternateNames if there were no subjectAlternateNames provided in the CSR. Instead, we should always add the CommonName to the subjectAlternateNames if it is not already present there.

Adjust example config to use UDP syslogging

When I follow the instructions in the README (under "A quick-start method for running a Boulder instance is to use one of the example configurations"), docker run fails with the following error:

➜  boulder git:(master) ✗ docker run --name=boulder --read-only=true --rm=true -v $(pwd)/.boulder-config:/boulder:ro -p 4000:4000 quay.io/letsencrypt/boulder:latest boulder  
Could not connect to Syslog: Unix syslog delivery error

Additional SANs in CSR are ignored

When I use the LE client to request a certificate for more than one hostname, only the first one seems to be included in the certificate. All additional hostnames seem to be ignored. However, the CSR which is generated appears to be correct - the problem seems to be occurring at the boulder end.

e.g. I request a cert for "example.org,www.example.org"
The CSR has CN=example.org, SAN={example.org,www.example.org}

Expected cert:
CN=example.org, SAN={example.org,www.example.org}

Actual issued cert:
CN=example.org, SAN={example.org}

I can't see any obvious error in certificate-authority.go - is this a bug upstream in CFSSL perhaps?

Check for weak keys

We need to check for keys less than 2048 bits and known weak private keys, per CPS.

The automated process will also verify the Public Key of a Device that is requested has less than 2048 bit encryption and if it uses a known weak Private Key. If either or both are automatically detected in the secure session, the Applicant will be required to correct the determined issue before the DV-SSL Certificate can be issued.

Limit account registrations & domain validations

Boulder needs to be able to limit the number of active accounts and validated domains, to let us slow-roll startup.

The administrators will want to be able to change the limits regularly, constantly and in an automated fashion. I think this should be done as a database table, so that it is persistent and up-datable.

I recommend writing the module to check for the existence of a table named Quotas and, if it exists, only permit a particular action if there is remaining quota, decrementing the quota as it does.

Schema idea:

CREATE TABLE Quota (id INTEGER, type VARCHAR(32), available INTEGER)

types:

  • accountRegistration
  • domainRegistration
  • certificateIssuance

We can then write simple test scripts that add 10 to "available" for each type, for example, to run when desired.

Assign serial numbers in Boulder-CA

The Boulder-CA instance must be responsible for determining the certificate serial number for a given signing request.

The serial number consists of three parts:

  1. A segment ID (8 bits), assigned in the configuration file (to let us distinguish between CA instances)
  2. A monotonically increasing identifier (56 bits)
  3. Random data (64 bits)

To maintain the monotonically increasing identifier, Boulder-CA should be reworked to use an instance of MariaDB/MySQL, and store the most recently used identifier in a table there. Incrementing that value should be done in a transaction that depends on the successful completion of a signing operation at CFSSL.

Non-standard JWK thumbprint computation

JsonWebKey ComputeThumbprint(), used to test for JsonWebKey equality, is non-standard and could potentially cause security issues. For instance, the thumbprint ignores the RSA public exponent value entirely. An attacker who can construct an ECDSA/RSA public key that matches the fingerprint of a registered key of either type can forge JWS signatures for the registered key.

The recommended fingerprint construction according to https://tools.ietf.org/html/draft-jones-jose-jwk-thumbprint-01 is:

   the SHA-256 hash of
   the octets of the UTF-8 representation of a JSON object [RFC7159]
   constructed containing only the REQUIRED members of a JWK
   representing the key and with no white space or line breaks before or
   after any syntactic elements and with the REQUIRED members ordered
   lexicographically by the Unicode code points of the member names.

Use Policy Database for decisions

Files like psl.go and blacklist.go will require regular recompiles of boulder; it'll be better to be able to feed updated config files or databases (we'll need the latter for the set of valid cert names) into a running boulder instance.

Validate input JWS in RA as well as WFE

Currently the RA trusts the WFE to validate input JWS and provide the correct public key in a NewCertificate request. If the WFE is compromised, and the attacker knows the public key of an account authorized for target site, they could cause issuance for that site by lying to the RA. We should probably pass a copy of the whole request to the RA for secondary validation.

Load testing

We should implement a load testing framework for Boulder and test it thoroughly.

Add test cases for every weird JSON ←→ JWS corner case

JSON is unfortunately not a uniform and deterministic language to parse. Many of the ambiguities in JSON turn into potential attacks against JWS. We need at least one test case to ensure that Boulder's JWS code rejects messages with these ambiguities.

Some known ambiguities are:

  • Duplicate keys in a JSON object (we should reject)
  • Trailing characters after a valid JSON object (we should reject)
  • Numeric types can be parsed to integers or floats (out of caution, we should reject any message containing numerical types)
  • Test ignoring of the JWS "Algorithm" field
  • Decide whether we're okay with messages containing unknown fields
  • Fix go's case insensitivity wrt JSON keys

Why AMQP for RPC?

The version of amqp that you're using is good but it's dead, because there is a 1.0 version which is seriously made and everyone using that should be executed on site. So why use the dead protocol version amqp 0.9.1?

Is "Expiry" really that unused?

While reading through the implementation, I found that Expiry is marked as not used:

    // Create the remote signer
    localProfile := config.SigningProfile{
        Expiry:       time.Hour, // BOGUS: Required by CFSSL, but not used
        RemoteName:   hostport,  // BOGUS: Only used as a flag by CFSSL
        RemoteServer: hostport,
    }

The cfssl implementation does not support that claim:

Is this interpretation correct?

Maintain a denied database

Our CPS requires that when we deny issuance,

DV-SSL applications that cannot pass this review will not be issued a DV-SSL Certificate. If the DV-SSL Certificate does not pass review, it will be added to a list of previously denied applications and kept for verification purposes of future DV-SSL Certificate applications.

We should add a table to store denied requests.

Certificate issuance should block on first OCSP signing

When a new certificate is issued, we need to also sign an OCSP response indicating the certificate is valid and push that response to our OCSP origin server*. We should make sure that this process completes before /certificate/NNN returns the new certificate. Depends on #72.

*we don't need to invalidate cache because certs are requested by serial and there should be no cached response for the new serial, right?

Handle AMQP disconnection

Currently if there is any interruption of the AMQP server (e.g., it restarts), the various clients will not reconnect. Rather, they each print logs such as:

2015/02/09 22:22:08 [c!] AMQP-RPC timeout [Get]

The clients should detect an RPC timeout and re-subscribe.

Flaky test

We have a flaky test that fails just some of the time, e.g. https://travis-ci.org/letsencrypt/boulder/builds/59786446:

--- FAIL: TestIssueCertificate (1.19s)
panic: runtime error: slice bounds out of range [recovered]
panic: runtime error: slice bounds out of range

My guess is that the slice in question is the slice that tries to take the first 16 bytes of the hex-encoded serial number. Perhaps the serial number is empty in some random cases? Could be related to timing issues with regards to the certificate authority's sequence DB?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.