We're configuring SSO for our web app for a customer, but unfortunately we don't have access to the domain controller (one more reason why we don't do more experimenting to check our assumptions). So, we asked to run ktpass.exe and prepare .ktpass file to use for our server configuration.
The issue we are facing is "specified version of key is not available".
I looked up the keytab file (knvo = 5), and checked out the traffic with Wireshark on our web server:
As you can see, kvno = 1 in AP-REQ ticket. I suppose that it's the right ticket to check kvno version.
I know there're compatibility issues with Windows 2000 domain (/kvno 1 must be used for Windows 2000 domain compatibility), but we are said to deal with Windows 2008R2 server (and I can see the value msDS-Behavior-Version = 4 for our domain controller, which matches 2008R2!).
Is there anything like W2K domain mode we are facing with?
Would explicit kvno=1 help to resolve the issue? I.e., ktpass.exe [..] /kvno 1
EDIT #1
The problem was about incorrectly specified SPN. It was HTTP/computer_name#DOMAIN.COM instead of using fully-qualified domain name. This would only work if WINS were enabled, but it turned out it wasn't.
After generating keytab with the correct SPN, everything works fine, and kvno sent according to actual account value.
Will kindly accept answer that explains the effect I observed.
I do not know the internals well, but MIT Kerberos clients do forward resolution of the hostname part of a host-based service principal to canonicalize the hostname. In my experience if the name does not resolve it does affect Kerberos auth. When I setup service accounts for SQL Server to do Kerberos I always have to register an SPN with the host name and the fully qualified domain name because different SQL components seem to use different resolution methods.
In a very basic network topology WINS would be able to resolve the name. Even without WINS though, the NetBIOS service would be able to resolve the hostname. WINS and NetBIOS rely heavily on broadcasts, so if your webserver is on a different subnet, NetBIOS name resolution would fail, and WINS too if not configured correctly. Also Windows need to use the TCP/IP NetBIOS Helper service.
The problem was about incorrectly specified SPN. It was HTTP/computer_name#DOMAIN.COM instead of using fully-qualified domain name. This would only work if WINS were enabled, but it turned out it wasn't.
After generating keytab with the correct SPN, everything works fine, and kvno sent according to actual account value.
Will kindly accept answer that explains the effect I observed.
Related
I have been developing Standard Logic Apps with SQL Server successfully for some time, but suddenly can no longer connect. I'm using Azure AD Integrated as my Authentication Type, which I know is OK as I use the same credentials in SSMS. If I try to create a new credential, it is apparently successful but on save the Logic App says "The API connection reference XXX is missing or not valid". Something has changed, but I don't know what ... help!
per above, this was submitted to M/S and has been resolved as follows: the root cause is if a Logic App Parameter name includes an embedded space the problem with SQL connections is triggered. This is a pernicious problem, as the error message is quite unrelated to the root cause. Further, since embedded spaces are supported in Logic Apps e.g. in Step Names, it is easy to assume the same applies across the board.
I'm pretty new to Kerberos. I'm testing the Single Sign On feature using Kerberos. The environment: Windows clients (with Active Directory authentication) connecting to an Apache server running on Linux machine. The called cgi script (in Perl) connects to a DB server using the forwarded user TGT. Everything works fine (I have the principals, the keytab files, config files and the result from the DB server :) ). So, if as win_usr_a on Windows side I launch my CGI request, the CGI script connects to the remote DB and queries select user from dual and it gets back win_usr_a#EXAMPLE.COM.
I have only one issue I'd like to solve. Currently the credential cache stored as FILE:.... On the intermediate Apache server, the user running the Apache server gets the forwarded TGTs of all authenticated users (as it can see all the credential caches) and while the TGTs lifetime are not expired it can requests any service principals for those users.
I know that the hosts are considered as trusted in Kerberos by definition, but I would be happy if I could limit the usability of the forwarded TGTs. For example can I set the Active Directory to limit the forwarded TGT to be valid only to request a given service principal? And/Or is there a way to define the forwarded TGT to make it able to be used only once, namely after requesting any service principal, become invalid. Or is there a way the cgi script could detect if the forwarded TGT was used by someone else (maybe check a usage counter?).
Now I have only one solution. I can define the lifetime of the forwarded TGT to 2 sec and initiate a kdestroy in the CGI script after the DB connection is established (I set that the CGI script can be executed by the apache-user, but it cannot modify the code). Can I do a bit more?
The credential caches should be hidden somehow. I think defining the credential cache as API: would be nice, but this is only defined for Windows. On Linux maybe the KEYRING:process:name or MEMORY: could be a better solution as this is local to the current process and destroyed when the process is exited. As I know apache create a new process for a new connection, so this may work. Maybe KEYRING:thread:name is the solution? But - according to the thread-keyring(7) man page - it is not inherited by clone and cleared by execve sys call. So, if e.g. Perl is called by execve it will not get the credential cache. Maybe using mod_perl + KEYRING:thread:name?
Any idea would be appreciated! Thanks in advance!
The short answer is that Kerberos itself does not provide any mechanism to limit the scope of who can use it if the client happens to have all the necessary bits at a given point in time. Once you have a usable TGT, you have a usable TGT, and can do with it what you like. This is a fundamentally flawed design as far as security concerns go.
Windows refers to this as unconstrained delegation, and specifically has a solution for this through a Kerberos extension called [MS-SFU] which is more broadly referred to as Constrained Delegation.
The gist of the protocol is that you send a regular service ticket (without attached TGT) to the server (Apache) and the server is enlightened enough to know that it can exchange that service ticket to itself for a service ticket to a delegated server (DB) from Active Directory. The server then uses the new service ticket to authenticate to the DB, and the DB see's it's a service ticket for win_usr_a despite being sent by Apache.
The trick of course is that enlightenment bit. Without knowing more about the specifics of how the authentication is happening in your CGI, it's impossible to say whether whatever you're doing supports [MS-SFU].
Quoting a previous answer of mine (to a different question, focused on "race conditions" when updating the cache)
If multiple processes create tickets independently, then they have no
reason to use the same credentials cache. In the worst case they would
even use different principals, and the side effects would be...
interesting.
Solution: change the environment of each process so that KRB5CCNAME
points to a specific file -- and preferably, in an
application-specific directory.
If your focus in on securing the credentials, then go one step further and don't use a cache. Modify your client app so that it creates the TGT and service tickets on-the-fly and keeps it private.
Note that Java never publishes anything to the Kerberos cache; it may either read from the cache or bypass it altogether, depending on the JAAS config. Too bad the Java implementation of Kerberos is limited and rather brittle, cf. https://steveloughran.gitbooks.io/kerberos_and_hadoop/content/sections/jdk_versions.html and https://steveloughran.gitbooks.io/kerberos_and_hadoop/content/sections/jaas.html
I'm struggling to resolve this error.
I think I've correctly set up the DNS-part, by creating Secondary Zones for forward and reverse look-up. I can ping all servers, ports are open etc. At some point, I can validate the trust perfectly. But when I check again at a later point (now = next day), I'm getting this error (I had this before, first tried recreating everything).
The outgoing trust was successfully validated.
The secure channel (SC) reset on Active Directory Domain Controller
\DC-02.mydomain2.local of domain mydomain2.local to domain
intranet.mydomain1.local failed with error: There are currently no
logon servers available to service the logon request.
Domain controllers:
mydomain2: DC-01, DC-02
mydomain1: has 4 domain controllers, DNS is NOT on the primary domain controller (still need to promote the new DNS server to PDC as well).
The issue always mentions DC-02, not sure if this is relevant?
What should I check?
I also tried resetting the password, as suggested. That leads to a "No Logon servers are available" error.
Update: when validating again from domain 1, it claims the RPC server is unavailable. Further investigation: it seems all of a sudden, from the PDC, I can't ping by the name of the domain or domain controllers of domain2. I double-checked this yesterday, then it worked. From other domain controllers in domain 1, it still works. I disabled Kaspersky Endpoint Security, then ran a ipconfig /flushdns and tried again: working. Could it be Kaspersky, or a DNS-issue (weird, since the same DNS-servers are used and on other DC's it's working?)
Please verify the following:
In the Condintional forwarders in DNS setting - Add the other domain's DNS server name and IP.
Open ncpa.cpl - Goto properties of IPv4 and then click on advanced.
Goto DNS - clcick on the radio button - "Append these DNS suffixes (in order):"
Then add the domain - e.g. lab.com in it.
Perform the above two steps in both the domain's Domain controllers/DNS servers.
I'm doing https web requests in silverlight using "WebRequest"/"WebResponse" framework classes.
Problem is: I do a request to an url like: https://12.34.56.78
I receive back a versign signed certificate which has as subject a domain name like: www.mydomain.com.
Hence this results in a remote certificate mismatch error.
First question: Can I somehow accept the invalid certificate, and get the WebBresponse content ? (even if it involves using other libraries, I'm open to it)
Additional details: (for those interested on why I need this scenario)
I'm trying to give a client access to a silverlight app deployed on a test server.
Client accesses the silverlight app at: www.mydomain.com/app
Then I do some rest requests to: https://xx.mydomain.com
Problem is I don't want to do requests on https://xx.mydomain.com, since that is on our productive server. For this reason I use https://12.34.56.78 instead of https://xx.mydomain.com.
Client has some firewalls/proxies and if I simply change his hosts file and map https://xx.mydomain.com to 12.34.56.78, web requests don't resolve to the mapped IP.
I say this because on his network webrequests fail if I try that, on my network I can use the hosts changing without problems.
UPDATE: Fixed the problem by deploying test releases to an alternative: https://yy.domain.com and allowing the user to configure for test purposes, the base url to which I do requests to be: https://yy.domain.com.
Using an certificate that contained the IP in the subject or an alternative subject would've probably worked too, but would have cost some money to be issued by a certified provider and would not be so good because IP's might change.
After doing more research looks like Microsoft won't add this feature too soon, unless there's a scenario for non-testing/debugging uses.
See: http://connect.microsoft.com/VisualStudio/feedback/details/368047/add-system-net-servicepointmanager-servercertificatevalidationcallback-property
I have set the ActiveDirectoryMembershipProvider connectionProtection attribute to secure, according to MSDN documentation states that when this is set to secure the following holds:
"The ActiveDirectoryMembershipProvider class will attempt to connect to Active Directory using SSL. If SSL fails, a second attempt to connect to Active Directory using sign-and-seal will be made. If both attempts fail, the ActiveDirectoryMembershipProvider instance will throw a ProviderException exception."
The code works and queries can be made against the LDAP but one issue that has me a little confused is that my connection string is prefixed with LDAP and not LDAPS. Changing this to LDAPS results in the following error:
"Parser Error Message: Error HRESULT E_FAIL has been returned from a call to a COM component."
What is happening here? In the first instance where the connection string is simply LDAP is SSL being used? The documentation indicates that if it is not, an exception should be thrown. If not, then what would be the likely cause for this error in this context?
As far as I know, all the LDAP DN's (distinguished names) always have an LDAP only prefix - whether they're over a secure link or not. The secure aspect typically shows up by means of the port on the server being used, 389 being the default for non-secure, and 636 being the default for a secure communication.
But the spec of the LDAP distinguished names doesn't have a LDAPS prefix, really. I've done a lot of LDAP work a few years ago, and I do remember having to deal with different ports for trusted or secured communications, but I never once had a full-qualified LDAP path have anything else but an LDAP:// prefix (case sensitive, too!).
The LDAP:// prefix is used both for clear and SSL connections, to check whether the communication is indeed under SSL try step 3 of this blog entry http://erlend.oftedal.no/blog/?blogid=7