My personal project and infrastructure archive
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nomicon/nixos/modules/services/networking/yggdrasil.xml

168 lines
5.0 KiB

<?xml version="1.0"?>
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" version="5.0" xml:id="module-services-networking-yggdrasil">
<title>Yggdrasil</title>
<para>
<emphasis>Source:</emphasis>
<filename>modules/services/networking/yggdrasil/default.nix</filename>
</para>
<para>
<emphasis>Upstream documentation:</emphasis>
<link xlink:href="https://yggdrasil-network.github.io/"/>
</para>
<para>
Yggdrasil is an early-stage implementation of a fully end-to-end encrypted
IPv6 network. It is lightweight, self-arranging, supported on multiple
platforms and allows pretty much any IPv6-capable application to communicate
securely with other Yggdrasil nodes.
</para>
<para>
When enabled the Yggdrasil service creates a tun device with a unique IPv6 in
the <literal>200::/8</literal> address space. This device and address can be
used to communicate with all other connected nodes in the
<literal>200::/7</literal> Yggdrasil network. Each Yggdrasil node can also
route a subnet using the first half of its address with the eighth bit masked
as a prefix, that is to say, within the <literal>300::/8</literal> space. This
prefix may be announced to locally attached networks.
</para>
<para>
Despite the normal distribution of nodes within the <literal>200::/8</literal>
space, the addresses of connected nodes can be readily enumerated, unlike the
the traditional global IPv6 network. For this reason, all open services on a
node should be considered public, or the system firewall should be enabled.
</para>
<section xml:id="module-services-networking-yggdrasil-configuration">
<title>Configuration</title>
<section xml:id="module-services-networking-yggdrasil-configuration-simple">
<title>Simple ephemeral node</title>
<para>
An annotated example of a simple configuration:
<programlisting>
{
services.yggdrasil = {
enable = true;
config = {
Peers = [
# Yggdrasil will automatically connect and "peer" with other nodes it
# discovers via link-local multicast annoucements. Unless this is the
# case (it probably isn't) a node needs peers within the existing
# network that it can tunnel to.
"tcp://1.2.3.4:1024"
"tcp://1.2.3.5:1024"
];
};
};
}
</programlisting>
</para>
</section>
<section xml:id="module-services-networking-yggdrasil-configuration-prefix">
<title>Persistent node with prefix</title>
<para>
A node with a fixed address that announces a prefix:
<programlisting>
let
address = "210:5217:69c0:9afc:1b95:b9f:8718:c3d2";
prefix = "310:5217:69c0:9afc";
# taken from the output of "yggdrasilctl getself".
in {
services.yggdrasil = {
enable = true;
persistentKeys = true; # Maintain a fixed public key and IPv6 address.
config = {
Peers = [ "tcp://1.2.3.4:1024" "tcp://1.2.3.5:1024" ];
NodeInfo = {
# This information is visible to the network.
name = config.networking.hostName;
location = "The North Pole";
};
};
};
boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
# Forward traffic under the prefix.
networking.interfaces.${eth0}.ipv6.addresses = [{
# Set a 300::/8 address on the local physical device.
address = prefix + "::1";
prefixLength = 64;
}];
services.radvd = {
# Annouce the 300::/8 prefix to eth0.
enable = true;
config = ''
interface eth0
{
AdvSendAdvert on;
AdvDefaultLifetime 0;
prefix ${prefix}::/64 {
AdvOnLink on;
AdvAutonomous on;
};
route 200::/8 {};
};
'';
};
}
</programlisting>
</para>
</section>
<section xml:id="module-services-networking-yggdrasil-configuration-container">
<title>Yggdrasil attached Container</title>
<para>
A NixOS container attached to the Yggdrasil network via a node running on the
host:
<programlisting>
let
yggPrefix64 = "&#x2026;";
in
{
boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;
# Enable IPv6 forwarding.
networking = {
bridges.br0.interfaces = [ ];
# A bridge only to containers&#x2026;
interfaces.br0 = {
# &#x2026; configured with a prefix address.
ipv6.addresses = [{
address = "${yggPrefix64}::1";
prefixLength = 64;
}];
};
};
containers.foo = {
autoStart = true;
privateNetwork = true;
hostBridge = "br0";
# Attach the container to the bridge only.
config = { config, pkgs, ... }: {
networking.interfaces.eth0.ipv6 = {
addresses = [{
# Configure a prefix address.
address = "${yggPrefix64}::2";
prefixLength = 64;
}];
routes = [{
# Configure the prefix route.
address = "200::";
prefixLength = 7;
via = "${yggPrefix64}::1";
}];
};
services.httpd.enable = true;
networking.firewall.allowedTCPPorts = [ 80 ];
};
};
}
</programlisting>
</para>
</section>
</section>
</chapter>