(define-module (vkraus services illyse) #:use-module ((guix gexp) #:select (gexp plain-file program-file file-append with-imported-modules mixed-text-file)) #:use-module ((guix modules) #:select (source-module-closure)) #:use-module ((guix packages) #:select (package-version)) #:use-module ((gnu services) #:select (service-type service-extension activation-service-type)) #:use-module ((gnu services shepherd) #:select (shepherd-root-service-type shepherd-service shepherd-configuration-action shepherd-action)) #:use-module ((gnu packages linux) #:select (iproute)) #:use-module ((srfi srfi-9 gnu) #:select (define-immutable-record-type)) #:use-module ((ice-9 match) #:select (match match-lambda)) #:export ( illyse-vpn-configuration illyse-vpn-configuration? illyse-vpn-configuration-identifier set-illyse-vpn-configuration-identifier illyse-vpn-configuration-openvpn-package set-illyse-vpn-configuration-openvpn-package illyse-vpn-configuration-my-ipv6 set-illyse-vpn-configuration-my-ipv6 illyse-vpn-configuration-device set-illyse-vpn-configuration-device illyse-vpn-configuration-credential-file set-illyse-vpn-configuration-credential-file illyse-vpn-configuration-log-file set-illyse-vpn-configuration-log-file illyse-vpn-service-type) #:duplicates (merge-generics) #:declarative? #t) (define-immutable-record-type (illyse-vpn-configuration identifier openvpn my-ipv6 device credential-file log-file) illyse-vpn-configuration? (identifier illyse-vpn-configuration-identifier set-illyse-vpn-configuration-identifier) (openvpn illyse-vpn-configuration-openvpn-package set-illyse-vpn-configuration-openvpn-package) (my-ipv6 illyse-vpn-configuration-my-ipv6 set-illyse-vpn-configuration-my-ipv6) (device illyse-vpn-configuration-device set-illyse-vpn-configuration-device) (credential-file illyse-vpn-configuration-credential-file set-illyse-vpn-configuration-credential-file) (log-file illyse-vpn-configuration-log-file set-illyse-vpn-configuration-log-file)) (define (up-script identifier my-ipv6 device) (program-file (string-append "illyse-vpn-" identifier "-up") (with-imported-modules (source-module-closure '((guix build utils))) #~(begin (use-modules (guix build utils)) (invoke #$(file-append iproute "/sbin/ip") "-6" "address" "add" #$my-ipv6 "dev" #$device))))) (define (make-illyse-vpn-configuration identifier my-ipv6 device credential-file log-file) (mixed-text-file (string-append "illyse-vpn-" identifier "-configuration") "# C'est nous qui prenons l'initiative de nous connecter au serveur. client # On route de l'IP, on ne fait pas de l'ethernet. dev "device" # si on ne reçoit pas d'IP pour "device": # - soit on configure l'interface avec des ip privées bidon #ifconfig 10.255.255.1 10.255.255.2 # - soit on utilise un script pour faire \"ifconfig "device" up\" #script-security 2 #up up.sh # Il est préférable d'utiliser udp, le résultat fonctionne mieux. Il est # cependant notable que les restrictions d'accès Internet laissent souvent # plus facilement passer tcp. Essayez donc udp, et seulement s'il ne fonctionne # pas, essayez tcp. # Transport sur udp v4. En v6, la redirection de passerelle par défaut fonctionne mal (openvpn ne crée pas l'équivalent de la route /32 IPv4 vers le serveur vpn via la passerelle sous-jacente) # Si on ne prévoit pas d'utiliser la directive \"redirect-gateway def1\", alors on peut choisir \"proto udp6\" pour monter le tunnel en IPv6. #proto udp6 proto udp #proto tcp # Certains réseaux ont en fait une MTU bien inférieure à 1450. Dire aux connexions # TCP d'être très conservatives, pour que ça marche plus ou moins partout. mssfix 1300 # En UDP, on peut s'assurer que ça passe de toutes façons en fragmentant au besoin # quand ça dépasse. fragment 1300 # Idéalement, ça devrait être détecté tout seul, mais c'est loin de toujours fonctionner... #mtu-disc yes # En udp, Prévenir le serveur quand on termine, permet de relancer # immédiatement sans attendre que le serveur se rende compte de la # déconnexion par timeout. explicit-exit-notify # L'adresse du serveur. remote vpn.illyse.net 1194 # Éventuellement, on peut avoir besoin de passer par un proxy http, décommenter cette ligne en mettant l'adresse et le port du proxy. #http-proxy 192.0.2.1 8080 # Attendre un peu avant d'ajouter les routes. route-delay 2 # Ne pas utiliser un port local statique, on est client de toutes façons. nobind # Garder la clé en mémoire, pour ne pas avoir besoin de la relire lors d'un # redémarrage. persist-key # Ne pas tuer l'interface du tunnel lors d'un redémarrage. #persist-tun # Décommenter cette ligne pour faire passer tout le trafic via le VPN: redirect-gateway def1 # On peut aussi vouloir plutôt router seulement quelques destinations, par # exemple ici tout Gitoyen: #route 80.67.160.0 255.255.224.0 # Activer IPv6 dans le tunnel tun-ipv6 script-security 2 up "(up-script identifier my-ipv6 device)" # et faire passer tout le trafic IPv6 via le VPN: route-ipv6 ::/1 route-ipv6 8000::/1 # Envoyer un login et un mot de passe. Pour éviter de taper à la main login # et mot de passe, vous pouvez ajouter à droite de \"auth-user-pass\" le nom d'un # fichier contenant ces deux informations, une par ligne. auth-user-pass "credential-file" # Retenter le l’authentification même si le serveur la refuse (utile pour # éviter de faire mourir le client si le serveur LDAP ne répond pas) auth-retry nointeract # Un minimum de debug, c'est toujours bien. verb 3 log-append "log-file" # Certificat permettant de vérifier que c'est bien à Illyse que # l'on se connecte et donc à qui on donne notre mot de passe. remote-cert-tls server -----BEGIN CERTIFICATE----- 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 sjvtdavgLFaMPLPrI2DAcjpVMUuL1VgdqUcQkhc= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- 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 Rrb85iqtO/GHnXEW0241zmg9e3hHVraMd5/U -----END CERTIFICATE----- ")) (define (run-illyse-vpn identifier openvpn-package my-ipv6 device credential-file log-file) (program-file (string-append "connect-illyse-vpn-" identifier) (with-imported-modules (source-module-closure '((guix build utils))) #~(begin (use-modules (guix build utils)) (invoke #$(file-append openvpn-package "/sbin/openvpn") #$(make-illyse-vpn-configuration identifier my-ipv6 device credential-file log-file)))))) (define illyse-vpn-shepherd-service/one (match-lambda (($ identifier openvpn-package my-ipv6 device credential-file log-file) (list (shepherd-service (documentation (format #f "Connect to Illyse VPN ~a (to get ~s with credentials ~s, log-file ~s, using openvpn ~s)" identifier my-ipv6 credential-file log-file (package-version openvpn-package))) (provision (list (string->symbol (string-append "illyse-vpn-" identifier)))) (start #~(make-forkexec-constructor (list #$(run-illyse-vpn identifier openvpn-package my-ipv6 device credential-file log-file)))) (stop #~(make-kill-destructor)) (actions (list (shepherd-configuration-action (make-illyse-vpn-configuration identifier my-ipv6 device credential-file log-file)) (shepherd-action (name 'files) (documentation "Display the location on the file system of the credential file and log file.") (procedure #~(lambda _ (format #t "The ~a illyse VPN connection uses credential file ~a, and logs to ~a." #$identifier #$credential-file #$log-file)))) (shepherd-action (name 'ipv6) (documentation (format #f "Print the requested IPv6 for the ~a illyse VPN connection (~s)." identifier my-ipv6)) (procedure #~(lambda _ (display #$my-ipv6) (newline)))) (shepherd-action (name 'device) (documentation (format #f "Print the requested device name for the ~a illyse VPN connection (~s)." identifier device)) (procedure #~(lambda _ (display #$device) (newline))))))))))) (define illyse-vpn-shepherd-service (match-lambda (() '()) (((and ($ _ _ _ _ _ _) head) rest ...) (append (illyse-vpn-shepherd-service/one head) (illyse-vpn-shepherd-service rest))))) (define illyse-vpn-activation-service (match-lambda ((($ _ _ _ _ credential-file _) ...) (with-imported-modules (source-module-closure '((guix build utils))) #~(begin (use-modules (guix build utils)) (for-each (lambda (credential-file) (if (file-exists? credential-file) (chmod credential-file #o600) (begin (mkdir-p (dirname credential-file)) (call-with-output-file credential-file (lambda (port) (chmod port #o600) (format port "\n") (format port "\n")))))) (list #$@credential-file))))))) (define illyse-vpn-service-type (service-type (name 'illyse-vpn) (description "Connect to a set of Illyse VPN configurations") (extensions (list (service-extension shepherd-root-service-type illyse-vpn-shepherd-service) (service-extension activation-service-type illyse-vpn-activation-service)))))