Tinc: Difference between revisions

imported>Falsifian
networking.interfaces: Add my experience getting tinc working.
imported>Makefu
pre -> syntaxHighlight
Line 24: Line 24:
Tinc clients need to verify themselves to each other, which is done by keys. There are multiple ways to generate your keys. Here is one.
Tinc clients need to verify themselves to each other, which is done by keys. There are multiple ways to generate your keys. Here is one.


<pre>nix-shell -p tinc_pre --run &quot;tinc generate-keys 4096&quot;</pre>
<pre>nix-shell -p tinc_pre --run "tinc generate-keys 4096"</pre>
The command ask you where to put the keys. If you hit enter a few times it will generate 4 files. (instead of hitting enter you can give it different file path)
The command ask you where to put the keys. If you hit enter a few times it will generate 4 files. (instead of hitting enter you can give it different file path)


Line 67: Line 67:
The simplest way is to use the networking module. But it has some minor flaws on package updates.
The simplest way is to use the networking module. But it has some minor flaws on package updates.


<pre># for heinz
<syntaxHighlight lang=nix># for heinz
networking.interfaces.&quot;tinc.private&quot; = [ { address = 10.1.1.25; } ];
networking.interfaces."tinc.private" = [ { address = 10.1.1.25; } ];
</pre>
</syntaxHighlight>


Another author has experienced problems with the network failing to restart when using the above to configure interfaces.
Another author has experienced problems with the network failing to restart when using the above to configure interfaces.
The following snippet '''seems''' to fix that (until perhaps a more proper fix is upstreamed?):
The following snippet '''seems''' to fix that (until perhaps a more proper fix is upstreamed?):
<pre>
<syntaxHighlight lang=nix>
   systemd.services."network-addresses-tinc.${networkName}".before = [ "tinc.${networkName}.service" ];
   systemd.services."network-addresses-tinc.${networkName}".before = [ "tinc.${networkName}.service" ];
   systemd.services."network-link-tinc.${networkName}".before = [ "tinc.${networkName}.service" ];
   systemd.services."network-link-tinc.${networkName}".before = [ "tinc.${networkName}.service" ];
</pre>
</syntaxHighlight>
Note 2019-12-28: another author found that those lines were counter-productive. Their system hung for 90 seconds on boot waiting for /sys/subsystem/net/devices/tinc.<tinc network name> to be available, and then after booting they had to manually do something to get tinc working. Removing those lines fixed both problems.
Note 2019-12-28: another author found that those lines were counter-productive. Their system hung for 90 seconds on boot waiting for /sys/subsystem/net/devices/tinc.<tinc network name> to be available, and then after booting they had to manually do something to get tinc working. Removing those lines fixed both problems.


Line 85: Line 85:
First we have to create the scripts:
First we have to create the scripts:


<pre># for heinz
<syntaxHighlight lang=nix># for heinz
environment.etc.&quot;tinc/private/tinc-up&quot;.source = pkgs.writeScript &quot;tinc-up-private'
environment.etc."tinc/private/tinc-up".source = pkgs.writeScript &quot;tinc-up-private'
   #!${pkgs.stdenv.shell}
   #!${pkgs.stdenv.shell}
   ${pkgs.nettools}/bin/ifconfig $INTERFACE 10.1.1.25 netmask 255.255.255.0
   ${pkgs.nettools}/bin/ifconfig $INTERFACE 10.1.1.25 netmask 255.255.255.0
'';
'';
environment.etc.&quot;tinc/private/tinc-down&quot;.source = pkgs.writeScript &quot;tinc-down-private''
environment.etc."tinc/private/tinc-down".source = pkgs.writeScript "tinc-down-private''
   #!${pkgs.stdenv.shell}
   #!${pkgs.stdenv.shell}
   /run/wrappers/bin/sudo ${pkgs.nettools}/bin/ifconfig $INTERFACE down
   /run/wrappers/bin/sudo ${pkgs.nettools}/bin/ifconfig $INTERFACE down
'';</pre>
'';</syntaxHighlight>
For the <code>tinc-down</code> we need to use sudo, because the user <code>tinc.private</code> who starts the service is not able to tear down the interface.
For the <code>tinc-down</code> we need to use sudo, because the user <code>tinc.private</code> who starts the service is not able to tear down the interface.


So we have to make sure this user can call sudo without entering a password.
So we have to make sure this user can call sudo without entering a password.


<pre> security.sudo.extraRules = [
<syntaxHighlight lang=nix> security.sudo.extraRules = [
     {
     {
       users    = [ &quot;tinc.private&quot; ];
       users    = [ "tinc.private" ];
       commands = [
       commands = [
         {
         {
           command  = &quot;${pkgs.nettools}/bin/ifconfig&quot;;
           command  = "${pkgs.nettools}/bin/ifconfig";
           options  = [ &quot;NOPASSWD&quot; ];
           options  = [ "NOPASSWD" ];
         }
         }
       ];
       ];
     }
     }
   ];</pre>
   ];</syntaxHighlight>
== Open the Firewall ==
== Open the Firewall ==


The computer which you connect to needs to open some ports.
The computer which you connect to needs to open some ports.


<pre>networking.firewall.allowedUDPPorts = [ 655 ];
<syntaxHighlight lang=nix>networking.firewall.allowedUDPPorts = [ 655 ];
networking.firewall.allowedTCPPorts = [ 655 ];</pre>
networking.firewall.allowedTCPPorts = [ 655 ];</syntaxHighlight>
== use service.tinc module ==
== use service.tinc module ==


Line 125: Line 125:
=== /etc/nixos/tinc.nix on heinz ===
=== /etc/nixos/tinc.nix on heinz ===


<pre>{ config, pkgs, ... }:
<syntaxHighlight lang=nix>{ config, pkgs, ... }:


let
let


   myMeshIp  = &quot;10.1.1.25&quot;;
   myMeshIp  = "10.1.1.25";
   myMeshMask = &quot;255.255.255.0&quot;;
   myMeshMask = "255.255.255.0";
   myMeshName = &quot;private&quot;;
   myMeshName = "private";


in {
in {
Line 137: Line 137:
   # simple interface setup
   # simple interface setup
   # ----------------------
   # ----------------------
   networking.interfaces.&quot;tinc.${myMeshName}&quot; = [ { address = myMeshIp; } ];
   networking.interfaces."tinc.${myMeshName}" = [ { address = myMeshIp; } ];




   # configure tinc service
   # configure tinc service
   # ----------------------
   # ----------------------
   services.tinc.networks.&quot;${myMeshName}&quot;= {
   services.tinc.networks."${myMeshName}"= {


     name          = &quot;heinz&quot;;      # who are we in this network.
     name          = "heinz";      # who are we in this network.


     debugLevel    = 3;            # the debug level for journal -u tinc.private
     debugLevel    = 3;            # the debug level for journal -u tinc.private
     chroot        = false;        # otherwise addresses can't be a DNS
     chroot        = false;        # otherwise addresses can't be a DNS
     interfaceType = &quot;tap&quot;;        # tun might also work.
     interfaceType = "tap";        # tun might also work.


     extraConfig  = ''
     extraConfig  = ''
Line 160: Line 160:
       # if you don't set the path as string, it will import the file in
       # if you don't set the path as string, it will import the file in
       # in the nix/store where everybody can read it.
       # in the nix/store where everybody can read it.
       Ed25519PrivateKeyFile = &quot;/root/secrets/heinz/ed25519_key.priv&quot;
       Ed25519PrivateKeyFile = "/root/secrets/heinz/ed25519_key.priv"
       PrivateKeyFile        = &quot;/root/secrets/heinz/rsa_key.priv&quot;
       PrivateKeyFile        = "/root/secrets/heinz/rsa_key.priv"
     '';
     '';
     hosts = {
     hosts = {
Line 187: Line 187:
   };
   };
}
}
</pre>
</syntaxHighlight>
=== /etc/nixos/tinc.nix on peter ===
=== /etc/nixos/tinc.nix on peter ===


<pre>{ config, pkgs, ... }:
<syntaxHighlight lang=nix>{ config, pkgs, ... }:


let
let


   myMeshIp  = &quot;10.1.1.21&quot;;
   myMeshIp  = "10.1.1.21";
   myMeshMask = &quot;255.255.255.0&quot;;
   myMeshMask = "255.255.255.0";
   myMeshName = &quot;private&quot;;
   myMeshName = "private";


in {
in {
Line 207: Line 207:
   # simple interface setup
   # simple interface setup
   # ----------------------
   # ----------------------
   networking.interfaces.&quot;tinc.${myMeshName}&quot; = [ { address = myMeshIp; } ];
   networking.interfaces."tinc.${myMeshName}" = [ { address = myMeshIp; } ];




   # configure tinc service
   # configure tinc service
   # ----------------------
   # ----------------------
   services.tinc.networks.&quot;${myMeshName}&quot;= {
   services.tinc.networks."${myMeshName}"= {


     name          = &quot;peter&quot;;      # who are we in this network.
     name          = "peter";      # who are we in this network.


     debugLevel    = 3;            # the debug level for journal -u tinc.private
     debugLevel    = 3;            # the debug level for journal -u tinc.private
     chroot        = false;        # otherwise addresses can't be a DNS
     chroot        = false;        # otherwise addresses can't be a DNS
     interfaceType = &quot;tap&quot;;        # tun might also work.
     interfaceType = "tap";        # tun might also work.


     extraConfig  = ''
     extraConfig  = ''
Line 225: Line 225:
       # if you don't set the path as string, it will import the file in
       # if you don't set the path as string, it will import the file in
       # in the nix/store where everybody can read it.
       # in the nix/store where everybody can read it.
       Ed25519PrivateKeyFile = &quot;/root/secrets/peter/ed25519_key.priv&quot;
       Ed25519PrivateKeyFile = "/root/secrets/peter/ed25519_key.priv"
       PrivateKeyFile        = &quot;/root/secrets/peter/rsa_key.priv&quot;
       PrivateKeyFile        = "/root/secrets/peter/rsa_key.priv"
     '';
     '';
     hosts = {
     hosts = {
Line 251: Line 251:
     };
     };
   };
   };
}</pre>
}</syntaxHighlight>