[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#46504: closed ([PATCH] services: wireguard: New service.)
From: |
GNU bug Tracking System |
Subject: |
bug#46504: closed ([PATCH] services: wireguard: New service.) |
Date: |
Wed, 17 Feb 2021 09:39:02 +0000 |
Your message dated Wed, 17 Feb 2021 10:38:33 +0100
with message-id <87czwzghk6.fsf@gnu.org>
and subject line Re: bug#46504: [PATCH] services: wireguard: New service.
has caused the debbugs.gnu.org bug report #46504,
regarding [PATCH] services: wireguard: New service.
to be marked as done.
(If you believe you have received this mail in error, please contact
help-debbugs@gnu.org.)
--
46504: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=46504
GNU Bug Tracking System
Contact help-debbugs@gnu.org with problems
--- Begin Message ---
Subject: |
[PATCH] services: wireguard: New service. |
Date: |
Sun, 14 Feb 2021 10:33:01 +0100 |
* gnu/services/vpn.scm (wireguard-peer, wireguard-configuration): New records.
(wireguard-service-type): New variable.
* doc/guix.texi (VPN Services): Document it.
---
doc/guix.texi | 78 +++++++++++++++++++++-
gnu/services/vpn.scm | 152 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 226 insertions(+), 4 deletions(-)
diff --git a/doc/guix.texi b/doc/guix.texi
index 68abb968b0..03ad7b0357 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -26243,9 +26243,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)]
@@ -26624,6 +26627,75 @@ 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{address} (default: @code{"10.0.0.1/32"})
+The address to be assigned to the above interface.
+
+@item @code{public-key} (default: @code{"/etc/wireguard/public.key"})
+The public key file for the interface. It is automatically generated
+from the private key file below if it does not exit.
+
+@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 with CIDR masks 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
diff --git a/gnu/services/vpn.scm b/gnu/services/vpn.scm
index 70f2617c7e..51cdf595a5 100644
--- a/gnu/services/vpn.scm
+++ b/gnu/services/vpn.scm
@@ -40,7 +40,26 @@
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-public-key
+ wireguard-peer-allowed-ips
+
+ wireguard-configuration
+ wireguard-configuration?
+ wireguard-configuration-wireguard
+ wireguard-configuration-interface
+ wireguard-configuration-address
+ wireguard-configuration-port
+ wireguard-configuration-public-key
+ wireguard-configuration-private-key
+ wireguard-configuration-peers
+
+ wireguard-service-type))
;;;
;;; OpenVPN.
@@ -507,3 +526,134 @@ 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"))
+ (address wireguard-configuration-address ;string
+ (default "10.0.0.1/32"))
+ (port wireguard-configuration-port ;integer
+ (default 51820))
+ (public-key wireguard-configuration-public-key ;string
+ (default "/etc/wireguard/public.key"))
+ (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 address 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~^~%~}"
+ #$address
+ #$(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>
+ (public-key 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)))
+
+ (mkdir-p (dirname #$public-key))
+ (unless (file-exists? #$public-key)
+ (let* ((pipe
+ (open-input-pipe (string-append
+ #$(file-append wireguard-tools "/bin/wg")
+ " genkey < " #$private-key)))
+ (key (read-line pipe)))
+ (call-with-output-file #$public-key
+ (lambda (port)
+ (display key port)))
+ (close-pipe pipe))))))
+
+(define (wireguard-shepherd-service config)
+ (match-record config <wireguard-configuration>
+ (wireguard)
+ (let ((wg-quick (file-append wireguard "/bin/wg-quick"))
+ (config (wireguard-configuration-file config)))
+ (list (shepherd-service
+ (requirement '(networking))
+ (provision '(wireguard))
+ (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)))))
--
2.30.0
--- End Message ---
--- Begin Message ---
Subject: |
Re: bug#46504: [PATCH] services: wireguard: New service. |
Date: |
Wed, 17 Feb 2021 10:38:33 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.1 (gnu/linux) |
Hello Brice,
> Cool, more intergration of Wireguard in Guix! I started wiriting such a
> service but didn't finialized it yet. Tho, I wasn't sure if it needed to
> be implemented with wg-quick since upstream describe it as « a very
> quick and dirty bash script for reading a few extra variables from
> wg(8)-style configuration files, and automatically configures the
> interface »¹.
Yeah, this made me hesitate too. However, I think that having this small
service is always better than a raw configuration file. It would of
course be nice to have a more complete service, maybe relying on
Guile-Netlink in the future.
> wg-quick(8) say that the ”Address” attribute can be specified multiple
> times and is « a comma-separated list of IP (v4 or v6) addresses
> (optionally with CIDR masks) to be assigned to the interface. », so the
> “address” field should probably be “addresses”, a list of string.
You're right, fixed.
> Some of the missing attributes from wg-quick(8) like “DNS” or hooks
> seems realy usefull, maybe a “extra-config” field to the record could be
> added to support all of thoses attributes.
Yes, I'll add it as a follow-up.
> Why having a “public-key” field since it is derived from the private
> key? It seems to allow missconfiguration: what happen if the private
> and public part of a key don't match, or if only the “public-key” is
> set?
The rationale was that when the private key is generated, the user can
just "cat /etc/wireguard/public.key" instead of running "wg pubkey <
/etc/wireguard/private.key" but I agree it is misleading and I removed
this field.
I pushed the revised patch as 43b2e440c38a39eb64088bd6c08771c060aa10fc.
Thanks,
Mathieu
--- End Message ---
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- bug#46504: closed ([PATCH] services: wireguard: New service.),
GNU bug Tracking System <=