Skip to content
This repository was archived by the owner on Apr 12, 2021. It is now read-only.
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: NixOS/nixpkgs-channels
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: a17e021b9486
Choose a base ref
...
head repository: NixOS/nixpkgs-channels
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e03eeffd6166
Choose a head ref
  • 9 commits
  • 12 files changed
  • 4 contributors

Commits on Apr 19, 2020

  1. openvswitch: 2.12.0 -> 2.13.0

    (cherry picked from commit c8523fe)
    r-ryantm authored and Kyle Copperfield committed Apr 19, 2020
    Copy the full SHA
    60ce810 View commit details
  2. pebble: v2.2.2 -> v2.3.0

    Also add myself to maintainers and correct meta.homepage.
    
    (cherry picked from commit 6285d5e)
    emilazy committed Apr 19, 2020
    Copy the full SHA
    e1c41b8 View commit details
  3. nixos/tests/common/acme: enable Pebble strict mode

    This lets us get early warning about any bugs or backwards-compatibility
    hazards in lego.
    
    Pebble will default to this in the future, but doesn't currently;
    see https://github.com/letsencrypt/pebble/blob/v2.3.0/README.md#strict-mode.
    
    (cherry picked from commit e6d5e83)
    emilazy committed Apr 19, 2020
    Copy the full SHA
    b0d26e9 View commit details
  4. nixos/tests/acme: don't restrict to x86_64

    This was added in aade4e5, but the
    implementation of the ACME module has been entirely rewritten since
    then, and the test seems to run fine on AArch64.
    
    (cherry picked from commit 352e30d)
    emilazy committed Apr 19, 2020
    Copy the full SHA
    8283094 View commit details
  5. nixos/tests/acme: use *.test domains

    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)
    emilazy committed Apr 19, 2020
    Copy the full SHA
    2b8100d View commit details
  6. nixos/tests/acme: use CAP_NET_BIND_SERVICE

    (cherry picked from commit 695fd78)
    emilazy committed Apr 19, 2020
    Copy the full SHA
    60e6ba6 View commit details
  7. nixos/tests/common/acme: don't set nameservers for client

    The resolver is mainly useful for the ACME server, and acme.nix uses its
    own DNS server to test DNS-01 challenges.
    
    (cherry picked from commit 21f183a)
    emilazy committed Apr 19, 2020
    Copy the full SHA
    f035e26 View commit details
  8. Merge pull request #85584 from emilazy/acme-test-cleanups-20.03

    [20.03] ACME test cleanups
    flokli authored Apr 19, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    426646c View commit details
  9. Merge pull request #85557 from kmcopper/r20.03/vswitch-2.13

    [20.03] openvswitch 2.12.0 -> 2.13.0
    Ma27 authored Apr 19, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e03eeff View commit details
102 changes: 48 additions & 54 deletions nixos/tests/acme.nix
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
let
commonConfig = ./common/letsencrypt/common.nix;
commonConfig = ./common/acme/client;

dnsScript = {writeScript, dnsAddress, bash, curl}: writeScript "dns-hook.sh" ''
#!${bash}/bin/bash
@@ -16,8 +16,8 @@ in import ./make-test-python.nix {
name = "acme";

nodes = rec {
letsencrypt = { nodes, lib, ... }: {
imports = [ ./common/letsencrypt ];
acme = { nodes, lib, ... }: {
imports = [ ./common/acme/server ];
networking.nameservers = lib.mkForce [
nodes.dnsserver.config.networking.primaryIPAddress
];
@@ -33,8 +33,7 @@ in import ./make-test-python.nix {
serviceConfig = {
ExecStart = "${pkgs.pebble}/bin/pebble-challtestsrv -dns01 ':53' -defaultIPv6 '' -defaultIPv4 '${nodes.webserver.config.networking.primaryIPAddress}'";
# Required to bind on privileged ports.
User = "root";
Group = "root";
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
};
};
};
@@ -45,19 +44,16 @@ in import ./make-test-python.nix {
nodes.dnsserver.config.networking.primaryIPAddress
];
networking.firewall.allowedTCPPorts = [ 80 ];
security.acme = {
server = "https://acme-v02.api.letsencrypt.org/dir";
certs."standalone.com" = {
webroot = "/var/lib/acme/acme-challenges";
};
security.acme.certs."standalone.test" = {
webroot = "/var/lib/acme/acme-challenges";
};
systemd.targets."acme-finished-standalone.com" = {};
systemd.services."acme-standalone.com" = {
wants = [ "acme-finished-standalone.com.target" ];
before = [ "acme-finished-standalone.com.target" ];
systemd.targets."acme-finished-standalone.test" = {};
systemd.services."acme-standalone.test" = {
wants = [ "acme-finished-standalone.test.target" ];
before = [ "acme-finished-standalone.test.target" ];
};
services.nginx.enable = true;
services.nginx.virtualHosts."standalone.com" = {
services.nginx.virtualHosts."standalone.test" = {
locations."/.well-known/acme-challenge".root = "/var/lib/acme/acme-challenges";
};
};
@@ -71,16 +67,16 @@ in import ./make-test-python.nix {

# A target remains active. Use this to probe the fact that
# a service fired eventhough it is not RemainAfterExit
systemd.targets."acme-finished-a.example.com" = {};
systemd.services."acme-a.example.com" = {
wants = [ "acme-finished-a.example.com.target" ];
before = [ "acme-finished-a.example.com.target" ];
systemd.targets."acme-finished-a.example.test" = {};
systemd.services."acme-a.example.test" = {
wants = [ "acme-finished-a.example.test.target" ];
before = [ "acme-finished-a.example.test.target" ];
after = [ "nginx.service" ];
};

services.nginx.enable = true;

services.nginx.virtualHosts."a.example.com" = {
services.nginx.virtualHosts."a.example.test" = {
enableACME = true;
forceSSL = true;
locations."/".root = pkgs.runCommand "docroot" {} ''
@@ -89,17 +85,17 @@ in import ./make-test-python.nix {
'';
};

security.acme.server = "https://acme-v02.api.letsencrypt.org/dir";
security.acme.server = "https://acme.test/dir";

nesting.clone = [
({pkgs, ...}: {
systemd.targets."acme-finished-b.example.com" = {};
systemd.services."acme-b.example.com" = {
wants = [ "acme-finished-b.example.com.target" ];
before = [ "acme-finished-b.example.com.target" ];
systemd.targets."acme-finished-b.example.test" = {};
systemd.services."acme-b.example.test" = {
wants = [ "acme-finished-b.example.test.target" ];
before = [ "acme-finished-b.example.test.target" ];
after = [ "nginx.service" ];
};
services.nginx.virtualHosts."b.example.com" = {
services.nginx.virtualHosts."b.example.test" = {
enableACME = true;
forceSSL = true;
locations."/".root = pkgs.runCommand "docroot" {} ''
@@ -109,8 +105,8 @@ in import ./make-test-python.nix {
};
})
({pkgs, config, nodes, lib, ...}: {
security.acme.certs."example.com" = {
domain = "*.example.com";
security.acme.certs."example.test" = {
domain = "*.example.test";
dnsProvider = "exec";
dnsPropagationCheck = false;
credentialsFile = with pkgs; writeText "wildcard.env" ''
@@ -119,17 +115,17 @@ in import ./make-test-python.nix {
user = config.services.nginx.user;
group = config.services.nginx.group;
};
systemd.targets."acme-finished-example.com" = {};
systemd.services."acme-example.com" = {
wants = [ "acme-finished-example.com.target" ];
before = [ "acme-finished-example.com.target" "nginx.service" ];
systemd.targets."acme-finished-example.test" = {};
systemd.services."acme-example.test" = {
wants = [ "acme-finished-example.test.target" ];
before = [ "acme-finished-example.test.target" "nginx.service" ];
wantedBy = [ "nginx.service" ];
};
services.nginx.virtualHosts."c.example.com" = {
services.nginx.virtualHosts."c.example.test" = {
forceSSL = true;
sslCertificate = config.security.acme.certs."example.com".directory + "/cert.pem";
sslTrustedCertificate = config.security.acme.certs."example.com".directory + "/full.pem";
sslCertificateKey = config.security.acme.certs."example.com".directory + "/key.pem";
sslCertificate = config.security.acme.certs."example.test".directory + "/cert.pem";
sslTrustedCertificate = config.security.acme.certs."example.test".directory + "/full.pem";
sslCertificateKey = config.security.acme.certs."example.test".directory + "/key.pem";
locations."/".root = pkgs.runCommand "docroot" {} ''
mkdir -p "$out"
echo hello world > "$out/index.html"
@@ -161,46 +157,44 @@ in import ./make-test-python.nix {
client.start()
dnsserver.start()
letsencrypt.wait_for_unit("default.target")
acme.wait_for_unit("default.target")
dnsserver.wait_for_unit("pebble-challtestsrv.service")
client.succeed(
'curl --data \'{"host": "acme-v02.api.letsencrypt.org", "addresses": ["${nodes.letsencrypt.config.networking.primaryIPAddress}"]}\' http://${nodes.dnsserver.config.networking.primaryIPAddress}:8055/add-a'
'curl --data \'{"host": "acme.test", "addresses": ["${nodes.acme.config.networking.primaryIPAddress}"]}\' http://${nodes.dnsserver.config.networking.primaryIPAddress}:8055/add-a'
)
client.succeed(
'curl --data \'{"host": "standalone.com", "addresses": ["${nodes.acmeStandalone.config.networking.primaryIPAddress}"]}\' http://${nodes.dnsserver.config.networking.primaryIPAddress}:8055/add-a'
'curl --data \'{"host": "standalone.test", "addresses": ["${nodes.acmeStandalone.config.networking.primaryIPAddress}"]}\' http://${nodes.dnsserver.config.networking.primaryIPAddress}:8055/add-a'
)
letsencrypt.start()
acme.start()
acmeStandalone.start()
letsencrypt.wait_for_unit("default.target")
letsencrypt.wait_for_unit("pebble.service")
acme.wait_for_unit("default.target")
acme.wait_for_unit("pebble.service")
with subtest("can request certificate with HTTPS-01 challenge"):
acmeStandalone.wait_for_unit("default.target")
acmeStandalone.succeed("systemctl start acme-standalone.com.service")
acmeStandalone.wait_for_unit("acme-finished-standalone.com.target")
acmeStandalone.succeed("systemctl start acme-standalone.test.service")
acmeStandalone.wait_for_unit("acme-finished-standalone.test.target")
client.wait_for_unit("default.target")
client.succeed("curl https://acme-v02.api.letsencrypt.org:15000/roots/0 > /tmp/ca.crt")
client.succeed(
"curl https://acme-v02.api.letsencrypt.org:15000/intermediate-keys/0 >> /tmp/ca.crt"
)
client.succeed("curl https://acme.test:15000/roots/0 > /tmp/ca.crt")
client.succeed("curl https://acme.test:15000/intermediate-keys/0 >> /tmp/ca.crt")
with subtest("Can request certificate for nginx service"):
webserver.wait_for_unit("acme-finished-a.example.com.target")
webserver.wait_for_unit("acme-finished-a.example.test.target")
client.succeed(
"curl --cacert /tmp/ca.crt https://a.example.com/ | grep -qF 'hello world'"
"curl --cacert /tmp/ca.crt https://a.example.test/ | grep -qF 'hello world'"
)
with subtest("Can add another certificate for nginx service"):
webserver.succeed(
"/run/current-system/fine-tune/child-1/bin/switch-to-configuration test"
)
webserver.wait_for_unit("acme-finished-b.example.com.target")
webserver.wait_for_unit("acme-finished-b.example.test.target")
client.succeed(
"curl --cacert /tmp/ca.crt https://b.example.com/ | grep -qF 'hello world'"
"curl --cacert /tmp/ca.crt https://b.example.test/ | grep -qF 'hello world'"
)
with subtest("Can request wildcard certificates using DNS-01 challenge"):
@@ -210,9 +204,9 @@ in import ./make-test-python.nix {
webserver.succeed(
"/run/current-system/fine-tune/child-2/bin/switch-to-configuration test"
)
webserver.wait_for_unit("acme-finished-example.com.target")
webserver.wait_for_unit("acme-finished-example.test.target")
client.succeed(
"curl --cacert /tmp/ca.crt https://c.example.com/ | grep -qF 'hello world'"
"curl --cacert /tmp/ca.crt https://c.example.test/ | grep -qF 'hello world'"
)
'';
}
2 changes: 1 addition & 1 deletion nixos/tests/all-tests.nix
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ let
in
{
_3proxy = handleTest ./3proxy.nix {};
acme = handleTestOn ["x86_64-linux"] ./acme.nix {};
acme = handleTest ./acme.nix {};
atd = handleTest ./atd.nix {};
automysqlbackup = handleTest ./automysqlbackup.nix {};
avahi = handleTest ./avahi.nix {};
15 changes: 15 additions & 0 deletions nixos/tests/common/acme/client/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{ lib, nodes, pkgs, ... }:

let
acme-ca = nodes.acme.config.test-support.acme.caCert;
in

{
security.acme = {
server = "https://acme.test/dir";
email = "hostmaster@example.test";
acceptTerms = true;
};

security.pki.certificateFiles = [ acme-ca ];
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
# The certificate for the ACME service is exported as:
#
# config.test-support.letsencrypt.caCert
# config.test-support.acme.caCert
#
# This value can be used inside the configuration of other test nodes to inject
# the snakeoil certificate into security.pki.certificateFiles or into package
# overlays.
#
# Another value that's needed if you don't use a custom resolver (see below for
# notes on that) is to add the letsencrypt node as a nameserver to every node
# notes on that) is to add the acme node as a nameserver to every node
# that needs to acquire certificates using ACME, because otherwise the API host
# for letsencrypt.org can't be resolved.
# for acme.test can't be resolved.
#
# A configuration example of a full node setup using this would be this:
#
# {
# letsencrypt = import ./common/letsencrypt;
# acme = import ./common/acme/server;
#
# example = { nodes, ... }: {
# networking.nameservers = [
# nodes.letsencrypt.config.networking.primaryIPAddress
# nodes.acme.config.networking.primaryIPAddress
# ];
# security.pki.certificateFiles = [
# nodes.letsencrypt.config.test-support.letsencrypt.caCert
# nodes.acme.config.test-support.acme.caCert
# ];
# };
# }
@@ -33,9 +33,9 @@
# override networking.nameservers like this:
#
# {
# letsencrypt = { nodes, ... }: {
# imports = [ ./common/letsencrypt ];
# networking.nameservers = [
# acme = { nodes, lib, ... }: {
# imports = [ ./common/acme/server ];
# networking.nameservers = lib.mkForce [
# nodes.myresolver.config.networking.primaryIPAddress
# ];
# };
@@ -55,16 +55,16 @@
let
snakeOilCerts = import ./snakeoil-certs.nix;

wfeDomain = "acme-v02.api.letsencrypt.org";
wfeDomain = "acme.test";
wfeCertFile = snakeOilCerts.${wfeDomain}.cert;
wfeKeyFile = snakeOilCerts.${wfeDomain}.key;

siteDomain = "letsencrypt.org";
siteDomain = "acme.test";
siteCertFile = snakeOilCerts.${siteDomain}.cert;
siteKeyFile = snakeOilCerts.${siteDomain}.key;
pebble = pkgs.pebble;
resolver = let
message = "You need to define a resolver for the letsencrypt test module.";
message = "You need to define a resolver for the acme test module.";
firstNS = lib.head config.networking.nameservers;
in if config.networking.nameservers == [] then throw message else firstNS;

@@ -76,15 +76,16 @@ let
httpPort = 80;
tlsPort = 443;
ocspResponderURL = "http://0.0.0.0:4002";
strict = true;
};

pebbleConfFile = pkgs.writeText "pebble.conf" (builtins.toJSON pebbleConf);
pebbleDataDir = "/root/pebble";

in {
imports = [ ../resolver.nix ];
imports = [ ../../resolver.nix ];

options.test-support.letsencrypt.caCert = lib.mkOption {
options.test-support.acme.caCert = lib.mkOption {
type = lib.types.path;
description = ''
A certificate file to use with the <literal>nodes</literal> attribute to
@@ -98,7 +99,7 @@ in {
resolver.enable = let
isLocalResolver = config.networking.nameservers == [ "127.0.0.1" ];
in lib.mkOverride 900 isLocalResolver;
letsencrypt.caCert = snakeOilCerts.ca.cert;
acme.caCert = snakeOilCerts.ca.cert;
};

# This has priority 140, because modules/testing/test-instrumentation.nix
@@ -126,8 +127,7 @@ in {
'';
serviceConfig = {
# Required to bind on privileged ports.
User = "root";
Group = "root";
AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
};
};
};
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
{ pkgs ? import <nixpkgs> {}
, lib ? pkgs.lib

, domains ? [ "acme-v02.api.letsencrypt.org" "letsencrypt.org" ]
, domains ? [ "acme.test" ]
}:

pkgs.runCommand "letsencrypt-snakeoil-ca" {
pkgs.runCommand "acme-snakeoil-ca" {
nativeBuildInputs = [ pkgs.openssl ];
} ''
addpem() {
Loading