]>
git.siccegge.de Git - dane-monitoring-plugins.git/blob - check_dane_ssh
5 from __future__
import print_function
13 from unbound
import ub_ctx
, ub_strerror
17 from unbound
import RR_TYPE_SSHFP
22 class HostKeyMatchSSHFP(BaseException
):
26 class HostKeyMismatchSSHFP(BaseException
):
30 class HostKeyLookup(paramiko
.client
.MissingHostKeyPolicy
):
31 def __init__(self
, args
):
33 self
._resolver
= ub_ctx()
34 self
._resolver
.add_ta_file(args
.ancor
)
37 def missing_host_key(self
, client
, hostname
, key
):
38 actualhostkey
= key
.asbytes()
39 actualkeytype
= key
.get_name()
40 hexencoder
= codecs
.getencoder('hex')
42 s
, r
= self
._resolver
.resolve(hostname
, RR_TYPE_SSHFP
)
48 logging
.error("No SSHFP record returned")
51 for record
in r
.data
.data
:
57 actualhash
= hashlib
.sha1(actualhostkey
).digest()
59 actualhash
= hashlib
.sha256(actualhostkey
).digest()
61 logging
.warning("Only hashtypes 1 and 2 supported")
63 if keytype
== 1 and actualkeytype
== 'ssh-rsa':
64 if data
== actualhash
:
65 logging
.info("Found matching record: `SSHFP %d %d %s`",
66 keytype
, hashtype
, hexencoder(data
)[0].decode())
67 raise HostKeyMatchSSHFP
69 elif keytype
== 2 and actualkeytype
== 'ssh-dss':
70 if data
== actualhash
:
71 logging
.info("Found matching record: `SSHFP %d %d %s`",
72 keytype
, hashtype
, hexencoder(data
)[0].decode())
73 raise HostKeyMatchSSHFP
75 elif keytype
== 3 and actualkeytype
== 'ssh-ecdsa':
76 if data
== actualhash
:
77 logging
.info("Found matching record: `SSHFP %d %d %s`",
78 keytype
, hashtype
, hexencoder(data
)[0].decode())
79 raise HostKeyMatchSSHFP
81 elif keytype
== 4 and actualkeytype
== 'ssh-ed25519':
82 if data
== actualhash
:
83 logging
.info("Found matching record: `SSHFP %d %d %s`",
84 keytype
, hashtype
, hexencoder(data
)[0].decode())
85 raise HostKeyMatchSSHFP
87 logging
.error("No matching SSHFP record found")
88 raise HostKeyMismatchSSHFP
91 def init_connection(args
):
92 connection
= paramiko
.client
.SSHClient()
93 connection
.set_missing_host_key_policy(HostKeyLookup(args
))
99 logging
.basicConfig(format
='%(levelname)5s %(message)s')
100 parser
= argparse
.ArgumentParser()
101 parser
.add_argument("Host")
103 parser
.add_argument("--verbose", action
="store_true")
104 parser
.add_argument("--quiet", action
="store_true")
105 parser
.add_argument("-p", "--port",
106 action
="store", type=int, default
=22,
109 parser
.add_argument("-a", "--ancor",
110 action
="store", type=str, default
="/etc/unbound/root.key",
111 help="DNSSEC root ancor")
113 group
= parser
.add_mutually_exclusive_group()
114 group
.add_argument("-6", "--6", action
="store_true", help="check via IPv6 only")
115 group
.add_argument("-4", "--4", action
="store_true", help="check via IPv4 only")
116 group
.add_argument("--64", action
="store_false", help="check via IPv4 and IPv6 (default)")
118 args
= parser
.parse_args()
121 logging
.getLogger().setLevel(logging
.DEBUG
)
123 logging
.getLogger().setLevel(logging
.WARNING
)
125 logging
.getLogger().setLevel(logging
.INFO
)
127 connection
= init_connection(args
)
130 connection
.connect(args
.Host
)
131 except HostKeyMatchSSHFP
:
133 except HostKeyMismatchSSHFP
:
137 if __name__
== '__main__':