getssl
getssl copied to clipboard
XMPP / SRV compatible certificate check
Feature request
Make SERVER_TYPE="xmpp"
use the SRV DNS records to check against the real XMPP server, which might be != the certificate domain.
Or as a workaround: allow to specify the host which should be checked for the certificate.
Background
I am using getssl
to generate a certificate for a private XMPP server hosted at home. The way XMPP works (in this scenario) is, that there is a SRV DNS entry pointing to the server providing the service, e.g.:
_xmpp-client._tcp.example.com. 18000 IN SRV 0 5 5222 xmpp.example.com.
When I use [email protected] as XMPP id, the client does a DNS query and then connects to xmpp.example.com
on port 5222. The server running at xmpp.example.com
needs to respond with a certificate for example.com
.
The generating part works fine. getssl
runs on the VM at xmpp.example.com
, it uploads the challenge token via SFTP to the webserver running at example.com
the certificates are successfully obtained.
When trying to validate the certificate getssl
fails:
Either it tries to validate it against example.com
and gives this error:
/root/.getssl/example.com/example.com.crt didn't match server
getssl: example.com - rsa certificate obtained but certificate on server is different from the new certificate
Which is an understandable since example.org
really does use a different certificate.
Or if I use
SERVER_TYPE="xmpp"
CHECK_REMOTE="true"
it fails with
example.com: no certificate obtained from host
example.com: certificate is valid for more than 30 days (until Jun 3 20:52:22 2021 GMT)
Which is also understandable, since example.com
does not run anything in port 5222.
Hi @masgo
This seems like a good enhancement, I'll add it to my list of things to do (happy to review a PR if you feel up to coding the change)
My bash skills are rather limited.
The easyest way would probably be to provide an additonoal variable like CHECK_REMOTE_HOSTNAME
where one could manually specify the host to check against. This would probably also be useful for mail servers, and others where SRV records are used. This would also deal with the situation where the SRV record points to multiple hosts with different priorities. In such a case the generated certificate might only be used for a subset of the servers.
OR
You could provide a variable like EXECUTE_EXTERNAL_CHECK_REMOTE
which would be a commandline to execute. Then one could provide an external script which does the certificate check. You would then just check the return value.
OR
If you, or somebody else, wants to do it for XMPP, here are more informations about the XMPP specifications. I am using the real public XMPP jabber.ccc.de
server as an example here.
- Query the DNS for the SRV records, for client and/or server
$ host -t SRV _xmpp-client._tcp.jabber.ccc.de
_xmpp-client._tcp.jabber.ccc.de has SRV record 10 0 5222 jabberd.jabber.ccc.de.
_xmpp-client._tcp.jabber.ccc.de has SRV record 30 0 5222 jabberd-ipv6.jabber.ccc.de.
_xmpp-client._tcp.jabber.ccc.de has SRV record 20 0 80 jabberd.jabber.ccc.de.
_xmpp-client._tcp.jabber.ccc.de has SRV record 31 0 5222 jabberd-ipv4.jabber.ccc.de.
$ host -t SRV _xmpp-server._tcp.jabber.ccc.de
_xmpp-server._tcp.jabber.ccc.de has SRV record 31 0 5269 jabberd-ipv4.jabber.ccc.de.
_xmpp-server._tcp.jabber.ccc.de has SRV record 30 0 5269 jabberd-ipv6.jabber.ccc.de.
_xmpp-server._tcp.jabber.ccc.de has SRV record 10 0 5269 jabberd.jabber.ccc.de.
Now one needs to parse the response according to the XMPP documentation.
An SRV record has the form:
_service._proto.name TTL class SRV priority weight port target
service: the symbolic name of the desired service.
proto: the transport protocol of the desired service; this is usually either TCP or UDP.
name: the domain name for which this record is valid.
TTL: standard DNS time to live field.
class: standard DNS class field (this is always IN).
priority: the priority of the target host, lower value means more preferred.
weight: A relative weight for records with the same priority.
port: the TCP or UDP port on which the service is to be found.
target: the canonical hostname of the machine providing the service.
Then check all(?) servers for the new certificate. As per defition the target
needs to be an A record, so no CNAME or similar problems here.
Thanks @masgo, that's some great requirements. I'll look at implementing it soonish