4

The backbone of my homelab consists of a set of Yubikeys with GPG keys on them; I use them as a CA, for SSH access into all my machines/VMs as well as encrypting important documents such as disk encryption passwords. I have all the infrastructure in place to keep these keys protected and I like that everything only depends on these keys and not having to manage multiple parallel infrastructures.

Now I want to use a VPN server so that I can connect to my homelab over the internet and I want to use these same GPG keys for authentication. So the question is if you know of a VPN client/server that allows RSA certificate authentication? I think OpenVPN might be able to do it but I have not had any luck in figuring out how to make it work.

In theory a raw IPSec tunnel should work with RSA but this still requires a client application that will do the challenge response with the Yubikey.

The holy grail would be such that I can plug the Yubikey in any computer, download/configure a client and connect to the VPN server.

Any help/thoughts are appreciated!

Tom Stock
  • 161

2 Answers2

7

The holy grail would be such that I can plug the Yubikey in any computer, download/configure a client and connect to the VPN server.

The issue with this plan is that configuring a VPN client generally requires Administrator rights. You can do that on your own PCs but not so much as a guest in random places (where the smart card would make the most sense). It also exposes your network to the unknown computer. Anywhere a portable key would be useful, SSH or HTTPS will work better.

So the question is if you know of a VPN client/server that allows RSA certificate authentication?

Many do – it's very common in enterprise networks. IKEv2 (IPsec), L2TP/IPsec, OpenVPN, OpenConnect (Cisco's AnyConnect), are just a few examples. Quite possibly Windows built-in SSTP – given that it's TLS-based – and technically even PPTP (uncommon but the Windows PPTP client can be convinced to do EAP-PEAP so it likely could do cert-based EAP as well).

However, as you noted, it is not enough for software to merely "use RSA keys" since the whole point of your Yubikey is that the software cannot access the actual RSA keys; the software has to specifically know how to request a signature from the card.

And the problem is that practically no software except GnuPG interfaces with OpenPGP cards (nor can verify trust of OpenPGP certificates, card or not) – everything else works either with PKCS#11 or Windows CAPI as the standard interfaces to smart-card contents, and generally with X.509 format certificates (the kind used for TLS) as the carrier for RSA public keys.

(Yes, GnuPG can emulate ssh-agent so that OpenSSH can use it for raw RSA, but hardly any software aside from SSH clients supports using an ssh-agent as a generic interface, either – though it's possible in theory.)

In short, it's not realistic to have OpenPGP as your sole PKI infrastructure. At least I don't think it's going to happen on Windows; it's maybe possible on Linux to use a PKCS#11-to-GnuPG adapter but will be a massive headache even there, given how 1) it was really buggy the last time I tried it, and 2) the VPN client is normally a system service and therefore cannot really depend on a user-level GnuPG 'scdaemon' process.

So instead you will have to start an X.509 PKI using the PIV (CCID) module that your Yubikeys also have. The Yubikey 4 has twelve slots for RSA2048 or P256/P384 certificates (the older Yubikey NEO has four and each is specific-purpose):

  • Latest tools:

    ykman piv keys generate -a RSA2048 9a tmp.pub
    ykman piv certificates generate -s "Example" -d 3650 9a tmp.pub 
    ykman piv certificates export 9a tmp.crt
    
  • Slightly older:

    ykman piv generate-key -a RSA2048 9a tmp.pub
    ykman piv generate-certificate -s "Example" -d 3650 9a tmp.pub
    

(Here 9a refers to a PIV certificate slot. These are specific to PIV-style cards, not PKCS#11 in general, and are similar to auth/enc/sign slots in OpenPGP cards – though Yubikey 4's im­ple­men­ta­tion makes them more generic.)

The (emulated) PIV card can then be used with most things that support PKCS#11 on Linux, or anything that supports CAPI on Windows:

  • Windows has a PIV card driver built in (due to PIV being the US DoD standard), so any software that uses CryptoAPI (CAPI) or CNG will automatically recognize the certificate.

    PuTTY-CAC/PageantCAC is one example, and of course the Windows built-in IKE clients (both IKEv2 and L2TP/IPsec) are another.

    Some software like 'OpenSSH for Windows' wants a PKCS#11 module even on Windows, in which case you'll need the DLLs from yubico-piv-tool:

    ssh -I libykcs11.dll root@somehost
    
  • OpenSSH on Linux:

    ssh-keygen -D libykcs11.so > yubikey_id_rsa.pub
    ssh -I libykcs11.so root@server
    

    opensc-pkcs11.so also works, as PIV is not Yubikey-specific.

  • OpenVPN on Linux:

    openvpn --show-pkcs11-ids should load the right module via p11-kit.

  • strongSwan for IPsec: https://docs.strongswan.org/docs/latest/plugins/pkcs11.html

  • Similarly, web browsers can authenticate to websites using a TLS "client certificate" – both Firefox and Chrome will load them from CAPI on Windows, and can be told to use PKCS#11 on Linux.

You can then extend this to using one Yubikey as an X.509 CA that signs e.g. device-bound certificates (both Windows and Linux can store an X.509 RSA certificate on your computer's TPM – which is also accessible via PKCS#11 and CAPI – and you can carry around a "roaming" certificate in a second Yubikey), although it does need some plan for deploying revocation data for it to be really secure, but it sounds like not having one is your current state anyway.

grawity
  • 501,077
2

SSH can do VPNs. From ssh(1):

SSH-BASED VIRTUAL PRIVATE NETWORKS

ssh contains support for Virtual Private Network (VPN) tunnelling using the tun(4) network pseudo-device, allowing two networks to be joined se‐ curely. The sshd_config(5) configuration option PermitTunnel controls whether the server supports this, and at what level (layer 2 or 3 traf‐ fic).

The following example would connect client network 10.0.50.0/24 with re‐ mote network 10.0.99.0/24 using a point-to-point connection from 10.1.1.1 to 10.1.1.2, provided that the SSH server running on the gate‐ way to the remote network, at 192.168.1.15, allows it.

On the client:

# ssh -f -w 0:1 192.168.1.15 true
# ifconfig tun0 10.1.1.1 10.1.1.2 netmask 255.255.255.252
# route add 10.0.99.0/24 10.1.1.2

On the server:

# ifconfig tun1 10.1.1.2 10.1.1.1 netmask 255.255.255.252
# route add 10.0.50.0/24 10.1.1.1

Client access may be more finely tuned via the /root/.ssh/authorized_keys file (see below) and the PermitRootLogin server option. The following entry would permit connections on tun(4) device 1 from user “jane” and on tun device 2 from user “john”, if PermitRootLogin is set to “forced-commands-only”:

tunnel="1",command="sh /etc/netstart tun1" ssh-rsa ... jane
tunnel="2",command="sh /etc/netstart tun2" ssh-rsa ... john

Since an SSH-based setup entails a fair amount of overhead, it may be more suited to temporary setups, such as for wireless VPNs. More perma‐ nent VPNs are better provided by tools such as ipsecctl(8) and isakmpd(8).

On -w:

-w local_tun[:remote_tun]

Requests tunnel device forwarding with the specified tun(4) de‐ vices between the client (local_tun) and the server (remote_tun).

The devices may be specified by numerical ID or the keyword “any”, which uses the next available tunnel device. If remote_tun is not specified, it defaults to “any”. See also the Tunnel and TunnelDevice directives in ssh_config(5).

If the Tunnel directive is unset, it will be set to the default tunnel mode, which is “point-to-point”. If a different Tunnel forwarding mode it desired, then it should be specified before -w.

On "any computer":

The holy grail would be such that I can plug the Yubikey in any computer, download/configure a client and connect to the VPN server.

IDK about what OpenSSH does in Windows or if Windows has any level of support for some equivalent to tunnel devices. Besides that, there's the issue that grawity raised that to e.g. add to the system's routing table or create the network interface, you need administrative access, which you might not have in e.g. an internet cafe.

Anyway, ignoring those issues, this seems like the simplest way to create a VPN with Yubikey OpenPGP authentication (via using gpg-agent as an ssh-agent as I imagine you must already be doing).

I imagine it can potentially suck as a VPN a bit, because you'll end up nesting TCP in TCP among other overhead, hence why it says "it may be more suited to temporary setups".

Another option might be to use your VPN software of choice and encrypt whatever it uses as a key with your Yubikey. You can e.g. pipe the private key to Wireguard:

# gpg -d < vpn.key.gpg | wg set wg0 private-key /dev/stdin

The problem with this is that if it's not your computer and something snatches the key as you decrypt it, then the Yubikey becomes moot for future access to your VPN. You can evaluate this risk on your own.

JoL
  • 377