Introduction
I ran across this archived reddit thread today: https://www.reddit.com/r/WireGuard/comments/gn7qob/wireguard_using_a_pkcs_token_on_hardware/
The problem to solve, is to figure out how to store a public key as a secret on a yubikey.
One part of the problem, is that for this approach to work, you must allow objects to be read from the yubikey without pin code. Mainly since I have not figured out a way to script pin input to ykman
.
- Store a secret as an object on the Yubikey
- Use the secret stored on the Yubikey in the
wireguard
configuration file
First, we need to have a look at how to store objects, and what addresses are available: https://developers.yubico.com/yubico-piv-tool/Actions/read_write_objects.html
I selected address 0x5fc106; “Security Object”. In my very limited testing, it looks like the 0x5fc106/“Security Object” is not protected by a pin code, whereas some others (e.g 0x5fc109/“Printed Information”) are protected by a pin code.
#--- Create a private key
$ wg genkey > myPrivKey.out
#--- or use an already existing private key (do not use this one)
$ ykman piv write-object 0x5fc106 ./myPrivKey.out
#--- test that the object could be written, and that you don't have a pin code set
$ ykman piv read-object 0x5fc106
2Hyrkc6MUFI17GXAHVv1K1oImYi1dIzZw8N8+o1XflA=
Now your yubikey is set up properly, and you can replace the [Intervace]
/PrivateKey
attribute in your /etc/wiregurad/wg0.conf
file with a PostUp
attribute.
#PrivateKey = 2Hyrkc6MUFI17GXAHVv1K1oImYi1dIzZw8N8+o1XflA=
PostUp = wg set %i private-key <(ykman piv read-object 0x5fc106)
Now, test that the interface comes up again:
$ sudo wg-quick down wg0
[#] ip link delete dev wg0
$ sudo wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.66.67.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] wg set wg0 private-key <(ykman piv read-object 0x5fc106)
$ ip a show wg0
11: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.66.67.1/24 scope global wg0
valid_lft forever preferred_lft forever
$ sudo wg show
interface: wg0
public key: Wk5ZOgVlGo8nZzoUY+ZmzhsyJSNqsGgZP0ZuIDXmu3A=
private key: (hidden)
listening port: 37551
peer: WCuj2WSxP3uf6QvVJLs6DvRiW/9wrGOUCQ+H1eG1/lc=
allowed ips: 10.66.67.2/32
persistent keepalive: every 25 seconds
peer: BDaWfOFmkvK5KMHRH+J/VrU2Tn7tvAR2bqX3SB9cqGE=
allowed ips: 10.66.67.3/32
persistent keepalive: every 25 seconds