summary refs log tree commit diff
path: root/nixos
diff options
context:
space:
mode:
Diffstat (limited to 'nixos')
-rw-r--r--nixos/doc/manual/installation/upgrading.xml16
-rw-r--r--nixos/doc/manual/release-notes/rl-2105.xml272
-rw-r--r--nixos/lib/make-ext4-fs.nix8
-rw-r--r--nixos/lib/test-driver/test-driver.py6
-rw-r--r--nixos/modules/module-list.nix3
-rw-r--r--nixos/modules/security/acme.nix2
-rw-r--r--nixos/modules/services/continuous-integration/buildkite-agents.nix3
-rw-r--r--nixos/modules/services/hardware/sane_extra_backends/brscan5.nix110
-rw-r--r--nixos/modules/services/hardware/sane_extra_backends/brscan5_etc_files.nix77
-rw-r--r--nixos/modules/services/misc/sdrplay.nix35
-rw-r--r--nixos/modules/services/web-apps/trilium.nix2
-rw-r--r--nixos/modules/services/web-apps/wordpress.nix4
-rw-r--r--nixos/modules/virtualisation/libvirtd.nix2
-rw-r--r--nixos/modules/virtualisation/podman-network-socket-ghostunnel.nix34
-rw-r--r--nixos/modules/virtualisation/podman-network-socket.nix91
-rw-r--r--nixos/modules/virtualisation/podman.nix43
-rw-r--r--nixos/tests/all-tests.nix1
-rw-r--r--nixos/tests/brscan5.nix42
-rw-r--r--nixos/tests/podman-tls-ghostunnel.nix150
-rw-r--r--nixos/tests/podman.nix38
20 files changed, 815 insertions, 124 deletions
diff --git a/nixos/doc/manual/installation/upgrading.xml b/nixos/doc/manual/installation/upgrading.xml
index 15ba5db9a37..960d4fa9a43 100644
--- a/nixos/doc/manual/installation/upgrading.xml
+++ b/nixos/doc/manual/installation/upgrading.xml
@@ -14,7 +14,7 @@
     <para>
      <emphasis>Stable channels</emphasis>, such as
      <literal
-    xlink:href="https://nixos.org/channels/nixos-20.09">nixos-20.09</literal>.
+    xlink:href="https://nixos.org/channels/nixos-21.05">nixos-21.05</literal>.
      These only get conservative bug fixes and package upgrades. For instance,
      a channel update may cause the Linux kernel on your system to be upgraded
      from 4.19.34 to 4.19.38 (a minor bug fix), but not from
@@ -38,7 +38,7 @@
     <para>
      <emphasis>Small channels</emphasis>, such as
      <literal
-    xlink:href="https://nixos.org/channels/nixos-20.09-small">nixos-20.09-small</literal>
+    xlink:href="https://nixos.org/channels/nixos-21.05-small">nixos-21.05-small</literal>
      or
      <literal
     xlink:href="https://nixos.org/channels/nixos-unstable-small">nixos-unstable-small</literal>.
@@ -63,8 +63,8 @@
  <para>
   When you first install NixOS, you’re automatically subscribed to the NixOS
   channel that corresponds to your installation source. For instance, if you
-  installed from a 20.09 ISO, you will be subscribed to the
-  <literal>nixos-20.09</literal> channel. To see which NixOS channel you’re
+  installed from a 21.05 ISO, you will be subscribed to the
+  <literal>nixos-21.05</literal> channel. To see which NixOS channel you’re
   subscribed to, run the following as root:
 <screen>
 <prompt># </prompt>nix-channel --list | grep nixos
@@ -75,13 +75,13 @@ nixos https://nixos.org/channels/nixos-unstable
 <prompt># </prompt>nix-channel --add https://nixos.org/channels/<replaceable>channel-name</replaceable> nixos
 </screen>
   (Be sure to include the <literal>nixos</literal> parameter at the end.) For
-  instance, to use the NixOS 20.09 stable channel:
+  instance, to use the NixOS 21.05 stable channel:
 <screen>
-<prompt># </prompt>nix-channel --add https://nixos.org/channels/nixos-20.09 nixos
+<prompt># </prompt>nix-channel --add https://nixos.org/channels/nixos-21.05 nixos
 </screen>
   If you have a server, you may want to use the “small” channel instead:
 <screen>
-<prompt># </prompt>nix-channel --add https://nixos.org/channels/nixos-20.09-small nixos
+<prompt># </prompt>nix-channel --add https://nixos.org/channels/nixos-21.05-small nixos
 </screen>
   And if you want to live on the bleeding edge:
 <screen>
@@ -132,7 +132,7 @@ nixos https://nixos.org/channels/nixos-unstable
    kernel, initrd or kernel modules.
    You can also specify a channel explicitly, e.g.
 <programlisting>
-<xref linkend="opt-system.autoUpgrade.channel"/> = https://nixos.org/channels/nixos-20.09;
+<xref linkend="opt-system.autoUpgrade.channel"/> = https://nixos.org/channels/nixos-21.05;
 </programlisting>
   </para>
  </section>
diff --git a/nixos/doc/manual/release-notes/rl-2105.xml b/nixos/doc/manual/release-notes/rl-2105.xml
index 12a9ae2f44e..d76d7446e6b 100644
--- a/nixos/doc/manual/release-notes/rl-2105.xml
+++ b/nixos/doc/manual/release-notes/rl-2105.xml
@@ -3,8 +3,11 @@
          xmlns:xi="http://www.w3.org/2001/XInclude"
          version="5.0"
          xml:id="sec-release-21.05">
- <title>Release 21.05 (“Okapi”, 2021.05/??)</title>
+ <title>Release 21.05 (“Okapi”, 2021.05/31)</title>
 
+ <para>
+  Support is planned until the end of December 2021, handing over to 21.11.
+ </para>
  <section xmlns="http://docbook.org/ns/docbook"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          xmlns:xi="http://www.w3.org/2001/XInclude"
@@ -18,114 +21,81 @@
   </para>
 
   <itemizedlist>
+
    <listitem>
     <para>
-     Support is planned until the end of December 2021, handing over to 21.11.
-    </para>
-   </listitem>
-   <listitem>
-    <para>The default Linux kernel was updated to the 5.10 LTS series, coming from the 5.4 LTS series.</para>
-    <para>The <package>linux_latest</package> kernel was updated to the 5.12 series. It currently is not officially supported for use with the zfs filesystem. If you use zfs, you should use a different kernel version (either the LTS kernel, or track a specific one). </para>
-   </listitem>
-   <listitem>
-    <para>GNOME desktop environment was upgraded to 40, see the release notes for <link xlink:href="https://help.gnome.org/misc/release-notes/40.0/">40.0</link> and <link xlink:href="https://help.gnome.org/misc/release-notes/3.38/">3.38</link>. The <code>gnome3</code> attribute set has been renamed to <code>gnome</code> and so have been the NixOS options.</para>
-   </listitem>
-   <listitem>
-    <para>
-     <link xlink:href="https://www.gnuradio.org/">GNURadio</link> 3.8 was
-     <link xlink:href="https://github.com/NixOS/nixpkgs/issues/82263">finally</link>
-     packaged, along with a rewrite to the Nix expressions, allowing users to
-     override the features upstream supports selecting to compile or not to.
-     Additionally, the attribute <code>gnuradio</code> and <code>gnuradio3_7</code>
-     now point to an externally wrapped by default derivations, that allow you to
-     also add `extraPythonPackages` to the Python interpreter used by GNURadio.
-     Missing environmental variables needed for operational GUI were also added
-     (<link xlink:href="https://github.com/NixOS/nixpkgs/issues/75478">#75478</link>).
-    </para>
-   </listitem>
-   <listitem>
-    <para>
-     <link xlink:href="https://www.gnuradio.org/">GNURadio</link> has a
-     <code>pkgs</code> attribute set, and there's a <code>gnuradio.callPackage</code>
-     function that extends <code>pkgs</code> with a <code>mkDerivation</code>, and a
-     <code>mkDerivationWith</code>, like Qt5. Now all <code>gnuradio.pkgs</code> are
-     defined with <code>gnuradio.callPackage</code> and some packages that depend
-     on gnuradio are defined with this as well.
-    </para>
-   </listitem>
-   <listitem>
-    <para>
-     <link xlink:href="https://www.privoxy.org/">Privoxy</link> has been updated
-     to version 3.0.32 (See <link xlink:href="https://lists.privoxy.org/pipermail/privoxy-announce/2021-February/000007.html">announcement</link>).
-     Compared to the previous release, Privoxy has gained support for HTTPS
-     inspection (still experimental), Brotli decompression, several new filters
-     and lots of bug fixes, including security ones. In addition, the package
-     is now built with compression and external filters support, which were
-     previously disabled.
-    </para>
-    <para>
-     Regarding the NixOS module, new options for HTTPS inspection have been added
-     and <option>services.privoxy.extraConfig</option> has been replaced by the new
-     <xref linkend="opt-services.privoxy.settings"/>
-     (See <link xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC 0042</link>
-     for the motivation).
-    </para>
-   </listitem>
-   <listitem>
-    <para>
-     Python optimizations were disabled again. Builds with optimizations enabled
-     are not reproducible. Optimizations can now be enabled with an option.
-    </para>
-   </listitem>
-   <listitem>
-    <para>
-     <link xlink:href="https://kodi.tv/">Kodi</link> has been updated to version 19.1 "Matrix". See
-     the <link xlink:href="https://kodi.tv/article/kodi-190-matrix-release">announcement</link> for
-     further details.
-    </para>
-   </listitem>
-   <listitem>
-    <para>
-     The <option>services.packagekit.backend</option> option has been removed as
-     it only supported a single setting which would always be the default.
-     Instead new <link
-     xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC
-     0042</link> compliant <xref linkend="opt-services.packagekit.settings"/>
-     and <xref linkend="opt-services.packagekit.vendorSettings"/> options have
-     been introduced.
+     Core version changes:
     </para>
+    <itemizedlist>
+     <listitem>
+      <para>
+       gcc: 9.3.0 -> 10.3.0
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       glibc: 2.30 -> 2.32
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+        default linux: 5.4 -> 5.10, all supported kernels available
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+        mesa: 20.1.7 -> 21.0.1
+      </para>
+     </listitem>
+    </itemizedlist>
    </listitem>
    <listitem>
     <para>
-      <link xlink:href="https://nginx.org">Nginx</link> has been updated to stable version 1.20.0.
-      Now nginx uses the zlib-ng library by default.
+     Desktop Environments:
     </para>
+    <itemizedlist>
+     <listitem>
+      <para>
+        Gnome: 3.36 -> 3.40, see its <link xlink:href="https://help.gnome.org/misc/release-notes/3.40/">release notes</link>
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+        Plasma5: 5.18.5 -> 5.21.3
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+        kdeApplications: 20.08.1 -> 20.12.3
+      </para>
+     </listitem>
+      <listitem>
+       <para>
+         cinnamon: 4.6 -> 4.8.1
+      </para>
+     </listitem>
+    </itemizedlist>
    </listitem>
+
    <listitem>
     <para>
-     KDE Gear (formerly KDE Applications) is upgraded to 21.04, see its
-     <link xlink:href="https://kde.org/announcements/gear/21.04/">release
-     notes</link> for details.
-    </para>
-    <para>
-     The <code>kdeApplications</code> package set is now <code>kdeGear</code>,
-     in keeping with the new name. The old name remains for compatibility, but
-     it is deprecated.
+     Programming Languages and Frameworks:
     </para>
+    <itemizedlist>
+
+     <listitem>
+      <para>
+       Python optimizations were disabled again. Builds with optimizations enabled
+       are not reproducible. Optimizations can now be enabled with an option.
+      </para>
+     </listitem>
+
+    </itemizedlist>
    </listitem>
    <listitem>
-    <para>
-     <link xlink:href="https://libreswan.org/">Libreswan</link> has been updated
-     to version 4.4. The package now includes example configurations and manual
-     pages by default. The NixOS module has been changed to use the upstream
-     systemd units and write the configuration in the <literal>/etc/ipsec.d/
-     </literal> directory. In addition, two new options have been added to
-     specify connection policies
-     (<xref linkend="opt-services.libreswan.policies"/>)
-     and disable send/receive redirects
-     (<xref linkend="opt-services.libreswan.disableRedirects"/>).
-    </para>
+    <para>The <package>linux_latest</package> kernel was updated to the 5.12 series. It currently is not officially supported for use with the zfs filesystem. If you use zfs, you should use a different kernel version (either the LTS kernel, or track a specific one). </para>
    </listitem>
+
   </itemizedlist>
  </section>
 
@@ -142,6 +112,20 @@
 
   <itemizedlist>
    <listitem>
+    <para>
+     <link xlink:href="https://www.gnuradio.org/">GNURadio</link> 3.8 was
+     <link xlink:href="https://github.com/NixOS/nixpkgs/issues/82263">finally</link>
+     packaged, along with a rewrite to the Nix expressions, allowing users to
+     override the features upstream supports selecting to compile or not to.
+     Additionally, the attribute <code>gnuradio</code> and <code>gnuradio3_7</code>
+     now point to an externally wrapped by default derivations, that allow you to
+     also add `extraPythonPackages` to the Python interpreter used by GNURadio.
+     Missing environmental variables needed for operational GUI were also added
+     (<link xlink:href="https://github.com/NixOS/nixpkgs/issues/75478">#75478</link>).
+    </para>
+   </listitem>
+
+   <listitem>
      <para>
        <link xlink:href="https://www.keycloak.org/">Keycloak</link>,
        an open source identity and access management server with
@@ -194,6 +178,10 @@
 
   <itemizedlist>
    <listitem>
+    <para>GNOME desktop environment was upgraded to 40, see the release notes for <link xlink:href="https://help.gnome.org/misc/release-notes/40.0/">40.0</link> and <link xlink:href="https://help.gnome.org/misc/release-notes/3.38/">3.38</link>. The <code>gnome3</code> attribute set has been renamed to <code>gnome</code> and so have been the NixOS options.</para>
+   </listitem>
+
+   <listitem>
     <para>
      If you are using <option>services.udev.extraRules</option> to assign
      custom names to network interfaces, this may stop working due to a change
@@ -600,7 +588,7 @@ http://some.json-exporter.host:7979/probe?target=https://example.com/some/json/e
        <programlisting>
 self: super:
 {
- mpi = super.mpich;
+  mpi = super.mpich;
 }
        </programlisting>
      </para>
@@ -804,6 +792,16 @@ environment.systemPackages = [
      the deprecated <option>services.radicale.config</option> is used.
     </para>
    </listitem>
+   <listitem>
+    <para>
+     In the <option>security.acme</option> module, use of <literal>--reuse-key</literal>
+     parameter  for Lego has been removed. It was introduced for HKPK, but this security
+     feature is now deprecated. It is a better security practice to rotate key pairs
+     instead of always keeping the same. If you need to keep this parameter, you can add
+     it back using <literal>extraLegoRenewFlags</literal> as an option for the
+     appropriate certificate.
+    </para>
+   </listitem>
   </itemizedlist>
  </section>
 
@@ -823,6 +821,85 @@ environment.systemPackages = [
      for details.
     </para>
    </listitem>
+
+   <listitem>
+    <para>
+     <link xlink:href="https://www.gnuradio.org/">GNURadio</link> has a
+     <code>pkgs</code> attribute set, and there's a <code>gnuradio.callPackage</code>
+     function that extends <code>pkgs</code> with a <code>mkDerivation</code>, and a
+     <code>mkDerivationWith</code>, like Qt5. Now all <code>gnuradio.pkgs</code> are
+     defined with <code>gnuradio.callPackage</code> and some packages that depend
+     on gnuradio are defined with this as well.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     <link xlink:href="https://www.privoxy.org/">Privoxy</link> has been updated
+     to version 3.0.32 (See <link xlink:href="https://lists.privoxy.org/pipermail/privoxy-announce/2021-February/000007.html">announcement</link>).
+     Compared to the previous release, Privoxy has gained support for HTTPS
+     inspection (still experimental), Brotli decompression, several new filters
+     and lots of bug fixes, including security ones. In addition, the package
+     is now built with compression and external filters support, which were
+     previously disabled.
+    </para>
+    <para>
+     Regarding the NixOS module, new options for HTTPS inspection have been added
+     and <option>services.privoxy.extraConfig</option> has been replaced by the new
+     <xref linkend="opt-services.privoxy.settings"/>
+     (See <link xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC 0042</link>
+     for the motivation).
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     <link xlink:href="https://kodi.tv/">Kodi</link> has been updated to version 19.1 "Matrix". See
+     the <link xlink:href="https://kodi.tv/article/kodi-190-matrix-release">announcement</link> for
+     further details.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     The <option>services.packagekit.backend</option> option has been removed as
+     it only supported a single setting which would always be the default.
+     Instead new <link
+     xlink:href="https://github.com/NixOS/rfcs/blob/master/rfcs/0042-config-option.md">RFC
+     0042</link> compliant <xref linkend="opt-services.packagekit.settings"/>
+     and <xref linkend="opt-services.packagekit.vendorSettings"/> options have
+     been introduced.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+      <link xlink:href="https://nginx.org">Nginx</link> has been updated to stable version 1.20.0.
+      Now nginx uses the zlib-ng library by default.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     KDE Gear (formerly KDE Applications) is upgraded to 21.04, see its
+     <link xlink:href="https://kde.org/announcements/gear/21.04/">release
+     notes</link> for details.
+    </para>
+    <para>
+     The <code>kdeApplications</code> package set is now <code>kdeGear</code>,
+     in keeping with the new name. The old name remains for compatibility, but
+     it is deprecated.
+    </para>
+   </listitem>
+   <listitem>
+    <para>
+     <link xlink:href="https://libreswan.org/">Libreswan</link> has been updated
+     to version 4.4. The package now includes example configurations and manual
+     pages by default. The NixOS module has been changed to use the upstream
+     systemd units and write the configuration in the <literal>/etc/ipsec.d/
+     </literal> directory. In addition, two new options have been added to
+     specify connection policies
+     (<xref linkend="opt-services.libreswan.policies"/>)
+     and disable send/receive redirects
+     (<xref linkend="opt-services.libreswan.disableRedirects"/>).
+    </para>
+   </listitem>
+
    <listitem>
     <para>
      The Mailman NixOS module (<literal>services.mailman</literal>) has a new
@@ -984,7 +1061,8 @@ environment.systemPackages = [
      PulseAudio was upgraded to 14.0, with changes to the handling of default sinks.
      See its <link xlink:href="https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/14.0/">release notes</link>.
     </para>
-
+   </listitem>
+   <listitem>
     <para>
      GNOME users may wish to delete their <literal>~/.config/pulse</literal> due to the changes to stream routing
      logic. See <link xlink:href="https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/issues/832">PulseAudio bug 832</link>
diff --git a/nixos/lib/make-ext4-fs.nix b/nixos/lib/make-ext4-fs.nix
index 33dbc8f5ec4..416beeb32f2 100644
--- a/nixos/lib/make-ext4-fs.nix
+++ b/nixos/lib/make-ext4-fs.nix
@@ -74,11 +74,9 @@ pkgs.stdenv.mkDerivation {
         return 1
       fi
 
-      echo "Resizing to minimum allowed size"
-      resize2fs -M $img
-
-      # And a final fsck, because of the previous truncating.
-      fsck.ext4 -n -f $img
+      # We may want to shrink the file system and resize the image to
+      # get rid of the unnecessary slack here--but see
+      # https://github.com/NixOS/nixpkgs/issues/125121 for caveats.
 
       if [ ${builtins.toString compressImage} ]; then
         echo "Compressing image"
diff --git a/nixos/lib/test-driver/test-driver.py b/nixos/lib/test-driver/test-driver.py
index e216e566f28..6bbca95a97f 100644
--- a/nixos/lib/test-driver/test-driver.py
+++ b/nixos/lib/test-driver/test-driver.py
@@ -128,18 +128,18 @@ def create_vlan(vlan_nr: str) -> Tuple[str, str, "subprocess.Popen[bytes]", Any]
     return (vlan_nr, vde_socket, vde_process, fd)
 
 
-def retry(fn: Callable) -> None:
+def retry(fn: Callable, timeout: int = 900) -> None:
     """Call the given function repeatedly, with 1 second intervals,
     until it returns True or a timeout is reached.
     """
 
-    for _ in range(900):
+    for _ in range(timeout):
         if fn(False):
             return
         time.sleep(1)
 
     if not fn(True):
-        raise Exception("action timed out")
+        raise Exception(f"action timed out after {timeout} seconds")
 
 
 class Logger:
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index aa4e2ccc46b..75405b17444 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -398,6 +398,7 @@
   ./services/hardware/ratbagd.nix
   ./services/hardware/sane.nix
   ./services/hardware/sane_extra_backends/brscan4.nix
+  ./services/hardware/sane_extra_backends/brscan5.nix
   ./services/hardware/sane_extra_backends/dsseries.nix
   ./services/hardware/spacenavd.nix
   ./services/hardware/tcsd.nix
@@ -547,6 +548,7 @@
   ./services/misc/ripple-data-api.nix
   ./services/misc/serviio.nix
   ./services/misc/safeeyes.nix
+  ./services/misc/sdrplay.nix
   ./services/misc/sickbeard.nix
   ./services/misc/siproxd.nix
   ./services/misc/snapper.nix
@@ -1112,6 +1114,7 @@
   ./virtualisation/openvswitch.nix
   ./virtualisation/parallels-guest.nix
   ./virtualisation/podman.nix
+  ./virtualisation/podman-network-socket-ghostunnel.nix
   ./virtualisation/qemu-guest-agent.nix
   ./virtualisation/railcar.nix
   ./virtualisation/spice-usb-redirection.nix
diff --git a/nixos/modules/security/acme.nix b/nixos/modules/security/acme.nix
index eb3599b924d..c0250171109 100644
--- a/nixos/modules/security/acme.nix
+++ b/nixos/modules/security/acme.nix
@@ -152,7 +152,7 @@ let
     );
     renewOpts = escapeShellArgs (
       commonOpts
-      ++ [ "renew" "--reuse-key" ]
+      ++ [ "renew" ]
       ++ optionals data.ocspMustStaple [ "--must-staple" ]
       ++ data.extraLegoRenewFlags
     );
diff --git a/nixos/modules/services/continuous-integration/buildkite-agents.nix b/nixos/modules/services/continuous-integration/buildkite-agents.nix
index 3dd1c40aaa4..b8982d757db 100644
--- a/nixos/modules/services/continuous-integration/buildkite-agents.nix
+++ b/nixos/modules/services/continuous-integration/buildkite-agents.nix
@@ -238,8 +238,7 @@ in
         in
           optionalString (cfg.privateSshKeyPath != null) ''
             mkdir -m 0700 -p "${sshDir}"
-            cp -f "${toString cfg.privateSshKeyPath}" "${sshDir}/id_rsa"
-            chmod 600 "${sshDir}"/id_rsa
+            install -m600 "${toString cfg.privateSshKeyPath}" "${sshDir}/id_rsa"
           '' + ''
             cat > "${cfg.dataDir}/buildkite-agent.cfg" <<EOF
             token="$(cat ${toString cfg.tokenPath})"
diff --git a/nixos/modules/services/hardware/sane_extra_backends/brscan5.nix b/nixos/modules/services/hardware/sane_extra_backends/brscan5.nix
new file mode 100644
index 00000000000..89b5ff0e028
--- /dev/null
+++ b/nixos/modules/services/hardware/sane_extra_backends/brscan5.nix
@@ -0,0 +1,110 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.hardware.sane.brscan5;
+
+  netDeviceList = attrValues cfg.netDevices;
+
+  etcFiles = pkgs.callPackage ./brscan5_etc_files.nix { netDevices = netDeviceList; };
+
+  netDeviceOpts = { name, ... }: {
+
+    options = {
+
+      name = mkOption {
+        type = types.str;
+        description = ''
+          The friendly name you give to the network device. If undefined,
+          the name of attribute will be used.
+        '';
+
+        example = literalExample "office1";
+      };
+
+      model = mkOption {
+        type = types.str;
+        description = ''
+          The model of the network device.
+        '';
+
+        example = literalExample "ADS-1200";
+      };
+
+      ip = mkOption {
+        type = with types; nullOr str;
+        default = null;
+        description = ''
+          The ip address of the device. If undefined, you will have to
+          provide a nodename.
+        '';
+
+        example = literalExample "192.168.1.2";
+      };
+
+      nodename = mkOption {
+        type = with types; nullOr str;
+        default = null;
+        description = ''
+          The node name of the device. If undefined, you will have to
+          provide an ip.
+        '';
+
+        example = literalExample "BRW0080927AFBCE";
+      };
+
+    };
+
+
+    config =
+      { name = mkDefault name;
+      };
+  };
+
+in
+
+{
+  options = {
+
+    hardware.sane.brscan5.enable =
+      mkEnableOption "the Brother brscan5 sane backend";
+
+    hardware.sane.brscan5.netDevices = mkOption {
+      default = {};
+      example =
+        { office1 = { model = "MFC-7860DW"; ip = "192.168.1.2"; };
+          office2 = { model = "MFC-7860DW"; nodename = "BRW0080927AFBCE"; };
+        };
+      type = with types; attrsOf (submodule netDeviceOpts);
+      description = ''
+        The list of network devices that will be registered against the brscan5
+        sane backend.
+      '';
+    };
+  };
+
+  config = mkIf (config.hardware.sane.enable && cfg.enable) {
+
+    hardware.sane.extraBackends = [
+      pkgs.brscan5
+    ];
+
+    environment.etc."opt/brother/scanner/brscan5" =
+      { source = "${etcFiles}/etc/opt/brother/scanner/brscan5"; };
+    environment.etc."opt/brother/scanner/models" =
+      { source = "${etcFiles}/etc/opt/brother/scanner/brscan5/models"; };
+    environment.etc."sane.d/dll.d/brother5.conf".source = "${pkgs.brscan5}/etc/sane.d/dll.d/brother.conf";
+
+    assertions = [
+      { assertion = all (x: !(null != x.ip && null != x.nodename)) netDeviceList;
+        message = ''
+          When describing a network device as part of the attribute list
+          `hardware.sane.brscan5.netDevices`, only one of its `ip` or `nodename`
+          attribute should be specified, not both!
+        '';
+      }
+    ];
+
+  };
+}
diff --git a/nixos/modules/services/hardware/sane_extra_backends/brscan5_etc_files.nix b/nixos/modules/services/hardware/sane_extra_backends/brscan5_etc_files.nix
new file mode 100644
index 00000000000..432f0316a4f
--- /dev/null
+++ b/nixos/modules/services/hardware/sane_extra_backends/brscan5_etc_files.nix
@@ -0,0 +1,77 @@
+{ stdenv, lib, brscan5, netDevices ? [] }:
+
+/*
+
+Testing
+-------
+From nixpkgs repo
+
+No net devices:
+
+~~~
+nix-build -E 'let pkgs = import ./. {};
+                  brscan5-etc-files = pkgs.callPackage (import ./nixos/modules/services/hardware/sane_extra_backends/brscan5_etc_files.nix) {};
+              in brscan5-etc-files'
+~~~
+
+Two net devices:
+
+~~~
+nix-build -E 'let pkgs = import ./. {};
+                  brscan5-etc-files = pkgs.callPackage (import ./nixos/modules/services/hardware/sane_extra_backends/brscan5_etc_files.nix) {};
+              in brscan5-etc-files.override {
+                   netDevices = [
+                     {name="a"; model="ADS-1200"; nodename="BRW0080927AFBCE";}
+                     {name="b"; model="ADS-1200"; ip="192.168.1.2";}
+                   ];
+              }'
+~~~
+
+*/
+
+let
+
+  addNetDev = nd: ''
+    brsaneconfig5 -a \
+    name="${nd.name}" \
+    model="${nd.model}" \
+    ${if (lib.hasAttr "nodename" nd && nd.nodename != null) then
+      ''nodename="${nd.nodename}"'' else
+      ''ip="${nd.ip}"''}'';
+  addAllNetDev = xs: lib.concatStringsSep "\n" (map addNetDev xs);
+in
+
+stdenv.mkDerivation {
+
+  name = "brscan5-etc-files";
+  version = "1.2.6-0";
+  src = "${brscan5}/opt/brother/scanner/brscan5";
+
+  nativeBuildInputs = [ brscan5 ];
+
+  dontConfigure = true;
+
+  buildPhase = ''
+    TARGET_DIR="$out/etc/opt/brother/scanner/brscan5"
+    mkdir -p "$TARGET_DIR"
+    cp -rp "./models" "$TARGET_DIR"
+    cp -rp "./brscan5.ini" "$TARGET_DIR"
+    cp -rp "./brsanenetdevice.cfg" "$TARGET_DIR"
+
+    export NIX_REDIRECTS="/etc/opt/brother/scanner/brscan5/=$TARGET_DIR/"
+
+    printf '${addAllNetDev netDevices}\n'
+
+    ${addAllNetDev netDevices}
+  '';
+
+  dontInstall = true;
+
+  meta = with lib; {
+    description = "Brother brscan5 sane backend driver etc files";
+    homepage = "https://www.brother.com";
+    platforms = platforms.linux;
+    license = licenses.unfree;
+    maintainers = with maintainers; [ mattchrist ];
+  };
+}
diff --git a/nixos/modules/services/misc/sdrplay.nix b/nixos/modules/services/misc/sdrplay.nix
new file mode 100644
index 00000000000..2801108f082
--- /dev/null
+++ b/nixos/modules/services/misc/sdrplay.nix
@@ -0,0 +1,35 @@
+{ config, lib, pkgs, ... }:
+with lib;
+{
+  options.services.sdrplayApi = {
+    enable = mkOption {
+      default = false;
+      example = true;
+      description = ''
+        Whether to enable the SDRplay API service and udev rules.
+
+        <note><para>
+          To enable integration with SoapySDR and GUI applications like gqrx create an overlay containing
+          <literal>soapysdr-with-plugins = super.soapysdr.override { extraPackages = [ super.soapysdrplay ]; };</literal>
+        </para></note>
+      '';
+      type = lib.types.bool;
+    };
+  };
+
+  config = mkIf config.services.sdrplayApi.enable {
+    systemd.services.sdrplayApi = {
+      description = "SDRplay API Service";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        ExecStart = "${pkgs.sdrplay}/bin/sdrplay_apiService";
+        DynamicUser = true;
+        Restart = "on-failure";
+        RestartSec = "1s";
+      };
+    };
+    services.udev.packages = [ pkgs.sdrplay ];
+
+  };
+}
diff --git a/nixos/modules/services/web-apps/trilium.nix b/nixos/modules/services/web-apps/trilium.nix
index ae41ba50d2e..35383c992fe 100644
--- a/nixos/modules/services/web-apps/trilium.nix
+++ b/nixos/modules/services/web-apps/trilium.nix
@@ -9,7 +9,7 @@ let
 
     # Disable automatically generating desktop icon
     noDesktopIcon=true
-    noBackup=${cfg.noBackup}
+    noBackup=${lib.boolToString cfg.noBackup}
 
     [Network]
     # host setting is relevant only for web deployments - set the host on which the server will listen
diff --git a/nixos/modules/services/web-apps/wordpress.nix b/nixos/modules/services/web-apps/wordpress.nix
index f251cfe32db..775ecb3acaf 100644
--- a/nixos/modules/services/web-apps/wordpress.nix
+++ b/nixos/modules/services/web-apps/wordpress.nix
@@ -61,8 +61,10 @@ let
     ?>
   '';
 
-  secretsVars = [ "AUTH_KEY" "SECURE_AUTH_KEY" "LOOGGED_IN_KEY" "NONCE_KEY" "AUTH_SALT" "SECURE_AUTH_SALT" "LOGGED_IN_SALT" "NONCE_SALT" ];
+  secretsVars = [ "AUTH_KEY" "SECURE_AUTH_KEY" "LOGGED_IN_KEY" "NONCE_KEY" "AUTH_SALT" "SECURE_AUTH_SALT" "LOGGED_IN_SALT" "NONCE_SALT" ];
   secretsScript = hostStateDir: ''
+    # The match in this line is not a typo, see https://github.com/NixOS/nixpkgs/pull/124839
+    grep -q "LOOGGED_IN_KEY" "${hostStateDir}/secret-keys.php" && rm "${hostStateDir}/secret-keys.php"
     if ! test -e "${hostStateDir}/secret-keys.php"; then
       umask 0177
       echo "<?php" >> "${hostStateDir}/secret-keys.php"
diff --git a/nixos/modules/virtualisation/libvirtd.nix b/nixos/modules/virtualisation/libvirtd.nix
index d12169787c5..61ebc3ab8cf 100644
--- a/nixos/modules/virtualisation/libvirtd.nix
+++ b/nixos/modules/virtualisation/libvirtd.nix
@@ -160,7 +160,7 @@ in {
       etc."qemu/bridge.conf".text = lib.concatMapStringsSep "\n" (e:
         "allow ${e}") cfg.allowedBridges;
       systemPackages = with pkgs; [ libressl.nc iptables cfg.package cfg.qemuPackage ];
-      etc.ethertypes.source = "${pkgs.iptables}/etc/ethertypes";
+      etc.ethertypes.source = "${pkgs.ebtables}/etc/ethertypes";
     };
 
     boot.kernelModules = [ "tun" ];
diff --git a/nixos/modules/virtualisation/podman-network-socket-ghostunnel.nix b/nixos/modules/virtualisation/podman-network-socket-ghostunnel.nix
new file mode 100644
index 00000000000..a0e7e433164
--- /dev/null
+++ b/nixos/modules/virtualisation/podman-network-socket-ghostunnel.nix
@@ -0,0 +1,34 @@
+{ config, lib, pkg, ... }:
+let
+  inherit (lib)
+    mkOption
+    types
+    ;
+
+  cfg = config.virtualisation.podman.networkSocket;
+
+in
+{
+  options.virtualisation.podman.networkSocket = {
+    server = mkOption {
+      type = types.enum [ "ghostunnel" ];
+    };
+  };
+
+  config = lib.mkIf (cfg.enable && cfg.server == "ghostunnel") {
+
+    services.ghostunnel = {
+      enable = true;
+      servers."podman-socket" = {
+        inherit (cfg.tls) cert key cacert;
+        listen = "${cfg.listenAddress}:${toString cfg.port}";
+        target = "unix:/run/podman/podman.sock";
+        allowAll = lib.mkDefault true;
+      };
+    };
+    systemd.services.ghostunnel-server-podman-socket.serviceConfig.SupplementaryGroups = ["podman"];
+
+  };
+
+  meta.maintainers = lib.teams.podman.members ++ [ lib.maintainers.roberth ];
+}
diff --git a/nixos/modules/virtualisation/podman-network-socket.nix b/nixos/modules/virtualisation/podman-network-socket.nix
new file mode 100644
index 00000000000..1429164630b
--- /dev/null
+++ b/nixos/modules/virtualisation/podman-network-socket.nix
@@ -0,0 +1,91 @@
+{ config, lib, pkg, ... }:
+let
+  inherit (lib)
+    mkOption
+    types
+    ;
+
+  cfg = config.virtualisation.podman.networkSocket;
+
+in
+{
+  options.virtualisation.podman.networkSocket = {
+    enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Make the Podman and Docker compatibility API available over the network
+        with TLS client certificate authentication.
+
+        This allows Docker clients to connect with the equivalents of the Docker
+        CLI <code>-H</code> and <code>--tls*</code> family of options.
+
+        For certificate setup, see https://docs.docker.com/engine/security/protect-access/
+
+        This option is independent of <xref linkend="opt-virtualisation.podman.dockerSocket.enable"/>.
+      '';
+    };
+
+    server = mkOption {
+      type = types.enum [];
+      description = ''
+        Choice of TLS proxy server.
+      '';
+      example = "ghostunnel";
+    };
+
+    openFirewall = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Whether to open the port in the firewall.
+      '';
+    };
+
+    tls.cacert = mkOption {
+      type = types.path;
+      description = ''
+        Path to CA certificate to use for client authentication.
+      '';
+    };
+
+    tls.cert = mkOption {
+      type = types.path;
+      description = ''
+        Path to certificate describing the server.
+      '';
+    };
+
+    tls.key = mkOption {
+      type = types.path;
+      description = ''
+        Path to the private key corresponding to the server certificate.
+
+        Use a string for this setting. Otherwise it will be copied to the Nix
+        store first, where it is readable by any system process.
+      '';
+    };
+
+    port = mkOption {
+      type = types.port;
+      default = 2376;
+      description = ''
+        TCP port number for receiving TLS connections.
+      '';
+    };
+    listenAddress = mkOption {
+      type = types.str;
+      default = "0.0.0.0";
+      description = ''
+        Interface address for receiving TLS connections.
+      '';
+    };
+  };
+
+  config = {
+    networking.firewall.allowedTCPPorts =
+      lib.optional (cfg.enable && cfg.openFirewall) cfg.port;
+  };
+
+  meta.maintainers = lib.teams.podman.members ++ [ lib.maintainers.roberth ];
+}
diff --git a/nixos/modules/virtualisation/podman.nix b/nixos/modules/virtualisation/podman.nix
index d6421d488b8..b16afb66894 100644
--- a/nixos/modules/virtualisation/podman.nix
+++ b/nixos/modules/virtualisation/podman.nix
@@ -1,4 +1,4 @@
-{ config, lib, pkgs, utils, ... }:
+{ config, lib, pkgs, ... }:
 let
   cfg = config.virtualisation.podman;
   toml = pkgs.formats.toml { };
@@ -25,6 +25,7 @@ let
 in
 {
   imports = [
+    ./podman-network-socket.nix
     (lib.mkRenamedOptionModule [ "virtualisation" "podman" "libpod" ] [ "virtualisation" "containers" "containersConf" ])
   ];
 
@@ -46,6 +47,20 @@ in
         '';
       };
 
+    dockerSocket.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Make the Podman socket available in place of the Docker socket, so
+        Docker tools can find the Podman socket.
+
+        Podman implements the Docker API.
+
+        Users must be in the <code>podman</code> group in order to connect. As
+        with Docker, members of this group can gain root access.
+      '';
+    };
+
     dockerCompat = mkOption {
       type = types.bool;
       default = false;
@@ -92,7 +107,7 @@ in
       environment.systemPackages = [ cfg.package ]
         ++ lib.optional cfg.dockerCompat dockerCompat;
 
-      environment.etc."cni/net.d/87-podman-bridge.conflist".source = utils.copyFile "${pkgs.podman-unwrapped.src}/cni/87-podman-bridge.conflist";
+      environment.etc."cni/net.d/87-podman-bridge.conflist".source = "${cfg.package}/etc/cni/net.d/87-podman-bridge.conflist";
 
       virtualisation.containers = {
         enable = true; # Enable common /etc/containers configuration
@@ -111,14 +126,36 @@ in
       };
 
       systemd.sockets.podman.wantedBy = [ "sockets.target" ];
+      systemd.sockets.podman.socketConfig.SocketGroup = "podman";
+
+      systemd.tmpfiles.packages = [
+        # The /run/podman rule interferes with our podman group, so we remove
+        # it and let the systemd socket logic take care of it.
+        (pkgs.runCommand "podman-tmpfiles-nixos" { package = cfg.package; } ''
+          mkdir -p $out/lib/tmpfiles.d/
+          grep -v 'D! /run/podman 0700 root root' \
+            <$package/lib/tmpfiles.d/podman.conf \
+            >$out/lib/tmpfiles.d/podman.conf
+        '') ];
 
-      systemd.tmpfiles.packages = [ cfg.package ];
+      systemd.tmpfiles.rules =
+        lib.optionals cfg.dockerSocket.enable [
+          "L! /run/docker.sock - - - - /run/podman/podman.sock"
+        ];
+
+      users.groups.podman = {};
 
       assertions = [
         {
           assertion = cfg.dockerCompat -> !config.virtualisation.docker.enable;
           message = "Option dockerCompat conflicts with docker";
         }
+        {
+          assertion = cfg.dockerSocket.enable -> !config.virtualisation.docker.enable;
+          message = ''
+            The options virtualisation.podman.dockerSocket.enable and virtualisation.docker.enable conflict, because only one can serve the socket.
+          '';
+        }
       ];
     }
   ]);
diff --git a/nixos/tests/all-tests.nix b/nixos/tests/all-tests.nix
index ab24c2c857a..f6417170a6f 100644
--- a/nixos/tests/all-tests.nix
+++ b/nixos/tests/all-tests.nix
@@ -335,6 +335,7 @@ in
   plotinus = handleTest ./plotinus.nix {};
   podgrab = handleTest ./podgrab.nix {};
   podman = handleTestOn ["x86_64-linux"] ./podman.nix {};
+  podman-tls-ghostunnel = handleTestOn ["x86_64-linux"] ./podman-tls-ghostunnel.nix {};
   pomerium = handleTestOn ["x86_64-linux"] ./pomerium.nix {};
   postfix = handleTest ./postfix.nix {};
   postfix-raise-smtpd-tls-security-level = handleTest ./postfix-raise-smtpd-tls-security-level.nix {};
diff --git a/nixos/tests/brscan5.nix b/nixos/tests/brscan5.nix
new file mode 100644
index 00000000000..715191b383c
--- /dev/null
+++ b/nixos/tests/brscan5.nix
@@ -0,0 +1,42 @@
+# integration tests for brscan5 sane driver
+#
+
+import ./make-test-python.nix ({ pkgs, ...} : {
+  name = "brscan5";
+  meta = with pkgs.lib.maintainers; {
+    maintainers = [ mattchrist ];
+  };
+
+  machine = { pkgs, ... }:
+    {
+      nixpkgs.config.allowUnfree = true;
+      hardware.sane = {
+        enable = true;
+        brscan5 = {
+          enable = true;
+          netDevices = {
+            "a" = { model="ADS-1200"; nodename="BRW0080927AFBCE"; };
+            "b" = { model="ADS-1200"; ip="192.168.1.2"; };
+          };
+        };
+      };
+    };
+
+  testScript = ''
+    # sane loads libsane-brother5.so.1 successfully, and scanimage doesn't die
+    strace = machine.succeed('strace scanimage -L 2>&1').split("\n")
+    regexp = 'openat\(.*libsane-brother5.so.1", O_RDONLY|O_CLOEXEC\) = \d\d*$'
+    assert len([x for x in strace if re.match(regexp,x)]) > 0
+
+    # module creates a config
+    cfg = machine.succeed('cat /etc/opt/brother/scanner/brscan5/brsanenetdevice.cfg')
+    assert 'DEVICE=a , "ADS-1200" , 0x4f9:0x459 , NODENAME=BRW0080927AFBCE' in cfg
+    assert 'DEVICE=b , "ADS-1200" , 0x4f9:0x459 , IP-ADDRESS=192.168.1.2' in cfg
+
+    # scanimage lists the two network scanners
+    scanimage = machine.succeed("scanimage -L")
+    print(scanimage)
+    assert """device `brother5:net1;dev0' is a Brother b ADS-1200""" in scanimage
+    assert """device `brother5:net1;dev1' is a Brother a ADS-1200""" in scanimage
+  '';
+})
diff --git a/nixos/tests/podman-tls-ghostunnel.nix b/nixos/tests/podman-tls-ghostunnel.nix
new file mode 100644
index 00000000000..0e687b199b2
--- /dev/null
+++ b/nixos/tests/podman-tls-ghostunnel.nix
@@ -0,0 +1,150 @@
+/*
+  This test runs podman as a backend for the Docker CLI.
+ */
+import ./make-test-python.nix (
+  { pkgs, lib, ... }:
+
+  let gen-ca = pkgs.writeScript "gen-ca" ''
+    # Create CA
+    PATH="${pkgs.openssl}/bin:$PATH"
+    openssl genrsa -out ca-key.pem 4096
+    openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -subj '/C=NL/ST=Zuid-Holland/L=The Hague/O=Stevige Balken en Planken B.V./OU=OpSec/CN=Certificate Authority' -out ca.pem
+
+    # Create service
+    openssl genrsa -out podman-key.pem 4096
+    openssl req -subj '/CN=podman' -sha256 -new -key podman-key.pem -out service.csr
+    echo subjectAltName = DNS:podman,IP:127.0.0.1 >> extfile.cnf
+    echo extendedKeyUsage = serverAuth >> extfile.cnf
+    openssl x509 -req -days 365 -sha256 -in service.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out podman-cert.pem -extfile extfile.cnf
+
+    # Create client
+    openssl genrsa -out client-key.pem 4096
+    openssl req -subj '/CN=client' -new -key client-key.pem -out client.csr
+    echo extendedKeyUsage = clientAuth > extfile-client.cnf
+    openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile extfile-client.cnf
+
+    # Create CA 2
+    PATH="${pkgs.openssl}/bin:$PATH"
+    openssl genrsa -out ca-2-key.pem 4096
+    openssl req -new -x509 -days 365 -key ca-2-key.pem -sha256 -subj '/C=NL/ST=Zuid-Holland/L=The Hague/O=Stevige Balken en Planken B.V./OU=OpSec/CN=Certificate Authority' -out ca-2.pem
+
+    # Create client signed by CA 2
+    openssl genrsa -out client-2-key.pem 4096
+    openssl req -subj '/CN=client' -new -key client-2-key.pem -out client-2.csr
+    echo extendedKeyUsage = clientAuth > extfile-client.cnf
+    openssl x509 -req -days 365 -sha256 -in client-2.csr -CA ca-2.pem -CAkey ca-2-key.pem -CAcreateserial -out client-2-cert.pem -extfile extfile-client.cnf
+
+    '';
+  in
+  {
+    name = "podman-tls-ghostunnel";
+    meta = {
+      maintainers = lib.teams.podman.members ++ [ lib.maintainers.roberth ];
+    };
+
+    nodes = {
+      podman =
+        { pkgs, ... }:
+        {
+          virtualisation.podman.enable = true;
+          virtualisation.podman.dockerSocket.enable = true;
+          virtualisation.podman.networkSocket = {
+            enable = true;
+            openFirewall = true;
+            server = "ghostunnel";
+            tls.cert = "/root/podman-cert.pem";
+            tls.key = "/root/podman-key.pem";
+            tls.cacert = "/root/ca.pem";
+          };
+
+          environment.systemPackages = [
+            pkgs.docker-client
+          ];
+
+          users.users.alice = {
+            isNormalUser = true;
+            home = "/home/alice";
+            description = "Alice Foobar";
+            extraGroups = ["podman"];
+          };
+
+        };
+
+      client = { ... }: {
+        environment.systemPackages = [
+          # Installs the docker _client_ only
+          # Normally, you'd want `virtualisation.docker.enable = true;`.
+          pkgs.docker-client
+        ];
+        environment.variables.DOCKER_HOST = "podman:2376";
+        environment.variables.DOCKER_TLS_VERIFY = "1";
+      };
+    };
+
+    testScript = ''
+      import shlex
+
+
+      def su_cmd(user, cmd):
+          cmd = shlex.quote(cmd)
+          return f"su {user} -l -c {cmd}"
+
+      def cmd(command):
+        print(f"+{command}")
+        r = os.system(command)
+        if r != 0:
+          raise Exception(f"Command {command} failed with exit code {r}")
+
+      start_all()
+      cmd("${gen-ca}")
+
+      podman.copy_from_host("ca.pem", "/root/ca.pem")
+      podman.copy_from_host("podman-cert.pem", "/root/podman-cert.pem")
+      podman.copy_from_host("podman-key.pem", "/root/podman-key.pem")
+
+      client.copy_from_host("ca.pem", "/root/.docker/ca.pem")
+      # client.copy_from_host("podman-cert.pem", "/root/podman-cert.pem")
+      client.copy_from_host("client-cert.pem", "/root/.docker/cert.pem")
+      client.copy_from_host("client-key.pem", "/root/.docker/key.pem")
+
+      # TODO (ghostunnel): add file watchers so the restart isn't necessary
+      podman.succeed("systemctl reset-failed && systemctl restart ghostunnel-server-podman-socket.service")
+
+      podman.wait_for_unit("sockets.target")
+      podman.wait_for_unit("ghostunnel-server-podman-socket.service")
+
+      with subtest("Create default network"):
+          podman.succeed("docker network create default")
+
+      with subtest("Root docker cli also works"):
+          podman.succeed("docker version")
+
+      with subtest("A podman member can also still use the docker cli"):
+          podman.succeed(su_cmd("alice", "docker version"))
+
+      with subtest("Run container remotely via docker cli"):
+          client.succeed("docker version")
+
+          # via socket would be nicer
+          podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
+
+          client.succeed(
+            "docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
+          )
+          client.succeed("docker ps | grep sleeping")
+          podman.succeed("docker ps | grep sleeping")
+          client.succeed("docker stop sleeping")
+          client.succeed("docker rm sleeping")
+
+      with subtest("Clients without cert will be denied"):
+          client.succeed("rm /root/.docker/{cert,key}.pem")
+          client.fail("docker version")
+
+      with subtest("Clients with wrong cert will be denied"):
+          client.copy_from_host("client-2-cert.pem", "/root/.docker/cert.pem")
+          client.copy_from_host("client-2-key.pem", "/root/.docker/key.pem")
+          client.fail("docker version")
+
+    '';
+  }
+)
diff --git a/nixos/tests/podman.nix b/nixos/tests/podman.nix
index 6078a936ede..7eae575fd7f 100644
--- a/nixos/tests/podman.nix
+++ b/nixos/tests/podman.nix
@@ -13,10 +13,23 @@ import ./make-test-python.nix (
         {
           virtualisation.podman.enable = true;
 
+          # To test docker socket support
+          virtualisation.podman.dockerSocket.enable = true;
+          environment.systemPackages = [
+            pkgs.docker-client
+          ];
+
           users.users.alice = {
             isNormalUser = true;
             home = "/home/alice";
             description = "Alice Foobar";
+            extraGroups = [ "podman" ];
+          };
+
+          users.users.mallory = {
+            isNormalUser = true;
+            home = "/home/mallory";
+            description = "Mallory Foobar";
           };
 
         };
@@ -26,9 +39,9 @@ import ./make-test-python.nix (
       import shlex
 
 
-      def su_cmd(cmd):
+      def su_cmd(cmd, user = "alice"):
           cmd = shlex.quote(cmd)
-          return f"su alice -l -c {cmd}"
+          return f"su {user} -l -c {cmd}"
 
 
       podman.wait_for_unit("sockets.target")
@@ -105,6 +118,27 @@ import ./make-test-python.nix (
           assert pid == "1"
           pid = podman.succeed("podman run --rm --init busybox readlink /proc/self").strip()
           assert pid == "2"
+
+      with subtest("A podman member can use the docker cli"):
+          podman.succeed(su_cmd("docker version"))
+
+      with subtest("Run container via docker cli"):
+          podman.succeed("docker network create default")
+          podman.succeed("tar cv --files-from /dev/null | podman import - scratchimg")
+          podman.succeed(
+            "docker run -d --name=sleeping -v /nix/store:/nix/store -v /run/current-system/sw/bin:/bin scratchimg /bin/sleep 10"
+          )
+          podman.succeed("docker ps | grep sleeping")
+          podman.succeed("podman ps | grep sleeping")
+          podman.succeed("docker stop sleeping")
+          podman.succeed("docker rm sleeping")
+          podman.succeed("docker network rm default")
+
+      with subtest("A podman non-member can not use the docker cli"):
+          podman.fail(su_cmd("docker version", user="mallory"))
+
+      # TODO: add docker-compose test
+
     '';
   }
 )