mirror of
https://github.com/systemd/systemd
synced 2024-09-06 16:56:43 +00:00
parent
9cc9021aed
commit
76df77794a
|
@ -1113,12 +1113,24 @@
|
|||
<para>The Base64 encoded private key for the interface. It can be
|
||||
generated using the <command>wg genkey</command> command
|
||||
(see <citerefentry project="wireguard"><refentrytitle>wg</refentrytitle><manvolnum>8</manvolnum></citerefentry>).
|
||||
This option is mandatory to use WireGuard.
|
||||
This option or <varname>PrivateKeyFile=</varname> is mandatory to use WireGuard.
|
||||
Note that because this information is secret, you may want to set
|
||||
the permissions of the .netdev file to be owned by <literal>root:systemd-network</literal>
|
||||
with a <literal>0640</literal> file mode.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>PrivateKeyFile=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a absolute path to a file which contains the Base64 encoded private key for the interface.
|
||||
If both <varname>PrivateKey=</varname> and <varname>PrivateKeyFile=</varname> are specified, and if
|
||||
the file specified in <varname>PrivateKeyFile=</varname> contains valid wireguard key, then
|
||||
the key provided by <varname>PrivateKey=</varname> is ignored.
|
||||
Note that the file must be readable by the user <literal>systemd-network</literal>, so it
|
||||
should be, e.g., owned by <literal>root:systemd-network</literal> with a
|
||||
<literal>0640</literal> file mode.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>ListenPort=</varname></term>
|
||||
<listitem>
|
||||
|
|
|
@ -167,6 +167,7 @@ VRF.Table, config_parse_uint32, 0,
|
|||
WireGuard.FwMark, config_parse_unsigned, 0, offsetof(Wireguard, fwmark)
|
||||
WireGuard.ListenPort, config_parse_wireguard_listen_port, 0, offsetof(Wireguard, port)
|
||||
WireGuard.PrivateKey, config_parse_wireguard_private_key, 0, 0
|
||||
WireGuard.PrivateKeyFile, config_parse_wireguard_private_key_file, 0, 0
|
||||
WireGuardPeer.AllowedIPs, config_parse_wireguard_allowed_ips, 0, 0
|
||||
WireGuardPeer.Endpoint, config_parse_wireguard_endpoint, 0, 0
|
||||
WireGuardPeer.PublicKey, config_parse_wireguard_public_key, 0, 0
|
||||
|
|
|
@ -11,12 +11,14 @@
|
|||
#include "alloc-util.h"
|
||||
#include "event-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "resolve-private.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
@ -529,6 +531,40 @@ int config_parse_wireguard_private_key(const char *unit,
|
|||
|
||||
}
|
||||
|
||||
int config_parse_wireguard_private_key_file(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_free_ char *path = NULL;
|
||||
Wireguard *w;
|
||||
|
||||
assert(data);
|
||||
w = WIREGUARD(data);
|
||||
assert(w);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
w->private_key_file = mfree(w->private_key_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
path = strdup(rvalue);
|
||||
if (!path)
|
||||
return log_oom();
|
||||
|
||||
if (path_simplify_and_warn(path, PATH_CHECK_ABSOLUTE, unit, filename, line, lvalue) < 0)
|
||||
return 0;
|
||||
|
||||
return free_and_replace(w->private_key_file, path);
|
||||
}
|
||||
|
||||
int config_parse_wireguard_preshared_key(const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
|
@ -807,11 +843,50 @@ static void wireguard_done(NetDev *netdev) {
|
|||
|
||||
sd_event_source_unref(w->resolve_retry_event_source);
|
||||
|
||||
free(w->private_key_file);
|
||||
|
||||
hashmap_free_with_destructor(w->peers_by_section, wireguard_peer_free);
|
||||
set_free(w->peers_with_unresolved_endpoint);
|
||||
set_free(w->peers_with_failed_endpoint);
|
||||
}
|
||||
|
||||
static int wireguard_read_private_key_file(Wireguard *w, bool fatal) {
|
||||
_cleanup_free_ char *contents = NULL;
|
||||
_cleanup_free_ void *key = NULL;
|
||||
size_t size, key_len;
|
||||
NetDev *netdev;
|
||||
int level, r;
|
||||
|
||||
assert(w);
|
||||
|
||||
netdev = NETDEV(w);
|
||||
|
||||
if (!w->private_key_file)
|
||||
return 0;
|
||||
|
||||
level = fatal ? LOG_ERR : LOG_INFO;
|
||||
|
||||
r = read_full_file(w->private_key_file, &contents, &size);
|
||||
if (r < 0)
|
||||
return log_netdev_full(netdev, level, r,
|
||||
"Failed to read private key from '%s'%s: %m",
|
||||
w->private_key_file, fatal ? "" : ", ignoring");
|
||||
|
||||
r = unbase64mem(contents, size, &key, &key_len);
|
||||
if (r < 0)
|
||||
return log_netdev_full(netdev, level, r,
|
||||
"Failed to decode private key%s: %m",
|
||||
fatal ? "" : ", ignoring");
|
||||
|
||||
if (key_len != WG_KEY_LEN)
|
||||
return log_netdev_full(netdev, level, SYNTHETIC_ERRNO(EINVAL),
|
||||
"Wireguard private key has invalid length (%zu bytes)%s: %m",
|
||||
key_len, fatal ? "" : ", ignoring");
|
||||
|
||||
memcpy(w->private_key, key, WG_KEY_LEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wireguard_peer_verify(WireguardPeer *peer) {
|
||||
NetDev *netdev = NETDEV(peer->wireguard);
|
||||
|
||||
|
@ -830,16 +905,23 @@ static int wireguard_peer_verify(WireguardPeer *peer) {
|
|||
static int wireguard_verify(NetDev *netdev, const char *filename) {
|
||||
WireguardPeer *peer, *peer_next;
|
||||
Wireguard *w;
|
||||
bool empty;
|
||||
int r;
|
||||
|
||||
assert(netdev);
|
||||
w = WIREGUARD(netdev);
|
||||
assert(w);
|
||||
|
||||
if (eqzero(w->private_key))
|
||||
empty = eqzero(w->private_key);
|
||||
if (empty && !w->private_key_file)
|
||||
return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
|
||||
"%s: Missing PrivateKey= or PrivateKeyFile=, ignoring.",
|
||||
filename);
|
||||
|
||||
r = wireguard_read_private_key_file(w, empty);
|
||||
if (r < 0 && empty)
|
||||
return r;
|
||||
|
||||
LIST_FOREACH_SAFE(peers, peer, peer_next, w->peers)
|
||||
if (wireguard_peer_verify(peer) < 0)
|
||||
wireguard_peer_free(peer);
|
||||
|
|
|
@ -38,6 +38,7 @@ struct Wireguard {
|
|||
|
||||
uint32_t flags;
|
||||
uint8_t private_key[WG_KEY_LEN];
|
||||
char *private_key_file;
|
||||
uint16_t port;
|
||||
uint32_t fwmark;
|
||||
|
||||
|
@ -60,5 +61,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_listen_port);
|
|||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_public_key);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_private_key);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_private_key_file);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_preshared_key);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_wireguard_keepalive);
|
||||
|
|
|
@ -9,6 +9,7 @@ Mode=
|
|||
[WireGuard]
|
||||
ListenPort=
|
||||
PrivateKey=
|
||||
PrivateKeyFile=
|
||||
FwMark=
|
||||
[MACVTAP]
|
||||
Mode=
|
||||
|
|
Loading…
Reference in a new issue