diff --git a/gnu/packages/gnunet.scm b/gnu/packages/gnunet.scm
index c98ceefad7..9012b25158 100644
--- a/gnu/packages/gnunet.scm
+++ b/gnu/packages/gnunet.scm
@@ -46,6 +46,7 @@ (define-module (gnu packages gnunet)
   #:use-module (gnu packages guile)
   #:use-module (gnu packages guile-xyz)
   #:use-module (gnu packages gstreamer)
+  #:use-module (gnu packages jose)
   #:use-module (gnu packages libidn)
   #:use-module (gnu packages linux)
   #:use-module (gnu packages image)
@@ -257,69 +258,94 @@ (define-public gnurl
 
 (define-public gnunet
   (package
-   (name "gnunet")
-   (version "0.16.3")
-   (source
-    (origin
-      (method url-fetch)
-      (uri (string-append "mirror://gnu/gnunet/gnunet-" version
-                          ".tar.gz"))
-      (sha256
-       (base32
-        "12n33r9nnkl5xwx8pwf571l2zvnvfllc8vm6mamrlyjk2cphaf9j"))))
-   (build-system gnu-build-system)
-   (inputs
-    (list bluez
-          glpk
-          gnurl
-          gnutls/dane
-          gstreamer
-          jansson
-          libextractor
-          libidn2
-          libgcrypt
-          libjpeg-turbo
-          libltdl
-          libmicrohttpd
-          libogg
-          libsodium
-          libunistring
-          miniupnpc
-          opus
-          pulseaudio
-          sqlite
-          zbar
-          zlib))
-   (native-inputs
-    (list curl openssl pkg-config python xxd
-          (@ (gnu packages base) which)))
-   (arguments
-    '(#:parallel-tests? #f ; Parallel tests aren't supported.
+    (name "gnunet")
+    (version "0.19.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://gnu/gnunet/gnunet-" version
+                           ".tar.gz"))
+       (sha256
+        (base32
+         "1zr25jn2jwnlx79wkykgp5jf0rhlxlfh7wcmmlyn5xpqxf94s0w6"))))
+    (build-system gnu-build-system)
+    (inputs
+     (list bluez
+           glpk
+           gnurl
+           gnutls/dane
+           ;;; pulse backend is going to be used anyway... also the configure
+           ;;; script will always say "gstreamer: no" even if it's there
+           ;;; unless it's chosen as the conversations backend.
+           ;;gstreamer
+           ;;gst-plugins-base
+           iproute
+           iptables
+           jansson
+           jose
+           libextractor
+           libidn2
+           libgcrypt
+           libjpeg-turbo
+           libltdl
+           libmicrohttpd
+           libogg
+           libsodium
+           libunistring
+           miniupnpc
+           net-tools
+           opus
+           procps
+           pulseaudio
+           sqlite
+           zbar
+           zlib))
+    (native-inputs
+     (list curl openssl pkg-config python xxd
+           (@ (gnu packages base) which)))
+    (outputs (list "out" "debug"))
+    (arguments
+     (list
+      #:tests? #f ;; tests currently fail, most likely guix-specific?
+      #:parallel-tests? #f              ; Parallel tests aren't supported.
+      #:configure-flags #~(list "--enable-gcc-hardening"
+                                "--enable-linker-hardening"
+                                "--enable-sanitizer"
+                                ;; have to do this to get udp working,
+                                ;; contrary to what configure outputs...
+                                ;;"--enable-experimental"
+                                "CFLAGS=-ggdb3"
+                                "--enable-logging=veryverbose")
       #:phases
-      (modify-phases %standard-phases
-        (add-before 'check 'set-env-var-for-tests
-          (lambda _
-            (setenv "LANG" "en_US.UTF-8")))
-        ;; Swap 'check and 'install phases and add installed binaries to $PATH.
-        (add-before 'check 'set-path-for-check
-          (lambda* (#:key outputs #:allow-other-keys)
-           (let ((out (assoc-ref outputs "out")))
-             (setenv "GNUNET_PREFIX" (string-append out "/lib"))
-             (setenv "PATH" (string-append (getenv "PATH") ":" out "/bin")))
-           #t))
-        (delete 'check)
-        (add-after 'install 'check
-          (assoc-ref %standard-phases 'check)))))
-   (synopsis "Secure, decentralized, peer-to-peer networking framework")
-   (description
+      #~(modify-phases %standard-phases
+          (add-after 'unpack 'fix-typo
+            (lambda _
+              (substitute* "./configure"
+                (("-Wstacl-protector")
+                 "-Wstack-protector"))))
+          (add-before 'check 'set-env-var-for-tests
+            (lambda _
+              (setenv "LANG" "en_US.UTF-8")))
+          ;; Swap 'check and 'install phases and add installed binaries to $PATH.
+          (add-before 'check 'set-path-for-check
+            (lambda* (#:key outputs #:allow-other-keys)
+              (let ((out (assoc-ref outputs "out")))
+                (setenv "GNUNET_PREFIX" (string-append out "/lib"))
+                (setenv "PATH" (string-append (getenv "PATH") ":" out "/bin")))
+              #t))
+          (delete 'check)
+          (add-after 'install 'check
+            (assoc-ref %standard-phases 'check)))))
+    (synopsis "Secure, decentralized, peer-to-peer networking framework")
+    (description
      "GNUnet is a framework for secure peer-to-peer networking.  The
 high-level goal is to provide a strong foundation of free software for a
 global, distributed network that provides security and privacy.  GNUnet in
 that sense aims to replace the current internet protocol stack.  Along with
 an application for secure publication of files, it has grown to include all
 kinds of basic applications for the foundation of a GNU internet.")
-   (license license:agpl3+)
-   (home-page "https://gnunet.org/en/")))
+    (license license:agpl3+)
+    (home-page "https://gnunet.org/en/")))
 
 (define-public guile-gnunet                       ;GSoC 2015!
   (let ((commit "d12167ab3c8d7d6caffd9c606e389ef043760602")
@@ -422,14 +448,15 @@ (define-public gnunet-scheme
 (define-public gnunet-gtk
   (package (inherit gnunet)
     (name "gnunet-gtk")
-    (version "0.13.1")
+    (version "0.19.0")
     (source (origin
               (method url-fetch)
               (uri (string-append "mirror://gnu/gnunet/gnunet-gtk-"
                                   version ".tar.gz"))
               (sha256
                (base32
-                "1zdzgq16h77w6ybwg3lqjsjr965np6iqvncqvkbj07glqd4wss0j"))))
+                ;;"1zdzgq16h77w6ybwg3lqjsjr965np6iqvncqvkbj07glqd4wss0j"
+                "0z2731l69vnfsa0cdsw8wh8g1d08wz15y5n0a58qjpf7baric01k"))))
     (arguments
      `(#:configure-flags
        (list "--with-libunique"
@@ -444,7 +471,9 @@ (define-public gnunet-gtk
        ("libextractor" ,libextractor)
        ("libgcrypt" ,libgcrypt)
        ("libunique" ,libunique)
-       ("qrencode" ,qrencode)))
+       ("qrencode" ,qrencode)
+       ;; XXX SHOULD BE FIXED IN GNUNET
+       ("libsodium" ,libsodium)))
     (native-inputs
      (list pkg-config libglade))
     (synopsis "Graphical front-end tools for GNUnet")
diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm
index 702404bc6c..7f76ec8b2e 100644
--- a/gnu/services/networking.scm
+++ b/gnu/services/networking.scm
@@ -45,6 +45,7 @@ (define-module (gnu services networking)
   #:use-module (gnu services admin)
   #:use-module (gnu system shadow)
   #:use-module (gnu system pam)
+  #:use-module (gnu system setuid)
   #:use-module ((gnu system file-systems) #:select (file-system-mapping))
   #:use-module (gnu packages admin)
   #:use-module (gnu packages base)
@@ -60,6 +61,7 @@ (define-module (gnu services networking)
   #:use-module (gnu packages ntp)
   #:use-module (gnu packages gnome)
   #:use-module (gnu packages ipfs)
+  #:use-module (gnu packages gnunet)
   #:use-module (gnu build linux-container)
   #:autoload   (guix least-authority) (least-authority-wrapper)
   #:use-module (guix gexp)
@@ -226,7 +228,15 @@ (define-module (gnu services networking)
 
             keepalived-configuration
             keepalived-configuration?
-            keepalived-service-type))
+            keepalived-service-type
+
+            %default-gnunet-config-file-contents
+            <gnunet-configuration>
+            gnunet-configuration
+            make-gnunet-configuration
+            gnunet-configuration-gnunet
+            gnunet-configuration-config-file
+            gnunet-service-type))
 
 ;;; Commentary:
 ;;;
@@ -2180,4 +2190,171 @@ (define keepalived-service-type
                  "Run @uref{https://www.keepalived.org/, Keepalived}
 routing software.")))
 
+
+;;;
+;;; Gnunet
+;;;
+
+(define %default-gnunet-config-file-contents
+  (string-join
+   '("[PATHS]"
+     "GNUNET_DATA_HOME = /var/lib/gnunet/data/"
+     "GNUNET_RUNTIME_DIR = /var/run/gnunet/"
+     "GNUNET_HOME = /var/lib/gnunet/"
+     "SERVICEHOME = /var/lib/gnunet/"
+     ;; Thank you, this is very useful :-)
+     "SUID_BINARY_PATH = /run/setuid-programs/"
+     ""
+     "[arm]"
+     "SYSTEM_ONLY = YES"
+     "USER_ONLY = NO"
+     "")
+   "\n"
+   'suffix))
+
+(define-record-type* <gnunet-configuration>
+  gnunet-configuration make-gnunet-configuration
+  gnunet-configuration?
+  (gnunet gnunet-configuration-gnunet   ;file-like
+          (default gnunet))
+  (config-file gnunet-configuration-config-file ;file-like
+               (default (plain-file "gnunet.conf"
+	                            %default-gnunet-config-file-contents))))
+
+(define gnunet-setuid-programs
+  (match-lambda
+    (($ <gnunet-configuration> gnunet)
+     (append
+      (list
+       (setuid-program
+        ;; gnunetdns group --> root user
+        (program
+         (file-append gnunet 
+                      "/lib/gnunet/libexec/gnunet-helper-dns"))
+        (setuid? #t)
+        (setgid? #f)
+        (user 0)
+        (group "gnunetdns")
+        (base-perms #o750))
+       (setuid-program
+        ;; gnunet user --> gnunetdns group
+        (program
+         (file-append gnunet
+                      "/lib/gnunet/libexec/gnunet-service-dns"))
+        (setuid? #f)
+        (setgid? #t)
+        (user "gnunet")
+        (group "gnunetdns")
+        (base-perms #o700)))
+      (map (lambda (name)
+             (setuid-program
+              (program (file-append gnunet
+                                    (string-append
+                                     "/lib/gnunet/libexec/gnunet-helper-"
+                                     name)))
+              (setuid? #t)
+              (setgid? #f)
+              (user 0)
+              (group "gnunet")
+              (base-perms #o750)))
+           '("vpn" "wlan" "bluetooth" "exit" "nat-server" "nat-client"))))))
+
+(define gnunet-shepherd-service
+  (match-lambda
+    (($ <gnunet-configuration> gnunet)
+     (define gnunet-arm
+       (file-append gnunet "/bin/gnunet-arm"))
+     (define gnunet-arm-cmd
+       (list gnunet-arm "-c" "/etc/gnunet.conf"))
+     (define (gnunet-arm-with-args . args)
+       #~(`(#$@gnunet-arm-cmd #$@args)
+          #:user "gnunet"
+          #:group "gnunet"
+          #:directory "/var/lib/gnunet"
+          #:environment-variables '(;; necessary for expanding in config files
+                                    "HOME=/var/lib/gnunet")))
+     (define (gnunet-arm-on-services flag services)
+       (gnunet-arm-with-args
+        #~,@(apply append
+                   (map (lambda (service)
+                          (list #$flag service))
+                        #$services))))
+     (define (wait/success? g-exp)
+       #~(zero? (status:exit-val (cdr (waitpid #$g-exp)))))
+
+     (list
+      (shepherd-service
+       (provision '(gnunet))
+       (documentation "Run a gnunet peer as a system user.")
+       (requirement '(networking))
+       (start (with-imported-modules (source-module-closure '((guix build utils)))
+                #~(lambda ()
+                    (use-modules (guix build utils))
+                    (mkdir-p "/var/run/gnunet")
+                    (chmod "/var/run/gnunet" #o755)
+                    (let* ((passwd (getpwnam "gnunet"))
+                           (uid (passwd:uid passwd))
+                           (gid (passwd:gid passwd)))
+                      (chown "/var/run/gnunet" uid gid))
+                    (fork+exec-command #$@(gnunet-arm-with-args "-s" "-m")))))
+       (stop #~(lambda (pid)
+                 (and #$(wait/success?
+                         #~(fork+exec-command
+                            #$@(gnunet-arm-with-args "-e")))
+                      ;; We started it with "-m", so it won't stop till ^C...
+                      (begin (kill pid SIGINT)
+                             (waitpid pid)))))
+       (actions
+        (list
+         (shepherd-action
+          (name 'start-subservices)
+          (documentation "Start the gnunet services provided, a sequence of
+service names as passed to 'gnunet-arm -i'.")
+          (procedure #~(lambda* (_ #:rest services)
+                         (or (null? services)
+                             #$(wait/success?
+                                #~(fork+exec-command
+                                   #$@(gnunet-arm-on-services "-i" 'services)))))))
+         (shepherd-action
+          (name 'stop-subservices)
+          (documentation "Stop the gnunet services provided, a sequence of
+service names as passed to 'gnunet-arm -k'.")
+          (procedure
+           #~(lambda* (_ #:rest services)
+               (or (null? services)
+                   #$(wait/success?
+                      #~(fork+exec-command
+                         #$@(gnunet-arm-on-services "-k" 'services))))))))))))))
+
+
+
+(define gnunet-service-type
+  (service-type
+   (name 'gnunet)
+   (extensions
+    (list
+     (service-extension shepherd-root-service-type
+                        gnunet-shepherd-service)
+     (service-extension account-service-type
+                        (lambda _
+                          (list (user-group
+                                 (name "gnunet")
+                                 (system? #t))
+                                (user-group
+                                 (name "gnunetdns")
+                                 (system? #t))
+                                (user-account
+                                 (name "gnunet")
+                                 (group "gnunet")
+                                 (system? #t)
+                                 (home-directory "/var/lib/gnunet")))))
+     (service-extension setuid-program-service-type
+                        gnunet-setuid-programs)
+     (service-extension etc-service-type
+                        (lambda (config)
+                          `(("gnunet.conf"
+                             ,(gnunet-configuration-config-file config)))))))
+   (description "Run a gnunet peer as a system user.")
+   (default-value (gnunet-configuration))))
+
 ;;; networking.scm ends here
