Skip to content

Commit c285d98

Browse files
committed
remove nginx tls cbc suites
1 parent 57b830e commit c285d98

4 files changed

Lines changed: 57 additions & 2 deletions

File tree

‎docs/07-tls-and-certificate-automation.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ In that model:
3333
- hosted domains can still be `example.com`, `example.net`, and `example.org`
3434
- MX records for each domain can point to the same mail host
3535

36+
The nginx public-edge TLS template is intentionally bounded to `TLSv1.2` and
37+
`TLSv1.3`. TLS 1.2 ciphers are listed explicitly as AEAD-only ECDHE suites
38+
using AES-GCM or ChaCha20-Poly1305. CBC-capable broad cipher aliases, including
39+
`AES256+EECDH`, are not part of the rendered baseline.
40+
3641
## Why this matters
3742

3843
This keeps the public project easier to deploy and document because it avoids:
@@ -94,6 +99,8 @@ The verify script checks:
9499
- hostname and certificate settings are valid
95100
- required commands exist
96101
- generated helper files exist when expected
102+
- the tracked nginx TLS template keeps TLS 1.2/1.3 only and does not include
103+
CBC-capable cipher aliases
97104

98105
## Recommended usage
99106

‎scripts/verify/verify-rendered-config-integrity.ksh‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ FAIL=0
2828
pass() { print -- "PASS $*"; }
2929
fail() { print -- "FAIL $*"; FAIL=1; }
3030

31+
TLS12_AEAD_CIPHERS='ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256'
32+
3133
check_file() {
3234
_file="$1"
3335
_label="$2"
@@ -53,6 +55,21 @@ check_regex() {
5355
fi
5456
}
5557

58+
check_no_regex() {
59+
_file="$1"
60+
_regex="$2"
61+
_label="$3"
62+
if [ ! -f "${_file}" ]; then
63+
fail "${_label} missing: ${_file}"
64+
return 0
65+
fi
66+
if grep -Eiq "${_regex}" "${_file}"; then
67+
fail "${_label} forbidden pattern found in ${_file}"
68+
else
69+
pass "${_label}"
70+
fi
71+
}
72+
5673
check_no_upper_placeholders() {
5774
_file="$1"
5875
_label="$2"
@@ -67,6 +84,32 @@ check_no_upper_placeholders() {
6784
fi
6885
}
6986

87+
check_nginx_tls_policy() {
88+
tls_policy_root="$1"
89+
tls_policy_label="$2"
90+
tls_policy_ssl_template="${tls_policy_root}/etc/nginx/templates/ssl.tmpl"
91+
92+
if [ ! -f "${tls_policy_ssl_template}" ]; then
93+
fail "${tls_policy_label} nginx TLS template missing: ${tls_policy_ssl_template}"
94+
return 0
95+
fi
96+
if grep -Eq '^ssl_protocols TLSv1\.2 TLSv1\.3;$' "${tls_policy_ssl_template}"; then
97+
pass "${tls_policy_label} nginx TLS protocols limited to TLS 1.2 and TLS 1.3"
98+
else
99+
fail "${tls_policy_label} nginx TLS protocol floor/ceiling not found in ${tls_policy_ssl_template}"
100+
fi
101+
if grep -Eq "^ssl_ciphers ${TLS12_AEAD_CIPHERS};$" "${tls_policy_ssl_template}"; then
102+
pass "${tls_policy_label} nginx TLS 1.2 ciphers are explicit AEAD-only suites"
103+
else
104+
fail "${tls_policy_label} nginx TLS 1.2 AEAD cipher list not found in ${tls_policy_ssl_template}"
105+
fi
106+
if grep -Eiq '(^|[^A-Z0-9])CBC([^A-Z0-9]|$)|AES[0-9]*-SHA($|:)|AES256\+EECDH|EECDH\+AES|EDH\+AES' "${tls_policy_ssl_template}"; then
107+
fail "${tls_policy_label} nginx TLS template contains CBC-capable broad cipher tokens: ${tls_policy_ssl_template}"
108+
else
109+
pass "${tls_policy_label} nginx TLS template has no CBC-capable broad cipher tokens"
110+
fi
111+
}
112+
70113
check_mail_root() {
71114
_root="$1"
72115
_label="$2"
@@ -81,6 +124,7 @@ check_mail_root() {
81124
check_regex "${_root}/etc/dovecot/dovecot.conf" 'protocols *= *imap lmtp' "${_label} dovecot protocol set"
82125
check_regex "${_root}/etc/dovecot/local.conf" 'mail_location *= *maildir:' "${_label} dovecot maildir location"
83126
check_regex "${_root}/etc/nginx/sites-available/main-ssl.conf" 'include /etc/nginx/templates/ssl\.tmpl;' "${_label} nginx ssl template include"
127+
check_nginx_tls_policy "${_root}" "${_label}"
84128
check_regex "${_root}/etc/rspamd/local.d/worker-proxy.inc" 'milter *= *yes;' "${_label} rspamd proxy milter enabled"
85129
check_regex "${_root}/etc/rspamd/local.d/worker-controller.inc" 'bind_socket *= *"' "${_label} rspamd controller bind configured"
86130
check_regex "${_root}/var/www/postfixadmin/config.local.php" "\$CONF\['configured'\] = true;" "${_label} postfixadmin configured flag"

‎services/generated/rootfs/etc/nginx/templates/ssl.tmpl‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
ssl_protocols TLSv1.2 TLSv1.3;
2-
ssl_ciphers EECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH;
2+
# TLS 1.3 ciphers are negotiated by the TLS library. Keep TLS 1.2 explicit
3+
# and AEAD-only so legacy block-mode suites cannot be selected at the public edge.
4+
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
35
ssl_prefer_server_ciphers on;
46

57
# Generate once if it does not exist:

‎services/nginx/etc/nginx/templates/ssl.tmpl.template‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
ssl_protocols TLSv1.2 TLSv1.3;
2-
ssl_ciphers EECDH+CHACHA20:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH;
2+
# TLS 1.3 ciphers are negotiated by the TLS library. Keep TLS 1.2 explicit
3+
# and AEAD-only so legacy block-mode suites cannot be selected at the public edge.
4+
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
35
ssl_prefer_server_ciphers on;
46

57
# Generate once if it does not exist:

0 commit comments

Comments
 (0)