Forráskód Böngészése

# This is a combination of 2 commits.
# This is the 1st commit message:

# This is a combination of 2 commits.
# This is the 1st commit message:

# This is a combination of 2 commits.
# This is the 1st commit message:

# This is a combination of 2 commits.
# This is the 1st commit message:

# This is a combination of 13 commits.
# This is the 1st commit message:

support for DNS srv records and retry features for other KDCs

# This is the commit message #2:

filter out unsupported etypes in krb5.conf

# This is the commit message #3:

env var for ip

# This is the commit message #4:

update entrypoint

# This is the commit message #5:

intg test env

# This is the commit message #6:

dns entries

# This is the commit message #7:

travis nameserver

# This is the commit message #8:

dns intg tests

# This is the commit message #9:

fix network infinite loop

# This is the commit message #10:

fix issue

# This is the commit message #11:

travis env var

# This is the commit message #12:

missing port

# This is the commit message #13:

rebase

# This is the commit message #2:

update entrypoint

# This is the commit message #2:

dns entries

# This is the commit message #2:

fix network infinite loop

# This is the commit message #2:

missing port

Jonathan Turner 8 éve
szülő
commit
b762b590bd

+ 7 - 1
.travis.yml

@@ -17,18 +17,24 @@ services:
 
 before_install:
   - docker pull jcmturner/gokrb5:http
+  - docker pull jcmturner/gokrb5:dns
   - docker pull jcmturner/gokrb5:kdc-centos-default
   - docker pull jcmturner/gokrb5:kdc-older
   - docker pull jcmturner/gokrb5:kdc-latest
+  - docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -e "TEST_KDC_ADDR=127.0.0.1" -p 53:53 -p 53:53/udp --name dns jcmturner/gokrb5:dns
   - docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 88:88 -p 88:88/udp --name krb5kdc jcmturner/gokrb5:kdc-centos-default
   - docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 78:88 -p 78:88/udp --name krb5kdc-old jcmturner/gokrb5:kdc-older
   - docker run -d -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -p 98:88 -p 98:88/udp --name krb5kdc-latest jcmturner/gokrb5:kdc-latest
   - docker run -d --add-host host.test.gokrb5:127.0.0.88 -v /etc/localtime:/etc/localtime:ro -p 80:80 -p 443:443 --name gokrb5-http jcmturner/gokrb5:http
 
+before_stript:
+  - cat /etc/resolv.conf
+
 env:
-  - TEST_KDC_ADDR=127.0.0.1 TEST_HTTP_URL="http://host.test.gokrb5/index.html"
+  - TEST_KDC_ADDR=127.0.0.1 TEST_HTTP_URL="http://host.test.gokrb5/index.html" DNSUTILS_OVERRIDE_NS="127.0.0.1:53"
 
 addons:
   hosts:
     - host.test.gokrb5
+    - kdc.test.gokrb5
 

+ 8 - 6
client/client.go

@@ -177,15 +177,17 @@ func (cl *Client) IsConfigured() (bool, error) {
 	if cl.Config.LibDefaults.DefaultRealm == "" {
 		return false, errors.New("client krb5 config does not have a default realm")
 	}
-	for _, r := range cl.Config.Realms {
-		if r.Realm == cl.Config.LibDefaults.DefaultRealm {
-			if len(r.KDC) > 0 {
-				return true, nil
+	if !cl.Config.LibDefaults.DNSLookupKDC {
+		for _, r := range cl.Config.Realms {
+			if r.Realm == cl.Config.LibDefaults.DefaultRealm {
+				if len(r.KDC) > 0 {
+					return true, nil
+				}
+				return false, errors.New("client krb5 config does not have any defined KDCs for the default realm")
 			}
-			return false, errors.New("client krb5 config does not have any defined KDCs for the default realm")
 		}
 	}
-	return false, errors.New("client does not have KDCs configured for the default realm")
+	return true, nil
 }
 
 // Login the client with the KDC via an AS exchange.

+ 64 - 0
client/client_integration_test.go

@@ -395,3 +395,67 @@ func TestNewClientFromCCache(t *testing.T) {
 		t.Fatalf("Client was not configured from CCache: %v", err)
 	}
 }
+
+// Only works for Go 1.9 creates false negativce for Go <= 1.8
+//func TestResolveKDC(t *testing.T) {
+//	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
+//	ns := os.Getenv("DNSUTILS_OVERRIDE_NS")
+//	if ns == "" {
+//		os.Setenv("DNSUTILS_OVERRIDE_NS", testdata.TEST_NS)
+//	}
+//	c.LibDefaults.DNSLookupKDC = true
+//	var cl Client
+//	cl.WithConfig(c)
+//	count, res, err := cl.resolveKDC(c.LibDefaults.DefaultRealm, true)
+//	if err != nil {
+//		t.Errorf("error resolving KDC via DNS TCP: %v", err)
+//	}
+//	assert.Equal(t, 5, count, "Number of SRV records not as expected")
+//	assert.Equal(t, count, len(res), "Map size does not match")
+//	expected := []string{
+//		"kdc.test.gokrb5:88",
+//		"kdc1a.test.gokrb5:88",
+//		"kdc2a.test.gokrb5:88",
+//		"kdc1b.test.gokrb5:88",
+//		"kdc2b.test.gokrb5:88",
+//	}
+//	for _, s := range expected {
+//		var found bool
+//		for _, v := range res {
+//			if s == v {
+//				found = true
+//				break
+//			}
+//		}
+//		assert.True(t, found, "Record %s not found in results", s)
+//	}
+//	c.LibDefaults.DNSLookupKDC = false
+//	count, res, err = cl.resolveKDC(c.LibDefaults.DefaultRealm, true)
+//	if err != nil {
+//		t.Errorf("error resolving KDCs from config: %v", err)
+//	}
+//	assert.Equal(t, "127.0.0.1:88", res[1], "KDC not read from config as expected")
+//}
+//
+//func TestClient_Login_DNSKDCs(t *testing.T) {
+//	ns := os.Getenv("DNSUTILS_OVERRIDE_NS")
+//	if ns == "" {
+//		os.Setenv("DNSUTILS_OVERRIDE_NS", testdata.TEST_NS)
+//	}
+//
+//	c, _ := config.NewConfigFromString(testdata.TEST_KRB5CONF)
+//	// Set to lookup KDCs in DNS
+//	c.LibDefaults.DNSLookupKDC = true
+//	//Blank out the KDCs to ensure they are not being used
+//	c.Realms = []config.Realm{}
+//
+//	b, err := hex.DecodeString(testdata.TESTUSER1_KEYTAB)
+//	kt, _ := keytab.Parse(b)
+//	cl := NewClientWithKeytab("testuser1", "TEST.GOKRB5", kt)
+//	cl.WithConfig(c)
+//
+//	err = cl.Login()
+//	if err != nil {
+//		t.Errorf("Error on logging in using DNS lookup of KDCs: %v\n", err)
+//	}
+//}

+ 127 - 53
client/network.go

@@ -3,54 +3,93 @@ package client
 import (
 	"bytes"
 	"encoding/binary"
+	"errors"
 	"fmt"
+	"gopkg.in/jcmturner/dnsutils.v1"
 	"io"
+	"gopkg.in/jcmturner/gokrb5.v2/iana/errorcode"
+	"gopkg.in/jcmturner/gokrb5.v2/messages"
 	"math/rand"
 	"net"
+	"strconv"
+	"strings"
 	"time"
-
-	"gopkg.in/jcmturner/gokrb5.v2/iana/errorcode"
-	"gopkg.in/jcmturner/gokrb5.v2/messages"
 )
 
-// SendToKDC performs network actions to send data to the KDC.
-func (cl *Client) SendToKDC(b []byte, realm string) ([]byte, error) {
-	var rb []byte
-	var kdcs []string
-	for _, r := range cl.Config.Realms {
-		if r.Realm == realm {
-			kdcs = r.KDC
-			break
+func (cl *Client) resolveKDC(realm string, tcp bool) (int, map[int]string, error) {
+	kdcs := make(map[int]string)
+	var count int
+
+	// Use DNS to resolve kerberos SRV records if configured to do so in krb5.conf.
+	if cl.Config.LibDefaults.DNSLookupKDC {
+		proto := "udp"
+		if tcp {
+			proto = "tcp"
+		}
+		c, addrs, err := dnsutils.OrderedSRV("kerberos", proto, realm)
+		if err != nil {
+			return count, kdcs, err
+		}
+		if len(addrs) < 1 {
+			return count, kdcs, fmt.Errorf("no KDC SRV records found for realm %s", realm)
+		}
+		count = c
+		for k, v := range addrs {
+			kdcs[k] = strings.TrimRight(v.Target, ".") + ":" + strconv.Itoa(int(v.Port))
 		}
-	}
-	if len(kdcs) < 1 {
-		return rb, fmt.Errorf("No KDCs defined in configuration for realm: %v", cl.Config.LibDefaults.DefaultRealm)
-	}
-	var kdc string
-	if len(kdcs) > 1 {
-		//Select one of the KDCs at random
-		kdc = kdcs[rand.Intn(len(kdcs))]
 	} else {
-		kdc = kdcs[0]
+		// Get the KDCs from the krb5.conf an order them randomly for preference.
+		var ks []string
+		for _, r := range cl.Config.Realms {
+			if r.Realm == realm {
+				ks = r.KDC
+				break
+			}
+		}
+		count = len(ks)
+		if count < 1 {
+			return count, kdcs, fmt.Errorf("no KDCs defined in configuration for realm %s", realm)
+		}
+		i := 1
+		if count > 1 {
+			l := len(ks)
+			for l > 0 {
+				ri := rand.Intn(l)
+				kdcs[i] = ks[ri]
+				if l > 1 {
+					// Remove the entry from the source slice by swapping with the last entry and truncating
+					ks[len(ks)-1], ks[ri] = ks[ri], ks[len(ks)-1]
+					ks = ks[:len(ks)-1]
+					l = len(ks)
+				} else {
+					l = 0
+				}
+				i += 1
+			}
+		} else {
+			kdcs[i] = ks[0]
+		}
 	}
+	return count, kdcs, nil
+}
 
+// SendToKDC performs network actions to send data to the KDC.
+func (cl *Client) SendToKDC(b []byte, realm string) ([]byte, error) {
+	var rb []byte
 	if cl.Config.LibDefaults.UDPPreferenceLimit == 1 {
 		//1 means we should always use TCP
-		rb, errtcp := sendTCP(kdc, b)
+		rb, errtcp := cl.sendTCP(realm, b)
 		if errtcp != nil {
 			if e, ok := errtcp.(messages.KRBError); ok {
 				return rb, e
 			}
-			return rb, fmt.Errorf("Failed to communicate with KDC %v via TCP (%v)", kdc, errtcp)
-		}
-		if len(rb) < 1 {
-			return rb, fmt.Errorf("No response data from KDC %v", kdc)
+			return rb, fmt.Errorf("communication error with KDC via TCP: %v", errtcp)
 		}
 		return rb, nil
 	}
 	if len(b) <= cl.Config.LibDefaults.UDPPreferenceLimit {
 		//Try UDP first, TCP second
-		rb, errudp := sendUDP(kdc, b)
+		rb, errudp := cl.sendUDP(realm, b)
 		if errudp != nil {
 			if e, ok := errudp.(messages.KRBError); ok && e.ErrorCode != errorcode.KRB_ERR_RESPONSE_TOO_BIG {
 				// Got a KRBError from KDC
@@ -58,82 +97,115 @@ func (cl *Client) SendToKDC(b []byte, realm string) ([]byte, error) {
 				return rb, e
 			}
 			// Try TCP
-			r, errtcp := sendTCP(kdc, b)
+			r, errtcp := cl.sendTCP(realm, b)
 			if errtcp != nil {
 				if e, ok := errtcp.(messages.KRBError); ok {
 					// Got a KRBError
 					return r, e
 				}
-				return r, fmt.Errorf("Failed to communicate with KDC %v. Attempts made with UDP (%v) and then TCP (%v)", kdc, errudp, errtcp)
+				return r, fmt.Errorf("failed to communicate with KDC. Attempts made with UDP (%v) and then TCP (%v)", errudp, errtcp)
 			}
 			rb = r
 		}
-		if len(rb) < 1 {
-			return rb, fmt.Errorf("No response data from KDC %v", kdc)
-		}
 		return rb, nil
 	}
 	//Try TCP first, UDP second
-	rb, errtcp := sendTCP(kdc, b)
+	rb, errtcp := cl.sendTCP(realm, b)
 	if errtcp != nil {
 		if e, ok := errtcp.(messages.KRBError); ok {
 			// Got a KRBError from KDC so returning and not trying UDP.
 			return rb, e
 		}
-		rb, errudp := sendUDP(kdc, b)
+		rb, errudp := cl.sendUDP(realm, b)
 		if errudp != nil {
 			if e, ok := errudp.(messages.KRBError); ok {
 				// Got a KRBError
 				return rb, e
 			}
-			return rb, fmt.Errorf("Failed to communicate with KDC %v. Attempts made with TCP (%v) and then UDP (%v)", kdc, errtcp, errudp)
+			return rb, fmt.Errorf("failed to communicate with KDC. Attempts made with TCP (%v) and then UDP (%v)", errtcp, errudp)
 		}
 	}
-	if len(rb) < 1 {
-		return rb, fmt.Errorf("No response data from KDC %v", kdc)
-	}
 	return rb, nil
 }
 
+func dialKDCUDP(count int, kdcs map[int]string) (conn *net.UDPConn, err error) {
+	i := 1
+	for i <= count {
+		udpAddr, e := net.ResolveUDPAddr("udp", kdcs[i])
+		if e != nil {
+			err = fmt.Errorf("error resolving KDC address: %v", e)
+			return
+		}
+		conn, err = net.DialUDP("udp", nil, udpAddr)
+		if err == nil {
+			conn.SetDeadline(time.Now().Add(time.Duration(5 * time.Second)))
+			return
+		}
+		i += 1
+	}
+	err = errors.New("error in getting a UDP connection to any of the KDCs")
+	return
+}
+
+func dialKDCTCP(count int, kdcs map[int]string) (conn *net.TCPConn, err error) {
+	i := 1
+	for i <= count {
+		tcpAddr, e := net.ResolveTCPAddr("tcp", kdcs[i])
+		if e != nil {
+			err = fmt.Errorf("error resolving KDC address: %v", e)
+			return
+		}
+		conn, err = net.DialTCP("tcp", nil, tcpAddr)
+		if err == nil {
+			conn.SetDeadline(time.Now().Add(time.Duration(5 * time.Second)))
+			return
+		}
+		i += 1
+	}
+	err = errors.New("error in getting a TCP connection to any of the KDCs")
+	return
+}
+
 // Send the bytes to the KDC over UDP.
-func sendUDP(kdc string, b []byte) ([]byte, error) {
+func (cl *Client) sendUDP(realm string, b []byte) ([]byte, error) {
 	var r []byte
-	udpAddr, err := net.ResolveUDPAddr("udp", kdc)
+	count, kdcs, err := cl.resolveKDC(realm, false)
 	if err != nil {
-		return r, fmt.Errorf("Error resolving KDC address: %v", err)
+		return r, err
 	}
-	conn, err := net.DialUDP("udp", nil, udpAddr)
+	conn, err := dialKDCUDP(count, kdcs)
 	if err != nil {
-		return r, fmt.Errorf("Error establishing connection to KDC: %v", err)
+		return r, err
 	}
 	defer conn.Close()
-	conn.SetDeadline(time.Now().Add(time.Duration(5 * time.Second)))
 	_, err = conn.Write(b)
 	if err != nil {
-		return r, fmt.Errorf("Error sending to KDC: %v", err)
+		return r, fmt.Errorf("error sending to KDC (%s): %v", conn.RemoteAddr().String(), err)
 	}
 	udpbuf := make([]byte, 4096)
 	n, _, err := conn.ReadFrom(udpbuf)
 	r = udpbuf[:n]
 	if err != nil {
-		return r, fmt.Errorf("Sending over UDP failed: %v", err)
+		return r, fmt.Errorf("sending over UDP failed to %s: %v", conn.RemoteAddr().String(), err)
+	}
+	if len(r) < 1 {
+		return r, fmt.Errorf("no response data from KDC %s", conn.RemoteAddr().String())
 	}
 	return checkForKRBError(r)
 }
 
 // Send the bytes to the KDC over TCP.
-func sendTCP(kdc string, b []byte) ([]byte, error) {
+func (cl *Client) sendTCP(realm string, b []byte) ([]byte, error) {
 	var r []byte
-	tcpAddr, err := net.ResolveTCPAddr("tcp", kdc)
+	count, kdcs, err := cl.resolveKDC(realm, true)
 	if err != nil {
-		return r, fmt.Errorf("Error resolving KDC address: %v", err)
+		return r, err
 	}
-	conn, err := net.DialTCP("tcp", nil, tcpAddr)
+	conn, err := dialKDCTCP(count, kdcs)
 	if err != nil {
-		return r, fmt.Errorf("Error establishing connection to KDC: %v", err)
+		return r, err
 	}
 	defer conn.Close()
-	conn.SetDeadline(time.Now().Add(time.Duration(5 * time.Second)))
 
 	/*
 		RFC https://tools.ietf.org/html/rfc4120#section-7.2.2
@@ -153,7 +225,7 @@ func sendTCP(kdc string, b []byte) ([]byte, error) {
 
 	_, err = conn.Write(b)
 	if err != nil {
-		return r, fmt.Errorf("Error sending to KDC: %v", err)
+		return r, fmt.Errorf("error sending to KDC (%s): %v", conn.RemoteAddr().String(), err)
 	}
 
 	sh := make([]byte, 4, 4)
@@ -168,7 +240,9 @@ func sendTCP(kdc string, b []byte) ([]byte, error) {
 	if err != nil {
 		return r, fmt.Errorf("error reading response: %v", err)
 	}
-
+	if len(rb) < 1 {
+		return r, fmt.Errorf("no response data from KDC %s", conn.RemoteAddr().String())
+	}
 	return checkForKRBError(rb)
 }
 

+ 1 - 0
testdata/test_vectors.go

@@ -132,6 +132,7 @@ const (
 	TEST_KDC_AD                   = "10.80.88.68:88"
 	TEST_KDC_AD_TRUST_USER_DOMAIN = "10.80.88.48:88"
 	TEST_KDC_AD_TRUST_RES_DOMAIN  = "10.80.88.49:88"
+	TEST_NS                       = "10.80.88.88:53"
 	TEST_KRB5CONF                 = `[libdefaults]
   default_realm = TEST.GOKRB5
   dns_lookup_realm = false

+ 22 - 0
testenv/docker/dns/Dockerfile

@@ -0,0 +1,22 @@
+FROM debian:latest
+MAINTAINER Jonathan Turner <jt@jtnet.co.uk>
+
+EXPOSE 53
+
+ENTRYPOINT ["/var/named/named.sh"]
+
+ENV DEBIAN_FRONTEND noninteractive
+RUN apt-get update && apt-get install -y bind9 && \
+  mkdir -p /var/named/data && \
+  mkdir -p /var/named/dynamic && \
+  chown -R bind /var/named && \
+  mkdir -p /etc/named && \
+  mkdir -p /var/run/named && chown bind /var/run/named
+
+ADD files/etc-named.conf /etc/named.conf
+ADD files/gokrb5.conf /etc/named/gokrb5.conf
+ADD files/zone-files/db.10 /var/named/data/
+ADD files/zone-files/db.test.gokrb5 /var/named/data/
+ADD files/named.sh /var/named/named.sh
+
+RUN chmod 744 /var/named/named.sh

+ 32 - 0
testenv/docker/dns/files/etc-named.conf

@@ -0,0 +1,32 @@
+options {
+	directory 	"/var/named";
+	dump-file 	"/var/named/data/cache_dump.db";
+        statistics-file "/var/named/data/named_stats.txt";
+        memstatistics-file "/var/named/data/named_mem_stats.txt";
+	allow-query     { localhost; 10.0.0.0/8; 172.17.0.0/16; 172.18.0.0/16; };
+	recursion yes;
+
+	dnssec-enable yes;
+	dnssec-validation yes;
+	dnssec-lookaside auto;
+
+	/* Path to ISC DLV key */
+	bindkeys-file "/etc/bind/bind.keys";
+
+	managed-keys-directory "/var/named/dynamic";
+
+	pid-file "/run/named/named.pid";
+	session-keyfile "/run/named/session.key";
+};
+
+logging {
+        channel default_debug {
+                file "data/named.run";
+                severity dynamic;
+        };
+};
+
+include "/etc/bind/named.conf.local";
+include "/etc/bind/named.conf.default-zones";
+include "/etc/bind/bind.keys";
+include "/etc/named/gokrb5.conf";

+ 9 - 0
testenv/docker/dns/files/gokrb5.conf

@@ -0,0 +1,9 @@
+zone "test.gokrb5" {
+	type master;
+	file "/var/named/data/db.test.gokrb5";
+};
+
+zone "10.in-addr.arpa" {
+	type master;
+	file "/var/named/data/db.10";
+};

+ 5 - 0
testenv/docker/dns/files/named.sh

@@ -0,0 +1,5 @@
+#!/bin/bash
+
+sed -i "s/<TEST_KDC_ADDR>/${TEST_KDC_ADDR}/g" /var/named/data/db.test.gokrb5
+
+/usr/sbin/named -g -c /etc/named.conf -u bind -4

+ 13 - 0
testenv/docker/dns/files/zone-files/db.10

@@ -0,0 +1,13 @@
+;
+; BIND reverse data file for 10.x.x.x
+;
+$TTL	604800
+@	IN	SOA	test.gokrb5. host.test.gokrb5. (
+			2017112701 	; Serial
+			 604800		; Refresh
+			  86400		; Retry
+			2419200		; Expire
+			 604800 )	; Negative Cache TTL
+;
+@	IN	NS	test.gokrb5.
+88.88.80 IN  PTR host.test.gokrb5.

+ 29 - 0
testenv/docker/dns/files/zone-files/db.test.gokrb5

@@ -0,0 +1,29 @@
+$ORIGIN .
+$TTL 86400	; 1 day
+test.gokrb5		IN SOA	test.gokrb5. ns.test.gokrb5. (
+				2017112801 ; serial
+				604800     ; refresh (1 week)
+				86400      ; retry (1 day)
+				2419200    ; expire (4 weeks)
+				86400      ; minimum (1 day)
+				)
+			NS	test.gokrb5.
+			A	10.80.88.88
+$ORIGIN _tcp.test.gokrb5.
+_kerberos		IN	SRV	0 0 88 kdc.test.gokrb5.
+_kerberos		IN	SRV	1 100 88 kdc1a.test.gokrb5.
+_kerberos		IN	SRV	1 50 88 kdc1b.test.gokrb5.
+_kerberos		IN	SRV	2 100 88 kdc2a.test.gokrb5.
+_kerberos		IN	SRV	2 100 88 kdc2b.test.gokrb5.
+$ORIGIN _udp.test.gokrb5.
+_kerberos		IN	SRV	0 0 88 kdc.test.gokrb5.
+_kerberos		IN	SRV	1 100 88 kdc1a.test.gokrb5.
+_kerberos		IN	SRV	1 50 88 kdc1b.test.gokrb5.
+_kerberos		IN	SRV	2 100 88 kdc2a.test.gokrb5.
+_kerberos		IN	SRV	2 100 88 kdc2b.test.gokrb5.
+$ORIGIN test.gokrb5.
+kdc		IN	A	<TEST_KDC_ADDR>
+kdc1a	IN	A	<TEST_KDC_ADDR>
+kdc1b	IN	A	<TEST_KDC_ADDR>
+kdc2a	IN	A	<TEST_KDC_ADDR>
+kdc2b	IN	A	<TEST_KDC_ADDR>

+ 2 - 1
testenv/mit-krb5kdc/bootstrap.sh

@@ -26,13 +26,14 @@ EOF
 
 cp /vagrant/krb5.conf /etc/krb5.conf
 cp /vagrant/*.service /etc/systemd/system/
-systemctl enable krb5kdc krb5kdc-latest krb5kdc-older httpd
+systemctl enable krb5kdc krb5kdc-latest krb5kdc-older httpd dns
 
 
 /usr/bin/docker pull jcmturner/gokrb5:http
 /usr/bin/docker pull jcmturner/gokrb5:kdc-centos-default
 /usr/bin/docker pull jcmturner/gokrb5:kdc-older
 /usr/bin/docker pull jcmturner/gokrb5:kdc-latest
+/usr/bin/docker pull jcmturner/gokrb5:dns
 
 
 reboot

+ 21 - 0
testenv/mit-krb5kdc/dns.service

@@ -0,0 +1,21 @@
+[Unit]
+Description=DNS
+After=docker.service
+After=network.target
+Requires=docker.service
+
+[Service]
+Environment="DOCKER_IMAGE=jcmturner/gokrb5:dns"
+Environment="PORT=53"
+Environment="TEST_KDC_ADDR=10.80.88.88"
+TimeoutStartSec=0
+#Restart=always
+ExecStartPre=-/usr/bin/docker kill %n
+ExecStartPre=-/usr/bin/docker rm %n
+ExecStartPre=-/usr/bin/docker pull ${DOCKER_IMAGE}
+ExecStart=/usr/bin/docker run -h kdc.test.gokrb5 -v /etc/localtime:/etc/localtime:ro -e "TEST_KDC_ADDR=${TEST_KDC_ADDR}" -p ${PORT}:${PORT} -p ${PORT}:${PORT}/udp --rm --name ${NAME} ${DOCKER_IMAGE}
+ExecStop=/usr/bin/docker stop --time=60 %n
+ExecStopPost=-/usr/bin/docker rm %n
+
+[Install]
+WantedBy=multi-user.target