Unable to connect to cloud RavenDb on Azure App Service (but works on localhost).

342 views
Skip to first unread message

Justin A

unread,
Jul 30, 2019, 10:24:44 AM7/30/19
to RavenDB - 2nd generation document database
Heya,

So i'm trying to see if I can connect an app on Azure App Service to my free cloud db to test stuff out but get the following error:

Failed to retrieve database topology from all known nodes.
https://a.free.<snip>.ravendb.cloud -> The SSL connection could not be established, see inner exception. -> The credentials supplied to the package were not recognized (The SSL connection could not be established, see inner exception.)

When I connect to this db host on my localhost, everything works great. I'm using the trick to convert the pfx file that came in the cloud certificate ZIP file and converting it to base 64 (ref: https://ayende.com/blog/186881-A/x509-certificates-vs-api-keys-in-ravendb),

I then check to make sure that both localhost and azure app service are actually using this really-long-string .

Here's the console out for localhost:

[00:12:14 INF] https://a.free.<snip>.ravendb.cloud
[00:12:14 INF] DB: <snip>
[00:12:14 INF] True
[00:12:14 INF] Cert Key: MIIQOQIBAz --- KfGAICCAA=
[00:12:14 INF] 5544
[00:12:14 INF] Loaded certificate
 
ok - so this shows me the host and cert key data (first 10 chars, last 10 chars). the cert key is 5544 chars long and was loaded. I then could access the host.

Now, on azure after I push the code up...

[Information] https://a.free.<snip>.ravendb.cloud
[Information] DB: <snip>
[Information] True
[Information] Key: MIIQOQIBAz --- KfGAICCAA=
[Information] 5544
[Information] Loaded certificate

so they are both the same.

App: ASP.NET Core 2.2 app
RavenDb nuget: RavenDB.Client 4.2.2
DB allowed IP's: 0.0.0.0

My first thought was that the Application Settings setup on Azure (for this App Service) are wrong. So I made sure the certificate was getting loaded and it looks like it, with the output above.

I just don't get it :/

There's not some weird difference between how i read in the base64 string into a cert, on localhost vs azure? Both computers should create the same cert which can validate with RavenDb? Or even how I generated the base64 data? 

It's not like port 443 is  blocked by azure app service? All outbound ports are usually open.

It's really weird :(

Justin A

unread,
Jul 30, 2019, 7:45:09 PM7/30/19
to RavenDB - 2nd generation document database
Some more info on this.

This is the low level stack trace/error message:

System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception. ---> System.ComponentModel.Win32Exception: The credentials supplied to the package were not recognized
   at System.Net.SSPIWrapper.AcquireCredentialsHandle(SSPIInterface secModule, String package, CredentialUse intent, SCHANNEL_CRED scc)
   at System.Net.Security.SslStreamPal.AcquireCredentialsHandle(CredentialUse credUsage, SCHANNEL_CRED secureCredential)

So it feels like my provided base64 string isn't being respected. Linking back to the initial post, I have checked what Azure App Service is using from the Environmental vars
- the 1st 10x chars and last 10x chars are the same.
- the length of the string is the same.

Is there some weirdness between OS's / Systems with how a certificate is created in code from the base64 string?

this is the code I'm using to generate the cert:

if (!string.IsNullOrWhiteSpace(ravenDbSettings.X509CertificateBase64))
{
    documentStore.Certificate = new X509Certificate2(Convert.FromBase64String(ravenDbSettings.X509CertificateBase64));
}


... so weird ...

Oren Eini (Ayende Rahien)

unread,
Jul 31, 2019, 4:06:40 AM7/31/19
to ravendb
This should work, and if the value isn't correct, it will throw.

Can you check the certificate's HasPrivateKey value?

--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ravendb/a01d86fc-c6a1-435b-8d9c-c50ed9949806%40googlegroups.com.


--
Oren Eini
CEO   /   Hibernating Rhinos LTD
Skype:  ayenderahien
Support:  sup...@ravendb.net

Justin A

unread,
Jul 31, 2019, 4:13:39 AM7/31/19
to RavenDB - 2nd generation document database
> This should work, and if the value isn't correct, it will throw.

Yeah i know! this is the weird thing which is why I keep thinking/checking the value of the base64 string that I am using.

> Can you check the certificate's HasPrivateKey value?

if (!string.IsNullOrWhiteSpace(ravenDbSettings.X509CertificateBase64))
{
    documentStore.Certificate = new X509Certificate2(Convert.FromBase64String(ravenDbSettings.X509CertificateBase64));
    Log.Logger.Information("Loaded certificate");
    Log.Logger.Information($"   -> HasPrivateKey: {documentStore.Certificate.HasPrivateKey}");
}

both LOCALHOST and Azure App Service version both report "TRUE" for that value.

-> HasPrivateKey: True

Iftah Ben Zaken

unread,
Jul 31, 2019, 4:24:57 AM7/31/19
to RavenDB - 2nd generation document database
Hi Justin,

How did you create the base64 value in the first place?

Justin A

unread,
Jul 31, 2019, 6:11:21 AM7/31/19
to RavenDB - 2nd generation document database
> How did you create the base64 value in the first place?

great question!


So what pfx file did i use?

this one:

Untitled.png


So this was the contents of the zip file which cloud ravendb gave me. 


Then I ran that PS script on my localhost windows machine and used the 5544 character length string.


Now, just in case there was some weird OS crap effecting the creation of the base64 string (which there shouldn't be of course) i even tried this:

- upload the pfx file to my azure app service -> sites/wwwroot

- went into the 'KUDU' admin section of the azure app service (which all azure app services have)

- went into debug -> powershell

- ran the script against that file .. and it worked!! i got some base64!


i then compared my localhost version against the azure shell version and it was identical.


Iftah Ben Zaken

unread,
Jul 31, 2019, 6:58:50 AM7/31/19
to rav...@googlegroups.com
So I'm not familiar with azure app service... but I wonder...

 > upload the pfx file to my azure app service -> sites/wwwroot

Is this something you have access to from the code? Do you get a file path?
Can you do the following?
store.Certificate = new X509Certificate("path_to_pfx", (string)null, X509KeyStorageFlags.MachineKeySet);

Iftah Ben Zaken
Core Team Developer   /   Hibernating Rhinos LTD
E-mail:    if...@ravendb.net
Support:  sup...@ravendb.net
Skype:  live:iftahbe



--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.

Justin A

unread,
Aug 1, 2019, 12:54:40 AM8/1/19
to RavenDB - 2nd generation document database
> Can you do the following? (load cert via file instead of base64).

Yep - I can.

- Hack code to use file if exists
- Publish code to Azure App Service  (yes, one click publish 'cause this is a test/hack)
- Now manually add the cert.pfx (only cause it's not part of the solution)
- Restart app
- Code works.

So i'm still trying to learn what's the difference between base64 and cert file...

Base64 logs:

01 Aug 2019 14:42:03.61308/01/2019 04:42:00 [Information] https://a.free.<snip>.ravendb.cloud
01 Aug 2019 14:42:03.61308/01/2019 04:42:00 [Information] <db name>: Foo
01 Aug 2019 14:42:03.61308/01/2019 04:42:00 [Information] True
01 Aug 2019 14:42:03.61308/01/2019 04:42:00 [Information] Key: MIIQOQIBAz --- KfGAICCAA=
01 Aug 2019 14:42:03.61308/01/2019 04:42:00 [Information] 5544  <--- size of cert
01 Aug 2019 14:42:03.61308/01/2019 04:42:00 [Information] Loaded certificate via base64
01 Aug 2019 14:42:03.61308/01/2019 04:42:00 [Information] -> IsPrivateKey: True
01 Aug 2019 14:42:03.61308/01/2019 04:42:00 [Information] B0E676098A86F2778A2FAFFC6378C71DB8A79208  <-- fingerprint
01 Aug 2019 14:42:03.61308/01/2019 04:42:00 [Information] 44A5D4A6F9E845C10E08FAF966A1AFE5961BF49E  <-- serial number
01 Aug 2019 14:42:03.61308/01/2019 04:42:01 [Information] RavenDb -> checking if the database '<snip>' exists and if any data exists...
** exception thrown **


Via cert file, if it exists, logs:

01 Aug 2019 14:44:36.83608/01/2019 04:44:33 [Information] https://a.free.<snip>.ravendb.cloud
01 Aug 2019 14:44:36.83608/01/2019 04:44:33 [Information] <db name>: Foo
01 Aug 2019 14:44:36.83608/01/2019 04:44:33 [Information] True
01 Aug 2019 14:44:36.83608/01/2019 04:44:33 [Information] Key: MIIQOQIBAz --- KfGAICCAA=
01 Aug 2019 14:44:36.83608/01/2019 04:44:33 [Information] 5544
01 Aug 2019 14:44:36.83608/01/2019 04:44:33 [Information] Loaded certificate via file.
01 Aug 2019 14:44:36.83608/01/2019 04:44:33 [Information] -> IsPrivateKey: True
01 Aug 2019 14:44:36.83608/01/2019 04:44:33 [Information] B0E676098A86F2778A2FAFFC6378C71DB8A79208  <-- fingerprint
01 Aug 2019 14:44:36.83608/01/2019 04:44:33 [Information] 44A5D4A6F9E845C10E08FAF966A1AFE5961BF49E  <-- serial number
01 Aug 2019 14:44:36.83608/01/2019 04:44:34 [Information] RavenDb -> checking if the database '<snip>' exists and if any data exists...
01 Aug 2019 14:44:43.46708/01/2019 04:44:40 [Information] - All finished setting up the database (⌐■_■)


so I'm not sure if having the fingerprint and/or serial number helps highlight if the cert 'loaded' is the same via both ways?

-me-

Luís Rudge

unread,
Aug 1, 2019, 3:59:13 AM8/1/19
to RavenDB - 2nd generation document database
I just want to note that I did the same as Justin in my own azure account (separate environment) and I get the same result.

Iftah Ben Zaken

unread,
Aug 1, 2019, 4:16:57 AM8/1/19
to rav...@googlegroups.com
I think the only difference is that you don't use the machine keyset flag in your code.

if (!string.IsNullOrWhiteSpace(ravenDbSettings.X509CertificateBase64))
{
    documentStore.Certificate = new X509Certificate2(Convert.FromBase64String(ravenDbSettings.X509CertificateBase64));
}

Let's try adding it?

Iftah Ben Zaken
Core Team Developer   /   Hibernating Rhinos LTD
E-mail:    if...@ravendb.net
Support:  sup...@ravendb.net
Skype:  live:iftahbe


--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.

Justin A

unread,
Aug 1, 2019, 9:22:30 AM8/1/19
to RavenDB - 2nd generation document database
> I think the only difference is that you don't use the machine keyset flag in your code.

wait what? what's this "Machine Keyset" thing you're talking about? huh??

/me googles the ctor for X509Certificate2....

ok. there's this enum called X509KeyStorageFlags ... 

lets try X509KeyStorageFlags.MachineKeySet ... OMG! that .. now works!!

hmm. lets play around with this.... If i wasn't providing a storage flag enum value, what was it defaulting to? ... there's X509KeyStorageFlags.DefaultKeySet ... and ... that fails! ok - this is good .. so what is the default?? it's a user key? so lets try X509KeyStorageFlags.UserKeySet ? that .. fails also ...

Okay ...I think i'll stick with the MachineKeySet.

So - this now works - problem solved!

-----

At the same time as I was doing this, I'll just make note that Luis also found another weird fix to this problem via this blog post. He ended up adding the Application Setting to the configuration in the Azure Portal UI WEBSITE_LOAD_USER_PROFILE = 1 which made it just work without having to provide the KeySet enum, above.

----

So ... with this fixed, is this documented anyone in the RavenDB docs?

Iftah Ben Zaken

unread,
Aug 1, 2019, 9:37:06 AM8/1/19
to rav...@googlegroups.com
Hi Justin,
I'm interested to know if setting WEBSITE_LOAD_USER_PROFILE = 1 works for you too (without using the machine keyset).
If it's not too much trouble try it as well, let me know and we can add this to the documentation.

Iftah Ben Zaken
Core Team Developer   /   Hibernating Rhinos LTD
E-mail:    if...@ravendb.net
Support:  sup...@ravendb.net
Skype:  live:iftahbe


--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.

Justin A

unread,
Aug 1, 2019, 10:17:54 AM8/1/19
to RavenDB - 2nd generation document database
> I'm interested to know if setting WEBSITE_LOAD_USER_PROFILE = 1 works for you too (without using the machine keyset).

Heh . Actually ... it did work. In fact, Luis added that _before_ I had a chance to try out the enums in the ctor. 

So when I got around to trying out the enums, everything was working and I was like, WTF?

I then noticed he added that to the Azure Portal so I nuked it and blammo -> default and user keys were exploding the site. Machine key didn't.

:)
Reply all
Reply to author
Forward
0 new messages