[PATCH/smart-proxy 1/1] Windows DNS: Secure connection using GSS-TSIG #1685

Signed-off-by: theforemanuser123 <oliver_weinmann@gmx.de>

··· --- config/settings.yml.example | 3 ++ lib/proxy/dns/bind.rb | 77 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/config/settings.yml.example b/config/settings.yml.example
index b472a13…ac17eaa 100644
— a/config/settings.yml.example
+++ b/config/settings.yml.example
@@ -31,6 +31,9 @@
:dns: false
#:dns_key: /etc/rndc.key

use this setting if you are managing a dns server which is not localhost though this proxy

+#:dns_tsig_keytab: /usr/share/smart-proxy/dns.keytab
+#:dns_tsig_principal: domainuser
+# use these two settings if you want to securely manage a ms dns server using GSS-TSIG
#:dns_server: dns.domain.com

Enable DHCP management

diff --git a/lib/proxy/dns/bind.rb b/lib/proxy/dns/bind.rb
index 1b7785f…81f8e3e 100644
— a/lib/proxy/dns/bind.rb
+++ b/lib/proxy/dns/bind.rb
@@ -1,5 +1,6 @@
require "proxy/dns"
require ‘resolv’
+require ‘date’

module Proxy::DNS
class Bind < Record
@@ -50,6 +51,31 @@ module Proxy::DNS
nsupdate "disconnect"
end

  • private

  • def nsupdate_args

  •    args = ""
    
  •    if SETTINGS.dns_key
    
  •    args += "-k #{SETTINGS.dns_key} "
    
  •            end
    
  •            if SETTINGS.dns_tsig_keytab
    
  •    args += "-g "
    
  •            logger.debug "DNS TSIG authentication enabled."
    
  •    end
    
  •  args
    
  • end

  • def kinit_args

  •    args = ""
    
  •    if SETTINGS.dns_tsig_keytab
    
  •    args += "-F -k "
    
  •    args += "-t #{SETTINGS.dns_tsig_keytab} "
    
  •    args += "#{SETTINGS.dns_tsig_principal}"
    
  •            logger.debug "kinit #{args}."
    
  •    end
    
  •  args
    
  • end

  • private

    def find_nsupdate
    @@ -60,11 +86,60 @@ module Proxy::DNS
    end
    end

  • def find_kinit

  •  @kinit = which("kinit", "/usr/bin")
    
  •  unless File.exists?("#{@kinit}")
    
  •    logger.warn "unable to find kinit binary, maybe missing krb5-user package?"
    
  •    raise "unable to find kinit binary"
    
  •  end
    
  • end

  • def find_krb5tgt

  • @krb5tgt = system("klist | grep -i #{SETTINGS.dns_tsig_principal} 2>&1")
    
  •  if @krb5tgt == false
    
  •   @exp = 1
    
  •    @now = 0
    
  •    @loggermsg = "unable to find kerberos ticket. Trying to aquire a valid TGT..."
    
  •    @raisemsg = "unable to find kerberos ticket. Trying to aquire a valid TGT..."
    
  •    kinit
    
  •  else
    
  •    @format = "%d/%m/%y %H:%M"
    
  •    @krbexp = `klist | grep A.SPACE.CORP | grep '/' | awk -F ' ' '{print $3,$4}'`
    
  •    @exp = DateTime.strptime(@krbexp, @format)
    
  •    @now = DateTime.now
    
  •  end
    
  •  if @now > @exp
    
  •   logger.warn @logger_msg
    
  •   kinit
    
  •   raise @raise_msg
    
  •  else
    
  •   logger.warn "Kerberos ticket still valid. Not aquiring new ticket."
    
  •  end
    
  • end

  • def kinit

  • status = nil
    
  •  find_kinit if @kinit.nil?
    
  •    @om = IO.popen("#{@kinit} #{kinit_args}", "r+")
    
  •    @om.close_write
    
  •    status = @om.readlines
    
  •    @om.close
    
  •    @om = nil # we cannot serialize an IO object, even if closed.
    
  •    # TODO Parse output for errors!
    
  •    if !status.empty? and status[1] !~ /status: NOERROR/
    
  •    logger.debug "kinit: errors\n" + status.join("\n")
    
  •    raise Proxy::DNS::Error.new("Update errors: #{status.join("\n")}")
    
  •   end
    
  • end

  • def nsupdate cmd
    status = nil
    if cmd == "connect"
    find_nsupdate if @nsupdate.nil?

  •    @om = IO.popen("#{@nsupdate} #{SETTINGS.dns_key ? "-k " + SETTINGS.dns_key : ""}", "r+")
    
  •   if SETTINGS.dns_tsig_keytab
    
  •      find_krb5tgt
    
  •    end
    
  •    @om = IO.popen("#{@nsupdate} #{nsupdate_args}", "r+")
       @om.puts "server #{@server}"
     elsif cmd == "disconnect"
       @om.puts "send"
    


1.7.9.5

thanks!, see my comments at

Ohad

··· On Thu, Aug 9, 2012 at 5:10 PM, theforemanuser123 wrote:

Signed-off-by: theforemanuser123 oliver_weinmann@gmx.de

config/settings.yml.example | 3 ++
lib/proxy/dns/bind.rb | 77
+++++++++++++++++++++++++++++++++++++++++±
2 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/config/settings.yml.example b/config/settings.yml.example
index b472a13…ac17eaa 100644
— a/config/settings.yml.example
+++ b/config/settings.yml.example
@@ -31,6 +31,9 @@
:dns: false
#:dns_key: /etc/rndc.key

use this setting if you are managing a dns server which is not

localhost though this proxy
+#:dns_tsig_keytab: /usr/share/smart-proxy/dns.keytab
+#:dns_tsig_principal: domainuser
+# use these two settings if you want to securely manage a ms dns server
using GSS-TSIG
#:dns_server: dns.domain.com

Enable DHCP management

diff --git a/lib/proxy/dns/bind.rb b/lib/proxy/dns/bind.rb
index 1b7785f…81f8e3e 100644
— a/lib/proxy/dns/bind.rb
+++ b/lib/proxy/dns/bind.rb
@@ -1,5 +1,6 @@
require “proxy/dns”
require ‘resolv’
+require ‘date’

module Proxy::DNS
class Bind < Record
@@ -50,6 +51,31 @@ module Proxy::DNS
nsupdate “disconnect”
end

  •   private
    
  • def nsupdate_args

  •    args = ""
    
  •    if SETTINGS.dns_key
    
  •    args += "-k #{SETTINGS.dns_key} "
    
  •            end
    
  •            if SETTINGS.dns_tsig_keytab
    
  •    args += "-g "
    
  •            logger.debug "DNS TSIG authentication enabled."
    
  •    end
    
  •  args
    
  • end

  • def kinit_args

  •    args = ""
    
  •    if SETTINGS.dns_tsig_keytab
    
  •    args += "-F -k "
    
  •    args += "-t #{SETTINGS.dns_tsig_keytab} "
    
  •    args += "#{SETTINGS.dns_tsig_principal}"
    
  •            logger.debug "kinit #{args}."
    
  •    end
    
  •  args
    
  • end

  • private

    def find_nsupdate
    @@ -60,11 +86,60 @@ module Proxy::DNS
    end
    end

  •   def find_kinit
    
  •  @kinit = which("kinit", "/usr/bin")
    
  •  unless File.exists?("#{@kinit}")
    
  •    logger.warn "unable to find kinit binary, maybe missing krb5-user
    

package?"

  •    raise "unable to find kinit binary"
    
  •  end
    
  • end
  •   def find_krb5tgt
    
  •     @krb5tgt = system("klist | grep -i
    

#{SETTINGS.dns_tsig_principal} 2>&1")

  •  if @krb5tgt == false
    
  •           @exp = 1
    
  •    @now = 0
    
  •    @loggermsg = "unable to find kerberos ticket. Trying to aquire a
    

valid TGT…"

  •    @raisemsg = "unable to find kerberos ticket. Trying to aquire a
    

valid TGT…"

  •    kinit
    
  •  else
    
  •    @format = "%d/%m/%y %H:%M"
    
  •    @krbexp = `klist | grep A.SPACE.CORP | grep '/' | awk -F ' '
    

‘{print $3,$4}’`

  •    @exp = DateTime.strptime(@krbexp, @format)
    
  •    @now = DateTime.now
    
  •  end
    
  •  if @now > @exp
    
  •           logger.warn @logger_msg
    
  •           kinit
    
  •           raise @raise_msg
    
  •  else
    
  •           logger.warn "Kerberos ticket still valid. Not aquiring new
    

ticket."

  •  end
    
  • end
  •   def kinit
    
  •     status = nil
    
  •  find_kinit if @kinit.nil?
    
  •    @om = IO.popen("#{@kinit} #{kinit_args}", "r+")
    
  •    @om.close_write
    
  •    status = @om.readlines
    
  •    @om.close
    
  •    @om = nil # we cannot serialize an IO object, even if closed.
    
  •    # TODO Parse output for errors!
    
  •    if !status.empty? and status[1] !~ /status: NOERROR/
    
  •    logger.debug "kinit: errors\n" + status.join("\n")
    
  •    raise Proxy::DNS::Error.new("Update errors: #{status.join("\n")}")
    
  •           end
    
  • end
  • def nsupdate cmd
    status = nil
    if cmd == “connect”
    find_nsupdate if @nsupdate.nil?
  •    @om = IO.popen("#{@nsupdate} #{SETTINGS.dns_key ? "-k " +
    

SETTINGS.dns_key : “”}", “r+”)

  •           if SETTINGS.dns_tsig_keytab
    
  •      find_krb5tgt
    
  •    end
    
  •    @om = IO.popen("#{@nsupdate} #{nsupdate_args}", "r+")
       @om.puts "server #{@server}"
     elsif cmd == "disconnect"
       @om.puts "send"
    


1.7.9.5