I am trying to make a connection to my kubernetes api and cant seem to get SSL to work from C#.
When i run the following via curl, everything seems to work as expected:
And I have this for c# to do the same:
try
{
// use the TLS protocol
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
// create HTTP web request with proper content type
HttpWebRequest request = WebRequest.Create(Constants.K8_API_RC_URI) as HttpWebRequest;
request.ContentType = "application/json;charset=UTF8";
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + Constants.K8_TOKEN);
// load the X.509 certificate and add to the web request
X509Certificate cert = new X509Certificate(Constants.K8_CRT);
request.ClientCertificates.Add(cert);
// call the web service and get response
WebResponse response = request.GetResponse();
Stream responseStream = response.GetResponseStream();
string jsonContents = new StreamReader(responseStream).ReadToEnd();
}
catch (Exception exc)
{
// log and print out error
log.Info(exc.Message);
}
Where
Constants.K8_CRT is the Path to ca.crt
and ca.crt contains the following:
-----BEGIN CERTIFICATE-----
MIIDMDCCAhigAwIBAgIIcwd9rrnaPcowDQYJKoZIhvcNAQELBQAwEzERMA8GA1UEAwwIYWNzazhz
and more letters.......
cwSfuIp7e49KC3HSqcU3Mz4oFNm5bw==
-----END CERTIFICATE-----
I get the following error:
Could not create SSL/TLS secure channel.
P.S. I know there are Kubernetes clients for .Net out there and I have tried just about all of them but since I am integrating this with Azure Functions most of the third party libraries do not work for various reasons.
The CA cert should be used to validate server cert chain, not passed as an ClientCertificate.
Here is an example.
ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => {
if (errors == SslPolicyErrors.None) return true;
X509Certificate2 serverCert = new X509Certificate2(certificate);
X509Certificate2 caCert = new X509Certificate2(@"./ca.cert");
chain.ChainPolicy.ExtraStore.Add(caCert);
chain.Build(serverCert);
foreach (var chainStatus in chain.ChainStatus) {
if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot) continue;
if (chainStatus.Status != X509ChainStatusFlags.NoError) return false;
}
return true;
};
HttpWebRequest request = WebRequest.CreateHttp("https://master:6443/api/v1");
request.Headers[HttpRequestHeader.Authorization] = "Bearer " + "SOME_TOKEN";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
var content = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.WriteLine(content);