Files
Deploy-Laboratory/ansible/roles/verify_common/tasks/tls-openssl-sni.yml
2026-03-29 09:08:01 +08:00

86 lines
4.3 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 可复用TLS 握手 + SNIopenssl s_client输出 [OC-ASSERT]Epic 3.3 入口侧 TLS 证据)。
#
# 必填verify_tls_connect_host建议 IP 或解析到的入口地址、verify_tls_servernameSNI常同 HTTP Host
# 可选verify_tls_port默认 443、verify_tls_timeout_sec默认 10
# verify_tls_expect_subject_substring若设置则 x509 subject 须包含该子串grep -F
# verify_tls_expect_san_substring若设置则 SAN 扩展文本须包含该子串)、
# verify_tls_cafile若设置s_client 增加 -CAfile路径须在执行主机存在
# verify_tls_insecure_skip_verify默认 falsetrue 时仅审计标注「不对链做强断言」,仍解析对端呈现证书)、
# verify_tls_assertion_label默认 tls_sni_handshake
- name: Assert tls-openssl-sni required vars
ansible.builtin.assert:
that:
- verify_tls_connect_host is defined
- (verify_tls_connect_host | trim | length) > 0
- verify_tls_servername is defined
- (verify_tls_servername | trim | length) > 0
fail_msg: "verify_common tls-openssl-sni需设置 verify_tls_connect_host 与 verify_tls_servername"
- name: TLS handshake + certificate subject (openssl s_client)
ansible.builtin.shell: |
set -euo pipefail
assertion={{ (verify_tls_assertion_label | default('tls_sni_handshake')) | quote }}
host={{ verify_tls_connect_host | trim | quote }}
port={{ verify_tls_port | default(443) | int }}
sni={{ verify_tls_servername | trim | quote }}
timeout={{ verify_tls_timeout_sec | default(10) | int }}
expect={{ (verify_tls_expect_subject_substring | default('') | trim) | quote }}
expect_san={{ (verify_tls_expect_san_substring | default('') | trim) | quote }}
cafile={{ (verify_tls_cafile | default('') | trim) | quote }}
insecure={{ ('1' if (verify_tls_insecure_skip_verify | default(false) | bool) else '0') | quote }}
extra_ca=""
if [ -n "$cafile" ]; then
if [ ! -f "$cafile" ]; then
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=cafile result=fail reason=missing_file path=${cafile}"
exit 1
fi
extra_ca="-CAfile ${cafile}"
fi
if [ "$insecure" = "1" ]; then
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=insecure_skip_verify value=1 note=peer_cert_only_lab_or_troubleshoot"
fi
raw=$(echo | timeout "$timeout" openssl s_client -connect "${host}:${port}" -servername "$sni" ${extra_ca} </dev/null 2>&1 || true)
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=s_client_log excerpt"
echo "$raw" | tail -25
subj=$(echo "$raw" | openssl x509 -noout -subject 2>/dev/null || true)
if [ -z "$subj" ]; then
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=subject result=fail reason=no_certificate_or_handshake"
exit 1
fi
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=subject value=${subj}"
dates=$(echo "$raw" | openssl x509 -noout -dates 2>/dev/null || true)
not_after=$(echo "$dates" | grep '^notAfter=' | cut -d= -f2- | tr -d '\r' || true)
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=cert_not_after value=${not_after:-unknown}"
san=$(echo "$raw" | openssl x509 -noout -ext subjectAltName 2>/dev/null || true)
if [ -z "$(echo "$san" | tr -d '[:space:]')" ]; then
san=$(echo "$raw" | openssl x509 -noout -text 2>/dev/null | awk '/X509v3 Subject Alternative Name:/{getline; print; exit}' || true)
fi
san_log=$(echo "$san" | tr '\n\r\t' ' ' | cut -c1-240)
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=san excerpt=${san_log:-<none>}"
if [ -n "$expect" ]; then
echo "$subj" | grep -Fq -- "$expect" || {
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=subject_match result=fail expected_substring=${expect}"
exit 1
}
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=subject_match result=ok"
fi
if [ -n "$expect_san" ]; then
echo "$san" | grep -Fq -- "$expect_san" || {
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=san_match result=fail expected_substring=${expect_san}"
exit 1
}
echo "[OC-ASSERT] assertion=${assertion} phase=tls probe=san_match result=ok"
fi
args:
executable: /bin/bash
changed_when: false