summaryrefslogtreecommitdiff
path: root/guix/vkraus/services/illyse.scm
blob: 1357519f607af1f6162c4f9a18284d18610da5c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
(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?
	    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>
  (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
<ca>
-----BEGIN CERTIFICATE-----
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
sjvtdavgLFaMPLPrI2DAcjpVMUuL1VgdqUcQkhc=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIG1zCCBL+gAwIBAgIUAQxspCb+1NLIr+bdR7gqrM1voLQwDQYJKoZIhvcNAQEL
BQAwgZsxCzAJBgNVBAYTAkZSMQwwCgYDVQQIDANSSEExDTALBgNVBAcMBEx5b24x
DzANBgNVBAoMBklMTFlTRTEQMA4GA1UECwwHb3BlbnZwbjEaMBgGA1UEAwwRaWxs
eXNlLW9wZW52cG4tY2ExDzANBgNVBCkMBklMTFlTRTEfMB0GCSqGSIb3DQEJARYQ
YWJ1c2VAaWxseXNlLm9yZzAeFw0yNDAyMjUxNzQ0MjBaFw0zNDAyMjIxNzQ0MjBa
MIGbMQswCQYDVQQGEwJGUjEMMAoGA1UECAwDUkhBMQ0wCwYDVQQHDARMeW9uMQ8w
DQYDVQQKDAZJTExZU0UxEDAOBgNVBAsMB29wZW52cG4xGjAYBgNVBAMMEWlsbHlz
ZS1vcGVudnBuLWNhMQ8wDQYDVQQpDAZJTExZU0UxHzAdBgkqhkiG9w0BCQEWEGFi
dXNlQGlsbHlzZS5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDK
Uoq9UFv3kaH0eQbQMUr4kGK/fcPvzE5ssaRyyyYHH6aI3c0va9f8VUOKKqomeL+Q
cWuDwWm5BuhSNcb/5/dHy4WFa3w9dp3CxbcaF5yhK+CmaJNyxxN2bbI7tFTVlhGw
hzxCvsNYGaOFLmzDdHGU0VdEPzRdE0Gb7fmFkk6d5TEcH+ltSEyYyr6jjP0DQLxF
JKfRv/kent8pxBZyJ0oyB36ES7HbblGoKfsvfrVax2rRrLCo0nj7Nfdkgf5R80DB
fbJbv159mWlljitGdeDfHv/EBblIxcc5pocV20PqFAeIzD9XvcY1gEhBistGimYM
9l7TMTBBGr1d45s/DAuMUu/kY6CuttVe1H/5+T3Dppo6/FB9xD+yngEMjsikMRHk
Zdzb47mk3p2MAZgb3CEYmAZBvSPTkmQVWRlTM9Eton2kXz373ZF1e8fdO3kYOv6x
yY3kGHAgF1bwyqTK6VPxIo1W1q08QzqtZ6HwkILohg+dJGNaNjpHALFGMLVBQ6ZT
b6GjG4V0d1VqlhGp4jCddgUqRhWmSLP9bzd94et2YvsZ7vUG4lp2DYSewMXguENg
YpijChcNdy5bzuVxaadr69Ky4tqyi5PKSZOBL9jUON3RuA0T9ETudPXSMFozMgTT
SXciWyTfKy6LhFxTx3z38QURwAaxNpE02u3ztCxvyQIDAQABo4IBDzCCAQswHQYD
VR0OBBYEFJubjwrxXkCGkGkz4YigLO8EUS6iMIHbBgNVHSMEgdMwgdCAFJubjwrx
XkCGkGkz4YigLO8EUS6ioYGhpIGeMIGbMQswCQYDVQQGEwJGUjEMMAoGA1UECAwD
UkhBMQ0wCwYDVQQHDARMeW9uMQ8wDQYDVQQKDAZJTExZU0UxEDAOBgNVBAsMB29w
ZW52cG4xGjAYBgNVBAMMEWlsbHlzZS1vcGVudnBuLWNhMQ8wDQYDVQQpDAZJTExZ
U0UxHzAdBgkqhkiG9w0BCQEWEGFidXNlQGlsbHlzZS5vcmeCFAEMbKQm/tTSyK/m
3Ue4KqzNb6C0MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAH8X6Pj+
Td3dnkI55iJ2xyF6+b0DzCMvNgiebZIBfBPO90ZxDrAg0121DEGyLOgVbNBkpmA0
ocuB7aS4OyGd17gi05oJuQtXwFY342JegU2tLrJPVP7aUjL1WVwTX45q44tA3dlC
OHpml65MPb7Ndn5hVzoPQuEQteEJgBJUh/bKFkeAlH4bsMZxm8qU+ydPm4QM7BHV
BaJciHxFISxgUieyX2ER7RVKZvWyyVSyfuAo/OzZ+qFXbkus6iwjtgIrm5mV99NL
GAs29PsxegpVPuG2tJXSs+xMXFqyup2H1LF5VS9N5qluHCwMcUNREs9/qVf5mG+E
kdyiiRLIn4kmX/7+VgIjcqhP7ZIhY2gIEbj768HCl0QCGN97mO3p72Ws9JqTyazN
MVIBSY72c6GxKYzji49pIuJ8o13/MzUNZN7Dt6kJSTmIwtxSSmpjzu26ibX2DTg8
hkHtYhh7bDEPSd8DX2XTtDNNloKLjS0MMuPu+cZeEk+aGiC1EyCylLth1SRHZZGR
ODOp5rCOtqJtXMtgMvwjXJQezkQ46KiiJVZTKgKoF2eJGjqCGEnbfQxO/nvbi5XR
uBmnNGY6c4vUfv96XFVGI5o0vRkBMhlzaLcAng6Tzet6GBtc7v5s6SFQYutKzc9Q
Rrb85iqtO/GHnXEW0241zmg9e3hHVraMd5/U
-----END CERTIFICATE-----
</ca>
"))

(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
    (($ <illyse-vpn-configuration> 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 ($ <illyse-vpn-configuration> _ _ _ _ _ _)
	   head)
      rest ...)
     (append
      (illyse-vpn-shepherd-service/one head)
      (illyse-vpn-shepherd-service rest)))))

(define illyse-vpn-activation-service
  (match-lambda
    ((($ <illyse-vpn-configuration> _ _ _ _ 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 "<your login here>\n")
		       (format port "<your password here>\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)))))