From: Ismaël Bouya Date: Thu, 13 Feb 2020 12:05:40 +0000 (+0100) Subject: Add Tinc VPN X-Git-Url: https://git.immae.eu/?p=perso%2FImmae%2FConfig%2FNix.git;a=commitdiff_plain;h=ea9c6fe8041faab128391a0c03ec3bde25e29fa3 Add Tinc VPN --- diff --git a/modules/private/default.nix b/modules/private/default.nix index 945a799..3996eac 100644 --- a/modules/private/default.nix +++ b/modules/private/default.nix @@ -46,6 +46,7 @@ set = { cloudTool = ./websites/tools/cloud; davTool = ./websites/tools/dav; + vpnTool = ./websites/tools/vpn; dbTool = ./websites/tools/db; diasporaTool = ./websites/tools/diaspora; etherTool = ./websites/tools/ether; @@ -72,6 +73,7 @@ set = { ssh = ./ssh; monitoring = ./monitoring; status = ./monitoring/status.nix; + vpn = ./vpn; environment = ./environment.nix; system = ./system.nix; diff --git a/modules/private/environment.nix b/modules/private/environment.nix index 3b51f37..2cecc6d 100644 --- a/modules/private/environment.nix +++ b/modules/private/environment.nix @@ -536,6 +536,16 @@ in }; }; }; + vpn = mkOption { + description = "VPN configuration"; + type = attrsOf (submodule { + options = { + prefix = mkOption { type = str; description = "ipv6 prefix for the vpn subnet"; }; + privateKey = mkOption { type = str; description = "Private key for the host"; }; + publicKey = mkOption { type = str; description = "Public key for the host"; }; + }; + }); + }; mail = mkOption { description = "Mail configuration"; type = submodule { diff --git a/modules/private/system/eldiron.nix b/modules/private/system/eldiron.nix index 0ff9963..5e3d45c 100644 --- a/modules/private/system/eldiron.nix +++ b/modules/private/system/eldiron.nix @@ -34,6 +34,7 @@ myServices.websites.enable = true; myServices.mail.enable = true; myServices.ejabberd.enable = true; + myServices.vpn.enable = true; services.pure-ftpd.enable = true; services.duplyBackup.enable = true; services.duplyBackup.profiles.oldies.rootDir = "/var/lib/oldies"; diff --git a/modules/private/vpn/default.nix b/modules/private/vpn/default.nix new file mode 100644 index 0000000..fbcba2f --- /dev/null +++ b/modules/private/vpn/default.nix @@ -0,0 +1,62 @@ +{ config, pkgs, lib, ... }: +let + cfg = config.myServices.vpn; +in +{ + options.myServices = { + vpn.enable = lib.mkEnableOption "Enable vpn service"; + }; + + config = lib.mkIf cfg.enable { + secrets.keys = [ + { + dest = "tinc/key.priv"; + user = "root"; + group = "root"; + permissions = "0400"; + text = config.myEnv.vpn.eldiron.privateKey; + } + { + dest = "tinc/key.pub"; + user = "root"; + group = "root"; + permissions = "0400"; + text = config.myEnv.vpn.eldiron.publicKey; + } + ]; + networking.firewall.allowedTCPPorts = [ 655 1194 ]; + system.activationScripts.tinc = let + configFiles = pkgs.runCommand "tinc-files" { + mainInterface = "eth0"; + hostName = "ImmaeEu"; + network = "Immae"; + keyFile = config.secrets.fullPaths."tinc/key.priv"; + } '' + mkdir -p $out + for i in ${./tinc}/*; do + substituteAll $i $out/$(basename $i) + done + ''; + in '' + install -m750 -o root -g root -d /var/lib/tinc/ /var/lib/tinc/Immae + install -m700 -o root -g root -t /var/lib/tinc/Immae ${configFiles}/{host-*,tinc-*} + install -m400 -o root -g root -t /var/lib/tinc/Immae ${configFiles}/tinc.conf + if [ ! -d /var/lib/tinc/Immae/hosts ]; then + ${pkgs.git}/bin/git clone -b master https://git.immae.eu/perso/Immae/Config/tinc/hosts /var/lib/tinc/Immae/hosts + fi + ''; + + systemd.services.tinc-Immae = { + description = "Tinc Daemon - Immae"; + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + path = [ pkgs.tinc pkgs.bashInteractive pkgs.iproute pkgs.gnused pkgs.gawk pkgs.git pkgs.glibc ]; + serviceConfig = { + Type = "simple"; + Restart = "always"; + RestartSec = "3"; + ExecStart = "${pkgs.tinc}/bin/tincd -d1 -D -c /var/lib/tinc/Immae --pidfile /run/tinc.Immae.pid"; + }; + }; + }; +} diff --git a/modules/private/vpn/tinc/host-down b/modules/private/vpn/tinc/host-down new file mode 100755 index 0000000..1e79bd3 --- /dev/null +++ b/modules/private/vpn/tinc/host-down @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +SUBDOMAIN=$(echo "$NODE" | sed -e "s/\([A-Z][a-z0-9]*\)/\L\1 /g;" | awk '{ for (i=NF; i>1; i--) printf("%s.",$i); print $1; }') +NODEIPS=`getent hosts ${SUBDOMAIN}.immae.eu | cut -d' ' -f1 | tr "\\n" ' '` +for NODEIP in $NODEIPS; do + ip neigh del proxy $NODEIP dev @mainInterface@ +done diff --git a/modules/private/vpn/tinc/host-up b/modules/private/vpn/tinc/host-up new file mode 100755 index 0000000..2f7cee2 --- /dev/null +++ b/modules/private/vpn/tinc/host-up @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +SUBDOMAIN=$(echo "$NODE" | sed -e "s/\([A-Z][a-z0-9]*\)/\L\1 /g;" | awk '{ for (i=NF; i>1; i--) printf("%s.",$i); print $1; }') +while [ -z "$NODEIPS" ]; do + NODEIPS=`getent hosts ${SUBDOMAIN}.immae.eu | cut -d' ' -f1 | tr "\\n" ' '` + sleep 5 +done +for NODEIP in $NODEIPS; do + ip neigh add proxy $NODEIP dev @mainInterface@ +done +(cd /var/lib/tinc/@network@/hosts && git pull -q origin master) || true diff --git a/modules/private/vpn/tinc/tinc-down b/modules/private/vpn/tinc/tinc-down new file mode 100755 index 0000000..1cc45c0 --- /dev/null +++ b/modules/private/vpn/tinc/tinc-down @@ -0,0 +1,12 @@ +#!/bin/sh +# This file closes down the tap device. + +echo 0 > /proc/sys/net/ipv6/conf/@mainInterface@/proxy_ndp +echo 0 > /proc/sys/net/ipv6/conf/all/forwarding + +GWIP=`getent hosts gw.vpn.immae.eu | head -n1 | cut -d' ' -f1` + +ip neigh del proxy $GWIP dev eth0 + +ip -6 addr del $GWIP/96 dev $INTERFACE +ip -6 link set $INTERFACE down diff --git a/modules/private/vpn/tinc/tinc-up b/modules/private/vpn/tinc/tinc-up new file mode 100755 index 0000000..26c1ec3 --- /dev/null +++ b/modules/private/vpn/tinc/tinc-up @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +echo 1 > /proc/sys/net/ipv6/conf/@mainInterface@/proxy_ndp +echo 1 > /proc/sys/net/ipv6/conf/all/forwarding + +SUBNET=`getent hosts sn.vpn.immae.eu | head -n1 | cut -d' ' -f1` +GWIP=`getent hosts gw.vpn.immae.eu | head -n1 | cut -d' ' -f1` + +ip -6 link set $INTERFACE up mtu 1280 txqueuelen 1000 + +ip -6 addr add $GWIP/96 dev $INTERFACE +ip -6 route add $SUBNET/80 dev $INTERFACE + +ip neigh add proxy $GWIP dev @mainInterface@ diff --git a/modules/private/vpn/tinc/tinc.conf b/modules/private/vpn/tinc/tinc.conf new file mode 100644 index 0000000..7a4f103 --- /dev/null +++ b/modules/private/vpn/tinc/tinc.conf @@ -0,0 +1,11 @@ +BindToAddress = * 655 +BindToAddress = * 1194 + +Name = @hostName@ +Interface = vpn6 + +Mode = switch + +Device = /dev/net/tun +GraphDumpFile = /var/lib/tinc/@network@/tinc_graph +PrivateKeyFile = @keyFile@ diff --git a/modules/private/websites/tools/tools/default.nix b/modules/private/websites/tools/tools/default.nix index f88cf06..9fb2d03 100644 --- a/modules/private/websites/tools/tools/default.nix +++ b/modules/private/websites/tools/tools/default.nix @@ -102,6 +102,7 @@ in { root = "/var/lib/ftp/tools.immae.eu"; extraConfig = [ '' + RedirectMatch 301 ^/vpn(.*)$ https://vpn.immae.eu$1 RedirectMatch 301 ^/roundcube(.*)$ https://mail.immae.eu/roundcube$1 RedirectMatch 301 ^/jappix(.*)$ https://im.immae.fr/converse @@ -152,6 +153,8 @@ in { RedirectMatch 301 ^/jappix(.*)$ https://im.immae.fr/converse + RedirectMatch 301 ^/vpn(.*)$ https://vpn.immae.eu$1 + RedirectMatch 301 ^/(.*)$ https://tools.immae.eu/$1 '' ]; diff --git a/modules/private/websites/tools/vpn/default.nix b/modules/private/websites/tools/vpn/default.nix new file mode 100644 index 0000000..cfe010c --- /dev/null +++ b/modules/private/websites/tools/vpn/default.nix @@ -0,0 +1,15 @@ +{ lib, pkgs, config, ... }: +let + cfg = config.myServices.vpn; +in { + config = lib.mkIf cfg.enable { + services.websites.env.tools.vhostConfs.vpn = { + certName = "eldiron"; + addToCerts = true; + hosts = [ "vpn.immae.eu" ]; + root = "/run/current-system/webapps/_vpn"; + }; + + myServices.websites.webappDirs._vpn = ./www; + }; +} diff --git a/modules/private/websites/tools/vpn/www/index.html b/modules/private/websites/tools/vpn/www/index.html new file mode 100644 index 0000000..08199fb --- /dev/null +++ b/modules/private/websites/tools/vpn/www/index.html @@ -0,0 +1,91 @@ + + + + VPN configuration + + + + + +
+

Installation

+ + +

Choix d'ip

+ +
+ + diff --git a/modules/private/websites/tools/vpn/www/style.css b/modules/private/websites/tools/vpn/www/style.css new file mode 100644 index 0000000..b177fec --- /dev/null +++ b/modules/private/websites/tools/vpn/www/style.css @@ -0,0 +1,61 @@ +* { + margin:0; + padding:0; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing: border-box; +} + +html { + min-height:100%; + border-top:10px solid #ECEEF1; + border-bottom:10px solid #ECEEF1; + color:#61666c; + font-weight:400; + font-size:1em; + font-family:'Open Sans', sans-serif; + line-height:2em; +} +body { + padding:20px; + -webkit-backface-visibility:hidden; +} +code { + font-family:consolas,monospace; +} +a { + color:#61666c; + text-decoration:none; +} +a, img { + border:none; + outline:none +} +a:hover { + color:#2a2a2a; +} + +.instructions { + margin:0 auto; + padding-top:20px; + max-width:80%; +} + +.instructions a { + text-decoration: underline; +} + +.instructions h2 { + margin-top: 10px; +} +.instructions em.important:before { + content: "⚠ Important ⚠ "; + color: red; +} +.instructions pre { + width: 50em; + padding: 10px 15px; + display: table; + border: 1px inset black; + line-height: 1em; +}