Duplicati & BackBlaze B2, cannot connect

The point was that a MITM attack is how an attacker can obtain those creds without your awareness, and the bucket will fill as usual. A MITM attack can be transparent to you, but does rely on you turning off cert checks.

No, the MITM we’re talking about is between Duplicati/Mono and B2. He can intercept those creds, such that Duplicati might “backing up” to him. However, that MITM cannot intercept the connection between my browser and B2, which is independently secured, and I can monitor that, to ensure that Duplicati is really backing up to the authentic B2. (Again to repeat: all this is hackish, usable/secure only for emergencies, nor for real-life use.)

No. Please look at the articles. It’s a pass-through, and the attacker not only sees everything without SSL/TLS encryption, but can modify it on its way through the “middle” after which it’s all reencrypted.

https://docs.mitmproxy.org/stable/ has a list of Features that describes capabilities I’m talking about.

Man-in-the-Middle (MITM) Attacks (from a large security firm) summarizes some MITM technical info.

With a MITM you’re not backing up to the attacker (which you could notice) but through the attacker.

Whether or not you accept this after your research, using certificates should help avoid this problem.

This we can agree on. Avoid –accept-any-ssl-certificate when possible. It’s not safe for everyday use.

@ts678 is correct. You want to avoid using the “accept all” SSL option except for testing. Although it is probably highly unlikely, some malicious actor could generate their own certificate and trick your Duplicati into talking to a rogue server, intercepting B2 authentication information or other details.

It is true that if you are using encryption in Duplicati the encryption key itself would not be shared with the theoretical malicious actor, but still I would play it safe by switching to the option where you accept a cert of a certain hash.

To do that we’d have to get the hash of the cert which isn’t too hard. Any time B2 renews/updates the cert you’d have to update it in Duplicati.

Ultimately the best approach would be to fix your mono cert store so that it can properly validate the chain of trust and you wouldn’t need either of these workarounds. I have done this on my Synology NAS… let me see if I can find the commands and if it’s different from what you’ve already tried…

Here is a command I’ve run on my Synology NAS to get the mono cert store updated…maybe it can be adapted to your Fedora system:

$ sudo /var/packages/Mono/target/usr/local/bin/cert-sync /etc/ssl/certs/ca-certificates.crt

More detail here:

Good luck!

As I mentioned above, on Fedora the command is:

But I’m still not understanding the MITM argument, somehow we’re still not communicating fully, so let me try again.

We’re making the underlying assumption that I have browser authentication to B2 (the browser has the padlock, I trust the cert and my laptop, etc.). Therefore, when I create a KeyID/AppKey, I can trust it (only I/browser and B2 share it, it’s strong, I trust the underlying crypto algos and implementation, etc.).

Now bring Duplicati/Mono into the mix (using PEK say, Personal Encryption Key, so no worries there), using its unauthenticated model (–accept-any-ssl-certificate), and using the above KeyID/AppKey. In that case, I fully agree it’s possible for an attacker to spoof B2, such that Duplicati “backs up” to the attacker. But the attacker/spoofer doesn’t/can’t learn the PEK and/or KeyID/AppKey, those remain secret/secure from the attacker.

And therefore, the purported attacker/spoofer cannot be a “MITM,” under the further out-of-band (of Duplicati) browser-checking scenario I’ve proposed. Namely, in the scenario I proposed, I turn to my browser and look at the Bucket where I’ve told Duplicati to back-up to, and I do see that Bucket is being populated. Only Duplicati can do that, not some purported “MITM,” because by hypothesis my browser’s connection to B2 is authenticated, and the only person/app/entity that knows the KeyID/AppKey (other than B2 and my browser) is Duplicati (well, OK, the attacker can see the KeyID that Duplicati sends on the wire, but obviously Duplicati doesn’t tell the AppKey to the attacker, it just uses the AppKey to protect the backup datastream it sends to B2). The purported MITM doesn’t know the KeyID/AppKey, hence cannot populate the B2 Bucket. Therefore, via this browser-check I conclude that Duplicati is indeed backing-up to B2. I.e., there is no MITM attack happening.

Now of course, it’s possible for the purported MITM to “act as a passive network wire, receiving/archiving the bits from Duplicati, then passing them blindly along to B2 unchanged, such that B2 then goes ahead and stores the data in the Bucket.” But that’s obviously not what we call a MITM attack, because those bits-on-the-wire are protected by the KeyID/AppKey, which are secure (the purported MITM doesn’t know them, and can’t get them assuming we trust all the other security we’ve been talking about here). That’s just normal network security, working the way it’s supposed to work.

Yes, I am not necessarily talking about a true MITM where the malicious actor would be passing your data dutifully up to the real B2. That step isn’t needed for you to lose valuable information (B2 bucket creds). Apologies if that threw you off.

As you mentioned, the private encryption key you configured with Duplicati is never sent over the wire so that’s not a concern. But your B2 user and password is transmitted over the wire during the B2 authorization process. It would be encrypted by TLS, but the malicious actor on the other end of that TLS connection will obviously be able to decrypt it.

While I agree the risk is extremely low, and they would only have access to encrypted Duplicati data (unless you happen to store other stuff in that same bucket), it’s just not a good security practice to turn off authentication. At a minimum you’d be making it quite a bit better by switching to accepting a specific certificate hash without much work at all.

Sorry, I missed that you had already tried it. I’m guessing that ca-bundle.crt file itself is too out of date…

What? Really?? Duplicati exposes the B2 KeyID/AppKEY (a.k.a “B2 Bucket creds”) on-the-wire, such that the attacker/spoofer can see them??? That’s absolutely insane!!! If that’s really what Duplicati does (or, really, the underlying B2 API software that Duplicati uses), then yes of course all bets are off, and there could indeed be a MITM attack.

BUT, are we really sure that’s what Duplicati/B2API does? It makes no sense to me. For, if the KeyID/AppKEY go together on-the-wire to B2, then why are both needed, why not just some single string (the KeyID presumably), why would a purportedly “secret” piece (the AppKey) ALSO be needed? The only way I can make sense of the KeyID/AppKey pair is that they’re synonymous with the username/userpassword pair, namely, the KeyID/username identifies the protection (integrity, confidentiality) that’s protecting the on-the-wire data, and the AppKey/userpassword verifies/validates that protection is correct. With this model in mind, it would be absolutely insane to send the username/userpassword paid on-the-wire, ever. That would make no sense to me.

I’ve tried finding more info about this on the BackBlaze website, but I’m not finding it. I can find decent documentation about BackBlaze’s BACKUP crypto (Security Question Round-up! – Help Desk), but not about their B2/API crypto. Do you have a reference for that?

Yes. See b2_authorize_account and you can see that both values are sent in the HTTP header during authorization process.

I don’t think it’s crazy per se - TLS is relied upon to protect this and logins to gazillions of web services. This is why we are so adamant about not leaving an important aspect of TLS (authentication) disabled in your Duplicati setup. :slight_smile:

Here’s how you can get the thumbrint/hash of a specific web server’s cert (all on one line):

$ openssl s_client -connect api.backblazeb2.com:443 < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin

Produces this output:

SHA1 Fingerprint=56:94:F8:40:76:38:71:41:D5:D7:20:12:60:15:CD:1E:CF:AC:6B:2F

I believe you need to take out the colons when putting it in Duplicati - I can’t remember for sure.
The hash would need to be updated any time B2 changes/renews their cert. The current cert doesn’t expire until 7/21/2020.

OK, thanks for the pointer, I see the B2 API manpage now, and it does seem to confirm what you’re saying. But it still doesn’t address the “insanity” question I have. Namely, if b2_authorize_account() is being used to get an authzToken, why is the pair KeyID/AppKey needed, why not just a single thing (called, say, KeyID)? I.e., if that so-called “AppKey” is nowhere used as a crypto key (and it isn’t, according to the b2_authorize_account() documentation), then why does it exist? It’s apparently only used to get an authzToken, but that doesn’t require any crypto, i.e, the KeyID/AppKey combination (concatenated string, if you wish) seems only to be being used as a “pre-authorization token” to get the “sesson authzToken.” I don’t get it.

(PS: The cert-sync DID work for me, after I finally discovered I was supposed to invoke it, and I AM doing everything securely over Duplicati/B2 now.)

As you theorized above, it’s just akin to user+password. I don’t know exactly why it is done this way with B2 and other cloud providers. (AWS IAM and Azure work the same way.) Maybe it is to allow situations where one of the two pieces needs to be shared openly/unencrypted? Not sure.


OK, it seems we’re communicating clearly now, thanks to all. But I repeat my “insanity” assertion (and this has nothing to do with “you,” it has to do with API designers, unless/until they can explain it to us): The idea of any kind of protocol that sends passwords/AppKeys on-the-wire is insane. I mean, in the normal/ordinary case (not cloud store), when I generate a password for myself, it’s never exposed anywhere (except when I have to type it in to authenticate myself to a local software), instead it’s hashed/transformed to a crypto key (Key derivation function - Wikipedia), which is in turn used to prove I know my password, without actually exposing the password string. I don’t know what’s going on with any kind of concatenated username+userpassword on-the-wire/communicated thing. At all. (Except possibly “abuse of language:” it’s CALLED an AppKey, but it’s not really a crypto key at all. But then why would anyone ever do that?)

EDIT: A big reason for not using “raw passwords” (and using key derivation functions instead, which in turn uses things like salts and other diversifiers) is that humans tend to use the same password for lots of things, so if it gets exposed in one context, it also compromises other contexts, a Bad Thing.

Remote software faces the same challenge. When you set your local password, the local software likely saved its salted hash somewhere, so that you can re-authenticate later by typing in the same password. You might say passing a hash to the remote is safer, but intercepting the hash gives an attacker access.

Wikipedia article Pass the hash opens with “In cryptanalysis and computer security, pass the hash is a hacking technique that allows an attacker to authenticate to a remote server or service by using the underlying NTLM or LanMan hash of a user’s password, instead of requiring the associated plaintext password as is normally the case. This is an example of security through obscurity, as it merely kicks the can down the road, by moving the goalposts, the need for stealing the plaintext to stealing the hash.”

Ultimately a secret shared between you and the remote must go on the wire. How else could it be done?
EDIT: One way (which does not suit HTTP well) is Challenge–response authentication or something that doesn’t have the shared secret right on the wire, but uses it algorithmically to prove you know the secret.

As you note, though, there are better and worse ways of doing it. Reusing passwords everywhere is bad.
Presumably few people will memorize their enormous AppKey, so at least that will avoid the reuse issue.

OAuth 2.0 is a security protocol used by some web services that (while it has its own security flaws) will help prevent the reuse problem by having the destination give you back a token with very specific abilities and meaningless outside of that service provider. This limits exposure from token theft, but you still must protect the token in storage and transit (meaning don’t use --accept-any-ssl-certificate or it may be read).

How we get along with OAuth explains how (and why) Duplicati holds the service provider’s token for you.

After some more reading, I think my last question turns out to be the right one: “it’s CALLED an AppKey, but it’s not really a crypto key at all. But then why would anyone ever do that?” These so-called “API keys” (for B2, it’s “KeyID+AppKey”) are indeed NOT “crypto keys” at all. Instead, they’re merely “tokens” [and should be called that!] (not used in crypto algos), used for authn and/or authz. Basically, they’re essentially just random numbers, which are supposed to be kept more-or-less secret/close-to-the-vest, but they’re not at all used to actually/technologically implement “protection” in the classical sense of integrity/confidentiality, or even authentication (well, actually they are used for authn/authz, but that’s after-the-fact, they’re used as evidence, but not used to prove authn/authz). Apparently this is more-or-less standard usage now in the HTTP/SOAP/REST/Cloud/Etc. space. I was coming from old-school language, where “key” really meant “crypto key, used as ingredient in crypto algo.” This confusion was exacerbated by the documentation (Duplicati and elsewhere) speaking of “equivalences” in the B2 case, of KeyID=username and AppKey=userpassword. I haven’t been complaining of any deficiencies in Duplicati technology, of course, just deficiencies in documentation/understanding/language (elsewhere, then adopted by Duplicati, with this “API key” business).

PS: As you note, shared secrets need not be transmitted on-the-wire, instead key-agreement protocols (beginning with Diffie-Hellman) are much better. And this is indeed used in Web space, at the highest levels (website certs, etc.), then once secrets are exchanged (er, agreed-upon), everything gets tunneled trough TLS. All that’s fine. Where I got confused was where I read about BackBlaze BACKUP (as opposed to B2) doing multi-level/redundant layers of encryption, then jumping to the conclusion that redundancy carried over into B2, with such concepts/language as “AppID/AppKey == username/userpassword.” At the end of the day, it all comes back to Cool Hand Luke - Wikipedia — “What we’ve got here is a failure to communicate.”

Correct… I don’t think AWS, Azure, or other cloud providers use these appid+key combos for any crypto. Just for authentication.