Univention Bugzilla – Attachment 8887 Details for
Bug 36748
Test kerberos/kdc
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
36748-diagnostic-kdc-420.patch
36748-diagnostic-kdc-420.patch (text/plain), 17.03 KB, created by
Lukas Oyen
on 2017-05-30 16:55 CEST
(
hide
)
Description:
36748-diagnostic-kdc-420.patch
Filename:
MIME Type:
Creator:
Lukas Oyen
Created:
2017-05-30 16:55 CEST
Size:
17.03 KB
patch
obsolete
>From 4e8fbf53338fd1df0bfd6b9ab8754d757c966996 Mon Sep 17 00:00:00 2001 >From: Lukas Oyen <oyen@univention.de> >Date: Tue, 30 May 2017 16:10:54 +0200 >Subject: [PATCH 1/3] Bug #36748: umc-diagnostic: add python-pyasn1 as > dependency > >--- > .../univention-management-console-module-diagnostic/debian/control | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/management/univention-management-console-module-diagnostic/debian/control b/management/univention-management-console-module-diagnostic/debian/control >index a2e98d1..e02a876 100644 >--- a/management/univention-management-console-module-diagnostic/debian/control >+++ b/management/univention-management-console-module-diagnostic/debian/control >@@ -17,6 +17,7 @@ Depends: ${misc:Depends}, > python-pycurl, > python-psutil, > python-dnspython, >+ python-pyasn1, > python-paramiko > Description: System Diagnosis UMC module > . >-- >2.7.4 > > >From 92d221ebea7c1be2b5a2be040f3ea1f2a6936020 Mon Sep 17 00:00:00 2001 >From: Lukas Oyen <oyen@univention.de> >Date: Mon, 22 May 2017 18:15:57 +0200 >Subject: [PATCH 2/3] Bug #36748: umc-diagnostic: new check kdc_service > >--- > .../umc/python/diagnostic/plugins/kdc_service.py | 355 +++++++++++++++++++++ > 1 file changed, 355 insertions(+) > create mode 100755 management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/kdc_service.py > >diff --git a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/kdc_service.py b/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/kdc_service.py >new file mode 100755 >index 0000000..08d5b12 >--- /dev/null >+++ b/management/univention-management-console-module-diagnostic/umc/python/diagnostic/plugins/kdc_service.py >@@ -0,0 +1,355 @@ >+#!/usr/bin/python2.7 >+# coding: utf-8 >+# >+# Univention Management Console module: >+# System Diagnosis UMC module >+# >+# Copyright 2016-2017 Univention GmbH >+# >+# http://www.univention.de/ >+# >+# All rights reserved. >+# >+# The source code of this program is made available >+# under the terms of the GNU Affero General Public License version 3 >+# (GNU AGPL V3) as published by the Free Software Foundation. >+# >+# Binary versions of this program provided by Univention to you as >+# well as other copyrighted, protected or trademarked materials like >+# Logos, graphics, fonts, specific documentations and configurations, >+# cryptographic keys etc. are subject to a license agreement between >+# you and Univention and not subject to the GNU AGPL V3. >+# >+# In the case you use this program under the terms of the GNU AGPL V3, >+# the program is provided in the hope that it will be useful, >+# but WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU Affero General Public License for more details. >+# >+# You should have received a copy of the GNU Affero General Public >+# License with the Debian GNU/Linux or Univention distribution in file >+# /usr/share/common-licenses/AGPL-3; if not, see >+# <http://www.gnu.org/licenses/>. >+ >+import struct >+import socket >+import random >+ >+import ldap >+import ipaddr >+import dns.resolver >+from pyasn1.type import tag >+from pyasn1.type import char >+from pyasn1.type import univ >+from pyasn1.type import useful >+from pyasn1.type import namedtype >+import pyasn1.codec.der.encoder >+import pyasn1.codec.der.decoder >+import pyasn1.error >+ >+from univention.config_registry import handler_set as ucr_set >+import univention.config_registry >+from univention.management.console.modules.diagnostic import Warning, Critical, ProblemFixed >+ >+from univention.lib.i18n import Translation >+_ = Translation('univention-management-console-module-diagnostic').translate >+ >+title = _('KDC service check') >+description = _('The check for the KDC reachability was succesful.') >+ >+ >+# This checks for the reachability of KDCs by sending a AS-REQ per TCP and UDP. >+# The AS-REQ is send with the fake user `kdc-reachability-check`. The KDCs will >+# respond in several ways: either with an KRB-ERROR (PREAUTH_REQUIRED, >+# PRINCIPAL_UNKNOWN or RESPONSE_TO_BIG) or a AS-REP with an anonymous ticket. >+# >+# If we do not receive one of the above, the connection is not accepted, the >+# socket is closed or an operation times out, we can assume, that the KDCs is >+# not reachable. >+# >+# This check will test the KDCs as specified in UCR `kerberos/kdc` with TCP and >+# UDP on port 88. If `kerberos/defaults/dns_lookup_kdc` is set, KDC discovery as >+# specified in section `7.2.3. KDC Discovery on IP Networks` [1] will be used. >+# In this case the ports as specified in the SRV records are used. >+# >+# This implements a minimal number of packages as defined in [1] and does not >+# rely on python-kerberos or python-krb5, as those are too high level and >+# outdated. >+# >+# Reachability checks of kpasswd servers are not implemented, as those are a >+# separate protocol. See [2]. >+# >+# [1]: https://tools.ietf.org/html/rfc4120 >+# [2]: https://tools.ietf.org/html/rfc3244 >+ >+ >+def add_lo_to_samba_interfaces(): >+ configRegistry = univention.config_registry.ConfigRegistry() >+ configRegistry.load() >+ >+ interfaces = configRegistry.get('samba/interfaces', '').split() >+ interfaces.append('lo') >+ ucr_set(['samba/interfaces={}'.format(' '.join(interfaces))]) >+ return run(retest=True) >+ >+ >+def reset_kerberos_kdc(): >+ ucr_set(['kerberos/kdc=127.0.0.1']) >+ return run(retest=True) >+ >+ >+actions = { >+ 'add_lo_to_samba_interfaces': add_lo_to_samba_interfaces, >+ 'reset_kerberos_kdc': reset_kerberos_kdc, >+} >+ >+ >+def _c(n, t): >+ return t.clone(tagSet=t.tagSet + tag.Tag(tag.tagClassContext, tag.tagFormatSimple, n)) >+ >+ >+class PrincipalName(univ.Sequence): >+ componentType = namedtype.NamedTypes( >+ namedtype.NamedType('name-type', _c(0, univ.Integer())), >+ namedtype.NamedType('name-string', _c(1, univ.SequenceOf(componentType=char.GeneralString())))) >+ >+ >+class KdcReqBody(univ.Sequence): >+ tagSet = univ.Sequence.tagSet + tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4) >+ componentType = namedtype.NamedTypes( >+ namedtype.NamedType('kdc-options', _c(0, univ.BitString())), >+ namedtype.OptionalNamedType('cname', _c(1, PrincipalName())), >+ namedtype.NamedType('realm', _c(2, char.GeneralString())), >+ namedtype.OptionalNamedType('sname', _c(3, PrincipalName())), >+ namedtype.NamedType('till', _c(5, useful.GeneralizedTime())), >+ namedtype.NamedType('nonce', _c(7, univ.Integer())), >+ namedtype.NamedType('etype', _c(8, univ.SequenceOf(componentType=univ.Integer())))) >+ >+ >+class PAData(univ.Sequence): >+ componentType = namedtype.NamedTypes( >+ namedtype.NamedType('padata-type', _c(1, univ.Integer())), >+ namedtype.NamedType('padata-value', _c(2, univ.OctetString()))) >+ >+ >+class AsReq(univ.Sequence): >+ tagSet = univ.Sequence.tagSet + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 10) >+ componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', _c(1, univ.Integer())), >+ namedtype.NamedType('msg-type', _c(2, univ.Integer())), >+ namedtype.NamedType('padata', _c(3, univ.SequenceOf(componentType=PAData()))), >+ namedtype.NamedType('req-body', KdcReqBody())) >+ >+ >+class AsRep(univ.Sequence): >+ tagSet = univ.Sequence.tagSet + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 11) >+ componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', _c(0, univ.Integer())), >+ namedtype.NamedType('msg-type', _c(1, univ.Integer())) >+ # some more omitted >+ ) >+ >+ >+class KrbError(univ.Sequence): >+ tagSet = univ.Sequence.tagSet + tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 30) >+ componentType = namedtype.NamedTypes( >+ namedtype.NamedType('pvno', _c(0, univ.Integer())), >+ namedtype.NamedType('msg-type', _c(1, univ.Integer())) >+ # some more omitted >+ ) >+ >+ >+class KerberosException(Exception): >+ pass >+ >+ >+class ServerUnreachable(KerberosException): >+ pass >+ >+ >+class InvalidResponse(KerberosException): >+ pass >+ >+ >+class EmptyResponse(KerberosException): >+ pass >+ >+ >+def build_kerberos_request(target_realm, user_name): >+ req_body = KdcReqBody() >+ req_body['kdc-options'] = "'01010000100000000000000000000000'B" >+ >+ req_body['cname'] = None >+ req_body['cname']['name-type'] = 1 # NT_PRINCIPAL >+ req_body['cname']['name-string'] = None >+ req_body['cname']['name-string'][0] = user_name >+ >+ req_body['realm'] = target_realm >+ >+ req_body['sname'] = None >+ req_body['sname']['name-type'] = 2 # NT_SRV_INST >+ req_body['sname']['name-string'] = None >+ req_body['sname']['name-string'][0] = 'krbtgt' >+ req_body['sname']['name-string'][1] = target_realm >+ >+ req_body['till'] = '19700101000000Z' >+ req_body['nonce'] = random.SystemRandom().getrandbits(31) >+ req_body['etype'] = None >+ req_body['etype'][0] = 18 # AES256_CTS_HMAC_SHA1_96 >+ >+ as_req = AsReq() >+ as_req['pvno'] = 5 >+ as_req['msg-type'] = 10 # AS-REQ >+ as_req['padata'] = None >+ as_req['req-body'] = req_body >+ >+ return pyasn1.codec.der.encoder.encode(as_req) >+ >+ >+def send_and_receive(kdc, port, protocol, as_req): >+ socket_type = socket.SOCK_DGRAM if protocol == 'udp' else socket.SOCK_STREAM >+ sock = socket.socket(socket.AF_INET, socket_type) >+ sock.settimeout(1) >+ >+ if protocol == 'tcp': >+ packed = struct.pack('>I', len(as_req)) + as_req >+ else: >+ packed = as_req >+ >+ try: >+ sock.connect((kdc, port)) >+ sock.sendall(packed) >+ except socket.error, socket.timeout: >+ sock.close() >+ raise ServerUnreachable() >+ >+ received = '' >+ num_received = 0 >+ if protocol == 'udp': # fake the length field >+ received += '\x00\x00\x00\x00' >+ num_received += 4 >+ while num_received < 128: >+ try: >+ (buf, addr) = sock.recvfrom(128) >+ except socket.error, socket.timeout: >+ buf = '' >+ if not buf: >+ break >+ received += buf >+ num_received += len(buf) >+ >+ if not received: >+ raise EmptyResponse() >+ >+ return received >+ >+ >+def probe_kdc(kdc, port, protocol, target_realm, user_name): >+ request = build_kerberos_request(target_realm, user_name) >+ >+ try: >+ received = send_and_receive(kdc, port, protocol, request) >+ except KerberosException: >+ return False >+ >+ try: >+ (error, _sub) = pyasn1.codec.der.decoder.decode(received, asn1Spec=KrbError()) >+ except pyasn1.error.PyAsn1Error: >+ pass >+ else: >+ return True >+ >+ try: >+ (rep, _sub) = pyasn1.codec.der.decoder.decode(received, asn1Spec=AsRep()) >+ except pyasn1.error.PyAsn1Error: >+ return False >+ >+ return True >+ >+ >+def is_service_active(service): >+ lo = univention.uldap.getMachineConnection() >+ raw_filter = '(&(univentionService=%s)(cn=%s))' >+ filter_expr = ldap.filter.filter_format(raw_filter, (service, socket.gethostname())) >+ for (dn, _attr) in lo.search(filter_expr, attr=['cn']): >+ if dn is not None: >+ return True >+ return False >+ >+ >+def run(retest=False): >+ configRegistry = univention.config_registry.ConfigRegistry() >+ configRegistry.load() >+ >+ target_realm = configRegistry.get('kerberos/realm') >+ user_name = 'kdc-reachability-check' >+ >+ kdc_fqds = configRegistry.get('kerberos/kdc', '').split() >+ dns_lookup_kdc = configRegistry.is_true('kerberos/defaults/dns_lookup_kdc', True) >+ if not dns_lookup_kdc and not kdc_fqds: >+ kerberos_dns_fqdn_tcp = '_kerberos._tcp.{}'.format(configRegistry.get('domainname')) >+ result_tcp = dns.resolver.query(kerberos_dns_fqdn_tcp, 'SRV') >+ kdc_to_check = [(r.target.to_text(True), r.port, 'tcp') for r in result_tcp] >+ >+ kerberos_dns_fqdn_udp = '_kerberos._udp.{}'.format(configRegistry.get('domainname')) >+ result_udp = dns.resolver.query(kerberos_dns_fqdn_udp, 'SRV') >+ kdc_to_check.extend((r.target.to_text(True), r.port, 'udp') for r in result_udp) >+ else: >+ kdc_to_check = [(kdc, 88, 'tcp') for kdc in kdc_fqds] >+ kdc_to_check.extend((kdc, 88, 'udp') for kdc in kdc_fqds) >+ >+ kdc_reachabe = [(probe_kdc(kdc, port, protocol, target_realm, user_name), >+ (kdc, port, protocol)) for (kdc, port, protocol) in kdc_to_check] >+ reachable_kdc = [(kdc, port, protocol) for (reachable, (kdc, port, protocol)) >+ in kdc_reachabe if reachable] >+ unreachable_kdc = [(kdc, port, protocol) for (reachable, (kdc, port, protocol)) >+ in kdc_reachabe if not reachable] >+ >+ error_descriptions = list() >+ >+ if unreachable_kdc: >+ error = _('The following KDCs were unreachable: {}') >+ unreach_string = ('{} {}:{}'.format(protocol, kdc, port) >+ for (kdc, port, protocol) in unreachable_kdc) >+ error_descriptions.append(error.format(', '.join(unreach_string))) >+ >+ if not reachable_kdc: >+ is_dc = configRegistry.get('server/role') == 'domaincontroller_master' >+ is_s4_dc = is_dc and is_service_active('Samba 4') >+ if is_s4_dc and configRegistry.is_true('samba/interfaces/bindonly', False): >+ local_included = False >+ for interface in configRegistry.get('samba/interfaces', '').split(): >+ try: >+ addr = ipaddr.IPAddress(interface) >+ except ValueError: >+ local_included |= interface == 'lo' >+ else: >+ local_included |= addr.is_loopback or addr.is_unspecified >+ error = _('samba/interfaces does not contain lo, 127.0.0.1 or 0.0.0.0.') >+ error_descriptions.append(error) >+ >+ description = '\n'.join(error_descriptions) >+ buttons = [{ >+ 'action': 'add_lo_to_samba_interfaces', >+ 'label': _('Add lo to samba/interfaces'), >+ }, { >+ 'action': 'reset_kerberos_kdc', >+ 'label': _('Reset kerberos/kdc to 127.0.0.1'), >+ }] >+ raise Critical(description=description, buttons=buttons) >+ >+ error_descriptions.append(_('No reachable KDCs were found.')) >+ description = '\n'.join(error_descriptions) >+ raise Critical(description=description) >+ >+ if error_descriptions: >+ error = '\n'.join(error_descriptions) >+ raise Warning(description=error) >+ >+ if retest: >+ raise ProblemFixed() >+ >+ >+if __name__ == '__main__': >+ from univention.management.console.modules.diagnostic import main >+ main() >-- >2.7.4 > > >From bc4899b3f8f1a3acf536e83ed0df1f4882d94250 Mon Sep 17 00:00:00 2001 >From: Lukas Oyen <oyen@univention.de> >Date: Tue, 30 May 2017 16:13:18 +0200 >Subject: [PATCH 3/3] Bug #36748: umc-diagnostic: new check kdc_service (po) > >--- > .../umc/python/diagnostic/de.po | 32 ++++++++++++++++++++-- > 1 file changed, 30 insertions(+), 2 deletions(-) > >diff --git a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po b/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po >index affad86..7f2a26f 100644 >--- a/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po >+++ b/management/univention-management-console-module-diagnostic/umc/python/diagnostic/de.po >@@ -2,8 +2,8 @@ > msgid "" > msgstr "" > "Project-Id-Version: univention-management-console-module-diagnostic\n" >-"Report-Msgid-Bugs-To: packages@univention.de\n" >-"POT-Creation-Date: 2016-01-14 12:19+0100\n" >+"Report-Msgid-Bugs-To: \n" >+"POT-Creation-Date: 2017-05-30 16:19+0200\n" > "PO-Revision-Date: \n" > "Last-Translator: Univention GmbH <packages@univention.de>\n" > "Language-Team: Univention GmbH <packages@univention.de>\n" >@@ -23,6 +23,10 @@ msgstr "" > "Eine Zeitüberschreitung trat beim Erreichen des Nameservers auf (ist er " > "online?)." > >+#: umc/python/diagnostic/plugins/kdc_service.py:334 >+msgid "Add lo to samba/interfaces" >+msgstr "Füge lo zu samba/interfaces hinzu" >+ > #: umc/python/diagnostic/plugins/security_limits.py:31 > msgid "Adjust to suggested limits" > msgstr "An vorgeschlagene Limits anpassen" >@@ -59,6 +63,10 @@ msgstr "" > "{ucr} oder durch automatische Anpassung auf die empfohlenen Limits zu " > "erhöhen." > >+#: umc/python/diagnostic/plugins/kdc_service.py:57 >+msgid "KDC service check" >+msgstr "KDC Erreichbarkeit" >+ > #: umc/python/diagnostic/plugins/ssh_connection.py:55 > #, python-format > msgid "" >@@ -97,6 +105,10 @@ msgstr "" > msgid "Nameserver(s) are not responsive" > msgstr "Nameserver sind nicht ansprechbar" > >+#: umc/python/diagnostic/plugins/kdc_service.py:341 >+msgid "No reachable KDCs were found." >+msgstr "Keine erreichbaren KDCs gefunden." >+ > #: umc/python/diagnostic/plugins/package_status.py:11 > msgid "Package status corrupt" > msgstr "Paketstatus korrupt" >@@ -129,6 +141,10 @@ msgstr "" > msgid "Proxy server failure" > msgstr "Proxy-Server-Fehler" > >+#: umc/python/diagnostic/plugins/kdc_service.py:337 >+msgid "Reset kerberos/kdc to 127.0.0.1" >+msgstr "Setze kerberos/kdc auf 127.0.0.1 zurück" >+ > #: umc/python/diagnostic/plugins/ssh_connection.py:16 > msgid "SSH connection to UCS server failed!" > msgstr "SSH-Verbindung zu anderem UCS Server fehlgeschlagen!" >@@ -141,6 +157,14 @@ msgstr "Sicherheitslimits überschritten" > msgid "Test again" > msgstr "Erneut testen" > >+#: umc/python/diagnostic/plugins/kdc_service.py:58 >+msgid "The check for the KDC reachability was succesful." >+msgstr "Erreichbarkeitstest der KDCs war erfolgreich." >+ >+#: umc/python/diagnostic/plugins/kdc_service.py:311 >+msgid "The following KDCs were unreachable: {}" >+msgstr "Die folgenden KDCs waren nicht erreichbar: {}" >+ > #: umc/python/diagnostic/plugins/ssh_connection.py:48 > msgid "" > "The following list shows the affected remote servers and the reason for the " >@@ -260,6 +284,10 @@ msgstr "" > "dass Authentifikations-Zugangsdaten (falls existierend) korrekt sind und die " > "ACL's des Proxy-Servers nicht verbieten, Anfragen an %s zu stellen." > >+#: umc/python/diagnostic/plugins/kdc_service.py:328 >+msgid "samba/interfaces does not contain lo, 127.0.0.1 or 0.0.0.0." >+msgstr "samba/interfaces enthält weder lo noch 127.0.0.1 noch 0.0.0.0." >+ > #: umc/python/diagnostic/plugins/package_status.py:28 > msgid "some" > msgstr "einigen" >-- >2.7.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 36748
: 8887