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
parent
6591e184f0
commit
43b2e440c3
|
@ -26336,9 +26336,12 @@ Defaults to @samp{()}.
|
||||||
@cindex virtual private network (VPN)
|
@cindex virtual private network (VPN)
|
||||||
|
|
||||||
The @code{(gnu services vpn)} module provides services related to
|
The @code{(gnu services vpn)} module provides services related to
|
||||||
@dfn{virtual private networks} (VPNs). It provides a @emph{client} service for
|
@dfn{virtual private networks} (VPNs).
|
||||||
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}.
|
@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 @
|
@deffn {Scheme Procedure} openvpn-client-service @
|
||||||
[#:config (openvpn-client-configuration)]
|
[#:config (openvpn-client-configuration)]
|
||||||
|
@ -26717,6 +26720,70 @@ Defaults to @samp{#f}.
|
||||||
|
|
||||||
@c %end of automatic openvpn-server documentation
|
@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
|
@node Network File System
|
||||||
@subsection Network File System
|
@subsection Network File System
|
||||||
|
|
|
@ -40,7 +40,24 @@
|
||||||
openvpn-remote-configuration
|
openvpn-remote-configuration
|
||||||
openvpn-ccd-configuration
|
openvpn-ccd-configuration
|
||||||
generate-openvpn-client-documentation
|
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.
|
;;; OpenVPN.
|
||||||
|
@ -507,3 +524,122 @@ is truncated and rewritten every minute.")
|
||||||
(remote openvpn-remote-configuration))
|
(remote openvpn-remote-configuration))
|
||||||
(openvpn-remote-configuration ,openvpn-remote-configuration-fields))
|
(openvpn-remote-configuration ,openvpn-remote-configuration-fields))
|
||||||
'openvpn-client-configuration))
|
'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)))))
|
||||||
|
|
Reference in New Issue