pleroma.debian.social

pleroma.debian.social

Is it possible to make OpenVPN validate that a certificate follows a specific chain?

Use case:
* Internal company root
* Internal company VPN intermediate
* Device certs for each client/server

Is it possible to do something like this but not allow other certs signed by the same root, under a different intermediate, to authenticate to the VPN?

In other words, I explicitly want the VPN to only allow certs signed by the root *via this specific intermediate*, rather than any valid cert chaining to the root.

Because if this isn't possible it seems like the only safe way to do this is to have a separate internal root for each VPN instance, such that you can tightly control which client certs are trusted for that particular server.

@azonenberg
In general with openssh you can specify where it searches for roots. Can you tell openvpn to use a specific file or directory for ca roots? Then you can put only your root there.

@azonenberg not sure about OpenVPN specifically, but generally for PKI systems if you set the intermediate instead of the root as the trust anchor that would do the trick wouldn’t it? Now draw the rest of the owl (eg ensuring that all certs signed by the intermediate can’t themselves be used as signing certs)

@FritzAdalis the issue is that I don't want to verify all the way up to the root necessarily.

I wonder if I can just set openvpn to use the intermediate as the CA to verify against (you can specify a CA cert in the config) and just not verify all the way up the chain. But it would be nice to verify that it chains all the way up too...

I'll poke around a bit. Rekeying my VPN and trying to improve the PKI setup.

@jpm Lol yeah exactly. It's going to take some experimenting and testing to do this properly.

@jpm although, if all device certs issued by the intermediate are trusted to the auth to the VPN, I'm not sure this buys you anything.

1) Joe schmoe's cert is compromised, attacker signs a bogus cert with it.

Attacker could have just used his cert directly to log in

2) Joe schmoe signs a cert an attacker bribed him to sign, attacker uses it to log in

You now have a malicious cert that is very obviously joe schmoe's responsibility, fire him, revoke his cert

Am I missing any attack scenarios here?

@jpm in other words the definition of a trusted user is "valid non-revoked cert signed by vpn.foobar.net intermediate" and I think you're good?

@azonenberg and normally those scenarios are covered by X.509 certificate usage policies anyway. The intermediate is a full certificate authority for its branch already

@azonenberg crossed-streams but yes. The intermediate is already a X.509 certificate authority in its own right for its branch.

@jpm Yeah. I guess another question is whether openvpn actually checks "basic constraints: is a CA" properly on ecrts. Gotta verify that

@azonenberg @FritzAdalis I'm quite sure that will work, most homelab style setups probably have an EasyRSA CA just for OpenVPN that's not trusted by the OS, so you just give it "ca" (intermediate), "cert", "key" and off you go

@azonenberg
I wonder if you can have the client send the cert+intermediate like web servers do.

@FritzAdalis it's more a question of making sure we discard root > web ca > web server cert as a valid cert chain for the vpn since it doesn't chain to the vpn ca under the same root

@azonenberg @jpm relatively sure TLS libraries enforce this particular one by default & you'd have to fuck with it to break it, but… needs verification anyway. Report results please? 🙂

@azonenberg curious what the base problem is?

If it's simplifying VPN config then wireguard all the way IMO. No cert chaining to worry about, just nice simple public/private key pairs.

Or tailscale/headacale for extra easy mode.

Not sure if that fits the situation though!

@azonenberg Do you mean you want to have:

root -> VPNIntermediate -> TeamA and TeamBClients...
Connect to: VPN with VPNIntermediate.Key
and
RootCA/Cert

=== or ====

root -> VPNIntermediateNetworkBoss -> TEAM_A_INTERMEDIATE -> TeamAClients...

root -> VPNIntermediateNetworkBoss -> TEAM_B_INTERMEDIATE -> TeamBClients...

Both TeamA and TeamB connecting to:
OneBigAssVPN with VPNIntermediatNetworkBoss.key
and
RootCA/Cert

@nikolaihampton The immediate goal is to make sure that a compromised HTTPS server cert issued by the same root can't be used to authenticate to the VPN.

But ultimately I want to support multiple independent VPNs under the same root with separate sets of client certs for each

@azonenberg
HTTPS Server Certs (extendedKeyUsage = serverAuth only)
VPN Server Cert (extendedKeyUsage = serverAuth only)
VPN Client Certs (extendedKeyUsage = clientAuth only)

For your immediate goal at least? make sure your servers are serwverAuth only in their extendedKeyUsage?

Is that sufficient?

@azonenberg @jpm IME it does, having accidentally tried to use a self-signed CA as a server cert before. I'd expect validation at that level to be well within the TLS library and not something the application would have to worry about, as long as the library is configured to do validation in the first place *glances at all the historical "doesn't actually validate certificate" bugs in proprietary SSLVPNs*

@astraleureka @jpm having found x509 parsing bugs allowing trivial cert forgery in the past I trust nothing unless I've verified it lol

@astraleureka @jpm the further you get from the well validated "browser talking to a https server" use case the more dragons there are

@azonenberg that sounds like you need to put the intermediate in the trust store, and not the root?
replies
0
announces
0
likes
0

@azonenberg If you really want belt-and-suspenders, you can have a tls-verify script that looks at the cert pointed by $peer_cert and checks the issuer name. But as others have said, having the intermediate specified in the "ca" statement should be enough. (Though not directly related, it's also a good idea to have "remote-cert-tls client" enabled on the server.)