Short description
For Windows Server 2012: Is there a way to define a default-certificate in case the client does not support SNI?
Long description
We are currently configuring a Windows Server 2012 that - for technical reasons - does only have a single IP. This server is used for two tasks:
SSTP-Host (vpn.example.com)
Host for a single TLS-Website (www.example.com)
Thus there are two certificates defined for the same IP-address and port. When a call is made to port 443, almost every client submits the SNI parameter "server_name". The server does then use this parameter in order to choose the correct certificate for the connection.
BUT:
Windows XP with Internet Explorer does not support SNI and the parameter "server_name" is missing. Thus the server has to make a guess, which certificate to return. In our case, it defaults to the vpn-certificate and the browser displays a certificate-error (since the certificate's hostname "vpn.example.com" does not match the hostname in the url "www.example.com").
Is there a way to advise the server to use the www-certificate instead as a default?
This would be a perfect solution in our case:
All www-requests would get the www-certificate, even if they do not support SNI.
All SSTP-requests would get the vpn-certificate, since they do all support SNI.
Can this be done?
I know you have already answered the question yourself but it puzzled me that there was no simple way of doing it.
I am not sure if you have time to try it but I think this method would save the settings even during restarts.
In your case, if you edit the https 443 binding for vpn.example.com and tick the box Require Server Name Indication and enter the hostname of course and click Ok.
Then on the other website www.example.com do the same, but remove the tick in "Require Server Name Indication".
When I ran the netsh http show sslcert it showed the two certificate I had in place swapped, one on ip:port and the other hostname:port
IP:port : 0.0.0.0:443
Certificate Hash : 41f099397ad4437f7af7bf1c3157a18bd2576ebc
Application ID : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name : WebHosting
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
Hostname:port : secure.localhost:443
Certificate Hash : 106073025a888e17e94a7843de844d270714e806
Application ID : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name : WebHosting
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
and after
IP:port : 0.0.0.0:443
Certificate Hash : 106073025a888e17e94a7843de844d270714e806
Application ID : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name : WebHosting
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
Hostname:port : localhost:443
Certificate Hash : 41f099397ad4437f7af7bf1c3157a18bd2576ebc
Application ID : {4dc3e181-e14b-4a21-b022-59fc669b0914}
Certificate Store Name : WebHosting
Verify Client Certificate Revocation : Enabled
Verify Revocation Using Cached Client Certificate Only : Disabled
Usage Check : Enabled
Revocation Freshness Time : 0
URL Retrieval Timeout : 0
Ctl Identifier : (null)
Ctl Store Name : (null)
DS Mapper Usage : Disabled
Negotiate Client Certificate : Disabled
Hopefully this will save you some time and anyone else for that matter!
I did some more research. The bottom line: It can be done, but only on the command line and probably not permanently.
Netsh can show the http-bindings.
netsh http show sslcert
There you can see that IIS registers a SNI-Binding: www.example.com:443
But the RAS-Service registers for the full port 443: 0.0.0.0:443 with the certificate vpn.example.com.
The latter one is also the default-certificate in case the client does not support SNI.
Now I used netsh to move the RAS-Binding to vpn.example.com:443 and to create a new binding on 0.0.0.0:443 for www.example.com.
Now the server behaves exactly the way I want. I even used Wireshark to ensure that my RAS-clients do indeed support SNI.
But this setting will probably not be permanent. As soon as either the IIS or RAS-Service reset the settings, they will be lost.
Of course you could use some kind of service to check these settings every couple of seconds. But I did not find anything that works out of the box and did not want to implement this. Thus I will wait for Microsoft to enable SNI for RAS via the gui and use a single certificate until then.
Related
Remote server is an IBM i (7.1) with DB2 installed on it. I am trying to connect to this remote db2 database on IBM i machine via JDBC encrypted link using SSL from my windows machine, I am using jt400-6.7.jar.
I can see that SSL is correctly configured on IBM i machine as I see the following in Digital Certificate Manager :
Current Certificate Store
You have selected to work with the certificate store listed below. The left frame is being refreshed to show the task list for this certificate store. Select a task from the left frame to begin working with this certificate store.
Certificate type: Server or client
Certificate store: *SYSTEM
Certificate store path and filename:
/QIBM/USERDATA/ICSS/CERT/SERVER/DEFAULT.KDB
I followed this link to set up SSL on my IBM i machine :
https://isupport.krengeltech.com/rxs/setting_up_ssl/
This is my JDBC program executed from my windows 10 machine:
import java.sql.*;
public class IBMiSSLConnect
{
public static void main(String[] args) throws Exception
{
try
{
Class.forName("com.ibm.as400.access.AS400JDBCDriver");
Connection con = DriverManager.getConnection("jdbc:as400://IBMiMachineIP:5021/DBNAME&secure=true", "USER", "PASSWORD");
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
I get the following error :
[PWS0082] library(s) not added to the library list.
If however I replace url as below (adding system library):
Connection con = DriverManager.getConnection("jdbc:as400://IBMiMachineIP:5021/DBNAME;naming=system;libraries=QSYS;secure=true", "USER", "PASSWORD");
I get the following error instead :
The application requester cannot establish the connection. (sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target)
I have two questions:
Q 1: Does one always needs to add naming and libraries in url for JDBC encryption using SSL ?
something like this:
dbc:as400://someserver;naming=system;libraries=devfiles,prodfiles,sysibm,etc
I am refering to this link :
How can I insert additional libraries to my jdbc/DB2 connection?
Q 2: Should I use secure or sslConnection as url parameter ?
that is:
a: jdbc:as400://IBMiMachineIP:5021/DBNAME&secure=true
or
b: jdbc:as400://IBMiMachineIP:5021/DBNAME&sslConnection=true
*Note: I have already made changes to SSL permissions for truststore files default.kdb and default.rdb as mentioned here :
https://isupport.krengeltech.com/rxs/configuring_ssl_permissions/
Q1. No, you do not need to add the naming and libraries properties when using SSL.
Q2. You shouldn't be using the :5021 as part of the URL. It is currently ignored, but may be used in the future. You should be using secure=true to get an SSL connection.
I suspect your problem is that the truststore used by the JVM on the client system does not have the certificate for your Certificate Authority (it looks like you are using a self signed certificate on the server). If you still have problems, turn on SSL trace on the client by using the following when starting java:
-Djavax.net.debug=ssl:handshake:verbose
Note, jt400.jar comes with a jdbcClient, so you can used that to test your connection. Here is an example of connecting using SSL. In this case, the cacerts is the trust store that contains a certificate for the CA that signed the server certificate.
java -Djavax.net.debug=ssl:handshake:verbose -Djavax.net.ssl.trustStore=cacerts -jar jt400.jar 'jdbc:as400:SYSTEM;secure=true' USERID PASSWORD
This will show the SSL negotiation that the JVM is doing.
what #jweberhard said in terms of question, use of library is not required
and ssl port is not 5021 is correct, thanks #jweberhard .However I realized
in my case particularly I was making one wrong assumption based on prior
knowledge .
I have done a similar SSL encrypted connection from windows machine to
remote machines with MySQL DB and Postgres DB and in both cases you see in
wireshark something like this:
1 source IP Dest IP TLSv1.2 220 Client Hello
2 Dest IP source IP TLSv1.2 1140 Server Hello, Certificate, Server Key Exchange, Server Hello Done
3 source IP Dest IP TLSv1.2 129 Client Key Exchange
4 source IP Dest IP TLSv1.2 60 Change Cipher Spec
5 source IP Dest IP TLSv1.2 99 Encrypted Handshake Message
I was looking for TLSv1.2 protocol usage in wireshark , but however I
realized that specially when you are working with DB2 database on IBM i you
would still see TCP protocol being used,
but the litmus test is if you see :
1: Port 9471 being used for SSL Connection in wireshark ( if it is not
secure you will see port 8471 being used instead).
Refer this link for port usage for IBM i :
https://www-03.ibm.com/systems/power/software/i/toolbox/faq/ports.html
and
2: QZDASSINIT job being created on your IBM i machine( Use green screen to
check your job by using WRKACTJOB command and check for this job , this job
is created for SSL connection to your DB2 database , else you would see
only QZDASONIT job which is for a non-secure connection.
I am trying to implement ActiveMQ ssl connection with server authentication.
When I try to connect I get :
Server Certificate name doesn't not match the uri host name value
According to ActiveMQ documentation :
You should note that in order to validate that the certificate that the broker sends is the one we want we must validate the "Common Name (CN)" field from the certificate against the host-name in the URI. If you have trouble connecting to the broker one of the first things to check it if your host-name matches the broker certificate common name.
My problem is that my server can have multiple names which are specified in the SubjectAlternativeName.
Can i change the ActiveMQ server certificate validation to ignore the CN? or to serarch also in the SubjectAlternativeName section?
I am trying to create an HTTPS-tunnel on my machine. My intention is having all requests to https://localhost:8888/<something> (the port where Fiddler is listening to) be directed to https://myserver.net/<something>. I am using the following script as per Fiddler doc:
static function OnBeforeRequest(oSession: Session) {
// <Fiddler 2 preexisting code>
// HTTPS redirect -----------------------
if (oSession.HTTPMethodIs("CONNECT") &&
(oSession.PathAndQuery == "localhost:8888"))
{
oSession.PathAndQuery = "myserver.net:443";
}
if (oSession.HostnameIs("localhost"))
oSession.hostname = "myserver.net";
// --------------------------------------
// <Fiddler 2 preexisting code>
}
Also in Fiddler settings I checked the decryption check and installed certificates as you can see in the image below:
I restart Fiddler, it prompts me to install its fake certificates, I agree. I can see the certificate in my Windows Certificate System Repository when using certmgr. It is a self-signed certificate.
So What I do is opening a browser and type: https://localhost:8888/mypage.html, and what I get is an error. Internet Explorer reports this:
Error: Mismatched Address. The security certificate presented by this
website was issued for a different website's address. This problem
might indicate an attempt to fool you or intercept any data...
When I get certificate info (basically the certificate presented by the contacted host is being rejected, the same certificate can be displayed), I can see that the rejected certificate was issued by Fiddler and the subject is myserver.net.
So the certificate is ok because it is certifying myserver.net, I see that the problem is that probably my browser was expecting a certificate whose subject is localhost. Is it true?
How to handle this situation?
Assumption
I can understand that the problem is a certificate being issued for a website which I did not ask for. So the solution would be using a certificate certifying localhost:8888?
A certificate is valid if it is directly or indirectly (via intermediate certificates) signed by a trusted CA and if the hostname matches the certificate. If the last condition would not be enforced anybody with a valid certificate from a trusted CA could incorporate any other site.
To make use of fiddler and not run into this problem you should configure your browser to use fiddler as a web proxy and then use the real URL inside the browser instead of ip:port of fiddler.
I started getting the following prompt each time I run a command like cm status:
cs:630#rep:MyServer#repserver:ssl://<obfuscated>:8088
WARNING: the secure connection hostname provided in the server
certificate doesn't match the server's hostname. This means that the
certificate was not issued to this hostname or that there is a network
configuration problem with this host.
- Certificate hostname: CN=ip-<obfuscated>
- Server hostname: CN=<obfuscated>
If you want to continue connecting to this host, choose 'Yes'. The certificate
validation will continue (not recommended).
If you want to abandon the connection, choose 'No' (recommended).
Choose an option (Y)es, (N)o (hitting Enter selects 'No'): Yes
The server you are connecting to has sent a certificate that is not in the
store. This is normal if it is the first time that you connect to this server.
Certificate details:
- Issued to: CN=ip-<obfuscated>
- Issued by: CN=ip-<obfuscated>
- Expiration date: 6/30/2023 6:15:40 AM
- Certificate hash: <obfuscated>
If you trust this host, choose 'Yes' to add the key to Plastic SCM's key store
(recommended if it is the first time you connect to this server).
If you want to carry on connecting just once, without adding the key to the
store, choose 'No'.
If you do not trust this host, choose 'Cancel' to abandon the connection.
Choose an option (Y)es, (N)o, (C)ancel (hitting Enter cancels): Yes
As you can see, it asks twice and I say yes twice each time. Same for the GUI. It appears that the trust relationship is not being remembered. Not sure what to check.
Possible Solution #1: Provide a server certificate that matches the server's hostname.
That happens when you are using an url with the short name of the server ('myserver'),
while the certificate has been issued for the fqn (fully qualified name, like 'myserver.fr.com').
Or vice-versa.
That is why, when I create a (self-signed) certificate, I always mention the complete subjectAltName, with short name and the FQN, as in this openssl config file:
[ v3_ca ]
subjectAltName = DNS:#FQN#, DNS:#HOSTNAME#
That way, your certificate can match multiple hostnames.
I am running Oracle Weblogic 11g (10.3.6) and attempting to configure two-way SSL (client certificate requested and enforced). The client certificate is on a smart card.
I have enabled "basic" ssl in the weblogic server, and used keytool to import the relevant root CA certificates into the DemoTruststore.jks file. I have set the Two-way client cert behavior to Client Certs Requested and Enforced for the server.
Unfortunately, attempting to access my application causes the following:
<Certificate chain received from 127.0.0.1 - 127.0.0.1 was incomplete.>
<NO_CERTIFICATE alert was received from 127.0.0.1 - 127.0.0.1. Verify the SSL configuration has a proper SSL certificate chain and private key specified.>
<Certificate chain received from 127.0.0.1 - 127.0.0.1 was incomplete.>
The ActivClient dialog never appears to select a certificate from the Smart Card, and a pin is never requested. Therefore, I think I misconfigured something.
Help would be greatly appreciated.
Jason
Had forgotten I asked this, so I couldn't prove an answer. Here are the steps I took to set this up:
Log into the weblogic console, http://whateveryourhostnameis.com:7001/console. You'll have to know your username and password (I won't know it)
Click on the Servers link, then the name of your actual server instance. (A dev box with weblogic will probably only have one)
On the general tab, click the "SSL Listen Port Enabled". Click save.
On the SSL tab, click the Advanced arrow to open up the advanced options.
Change the "Two Way Client Cert Behavior" to "Client Certs Requested and Enforced"
Check the box for "Use JSSE SSL"
Even though the server might say a restart is not required, keep in mind it's an Oracle product and thus inherently evil. I recommend a server restart.