Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Directory endpoint should be configurable #283

Closed
picnoir opened this issue Oct 21, 2019 · 4 comments
Closed

Directory endpoint should be configurable #283

picnoir opened this issue Oct 21, 2019 · 4 comments

Comments

@picnoir
Copy link

picnoir commented Oct 21, 2019

Currently, the directory endpoint is hardcoded to /dir, which differs from Boulder's /directory. This can be annoying if one want his integration tests to be as identical as possible to the production environment.

We might expose this endpoint either though pebble's configuration file, either through a flag, either through an env variable.

Context: we plan to use pebble in nixos's let's encrypt integration tests. We currently have to patch the source to match Boulder's endpoint name.

https://github.com/NixOS/nixpkgs/pull/71291/files#diff-8a1cb870381d92cc3e3a452adbf2545dR1
https://github.com/NixOS/nixpkgs/pull/71291/files#diff-65131a3d361d86f9ef3d48516efe904aR71

@cpu
Copy link
Contributor

cpu commented Oct 21, 2019

👋 Hi @NinjaTrappeur

Currently, the directory endpoint is hardcoded to /dir, which differs from Boulder's /directory. This can be annoying if one want his integration tests to be as identical as possible to the production environment.

Can you help me understand this part better? Pebble isn't run in a production setting anywhere (I hope!) so I'm not sure I understand the framing. RFC 8555 servers are primarily identified by their directory URL so I'd expect clients/integration tests to be able to accept the directory URL to run against as a parameter.

@picnoir
Copy link
Author

picnoir commented Oct 22, 2019

Hi @cpu,

Pebble isn't run in a production setting anywhere (I hope!) so I'm not sure I understand the framing

It looks like I've been rushing the use case description here :)

Nixos is a Linux distribution built around the Nix package manager.

On a very high level, the distribution consists in the combination of both a set of packages and a set of service descriptions (modules in Nix's terminology) which allows you to declaratively describe your system.

The Nixos project is providing a module in charge of generating LE certificates [1].

Under the hood, the module is using certbot and hits the official let's encrypt infrastructure to request certificates.

Now, the NixOS project want to run some tests on our CI to:

  • Ensure we don't break the acme nixos module after a certbot version bump.
  • Make sure the certificates issued with this module are usable on a nginx server.

This test currently lives here: [2].

We do not want the test to rely on an external service, hence, for the tests, we are mocking the let's encrypt end with a local Boulder instance + some hosts file + a custom CA trickery.

As you can see here (warning: it's pretty long), setting up boulder for a test is pretty heavy. That's precisely why we were thinking about replacing this heavy boulder setup with a simpler pebble one.

I wrote this refactoring here, and as you can see, it kills quite some complexity. Yay to that.

That said, on this test, the client is behaving exactly the same way it would on production (modulo the fact it will use a custom CA to verify the identity of the mocked letsencrypt endpoint). The problem I had was that instead of exposing the directory on /directory, Pebble exposes it on /dir, making effectively fail my test.

Since the goal here is to test the nixos module (not certbot), I don't really want to change this endpoint and keep the nixos module as close as possible as it would be in the real world; hence my need to make Pebble exposes the directory endpoint on /directory, exactly as the let's encrypt real endpoint would do.

Now comes this issue request :) Would you accept exposing this endpoint through some kind of configuration?

I'd be up to write this PR if necessary.

@jsha
Copy link
Contributor

jsha commented Oct 22, 2019

That's an interesting approach! It sounds like you are jumping through a lot of hoops to get Certbot in your test environment to think it's talking to the real https://acme-v02.api.letsencrypt.org/directory. However, Certbot supports configuring the ACME server with --server https://example.com/foo.

From your comment it sounds like you prefer the approach of mocking out Let's Encrypt at the URL layer, and I can see why that's appealing. However, I think it's probably more straightforward and easier to make the ACME server URL a configuration parameter in your Nix modules, and assign a specific URL for ACME testing servers in your test environment. This also helps to ensure that if your mock DNS setup fails in some way, you are not sending test traffic to the live Let's Encrypt servers. This has the added benefit that it allows your users to easily select an ACME server of their choosing - more and more ACME servers are coming online these days.

For the Pebble side of things, we specifically chose a different path for the directory because we want to ensure that the ACME ecosystem doesn't bake in the idea that directories are under /directory. I can see that that's not what you're doing here, but I am concerned that if we made this configurable, other people might write ACME clients that have that assumption baked in, and use the configuration parameter to change it.

@picnoir
Copy link
Author

picnoir commented Oct 22, 2019

This also helps to ensure that if your mock DNS setup fails in some way, you are not sending test traffic to the live Let's Encrypt servers.

Those tests don't have any kind of external network access, this shouldn't happen.

For the Pebble side of things, we specifically chose a different path for the directory because we want to ensure that the ACME ecosystem doesn't bake in the idea that directories are under /directory. I can see that that's not what you're doing here, but I am concerned that if we made this configurable, other people might write ACME clients that have that assumption baked in, and use the configuration parameter to change it.

👍 Sounds like a sensible position.

This has the added benefit that it allows your users to easily select an ACME server of their choosing - more and more ACME servers are coming online these days.

That's a good point, you're right, that's definitely something we should do.

@picnoir picnoir closed this as completed Oct 22, 2019
emilazy added a commit to emilazy/nixpkgs that referenced this issue Mar 24, 2020
Shimming out the Let's Encrypt domain name to reuse client configuration
doesn't work properly (Pebble uses different endpoint URL formats), is
recommended against by upstream,[1] and is unnecessary now that the ACME
module supports specifying an ACME server. This commit changes the tests
to use the domain name acme.test instead, and renames the letsencrypt
node to acme to reflect that it has nothing to do with the ACME server
that Let's Encrypt runs. The imports are renamed for clarity:

* nixos/tests/common/{letsencrypt => acme}/{common.nix => client}
* nixos/tests/common/{letsencrypt => acme}/{default.nix => server}

The test's other domain names are also adjusted to use *.test for
consistency (and to avoid misuse of non-reserved domain names such
as standalone.com).

[1] letsencrypt/pebble#283 (comment)

Co-authored-by: Yegor Timoshenko <yegortimoshenko@riseup.net>
emilazy added a commit to emilazy/nixpkgs that referenced this issue Apr 18, 2020
Shimming out the Let's Encrypt domain name to reuse client configuration
doesn't work properly (Pebble uses different endpoint URL formats), is
recommended against by upstream,[1] and is unnecessary now that the ACME
module supports specifying an ACME server. This commit changes the tests
to use the domain name acme.test instead, and renames the letsencrypt
node to acme to reflect that it has nothing to do with the ACME server
that Let's Encrypt runs. The imports are renamed for clarity:

* nixos/tests/common/{letsencrypt => acme}/{common.nix => client}
* nixos/tests/common/{letsencrypt => acme}/{default.nix => server}

The test's other domain names are also adjusted to use *.test for
consistency (and to avoid misuse of non-reserved domain names such
as standalone.com).

[1] letsencrypt/pebble#283 (comment)

Co-authored-by: Yegor Timoshenko <yegortimoshenko@riseup.net>
emilazy added a commit to emilazy/nixpkgs that referenced this issue Apr 19, 2020
Shimming out the Let's Encrypt domain name to reuse client configuration
doesn't work properly (Pebble uses different endpoint URL formats), is
recommended against by upstream,[1] and is unnecessary now that the ACME
module supports specifying an ACME server. This commit changes the tests
to use the domain name acme.test instead, and renames the letsencrypt
node to acme to reflect that it has nothing to do with the ACME server
that Let's Encrypt runs. The imports are renamed for clarity:

* nixos/tests/common/{letsencrypt => acme}/{common.nix => client}
* nixos/tests/common/{letsencrypt => acme}/{default.nix => server}

The test's other domain names are also adjusted to use *.test for
consistency (and to avoid misuse of non-reserved domain names such
as standalone.com).

[1] letsencrypt/pebble#283 (comment)

Co-authored-by: Yegor Timoshenko <yegortimoshenko@riseup.net>
(cherry picked from commit d0f04c1)
stigok pushed a commit to stigok/nixpkgs that referenced this issue Jun 12, 2020
Shimming out the Let's Encrypt domain name to reuse client configuration
doesn't work properly (Pebble uses different endpoint URL formats), is
recommended against by upstream,[1] and is unnecessary now that the ACME
module supports specifying an ACME server. This commit changes the tests
to use the domain name acme.test instead, and renames the letsencrypt
node to acme to reflect that it has nothing to do with the ACME server
that Let's Encrypt runs. The imports are renamed for clarity:

* nixos/tests/common/{letsencrypt => acme}/{common.nix => client}
* nixos/tests/common/{letsencrypt => acme}/{default.nix => server}

The test's other domain names are also adjusted to use *.test for
consistency (and to avoid misuse of non-reserved domain names such
as standalone.com).

[1] letsencrypt/pebble#283 (comment)

Co-authored-by: Yegor Timoshenko <yegortimoshenko@riseup.net>
(cherry picked from commit d0f04c1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants