Project

General

Profile

Feature #1685

Windows DNS: Secure connection using GSS-TSIG

Added by Oliver Weinmann about 7 years ago. Updated about 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
DNS
Target version:
Difficulty:
Triaged:
No
Bugzilla link:
Pull request:
Team Backlog:
Fixed in Releases:
Found in Releases:

Description

Hi,

we are using foreman in our heterogenous windows / linux environment. Our Master DNS servers are running on Windows / Active Directory. It is a big security issue to leave the dynamic updates on "Nonsecure and secure". I know that foreman is using nsupdate to update dns records. This supports GSS-TSIG to securely communicate with Windows DNS servers. I have tested this on a Ubuntu 12.04 machine and I can manipulate Windows DNS servers using nsupdate with GSS-TSIG just fine.

The following blog post put me in the right direction: http://blog.michael.kuron-germany.de/2011/02/isc-dhcpd-dynamic-dns-updates-against-secure-microsoft-dns/

Basically all that is needed is a keytab file, so a valid username and password that can connect to AD:

keytab can be generated using
$ ktutil
ktutil: addent -password -p -k 1 -e aes256-cts-hmac-sha1-96
Password for :
ktutil: wkt dnsuser.keytab
ktutil: quit

With the keytab created, nsupdate can be run with the "-g" switch to enable secure GSS-TSIG communication.

My ruby skills are absolutely zero and I only have a stable foreman environment setup here at work. I'm happy to setup a new foreman dev environment and to test. :)

Regards,
Oliver


Related issues

Related to Smart Proxy - Feature #1809: Smart-Proxy control of IPA ServerClosed2012-08-06
Has duplicate Smart Proxy - Feature #61: Add Microsoft DNS SupportResolved2009-11-05

Associated revisions

Revision 7e72434b (diff)
Added by Dominic Cleal about 6 years ago

fixes #1685 - GSS-TSIG support for DNS updates

History

#1 Updated by Ohad Levy about 7 years ago

Thanks Oliver!

this is surely a big step in the right direction, and I assume should not be more then a bit of documentation and a configuration value.

thanks for your help.

if you are interested to solve it your self, you can simply try to add it to this line https://github.com/theforeman/smart-proxy/blob/develop/lib/proxy/dns/bind.rb#L67

#2 Updated by Oliver Weinmann about 7 years ago

I also think this shouldn't be too hard to accomplish even with almost no ruby skills. I will start setting up a new foreman dev environment with a Windows 2003 and 2008 Server at home and try to change the code so it uses the -g switch. The creation of the keytab file will be manually on the cmdline for now. Maybe someone can include this in the GUI Settings later on.

Thanks for the link, that points me in the right direction.

Oliver

#3 Updated by Ohad Levy about 7 years ago

I would extracting the parameter handling into a seperate method, e.g. something like that

change the relevant line to

@om = IO.popen("#{@nsupdate} #{nsupdate_args}", "r+")

and add a new method

private
def nsupdate_args
  args = "" 
  if SETTINGS.dns_key
    args += "-k #{SETTINGS.dns_key} " 
    args += "-g " if SETTINGS.dns_tsig # need to add that setting

  end
  args
end

#4 Updated by Oliver Weinmann about 7 years ago

Hi Ohad,

I tried to setup a fresh ubuntu 12.04 box with latest foreman dev installed, but unfortunately the company I work for, has blocked git (in and outgoing) and I'm not able to download the latest foreman dev using the bundler script. This also means that I'm not able to push any changes via git to the repo. :(

To test this at home I have to setup a win2k8 r2 server and a ubuntu box. This will take some time... I don't think I have this fixed for the 1.0 release.

Regards,
Oliver

#5 Updated by Ohad Levy about 7 years ago

git can work over https, just change all of the git:// to https://

#6 Updated by Oliver Weinmann about 7 years ago

Thanks. I was now able to pull the dev version, but:

You can run Foreman with the command "RAILS_ENV=production rails s"

this just creates files below my /usr/share/foreman folder but no webrick is started?

How do I start the webrick server?

#7 Updated by Oliver Weinmann almost 7 years ago

Ok,

Took a long long time but... I got it working. :)

I will clean up the code a little bit and then push it.

Regards,
Oliver

#8 Updated by Oliver Weinmann almost 7 years ago

Submitted a patch. :)

#9 Updated by Ohad Levy almost 7 years ago

Oliver Weinmann wrote:

Submitted a patch. :)

where is it ? :)

#10 Updated by Oliver Weinmann almost 7 years ago

I have no github account so I used the old way:

root@ubuntu120464:/usr/share/smart-proxy# rake mail_patches WARNING: 'require 'rake/rdoctask'' is deprecated. Please use 'require 'rdoc/task' (in RDoc 2.4.2+)' instead.
at /usr/lib/ruby/vendor_ruby/rake/rdoctask.rb
rake/gempackagetask is deprecated. Use rubygems/package_task instead
git format-patch -C -M -s -n --subject-prefix='PATCH/smart-proxy' origin/develop
0001-Windows-DNS-Secure-connection-using-GSS-TSIG-1685.patch
git send-email --no-signed-off-by-cc --suppress-from --to 00*.patch
0001-Windows-DNS-Secure-connection-using-GSS-TSIG-1685.patch
Who should the emails appear to be from? [theforemanuser123 <>]
Emails will be sent from: theforemanuser123 <>
Message-ID to be used as In-Reply-To for the first email?
OK. Log says:
Sendmail: /usr/sbin/sendmail -i
From: theforemanuser123 <>
To:
Subject: [PATCH/smart-proxy 1/1] Windows DNS: Secure connection using GSS-TSIG #1685
Date: Thu, 9 Aug 2012 15:50:25 +0200
Message-Id: <>
X-Mailer: git-send-email 1.7.9.5

Result: OK
In git 1.7.0, the default has changed to --no-chain-reply-to
Set sendemail.chainreplyto configuration variable to true if
you want to keep --chain-reply-to as your default.
rm 00*.patch

Does this look good?

#11 Updated by Florent Delvaille over 6 years ago

Hep,

I implemented the thing but even if foreman-proxy logs says the entries are created, they are not created in the MS DNS Server.

Here is a pastie of all interesting things: http://pastie.org/6073962

Regards;

#12 Updated by Oliver Weinmann over 6 years ago

Hi,

what foreman version are you using?

Can you please try to manaully create a dns record using the nsupdate command.

e.g.

nsupdate -g
server yourdnsserver
realm yourkrb5realm
update add testhost123.your.domain 3600 A 192.168.100.1
send
UPDATE

I really want to see this feature included in Foreman 1.1 but no one really wants to test it. :)

#13 Updated by Florent Delvaille over 6 years ago

Hep,

I am using Foreman 1.1RC5

Here is the result of our tests:

/etc/krb5.conf
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log

[libdefaults]
default_realm = ONPRVP.FGOV.BE
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true

[realms]
ONPRVP.FGOV.BE = {
default_domain = onprvp.fgov.be
}

[domain_realm]
.onprvp.fgov.be = ONPRVP.FGOV.BE

root@lpr-mgmt01 foreman-proxy]# ktutil
ktutil: addent -password -p -k 1 -e aes256-cts-hmac-sha1-96
Password for :
ktutil: wkt dns.keytab
ktutil: quit
[root@lpr-mgmt01 foreman-proxy]# kinit -F -k -t /usr/share/foreman-proxy/dns.keytab
[root@lpr-mgmt01 foreman-proxy]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal:

Valid starting Expires Service principal
02/06/13 15:43:21 02/07/13 01:43:21
renew until 02/13/13 15:43:21

[root@lpr-mgmt01 foreman-proxy]# nsupdate -g

server spr-cen01.onprvp.fgov.be
realm ONPRVP.FGOV.BE
update add ldv-demo01.onprvp.fgov.be 3600 A 192.168.151.191
send

Result:
devaf@PC-20100257LINUX:~$ nslookup ldv-demo01
Server: 192.168.147.31
Address: 192.168.147.31#53

Name: ldv-demo01.onprvp.fgov.be
Address: 192.168.151.191

In foreman when creating the host: Error400 BAD REQUEST
Here is the logs of foreman-proxy with strange error:
D, [2013-02-06T15:49:35.483188 #15542] DEBUG -- : omshell: executed - set name = "ldv-demo01.onprvp.fgov.be"
D, [2013-02-06T15:49:35.483771 #15542] DEBUG -- : true
D, [2013-02-06T15:49:35.483853 #15542] DEBUG -- : omshell: executed - set ip-address = 192.168.151.191
D, [2013-02-06T15:49:35.483907 #15542] DEBUG -- : true
D, [2013-02-06T15:49:35.483983 #15542] DEBUG -- : omshell: executed - set hardware-address = 00:50:56:af:70:0a
D, [2013-02-06T15:49:35.484100 #15542] DEBUG -- : true
D, [2013-02-06T15:49:35.484203 #15542] DEBUG -- : omshell: executed - set hardware-type = 1
D, [2013-02-06T15:49:35.484259 #15542] DEBUG -- : true
D, [2013-02-06T15:49:35.484382 #15542] DEBUG -- : omshell: executed - set statements = "filename = \"pxelinux.0\"; next-server = c0:a8:97:6f; option host-name = \"ldv-demo01.onprvp.fgov.be\";"
D, [2013-02-06T15:49:35.484462 #15542] DEBUG -- : true
D, [2013-02-06T15:49:35.484537 #15542] DEBUG -- : omshell: executed - create
D, [2013-02-06T15:49:35.484592 #15542] DEBUG -- : true
I, [2013-02-06T15:49:35.489947 #15542] INFO -- : Added DHCP reservation for ldv-demo01.onprvp.fgov.be (192.168.151.191 / 00:50:56:af:70:0a)
E, [2013-02-06T15:49:35.675832 #15542] ERROR -- : invalid date
D, [2013-02-06T15:49:35.675933 #15542] DEBUG -- : /usr/lib/ruby/1.8/date.rb:1576:in `new_by_frags'
/usr/lib/ruby/1.8/date.rb:1601:in `strptime'
/usr/share/foreman-proxy/bin/../lib/proxy/dns/bind.rb:102:in `find_krb5tgt'
/usr/share/foreman-proxy/bin/../lib/proxy/dns/bind.rb:134:in `nsupdate'
/usr/share/foreman-proxy/bin/../lib/proxy/dns/bind.rb:20:in `create'
/usr/share/foreman-proxy/bin/../lib/dns_api.rb:14:in `POST /dns/'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:1032:in `call'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:1032:in `compile!'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:620:in `instance_eval'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:620:in `route_eval'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:604:in `route!'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:656:in `process_route'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:653:in `catch'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:653:in `process_route'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:603:in `route!'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:602:in `each'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:602:in `route!'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:741:in `dispatch!'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:530:in `call!'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:706:in `instance_eval'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:706:in `invoke'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:706:in `catch'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:706:in `invoke'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:530:in `call!'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:516:in `call'
/usr/lib/ruby/gems/1.8/gems/rack-1.2.5/lib/rack/methodoverride.rb:24:in `call'
/usr/lib/ruby/gems/1.8/gems/rack-1.2.5/lib/rack/showexceptions.rb:24:in `call'
/usr/lib/ruby/gems/1.8/gems/rack-1.2.5/lib/rack/commonlogger.rb:18:in `call'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:1142:in `call'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:1168:in `synchronize'
/usr/lib/ruby/gems/1.8/gems/sinatra-1.1.0/lib/sinatra/base.rb:1142:in `call'
/usr/lib/ruby/gems/1.8/gems/rack-1.2.5/lib/rack/content_length.rb:13:in `call'
/usr/lib/ruby/gems/1.8/gems/rack-1.2.5/lib/rack/handler/webrick.rb:52:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/usr/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/usr/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/usr/lib/ruby/1.8/webrick/server.rb:95:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `each'
/usr/lib/ruby/1.8/webrick/server.rb:92:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:23:in `start'
/usr/lib/ruby/1.8/webrick/server.rb:82:in `start'
/usr/lib/ruby/gems/1.8/gems/rack-1.2.5/lib/rack/handler/webrick.rb:13:in `run'
/usr/share/foreman-proxy/bin/../lib/sinatra-patch.rb:42:in `run!'
/usr/share/foreman-proxy/bin/smart-proxy:44

#14 Updated by Oliver Weinmann over 6 years ago

I think the problem is that I've written this patch for a much older foreman release and it was working fine. When I upgraded to Foreman 1.0 I saw the same error message:

E, [2013-02-06T15:49:35.675832 #15542] ERROR -- : invalid date

I think this is related to a ruby update that has broken a few lines of code that I was using to determine if the kerberos ticket was still valid.

I'm not a ruby code expert and It was really hard for me to even write these few lines of code. Do you have any experience in ruby coding??

#15 Updated by Florent Delvaille over 6 years ago

Unfortunately not at all.
But since it was working for you and then suddenly it does not anymore in 1.0 ... and since we have the same error ... I assume the problem is somewhere else.

Hope to get somebody to help us with this, coz it is almost OK :-)

#16 Updated by Oliver Weinmann over 6 years ago

If I find some time today I might setup a fresh 1.0 install and try this patch myself. I have asked many many times in the irc channel for help with this, but unfortunately no one seems to have some spare time to test and fix it. I was asked to clean up the code by the foreman maintainers, but unfortunately my coding skills are nearly zero. 

#17 Updated by Florent Delvaille over 6 years ago

Please have a look at https://github.com/theforeman/smart-proxy/pull/29/files
Then it will work :)

#18 Updated by Oliver Weinmann over 6 years ago

What do you mean? Does the code that I (r0k5t4r) have reworked work for you?

#19 Updated by Florent Delvaille over 6 years ago

Yes, the one with the third parameter.
It worked perfectly …

#20 Updated by Oliver Weinmann over 6 years ago

Hi,

glad to hear that my code actually works. I guess all that is left to do is to clean it up and include it in the next stable release 1.1.

I will try to get a hold of one of the maintainers if they can clean up the code and include it.

Thanks a lot for testing. Would you also be happy to test the final code?

Cheers,
Oli

#21 Updated by Florent Delvaille over 6 years ago

I think there is still a problem.
We had the thing working perfectly yesterday … today was FAIL …

Apparently every day the kerberos ticket must be recreated. I am not a ruby expert but apparently your code takes care of this …

But we are almost sure that the dns.keytab must also be regenerated every day … does this make sense to you ?

By deleting only the ticket, foreman wasnt able to create the dns record. After deletion/recreation of the dns.keytab it works.

Thx for any feedback.

About final code, yeah we will test it :)

#22 Updated by Oliver Weinmann over 6 years ago

As far as I can remember the dns.keytab doesn't have to be renewed every day.

It was working all the time without renewing the keytab.

I need to get my testsystem up and running to check what is going on.

Regards,
Oliver

#23 Updated by Florent Delvaille over 6 years ago

I did a new test this morning, and not working anymore.
The proxy logs say:

W, [2013-02-09T10:47:52.017939 #16239] WARN -- : Kerberos ticket still valid. Not aquiring new ticket.
D, [2013-02-09T10:47:52.018063 #16239] DEBUG -- : DNS TSIG authentication enabled.
D, [2013-02-09T10:47:52.024508 #16239] DEBUG -- : nsupdate: executed - update add ldv-demo04.onprvp.fgov.be. 86400 A 192.168.151.190
W, [2013-02-09T10:47:52.233962 #16239] WARN -- : Kerberos ticket still valid. Not aquiring new ticket.
D, [2013-02-09T10:47:52.234070 #16239] DEBUG -- : DNS TSIG authentication enabled.
D, [2013-02-09T10:47:52.237497 #16239] DEBUG -- : nsupdate: executed - update add 190.151.168.192.in-addr.arpa. 86400 IN PTR ldv-demo04.onprvp.fgov.be

But nothing in the DNS server.
I deleted the file /tmp/krb5cc_438 (only krb file in /tmp), deleted and recreated the host, and now it works.

W, [2013-02-09T10:53:12.709908 #16239] WARN -- : unable to find kerberos ticket. Trying to aquire a valid TGT...
D, [2013-02-09T10:53:12.710107 #16239] DEBUG -- : kinit F -k -t /usr/share/foreman-proxy/dns.keytab .
D, [2013-02-09T10:53:12.785197 #16239] DEBUG -
: DNS TSIG authentication enabled.
D, [2013-02-09T10:53:12.792365 #16239] DEBUG -- : nsupdate: executed - update add ldv-demo04.onprvp.fgov.be. 86400 A 192.168.151.190
W, [2013-02-09T10:53:13.013859 #16239] WARN -- : Kerberos ticket still valid. Not aquiring new ticket.
D, [2013-02-09T10:53:13.013954 #16239] DEBUG -- : DNS TSIG authentication enabled.
D, [2013-02-09T10:53:13.016803 #16239] DEBUG -- : nsupdate: executed - update add 190.151.168.192.in-addr.arpa. 86400 IN PTR ldv-demo04.onprvp.fgov.be

Here is the content of krb ticket before deletion:

root@lpr-mgmt01 ~]# klist /tmp/krb5cc_438
Ticket cache: FILE:/tmp/krb5cc_438
Default principal:

Valid starting Expires Service principal
02/08/13 13:12:45 02/08/13 23:12:45
renew until 02/09/13 13:12:45
02/08/13 13:12:45 02/08/13 23:12:45
renew until 02/09/13 13:12:45

I am surprised to see 2 entries … but well anyway …
Your patch do the following:

klist | grep #{SETTINGS.dns_tsig_realm} | grep '/' | awk -F ' ' '{print $3,$4}'
In our case, dns_tsig_realm = ONPRVP.FGOV.BE,
so …

[root@lpr-mgmt01 tmp]# klist /tmp/krb5cc_438 | grep ONPRVP.FGOV.BE | grep '/' | awk -F ' ' '{print $3,$4}'
02/08/13 23:12:45
02/08/13 23:12:45

I did the test not working this morning, so 02/09/13 … so the ticket is not valid anymore but if you check the first proxy log above, it says still valid.

So I think there is something wrong in the patch, related to the expiration of a ticket AND the recreation of an expired ticket.

I hope my debugging helped you enough.

Regards;

#24 Updated by Florent Delvaille over 6 years ago

The patch contains:

@format = "%d/%m/%y %H:%M"
@krbexp = `klist | grep #{SETTINGS.dns_tsig_realm} | grep '/' | awk -F ' ' '{print $3,$4}'`

The result of the klist command is:
02/08/13 23:12:45
02/08/13 23:12:45

So for me there is a problem in the @format, it should be:
@format = "%m/%d/%y %H:%M:%S"

No ?

I did the change above, and created a new vm.
I will retry tomorrow, I suspect it will work :)

Thx for any feedback

#25 Updated by Florent Delvaille over 6 years ago

So ...
Ticket created yesterday, expiration today 9AM.
I creaTed a new vm today at 11AM.

Proxy logs says that kinit is executed, so it creates a new ticket.
Dns record created successfully.

So please just change the @format and it will works.

#26 Updated by Oliver Weinmann over 6 years ago

Hi,

thanks for the fix. You are right the format is wrong.

root@gedappl01:~# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal:

Valid starting Expires Service principal
02/07/13 11:59:02 02/07/13 18:39:02

I will submit a patch.

Cheers,
Oliver

#27 Updated by Oliver Weinmann over 6 years ago

Hi,

patch submitted. I will setup a test env clean up the code a bit and check if it is working.

Regards,
Oliver

#28 Updated by Oliver Weinmann over 6 years ago

Hi,

can someone have a look at the submitted code and clean it up if required. This patch is really helpful for everyone that wants to use secure DNS management between Proxy and Windows DNS Server. Leaving Windows DNS set to unsecure is not a good idea as anyone on your network can delete or modify DNS records without authentication.

Please help, I'm willing to test any changes.

Regards,
Oliver

#29 Updated by Dominic Cleal over 6 years ago

  • Status changed from New to Assigned
  • Assignee set to Dominic Cleal

I'm planning to look at the GSS-TSIG support soon as it's required for FreeIPA too, which is on my TODO list. If it is, then I'll take ownership of this - if you're happy to test it still works under Windows, Oliver!

#30 Updated by Dominic Cleal over 6 years ago

  • Target version set to 1.2.0

#31 Updated by Oliver Weinmann over 6 years ago

Hi Dominic,

thanks a lot. I would really appreciate to see this feature in Foreman 1.2. I have also added it on the deepdive list.

Regards,
Oliver

#32 Updated by Dominic Cleal about 6 years ago

  • Status changed from Assigned to Ready For Testing

#33 Updated by Dominic Cleal about 6 years ago

  • Status changed from Ready For Testing to Closed
  • % Done changed from 0 to 100

Applied in changeset commit:"7e72434b829ccc47ef3704c72722277aa547609a".

#34 Updated by Dominic Cleal over 5 years ago

  • Has duplicate Feature #61: Add Microsoft DNS Support added

Also available in: Atom PDF