Browse Source

gluon-mesh-vpn-core: add public key to nodeinfo response

This is currently only implemented in the gluon-mesh-vpn-fastd
package.

Advertising the public key may be deemed problematic when
your threat-model involves protecting the nodes privacy
from tunnel traffic correlation by onlink observers.

It can be enabled by setting site.mesh_vpn.fastd.pubkey_privacy
to `false`.
Martin Weinelt 6 years ago
parent
commit
42763d21dc

+ 7 - 0
docs/user/site.rst

@@ -198,6 +198,12 @@ mesh_vpn
     defines the MTU of the VPN interface, determining a proper MTU value is described
     in the :ref:`FAQ <faq-mtu>`.
 
+    By default the public key of a node's VPN daemon is not added to announced respondd
+    data; this prevents malicious ISPs from correlating VPN sessions with specific mesh
+    nodes via public respondd data. If this is of no concern in your threat model,
+    this behaviour can be disabled (and thus announcing the public key be enabled) by
+    setting `pubkey_privacy` to `false`. At the moment, this option only affects fastd.
+
     The `fastd` section configures settings specific to the *fastd* VPN
     implementation.
 
@@ -225,6 +231,7 @@ mesh_vpn
       mesh_vpn = {
         -- enabled = true,
         mtu = 1312,
+        -- pubkey_privacy = true,
 
         fastd = {
           methods = {'salsa2012+umac'},

+ 1 - 0
package/gluon-mesh-vpn-core/check_site.lua

@@ -1,5 +1,6 @@
 need_boolean(in_site({'mesh_vpn', 'enabled'}), false)
 need_number({'mesh_vpn', 'mtu'})
+need_boolean(in_site({'mesh_vpn', 'pubkey_privacy'}), false)
 
 need_boolean(in_site({'mesh_vpn', 'bandwidth_limit', 'enabled'}), false)
 need_number(in_site({'mesh_vpn', 'bandwidth_limit', 'ingress'}), false)

+ 52 - 0
package/gluon-mesh-vpn-fastd/src/respondd.c

@@ -73,6 +73,56 @@ static struct json_object * get_fastd_version(void) {
 	return ret;
 }
 
+static struct json_object * get_fastd_public_key(void) {
+	FILE *f = popen("/etc/init.d/fastd show_key mesh_vpn", "r");
+	if (!f)
+		return NULL;
+
+	char *line = NULL;
+	size_t len = 0;
+
+	ssize_t r = getline(&line, &len, f);
+
+	pclose(f);
+
+	if (r >= 0) {
+		len = strlen(line); /* The len given by getline is the buffer size, not the string length */
+
+		if (len && line[len-1] == '\n')
+			line[len-1] = 0;
+	}
+	else {
+		free(line);
+		line = NULL;
+	}
+
+	return gluonutil_wrap_and_free_string(line);
+}
+
+static bool get_pubkey_privacy(void) {
+	bool ret = true;
+	struct json_object *site = NULL;
+
+	site = gluonutil_load_site_config();
+	if (!site)
+		goto end;
+
+	struct json_object *mesh_vpn;
+	if (!json_object_object_get_ex(site, "mesh_vpn", &mesh_vpn))
+		goto end;
+
+	struct json_object *pubkey_privacy;
+	if (!json_object_object_get_ex(mesh_vpn, "pubkey_privacy", &pubkey_privacy))
+		goto end;
+
+	ret = json_object_get_boolean(pubkey_privacy);
+
+end:
+	json_object_put(site);
+
+	return ret;
+}
+
 static struct json_object * get_fastd(void) {
 	bool enabled = false;
 	struct json_object *ret = json_object_new_object();
@@ -100,6 +150,8 @@ disabled:
 disabled_nofree:
 	json_object_object_add(ret, "version", get_fastd_version());
 	json_object_object_add(ret, "enabled", json_object_new_boolean(enabled));
+	if (enabled && !get_pubkey_privacy())
+		json_object_object_add(ret, "public_key", get_fastd_public_key());
 	return ret;
 }