Skip to content

docs: S7 Pro Ultra compatibility + cert hostname requirement + post-handshake rejection troubleshooting#65

Open
oborichkin wants to merge 1 commit into
Python-roborock:mainfrom
oborichkin:docs/s7-pro-ultra-actalis
Open

docs: S7 Pro Ultra compatibility + cert hostname requirement + post-handshake rejection troubleshooting#65
oborichkin wants to merge 1 commit into
Python-roborock:mainfrom
oborichkin:docs/s7-pro-ultra-actalis

Conversation

@oborichkin

@oborichkin oborichkin commented Jul 19, 2026

Copy link
Copy Markdown

❗❗❗WARNING! Everything was mostly vibe coded and rolled out using LLM. MR is also AI generated (this comment is not), sorry...

What

Documents the onboarding result for Roborock S7 Pro Ultra (model roborock.vacuum.a62) and fills in two gaps in the cert/onboarding docs that I had to reverse-engineer from packet captures.

Compatibility result

Model Firmware ZeroSSL Actalis LetsEncrypt Provided
S7 Pro Ultra (a62) Not reported
  • Actalis RSA-2048 (free 90-day DV via ACME, EAB credentials from the Actalis portal): vacuum trusted the chain end-to-end, recovered the public key from query signatures, and completed MQTT CONNECT within ~95 seconds of the first cfgwifi cycle.
  • Let's Encrypt (R3/E1 chain): vacuum rejects the cert post-handshake. Server-side TLS handshake ok succeeds, but the vacuum closes the TCP connection without sending any HTTP or MQTT request (no tls.alert either way, just a TCP FIN). This is distinct from a TLS handshake failure.

What changed

docs/tested_vacuums.md

  • Added the S7 Pro Ultra row between S7 and S7 MaxV.
  • New ## Diagnosing cert rejection section describing the post-handshake-close signature: mqtt_server.log shows TLS handshake okclient closed before MQTT CONNECT, decompiled_http.jsonl stays empty, packet capture shows repeated ~30 ms TLS connections with TCP FIN and no alert.
  • Subsection ### Hostname verification documenting that the vacuum uses the stack hostname (the api-... value from network.stack_fqdn) for both SNI in ClientHello and hostname verification against the certificate — not the value of the r field from the cfgwifi packet (which is the stack hostname with api- stripped).

docs/custom_cert_management.md

  • New ## Which hostname to cover section: a single-domain certificate on the stack hostname is sufficient, no SAN for the stripped hostname or wildcard is needed, and DNS resolution for the stripped hostname is unnecessary. Relevant for users migrating to Actalis's free single-domain DV quota.

docs/onboarding.md

  • New ## Troubleshooting section (between the guided flow and the Web UI section) covering three patterns:
    • samples=0 / client closed before MQTT CONNECT → cert rejection (links to the diagnosis flowchart in tested_vacuums.md and the hostname section in custom_cert_management.md).
    • state=missing → run another cfgwifi cycle.
    • public_key=False with samples > 0 → recovery needs ≥2 samples, wait or retry.

Why this matters

The post-handshake rejection pattern is non-obvious: the server logs look healthy (TLS handshake ok) and there's no TLS alert, so the natural conclusion is that onboarding is progressing slowly rather than failing. The hostname requirement is similarly easy to miss — users following the cfgwifi r= field intuitively issue a cert for the stripped hostname, which works at the TLS layer (SNI matches) but fails the vacuum's own hostname verification. Both of these cost me several hours of packet capture to pin down; documenting them should save the next person the same.

How to verify

The S7 Pro Ultra row is based on a real device (did: 1103817054923) onboarded against a self-hosted stack on firmware current as of 2026-07. Actalis chain confirmed via tcpdump on the server host: vacuum completes TLS, sends query signature samples, recovers public key, then issues MQTT CONNECT. Let's Encrypt rejection confirmed via the same capture: identical ClientHello, identical server response, but TCP FIN from the vacuum immediately after the server's Finished with no application data. No other models were re-tested in this round.

Scope

Docs only. No code changes, no config schema changes. All three files are plain markdown.

…andshake rejection

Tested Roborock S7 Pro Ultra (model a62) with custom certs:
- Actalis: working (RSA-2048, 90-day DV via ACME)
- Let's Encrypt: rejected post-handshake (TLS handshake completes
  server-side, but vacuum sends TCP FIN without HTTP/MQTT request)

Key finding documented in custom_cert_management.md and tested_vacuums.md:
the vacuum uses the stack hostname (api-... value from network.stack_fqdn)
for SNI and certificate hostname verification, not the value of the r
field from the cfgwifi packet. A single-domain certificate on the stack
hostname is therefore sufficient - no SAN for the stripped hostname
required.

Added troubleshooting section to onboarding.md covering the
samples=0 / 'client closed before MQTT CONNECT' pattern that signals
cert rejection.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant