Commit Graph

39 Commits

Author SHA1 Message Date
Aaron Gable 47499233bf
Remove duplicate _db-next migration files (#4889)
These files have already been moved to the _db directory,
so they no longer need to exist in _db-next.

Fixes #4888
2020-06-22 18:18:15 -07:00
Aaron Gable 91d4e235ad
Deprecate the BlockedKeyTable feature flag (#4881)
This commit consists of three classes of changes:
1) Changing various command main.go files to always behave as they
   would have when features.BlockedKeyTable was true. Also changing
   one test in the same manner.
2) Removing the BlockedKeyTable flag from configuration in config-next,
   because the flag is already live.
3) Moving the BlockedKeyTable flag to the "deprecated" section of
   features.go, and regenerating featureflag_strings.go.

A future change will remove the BlockedKeyTable flag (and other
similarly deprecated flags) from features.go entirely.

Fixes #4873
2020-06-22 16:35:37 -07:00
Jacob Hoffman-Andrews 3d9c31580a
Remove StoreIssuerInfo flag in SA. (#4849)
Now that the migration has been applied, we can reference the issuerID
field unconditionally. Also remove the migration file. It had already
been copied to sa/_db/migrations, but not removed from _db-next.

Part of a multi-PR changeset removing the StoreIssuerInfo flag.
2020-06-12 11:45:04 -07:00
Roland Bracewell Shoemaker b7ad70caff
sa: implement faster new orders rate limit (#4857)
Fixes #4840
2020-06-09 17:14:23 -07:00
Roland Bracewell Shoemaker 70ff4d9347
Add bad-key-revoker daemon (#4788)
Adds a daemon which monitors the new blockedKeys table and checks for any unexpired, unrevoked certificates that are associated with the added SPKI hashes and revokes them, notifying the user that issued the certificates.

Fixes #4772.
2020-04-23 11:51:59 -07:00
Roland Bracewell Shoemaker 9df97cbf06
Add a blocked keys table, and use it (#4773)
Fixes #4712 and fixes #4711.
2020-04-15 13:42:51 -07:00
Roland Bracewell Shoemaker fb0d2ffaa8
Store key hash when adding precertificate, add backfill tool (#4753)
Fixes #4749
2020-04-08 13:53:19 -07:00
Daniel McCarney fc15f2f4cd
SA: add unit test for auto_increment schemas. (#4586)
* SA: add unit test for auto_increment schemas.

`TestAutoIncrementSchema` uses a root user connection to the
`information_schema` MariaDB database to try and find table columns from
the Boulder schemas that are both `auto_increment` and not `int64`.

* SA: rename _db-next RemoveOCSPResponses.sql migration.

Based on the order that we apply migrations the
`RemoveOCSPResponses.sql` migration with its old prefix
(`20181101105733`) was never being applied. That in turn caused the new
`TestAutoIncrementSchema` unit test to fail because the old
`ocspResponses` table has an `id` field that is `auto_increment` but
`sized `int(11)`.

Renaming the migration with a newer prefix solves the problem. The
`ocspResponses` table ends up dropped when `config-next` is used.
Afterwards the `TestAutoIncrementSchema` unit test passes again.
2019-12-02 11:33:36 -05:00
Daniel McCarney 47b875f01f
SA: migrate `fqdnSets.id`, `issuedNames.id` to BIGINT. (#4557)
Based on the volume of data Boulder supports we use `BIGINT(20)` for
database ID fields throughout all of our tables except for two that were
missed: `fqdnSets` and `issuedNames`. Prior to this migration both were
using `INT(11)`, allowing only values up to 2,147,483,647. After the
migration is applied the `BIGINT(20)` type allows values up to 2^63-1.
2019-11-18 13:35:20 -05:00
Roland Bracewell Shoemaker b557d870c7 CA/SA: Store issuer info in certificateStatus, use for OCSP generation (#4546)
This avoids needing to send the entire certificate in OCSP generation
RPCs.

Ended up including a few cleanups that made the implementation easier.

Initially I was struggling with how to derive the issuer identification info.
We could just stick the full SPKI hash in certificateStatus, but that takes a
significant amount of space, we could configure unique issuer IDs in the CA
config, but that would require being very careful about keeping the IDs
constant, and never reusing an ID, or we could store issuers in a table in the
database and use that as a lookup table, but that requires figuring out how to
get that info into the table etc. Instead I've just gone with what I found to
be the easiest solution, deriving a stable ID from the cert hash. This means we
don't need to remember to configure anything special and the CA config stays
the same as it is now.

Fixes #4469.
2019-11-18 09:15:29 -05:00
Roland Bracewell Shoemaker a44f346f88 SA: remove old authorization tables from the schema (#4538) 2019-11-11 16:17:16 -05:00
Jacob Hoffman-Andrews fead807c7c Make PrecertificateOCSP the default behavior. (#4465)
In the process, rename generateOCSPAndStoreCertificate to just
storeCertificate, because that function doesn't generate OCSP anymore;
instead the OCSP is generated (and stored) at precertificate issuance
time.
2019-10-09 17:11:58 -07:00
Jacob Hoffman-Andrews 9906c93217
Generate and store OCSP at precertificate signing time (#4420)
This change adds two tables and two methods in the SA, to store precertificates
and serial numbers.

In the CA, when the feature flag is turned on, we generate a serial number, store it,
sign a precertificate and OCSP, store them, and then return the precertificate. Storing
the serial as an additional step before signing the certificate adds an extra layer of
insurance against duplicate serials, and also serves as a check on database availability.
Since an error storing the serial prevents going on to sign the precertificate, this decreases
the chance of signing something while the database is down.

Right now, neither table has read operations available in the SA.

To make this work, I needed to remove the check for duplicate certificateStatus entry
when inserting a final certificate and its OCSP response. I also needed to remove
an error that can occur when expiration-mailer processes a precertificate that lacks
a final certificate. That error would otherwise have prevented further processing of
expiration warnings.

Fixes #4412

This change builds on #4417, please review that first for ease of review.
2019-09-09 12:21:20 -07:00
Jacob Hoffman-Andrews b7250c1d43
integration: test for DisableAuthz2Orders. (#4390)
To make this work, I changed the twenty_days_ago setup to use
`config-next` when the main test phase is running `config`. That, in
turn, made the recheck_caa test fail, so I added a tweak to that.

I also moved the authzv2 migrations into `db`. Without that change,
the integration test would fail during the twenty_days_ago setup because
Boulder would attempt to create authzv2 objects but the table wouldn't
exist yet.
2019-08-08 17:07:29 -07:00
Daniel McCarney 028822d435 sa: drop SCTReceipts table and assoc. code. (#4344)
The `SCTReceipts` database table and associated model linkages are
legacy cruft from before Boulder implemented SCT embedding. We can
safely remove all of this stuff.
2019-07-17 11:12:42 -07:00
Roland Bracewell Shoemaker 11d16df3a6
Add authz2 expired-authz-purger tool (#4226)
Fixes #4188.
2019-05-30 14:01:01 -07:00
Jacob Hoffman-Andrews 09ba859366 SA: Deprecate FasterRateLimit feature flag (#4210)
This makes the behavior behind that flag the default.
2019-05-09 15:06:21 -04:00
Jacob Hoffman-Andrews e49ffaf94c sa: use a faster query for certificates per name rate limit (#4179)
Right now we run a `SELECT COUNT` query on issuedNames to calculate this rate limit.
Unfortunately, counting large numbers of rows is very slow. This change introduces a
dedicated table for keeping track of that rate limit.

Instead of being keyed by FQDN, this new `certificatesPerName` table is keyed by
the same field as rate limits are calculated on: the base domain. Each row has a base
domain, a time (chunked by hour), and a count. This means calculating the rate limit
status for each domain reads at most 7 * 24 rows.

This should particularly speed up cases when a single domain has lots of subdomains.

Fixes #4152
2019-04-26 10:53:47 -07:00
Roland Bracewell Shoemaker d06c6a5285
New style authorizations: All SA methods (#4134)
This PR implements new SA methods for handling authz2 style authorizations and updates existing SA methods to count and retrieve them where applicable when the `NewAuthorizationSchema` feature is enabled.

Fixes #4093
Fixes #4082
Updates #4078 
Updates #4077
2019-04-24 09:40:38 -07:00
Daniel McCarney 5be559debb
sa: remove CertStatus.LockCol and SubscriberApproved. (#4175)
Both of these database fields are not being used.
2019-04-23 15:14:48 -04:00
Roland Bracewell Shoemaker 6f44b8bde7 Add schema for authz2 table (#4081)
Adds the schema described by the model added in #3967.

Fixes #4051.
2019-02-22 11:05:15 -08:00
Roland Bracewell Shoemaker 4bd1623c55 Remove ocspResponses table (#3920)
Fixes #3906.
2018-11-02 11:35:49 -07:00
Jacob Hoffman-Andrews 4a961c3bc8 Ungate config-next for wfe2 and Wildcards. 2018-03-14 13:18:37 -07:00
Daniel McCarney f2d3ad6d52 Enforce new orders per acct per window rate limit. (#3501)
Previously we introduced the concept of a "pending orders per account
ID" rate limit. After struggling with making an implementation of this
rate limit perform well we reevaluated the problem and decided a "new
orders per account per time window" rate limit would be a better fit for
ACMEv2 overall.

This commit introduces the new newOrdersPerAccount rate limit. The RA
now checks this before creating new pending orders in ra.NewOrder. It
does so after order reuse takes place ensuring the rate limit is only
applied in cases when a distinct new pending order row would be created.
To accomplish this a migration for a new orders field (created) and an
index over created and registrationID is added. It would be possible to
use the existing expires field for this like we've done in the past, but that
was primarily to avoid running a migration on a large table in prod. Since
we don't have that problem yet for V2 tables we can Do The Right Thing
and add a column.

For deployability the deprecated pendingOrdersPerAccount code & SA
gRPC bits are left around. A follow-up PR will be needed to remove
those (#3502).

Resolves #3410
2018-03-02 10:47:39 -08:00
Daniel McCarney eea049da40
Fix order reuse, calc order status by authz status (#3402)
This PR is a rework of what was originally https://github.com/letsencrypt/boulder/pull/3382, integrating the design feedback proposed by @jsha: https://github.com/letsencrypt/boulder/pull/3382#issuecomment-359912549 

This PR removes the stored Order status field and replaces it with a value that is calculated on-the-fly by the SA when fetching an order, based on the order's associated authorizations. 

In summary (and order of precedence):
* If any of the order's authorizations are invalid, the order is invalid.
* If any of the order's authorizations are deactivated, the order is deactivated.
* If any of the order's authorizations are pending, the order is pending.
* If all of the order's authorizations are valid, and there is a certificate serial, the order is valid.
* If all of the order's authorizations are valid, and we have began processing, but there is no certificate serial, the order is processing.
* If all of the order's authorizations are valid, and we haven't processing, then the order is pending waiting a finalization request.

This avoids having to explicitly update the order status when an associated authorization changes status.

The RA's implementation of new-order is updated to only reuse an existing order if the calculated status is pending. This avoids giving back invalid or deactivated orders to clients.

Resolves #3333
2018-02-01 16:33:42 -05:00
Jacob Hoffman-Andrews f6ff59c9ab Move db-next migrations into db. (#3379)
These have now all been applied in production.
2018-01-18 15:13:21 -05:00
Andrew Gabbitas 50596ef386 Remove redundant semicolon. (#3355)
The redundant semicolon breaks the goose down
function for this migration
2018-01-10 16:26:53 -08:00
Daniel McCarney 7bb16ff21e ACMEv2: Add pending order reuse (#3290)
This commit adds pending order reuse. Subsequent to this commit multiple
add-order requests from the same account ID for the same set of order
names will result in only one order being created. Orders are only
reused while they are not expired. Finalized orders will not be reused
for subsequent new-order requests allowing for duplicate order issuance.

Note that this is a second level of reuse, building on the pending
authorization reuse that's done between separate orders already.

To efficiently find an appropriate order ID given a set of names,
a registration ID, and the current time a new orderFqdnSets table is
added with appropriate indexes and foreign keys.

Resolves #3258
2018-01-02 13:27:16 -08:00
Daniel McCarney 0684d5fc73
Add pending orders rate limit to new-order. (#3257)
This commit adds a new rate limit to restrict the number of outstanding
pending orders per account. If the threshold for this rate limit is
crossed subsequent new-order requests will return a 429 response.

Note: Since this the rate limit object itself defines an `Enabled()`
test based on whether or not it has been configured there is **not**
a feature flag for this change.

Resolves https://github.com/letsencrypt/boulder/issues/3246
2017-12-04 16:36:48 -05:00
Jacob Hoffman-Andrews 9dc32b010f Add indexes on certificateStatus. (#3225)
In #1864 we discussed possible
optimizations to how expiration-mailer and ocsp-updater query the
certificateStatus table. In #2177 we
added the notAfter and isExpired fields for more efficient querying.
However, we forgot to add indexes on these fields. This change adds new indexes
and drops the old indexes, and should result in much more efficient querying in
those two components.

Also, remove a comment that goose couldn't understand.

Running EXPLAINs to show the difference:

For expiration-mailer, before:

MariaDB [boulder_sa_integration]> EXPLAIN SELECT  cs.serial  FROM certificateStatus AS cs  WHERE cs.notAfter > DATE_ADD(NOW(), INTERVAL 21 DAY)  AND cs.notAfter < DATE_ADD(NOW(), INTERVAL 10 DAY)  AND cs.status != "revoked"  AND COALESCE(TIMESTAMPDIFF(SECOND, cs.lastExpirationNagSent, cs.notAfter) > 10 * 86400, 1)  ORDER BY cs.notAfter ASC  LIMIT 100000;
+------+-------------+-------+------+------------------------------+------+---------+------+------+-----------------------------+
| id   | select_type | table | type | possible_keys                | key  | key_len | ref  | rows | Extra                       |
+------+-------------+-------+------+------------------------------+------+---------+------+------+-----------------------------+
|    1 | SIMPLE      | cs    | ALL  | status_certificateStatus_idx | NULL | NULL    | NULL |  486 | Using where; Using filesort |
+------+-------------+-------+------+------------------------------+------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)

For expiration-mailer, after:

MariaDB [boulder_sa_integration]> EXPLAIN SELECT  cs.serial  FROM certificateStatus AS cs  WHERE cs.notAfter < DATE_ADD(NOW(), INTERVAL 21 DAY)  AND cs.notAfter < DATE_ADD(NOW(), INTERVAL 10 DAY)  AND cs.status != "revoked"  AND COALESCE(TIMESTAMPDIFF(SECOND, cs.lastExpirationNagSent, cs.notAfter) > 10 * 86400, 1)  ORDER BY cs.notAfter ASC  LIMIT 100000;
+------+-------------+-------+-------+---------------+--------------+---------+------+------+------------------------------------+
| id   | select_type | table | type  | possible_keys | key          | key_len | ref  | rows | Extra                              |
+------+-------------+-------+-------+---------------+--------------+---------+------+------+------------------------------------+
|    1 | SIMPLE      | cs    | range | notAfter_idx  | notAfter_idx | 6       | NULL |    1 | Using index condition; Using where |
+------+-------------+-------+-------+---------------+--------------+---------+------+------+------------------------------------+

For ocsp-updater, before:

MariaDB [boulder_sa_integration]> EXPLAIN SELECT    cs.serial,    cs.status,    cs.revokedDate,    cs.notAfter    FROM certificateStatus AS cs    WHERE cs.ocspLastUpdated > DATE_SUB(NOW(), INTERVAL 10 DAY)    AND cs.ocspLastUpdated < DATE_SUB(NOW(), INTERVAL 3 DAY)    AND NOT cs.isExpired    ORDER BY cs.ocspLastUpdated ASC    LIMIT 100000;
+------+-------------+-------+-------+---------------------------------------+---------------------------------------+---------+------+------+------------------------------------+
| id   | select_type | table | type  | possible_keys                         | key                                   | key_len | ref  | rows | Extra                              |
+------+-------------+-------+-------+---------------------------------------+---------------------------------------+---------+------+------+------------------------------------+
|    1 | SIMPLE      | cs    | range | ocspLastUpdated_certificateStatus_idx | ocspLastUpdated_certificateStatus_idx | 5       | NULL |    1 | Using index condition; Using where |
+------+-------------+-------+-------+---------------------------------------+---------------------------------------+---------+------+------+------------------------------------+
1 row in set (0.00 sec)

For ocsp-updater, after:

MariaDB [boulder_sa_integration]> EXPLAIN SELECT    cs.serial,    cs.status,    cs.revokedDate,    cs.notAfter    FROM certificateStatus AS cs    WHERE cs.ocspLastUpdated > DATE_SUB(NOW(), INTERVAL 10 DAY)    AND cs.ocspLastUpdated < DATE_SUB(NOW(), INTERVAL 3 DAY)    AND NOT cs.isExpired    ORDER BY cs.ocspLastUpdated ASC    LIMIT 100000;
+------+-------------+-------+-------+-------------------------------+-------------------------------+---------+------+------+-----------------------+
| id   | select_type | table | type  | possible_keys                 | key                           | key_len | ref  | rows | Extra                 |
+------+-------------+-------+-------+-------------------------------+-------------------------------+---------+------+------+-----------------------+
|    1 | SIMPLE      | cs    | range | isExpired_ocspLastUpdated_idx | isExpired_ocspLastUpdated_idx | 7       | NULL |    1 | Using index condition |
+------+-------------+-------+-------+-------------------------------+-------------------------------+---------+------+------+-----------------------+
1 row in set (0.00 sec)
2017-11-08 13:25:30 -08:00
Daniel McCarney 2f263f8ed5 ACME v2 Finalize order support (#3169)
This PR implements order finalization for the ACME v2 API.

In broad strokes this means:

* Removing the CSR from order objects & the new-order flow
* Adding identifiers to the order object & new-order
* Providing a finalization URL as part of orders returned by new-order
* Adding support to the WFE's Order endpoint to receive finalization POST requests with a CSR
* Updating the RA to accept finalization requests and to ensure orders are fully validated before issuance can proceed
* Updating the SA to allow finding order authorizations & updating orders.
* Updating the CA to accept an Order ID to log when issuing a certificate corresponding to an order object

Resolves #3123
2017-11-01 12:39:44 -07:00
Jacob Hoffman-Andrews da31fc8b70 Add a renewal bit to issuedNames. (#3178)
This is only the migration, so far. Rather than doing the feature-switch dance,
we can wait for this migration to be applied, and then commit the code to start
setting it, with a feature switch to start checking it, which can be turned on
once we've been setting the bit in production for a week.

Having this as an indexed bit on issuedNames allows us to cheaply exclude
renewals from our rate limit queries, so we can avoid the ordering dependency
for renewals vs new issuances on the same domain.

Fixes #3161
2017-10-19 09:29:43 -04:00
Roland Bracewell Shoemaker 90ba766af9 Add NewOrder RPCs + methods to SA and RA (#2907)
Fixes #2875, #2900 and #2901.
2017-08-11 14:24:25 -04:00
Roland Bracewell Shoemaker fcef38f78c Performance and cleanup database migration (#2882)
Switch certificates and certificateStatus to use autoincrement primary keys to avoid performance problems with clustered indexes (fixes #2754).

Remove empty externalCerts and identifierData tables (fixes #2881).

Make progress towards deleting unnecessary LockCol and subscriberApproved fields (#856,  #873) by making them NULLable and not including them in INSERTs and UPDATEs.
2017-07-26 15:18:28 -07:00
Daniel McCarney 5430c51e20 Move two migrations from `sa/_db-next/ to `sa/_db/`. (#2588)
Both the `20160818140745_AddRegStatus.sql` and
`20160914105917_RemoveChallengesAcctKeyAndTLS.sql` migrations have been
applied in production and can be moved out of `sa/_db-next/` to reflect
this fact.
2017-02-27 10:41:50 -08:00
Jacob Hoffman-Andrews 8cce04b058 Use `DEFAULT "valid"` for new status column on reg. (#2380) 2016-12-01 13:14:50 -08:00
Daniel McCarney a37bb5638d Adds migration to drop `accountKey`, `tls` fields. (#2176)
This PR adds a migration that removes the accountKey and tls fields from the challenges table.

Both fields are no longer required and the accountKey field consumes a significant amount of space, contributing to the challenges table being the overall largest table in our DB. Removing this field will free up substantial disk space.
2016-11-30 12:27:38 -08:00
Roland Bracewell Shoemaker c6e3ef660c Re-apply 2138 with proper gating (#2199)
Re-applies #2138 using the new style of feature-flag gated migrations. Account deactivation is gated behind `features.AllowAccountDeactivation`.
2016-09-29 17:16:03 -04:00
Daniel McCarney 8c2823ff83 Local DB migration improvements (`-next` directory, auto-migrate) (#2206)
This PR makes two improvements to how we handle migrations locally:

1)  Prior to this PR an optimization was present in `test/create_db.sh` that would `exit 0` if the `boulder_sa_integration` database existed. This early exit meant that after the first invocation of `create_db.sh` no further `goose` migrations would be applied unless the operator dropped their databases or edited the script.

This PR reworks the existing DB optimization so that it only skips the `CREATE DATABASE` statements and allows `goose` to try and apply migrations. This doesn't result in significantly longer start up times because Goose is smart enough to know when no migrations are required and outputs something similar to:
  `goose: no migrations to run. current version: 20160602142227`

This should address #2174.

2) This PR also implements a separate `sa/_db-next/` directory for "pending" migrations. This is meant to follow the "test/config" vs "test/config-next" approach to managing changes that are developed but not yet activated in production.

Migrations that are to-be-performed by Ops should be created in the `sa/_db-next` directory first. Once they have been performed by ops in staging/prod and the config flag gate for the migration (see CONTRIBUTING.md) has been set to true, the migration can be moved from `_db-next` to `_db`.

By default all pending migrations from the `-next` directory are applied in the local dev env. If you **do not** wish these migrations to be applied then set the `APPLY_NEXT_MIGRATIONS` env var to false. E.g.:  
   `docker-compose run -eAPPLY_NEXT_MIGRATIONS=false boulder`

This should address #2195
2016-09-26 21:37:05 -07:00