me
/
guix
Archived
1
0
Fork 0

services: wireguard: New service.

* gnu/services/vpn.scm (wireguard-peer, wireguard-configuration): New records.
(wireguard-service-type): New variable.
* doc/guix.texi (VPN Services): Document it.
master
Mathieu Othacehe 2021-02-13 10:07:47 +01:00
parent 6591e184f0
commit 43b2e440c3
No known key found for this signature in database
GPG Key ID: 8354763531769CA6
2 changed files with 207 additions and 4 deletions

View File

@ -26336,9 +26336,12 @@ Defaults to @samp{()}.
@cindex virtual private network (VPN)
The @code{(gnu services vpn)} module provides services related to
@dfn{virtual private networks} (VPNs). It provides a @emph{client} service for
your machine to connect to a VPN, and a @emph{server} service for your machine
to host a VPN@. Both services use @uref{https://openvpn.net/, OpenVPN}.
@dfn{virtual private networks} (VPNs).
@subsubheading OpenVPN
It provides a @emph{client} service for your machine to connect to a
VPN, and a @emph{server} service for your machine to host a VPN@.
@deffn {Scheme Procedure} openvpn-client-service @
[#:config (openvpn-client-configuration)]
@ -26717,6 +26720,70 @@ Defaults to @samp{#f}.
@c %end of automatic openvpn-server documentation
@subsubheading Wireguard
@defvr {Scheme Variable} wireguard-service-type
A service type for a Wireguard tunnel interface. Its value must be a
@code{wireguard-configuration} record as in this example:
@lisp
(service wireguard-service-type
(wireguard-configuration
(peers
(list
(wireguard-peer
(name "my-peer")
(endpoint "my.wireguard.com:51820")
(public-key "hzpKg9X1yqu1axN6iJp0mWf6BZGo8m1wteKwtTmDGF4=")
(allowed-ips '("10.0.0.2/32")))))))
@end lisp
@end defvr
@deftp {Data Type} wireguard-configuration
Data type representing the configuration of the Wireguard service.
@table @asis
@item @code{wireguard}
The wireguard package to use for this service.
@item @code{interface} (default: @code{"wg0"})
The interface name for the VPN.
@item @code{addresses} (default: @code{'("10.0.0.1/32")})
The IP addresses to be assigned to the above interface.
@item @code{private-key} (default: @code{"/etc/wireguard/private.key"})
The private key file for the interface. It is automatically generated if
the file does not exist.
@item @code{peers} (default: @code{'()})
The authorized peers on this interface. This is a list of
@var{wireguard-peer} records.
@end table
@end deftp
@deftp {Data Type} wireguard-peer
Data type representing a Wireguard peer attached to a given interface.
@table @asis
@item @code{name}
The peer name.
@item @code{endpoint} (default: @code{#f})
The optional endpoint for the peer, such as
@code{"demo.wireguard.com:51820"}.
@item @code{public-key}
The peer public-key represented as a base64 string.
@item @code{allowed-ips}
A list of IP addresses from which incoming traffic for this peer is
allowed and to which incoming traffic for this peer is directed.
@end table
@end deftp
@node Network File System
@subsection Network File System

View File

@ -40,7 +40,24 @@
openvpn-remote-configuration
openvpn-ccd-configuration
generate-openvpn-client-documentation
generate-openvpn-server-documentation))
generate-openvpn-server-documentation
wireguard-peer
wireguard-peer?
wireguard-peer-name
wireguard-peer-endpoint
wireguard-peer-allowed-ips
wireguard-configuration
wireguard-configuration?
wireguard-configuration-wireguard
wireguard-configuration-interface
wireguard-configuration-addresses
wireguard-configuration-port
wireguard-configuration-private-key
wireguard-configuration-peers
wireguard-service-type))
;;;
;;; OpenVPN.
@ -507,3 +524,122 @@ is truncated and rewritten every minute.")
(remote openvpn-remote-configuration))
(openvpn-remote-configuration ,openvpn-remote-configuration-fields))
'openvpn-client-configuration))
;;;
;;; Wireguard.
;;;
(define-record-type* <wireguard-peer>
wireguard-peer make-wireguard-peer
wireguard-peer?
(name wireguard-peer-name)
(endpoint wireguard-peer-endpoint
(default #f)) ;string
(public-key wireguard-peer-public-key) ;string
(allowed-ips wireguard-peer-allowed-ips)) ;list of strings
(define-record-type* <wireguard-configuration>
wireguard-configuration make-wireguard-configuration
wireguard-configuration?
(wireguard wireguard-configuration-wireguard ;<package>
(default wireguard-tools))
(interface wireguard-configuration-interface ;string
(default "wg0"))
(addresses wireguard-configuration-addresses ;string
(default '("10.0.0.1/32")))
(port wireguard-configuration-port ;integer
(default 51820))
(private-key wireguard-configuration-private-key ;string
(default "/etc/wireguard/private.key"))
(peers wireguard-configuration-peers ;list of <wiregard-peer>
(default '())))
(define (wireguard-configuration-file config)
(define (peer->config peer)
(let ((name (wireguard-peer-name peer))
(public-key (wireguard-peer-public-key peer))
(endpoint (wireguard-peer-endpoint peer))
(allowed-ips (wireguard-peer-allowed-ips peer)))
(format #f "[Peer] #~a
PublicKey = ~a
AllowedIPs = ~a
~a"
name
public-key
(string-join allowed-ips ",")
(if endpoint
(format #f "Endpoint = ~a\n" endpoint)
"\n"))))
(match-record config <wireguard-configuration>
(wireguard interface addresses port private-key peers)
(let* ((config-file (string-append interface ".conf"))
(peers (map peer->config peers))
(config
(computed-file
"wireguard-config"
#~(begin
(mkdir #$output)
(chdir #$output)
(call-with-output-file #$config-file
(lambda (port)
(let ((format (@ (ice-9 format) format)))
(format port "[Interface]
Address = ~a
PostUp = ~a set %i private-key ~a
~a
~{~a~^~%~}"
#$(string-join addresses ",")
#$(file-append wireguard "/bin/wg")
#$private-key
#$(if port
(format #f "ListenPort = ~a" port)
"")
(list #$@peers)))))))))
(file-append config "/" config-file))))
(define (wireguard-activation config)
(match-record config <wireguard-configuration>
(private-key)
#~(begin
(use-modules (guix build utils)
(ice-9 popen)
(ice-9 rdelim))
(mkdir-p (dirname #$private-key))
(unless (file-exists? #$private-key)
(let* ((pipe
(open-input-pipe (string-append
#$(file-append wireguard-tools "/bin/wg")
" genkey")))
(key (read-line pipe)))
(call-with-output-file #$private-key
(lambda (port)
(display key port)))
(chmod #$private-key #o400)
(close-pipe pipe))))))
(define (wireguard-shepherd-service config)
(match-record config <wireguard-configuration>
(wireguard interface)
(let ((wg-quick (file-append wireguard "/bin/wg-quick"))
(config (wireguard-configuration-file config)))
(list (shepherd-service
(requirement '(networking))
(provision (list
(symbol-append 'wireguard-
(string->symbol interface))))
(start #~(lambda _
(invoke #$wg-quick "up" #$config)))
(stop #~(lambda _
(invoke #$wg-quick "down" #$config)))
(documentation "Run the Wireguard VPN tunnel"))))))
(define wireguard-service-type
(service-type
(name 'wireguard)
(extensions
(list (service-extension shepherd-root-service-type
wireguard-shepherd-service)
(service-extension activation-service-type
wireguard-activation)))))