Skip to content

Commit e947257

Browse files
committed
ACME: module configuration.
1 parent 6128488 commit e947257

File tree

14 files changed

+2138
-49
lines changed

14 files changed

+2138
-49
lines changed

Cargo.lock

Lines changed: 358 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ rust-version = "1.81.0"
1010
crate-type = ["cdylib"]
1111

1212
[dependencies]
13+
http = "1.3.1"
14+
openssl = { version = "0.10.73", features = ["bindgen"] }
15+
openssl-foreign-types = { package = "foreign-types", version = "0.3" }
16+
openssl-sys = { version = "0.9.109", features = ["bindgen"] }
17+
siphasher = { version = "1.0.1", default-features = false }
18+
thiserror = { version = "2.0.12", default-features = false }
1319

1420
[dependencies.nginx-sys]
1521
git = "https://github.com/nginx/ngx-rust"

README.md

Lines changed: 214 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ certificate management ([ACME]) protocol.
1010

1111
### Requirements
1212

13-
* Regular nginx build dependencies
14-
* System-wide installation of OpenSSL 1.1.1 or later
15-
* Rust toolchain (1.81.0 or later)
13+
- Regular nginx build dependencies
14+
- System-wide installation of OpenSSL 1.1.1 or later
15+
- Rust toolchain (1.81.0 or later)
1616

1717
### Commands
1818

@@ -25,24 +25,233 @@ cd nginx-acme
2525
export NGINX_BUILD_DIR=$(realpath ../nginx/objs)
2626
cargo build --release
2727
```
28+
2829
The result will be located at `target/release/libnginx_acme.so`.
2930

3031
Another way is to use the provided config script:
32+
3133
```sh
3234
# in the nginx source directory
3335
auto/configure \
3436
--with-compat \
3537
--with-http_ssl_module \
3638
--add-[dynamic-]module=/path/to/nginx-acme
3739
```
40+
3841
The result will be located at `$NGX_OBJS/ngx_http_acme_module.so`.
3942

4043
Currently this method produces a slightly larger library, as we don't instruct
41-
the linker to perform dead code elimination.
44+
the linker to perform LTO and dead code elimination.
4245

4346
## How to Use
4447

45-
To be added later.
48+
Add the module to the nginx configuration and configure as described below.
49+
50+
## Example Configuration
51+
52+
```nginx
53+
resolver 127.0.0.1:53;
54+
55+
acme_issuer example {
56+
uri https://acme.example.com/directory;
57+
contact mailto:[email protected];
58+
state_path /var/lib/nginx/acme-example;
59+
}
60+
61+
acme_shared_zone zone=acme_shared:1M;
62+
63+
server {
64+
listen 443 ssl;
65+
server_name .example.test;
66+
67+
acme_certificate example .example.test;
68+
69+
ssl_certificate $acme_certificate;
70+
ssl_certificate_key $acme_certificate_key;
71+
72+
ssl_certificate_cache max=2;
73+
}
74+
75+
server {
76+
# listener on port 80 is required to process ACME HTTP-01 challenges
77+
listen 80;
78+
79+
location / {
80+
return 404;
81+
}
82+
}
83+
```
84+
85+
## Directives
86+
87+
### acme_issuer
88+
89+
**Syntax:** acme_issuer `name` { ... }
90+
91+
**Default:** -
92+
93+
**Context:** http
94+
95+
Defines an ACME certificate issuer object.
96+
97+
### uri
98+
99+
**Syntax:** uri `uri`
100+
101+
**Default:** -
102+
103+
**Context:** acme_issuer
104+
105+
The [directory URL](https://www.rfc-editor.org/rfc/rfc8555#section-7.1.1)
106+
of the ACME server. This is the only mandatory parameter in the
107+
[](#acme_issuer) block.
108+
109+
### account_key
110+
111+
**Syntax:** account_key `alg[:size]` | `file`
112+
113+
**Default:** -
114+
115+
**Context:** acme_issuer
116+
117+
The account's private key used for request authentication.
118+
Accepted values:
119+
120+
- `ecdsa:256/384/521` for `ES256` / `ES384` / `ES512` JSON Web Signature algorithms
121+
- `rsa:2048..4096` for `RS256` .
122+
- File path for an existing key, using one of the algorithms above.
123+
124+
The generated account keys are preserved across reloads, but will be lost on
125+
restart unless [](#state_path) is configured.
126+
127+
### contact
128+
129+
**Syntax:** contact `url`
130+
131+
**Default:** -
132+
133+
**Context:** acme_issuer
134+
135+
An array of URLs that the ACME server can use to contact the client for issues
136+
related to this account.
137+
138+
Can be specified multiple times.
139+
140+
### resolver
141+
142+
**Syntax:** resolver `address` ... [ `valid` = `time` ] [ `ipv4` = `on` | `off` ] [ `ipv6` = `on` | `off` ] [ `status_zone` = `zone` ]
143+
144+
**Default:** -
145+
146+
**Context:** acme_issuer
147+
148+
Configures name servers used to resolve names of upstream servers into
149+
addresses.
150+
See [resolver](https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver)
151+
for the parameter reference.
152+
153+
Required, but can be inherited from the `http` block.
154+
### resolver_timeout
155+
156+
**Syntax:** resolver_timeout `time`
157+
158+
**Default:** 30s
159+
160+
**Context:** acme_issuer
161+
162+
Sets a timeout for name resolution, for example:
163+
164+
```nginx
165+
resolver_timeout 5s;
166+
167+
```
168+
169+
### ssl_trusted_certificate
170+
171+
**Syntax:** ssl_trusted_certificate `file`
172+
173+
**Default:** system CA bundle
174+
175+
**Context:** acme_issuer
176+
177+
Specifies a `file` with trusted CA certificates in the PEM format
178+
used to [verify](#ssl_verify)
179+
the certificate of the ACME server.
180+
181+
### ssl_verify
182+
183+
**Syntax:** ssl_verify `on` | `off`
184+
185+
**Default:** on
186+
187+
**Context:** acme_issuer
188+
189+
Enables or disables verification of the ACME servier certificate.
190+
191+
### state_path
192+
193+
**Syntax:** state_path `path`
194+
195+
**Default:** -
196+
197+
**Context:** acme_issuer
198+
199+
Defines a directory for storing the module data that can be persisted across
200+
restarts. This could greatly improve the time until the server is ready and
201+
help with rate-limiting ACME servers.
202+
203+
The directory, if configured, will contain sensitive content:
204+
the account key, the issued certificates and private keys.
205+
206+
### acme_shared_zone
207+
208+
**Syntax:** acme_shared_zone `zone` = `name:size`
209+
210+
**Default:** ngx_acme_shared:256k
211+
212+
**Context:** http
213+
214+
An optional directive that allows increasing the size of in-memory storage of
215+
the module.
216+
The shared memory zone will be used to store the issued certificates, keys and
217+
challenge data for all the configured certificate issuers.
218+
219+
### acme_certificate
220+
221+
**Syntax:** acme_certificate `issuer` `identifier` ... [ `key` = `alg[:size]` | `file` ]
222+
223+
**Default:** -
224+
225+
**Context:** server
226+
227+
Defines a certificate with the list of `identifier`s requested from
228+
issuer `issuer`.
229+
The `key` parameter sets the type of generated private key or a
230+
path to an existing file. Supported key algorithms and sizes:
231+
`ecdsa:256` (default), `ecdsa:384`,
232+
`ecdsa:521`,
233+
`rsa:2048` .. `rsa:4096`.
234+
235+
> Since 1.27.2, the `key` parameter supports the additional schemes implemented in the
236+
> [ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key)
237+
> directive: `data:` , `engine:` and more recently `store:` ,
238+
> with a caveat that password-protected keys are not supported.
239+
240+
## Embedded Variables
241+
242+
The `ngx_http_acme_module` module defines following embedded
243+
variables, valid in the `server` block with the
244+
[acme_certificate](#acme_certificate) directive:
245+
246+
### ``$acme_certificate``
247+
248+
SSL certificate that can be passed to the
249+
[ssl_certificate](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate).
250+
251+
### ``$acme_certificate_key``
252+
253+
SSL certificate private key that can be passed to the
254+
[ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key).
46255

47256
## License
48257

build.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,16 @@ fn detect_nginx_features() {
4444
if let Ok(os) = env::var("DEP_NGINX_OS") {
4545
println!("cargo::rustc-cfg=ngx_os=\"{os}\"");
4646
}
47+
48+
// Generate cfg values for version checks
49+
50+
println!("cargo::rustc-check-cfg=cfg(ngx_ssl_cache)");
51+
println!("cargo::rerun-if-env-changed=DEP_NGINX_VERSION_NUMBER");
52+
if let Ok(version) = env::var("DEP_NGINX_VERSION_NUMBER") {
53+
let version: u64 = version.parse().unwrap();
54+
55+
if version >= 1_027_002 {
56+
println!("cargo::rustc-cfg=ngx_ssl_cache");
57+
}
58+
}
4759
}

0 commit comments

Comments
 (0)