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)
|
||||
|
||||
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
|
||||
|
|
|
@ -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)))))
|
||||
|
|
Reference in New Issue