|
274 | 274 | "--http.port" |
275 | 275 | data.listenHTTP |
276 | 276 | ] |
| 277 | + else if data.tlsMode then |
| 278 | + [ |
| 279 | + "--tls" |
| 280 | + "--tls.port" |
| 281 | + ":${toString data.tlsPort}" |
| 282 | + ] |
277 | 283 | else |
278 | 284 | [ |
279 | 285 | "--http" |
|
404 | 410 |
|
405 | 411 | renewService = lockfileName: { |
406 | 412 | description = "Renew ACME certificate for ${cert}"; |
| 413 | + # stop conflicting services while certs are renewed |
| 414 | + conflicts = data.conflictingServices; |
| 415 | + # start conflicting services again after cert renewal |
| 416 | + # This causes systemd to issue a warning 'multiple trigger source candidates for exit status propagation', |
| 417 | + # but this is more robust and not prone to race conditions as invoking systemctl in ExecStartPost/ExecStopPost |
| 418 | + onSuccess = data.conflictingServices; |
| 419 | + onFailure = data.conflictingServices; |
407 | 420 | after = [ |
408 | 421 | "network.target" |
409 | 422 | "network-online.target" |
@@ -471,13 +484,17 @@ let |
471 | 484 | fi |
472 | 485 | ''); |
473 | 486 | } |
474 | | - // |
475 | | - lib.optionalAttrs |
476 | | - (data.listenHTTP != null && lib.toInt (lib.last (lib.splitString ":" data.listenHTTP)) < 1024) |
477 | | - { |
478 | | - CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; |
479 | | - AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; |
480 | | - }; |
| 487 | + // ( |
| 488 | + let |
| 489 | + needsToOpenPrivilegedPort = |
| 490 | + (data.listenHTTP != null && lib.toInt (lib.last (lib.splitString ":" data.listenHTTP)) < 1024) |
| 491 | + || (data.tlsMode && data.tlsPort < 1024); |
| 492 | + in |
| 493 | + lib.optionalAttrs needsToOpenPrivilegedPort { |
| 494 | + CapabilityBoundingSet = [ "CAP_NET_BIND_SERVICE" ]; |
| 495 | + AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ]; |
| 496 | + } |
| 497 | + ); |
481 | 498 |
|
482 | 499 | # Working directory will be /tmp |
483 | 500 | script = (if (lockfileName == null) then lib.id else wrapInFlock "${lockdir}${lockfileName}") '' |
|
670 | 687 | description = "Group running the ACME client."; |
671 | 688 | }; |
672 | 689 |
|
| 690 | + conflictingServices = lib.mkOption { |
| 691 | + type = lib.types.listOf lib.types.str; |
| 692 | + inherit (defaultAndText "conflictingServices" [ ]) default defaultText; |
| 693 | + description = '' |
| 694 | + List of conflicting systemd services that should be temporarily stopped |
| 695 | + while renewing/checking certificates. This might be necessary with `tlsMode=true` |
| 696 | + when a webserver occupies the `tlsPort`. |
| 697 | + ''; |
| 698 | + example = '' |
| 699 | + [ "nginx.service" ] # stops nginx temporarily while renewing/checking certificates |
| 700 | + ''; |
| 701 | + }; |
| 702 | + |
673 | 703 | reloadServices = lib.mkOption { |
674 | 704 | type = lib.types.listOf lib.types.str; |
675 | 705 | inherit (defaultAndText "reloadServices" [ ]) default defaultText; |
|
733 | 763 | ''; |
734 | 764 | }; |
735 | 765 |
|
| 766 | + tlsMode = lib.mkOption { |
| 767 | + type = lib.types.bool; |
| 768 | + inherit (defaultAndText "tlsMode" false) default defaultText; |
| 769 | + description = "Use TLS challenge instead of HTTP."; |
| 770 | + }; |
| 771 | + |
| 772 | + tlsPort = lib.mkOption { |
| 773 | + type = lib.types.port; |
| 774 | + inherit (defaultAndText "tlsPort" 443) default defaultText; |
| 775 | + description = "Port to use for TLS challenge."; |
| 776 | + }; |
| 777 | + |
736 | 778 | environmentFile = lib.mkOption { |
737 | 779 | type = lib.types.nullOr lib.types.path; |
738 | 780 | inherit (defaultAndText "environmentFile" null) default defaultText; |
|
1090 | 1132 | webroot |
1091 | 1133 | listenHTTP |
1092 | 1134 | s3Bucket |
| 1135 | + tlsMode |
1093 | 1136 | ; |
1094 | 1137 | }; |
1095 | 1138 | in |
|
1101 | 1144 | `security.acme.certs.${cert}.webroot`, |
1102 | 1145 | `security.acme.certs.${cert}.listenHTTP` and |
1103 | 1146 | `security.acme.certs.${cert}.s3Bucket` |
| 1147 | + `security.acme.certs.${cert}.tlsMode` |
1104 | 1148 | is required. |
1105 | 1149 | Current values: ${(lib.generators.toPretty { } exclusiveAttrs)}. |
1106 | 1150 | ''; |
|
0 commit comments