Wireguard connection without storing private keys


Is it possible to create a Wireguard VPN client connection from an openWRT device without storing the private key persistently?
I would like to supply the key each time a connection needs to be made without ever storing it on the file system (eg in configuration files). The key can be supplied through any local commands that can be executed over ssh.

To provide a bit of context we are using openWRT based devices to connect remote clients to our internal infrastructure. The connected computers on the lan side should not have direct internet access, the openWRT device only exposes the VPN network. However, the wireguard private keys should only be stored on the computers and not the router. This way if the device is misplaced or stolen it cannot make a connection to the internal network and the keys cannot be retrieved.

I know that this can be achieved when the wireguard connection is managed by systemd or nmcli, but I am not very familiar with openWRT so any help is welcome!

The private key for the remote peer does not need to be stored persistently on the OpenWrt side. You can generate it and then delete it via LuCI or use the CLI for key generation and output to a text file or just the standard output, then toss the private key once it has been transferred to the remote peer. You must keep the public key, of course.

But, keep in mind that each time you add/modify the keys, you need to restart the wireguard interface on the OpenWrt side. If there are other connected peers, this would be disruptive.

I understand the general reasoning for this, but I think this might produce a lot of friction, including the process of key exchanges and the like.

Another way to approach this would be with the firewall (in OpenWrt)... you could allow/prohibit the access from remote peers with firewall rules that you would enable/disable as appropriate (i.e. when you need to grant access, you enable access, block access when they are done).

Thank you for the answer, it is much appreciated.

I feel like like I have not explained well enough the setup I am trying to build.
The wireguard server runs on the infra side on a Debian based system, it stores the public keys of each permitted client.
Each client connects with their openWRT device. To establish the connection they need the server's public key and their own private key (associated with the public keys accepted by the server).
I don't want to issue new keys for each connection, because that complicates everything on server side and introduces a complicated key management process.
All I want to avoid is the need to store this private key on the device itself.

I know that with nmcli you can do something like this:

 <some command that provides the private key> | nmcli connection up wg0 passwd-file /dev/fd/0'

If nmcli is configured to not store the password this will be required each time to initiate the connection.
Similarly, if the wireguard client is managed by systemd this can be added to the config:

PostUp = wg set %i private-key <(some command here)

I am trying to achieve something similar with openWRT. When the openwrt client attempts to connect to the wireguard server the user should supply the private key from their computer so a device by itself is not able to make a connection.

Let me rephrase, I want to avoid storing the local peers private key on the openWRT device persistently. So that it needs to be supplied each time the connection is made.

So your intent is to have the remote peer retrieve the private key at the time that it needs to connect? Do you expect this to be a pull operation (i.e. the peer asks some server to return the key)? or a push (something sends the peer the private key unsolicited but when needed)?

I think you're creating a chicken-or-egg situation.

A few thoughts:

  1. I understand the reason you would want the remote peer to not keep the private key -- in the even of loss or theft... but if it can retrieve its key upon connecting, how does that help with security?
  2. How would the remote peer connect in order to request its private key?
  3. How would the server containing the private key library authenticate the request, send the correct private key, and ensure that the device isn't lost/stolen?
  4. When would the remote peer clear the private key, and how would it do this (what mechanism)?

The key can be pushed upon connection establishment even through ssh.
Ideally the device should not store the local peer key in a config file ever, so if it is power cycled the key is lost.
The connection establishment would look something like this:

  1. The user wants to connect to the remote site so it connects the openwrt device to his laptop
  2. The user invokes the shell script that creates the connection and pushes over the (local peer) private key from the laptop to the device (e.g over ssh).
  3. Once the user is done they disconnect the device which powers off (the key is not stored there)

It is ok, or even better if the key needs to be supplied again if the connection is interrupted.

IMO, this creates a more significant security vulnerability than just keeping the keys in the device.

Assuming that the laptop is reasonably well secured, why not just run Wireguard on the laptop itself.

This is unfortunately a non-technical limitation that I need to work with.
The laptop is never allowed to directly connect to the internet, not even a specific remote address.

So how does it get the keys? And once it has keys and somehow loads them into the openwrt router, how are those routes established?

The base assumption is that the laptop has the keys. It is distributed out of band through some other means. It connects to the openwrt device via lan. It shall only access the device itself and the internal network that the openwrt device connects to.

Basically what I am looking for is a set of commands that can be executed over ssh (from lan) on the openwrt router that creates a non-persistent wireguard connection. The interface and configuration can be persistent, but the local peer private key should not.

I guess you could try one of these:

  • set the OpenWrt working space to ram rather than mounted against a standard storage area.
  • Create a boot-time script that would delete the private key upon boot (if it exists).
1 Like

I have some idea how this can be done.
When you setup WG you need to set a private key first (the public key is derived from the private key)
The private key need to be a file

I do this on another third party firmware like this:
Get private key from nvram and store in file on /tmp/wg0
Set the private key in wg: wg set private-key /tmp/wg0
(wg is the wg tool command)
Next setup: wg

After a reboot the private key file in /tmp is of course gone.

Instead of getting the private key from nvram you can retrieve it from somewhere else e.g. protected with password

So I think it can be done with a hotplug script

1 Like