diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
index 25b3a686c0d90..7f788be2b0a55 100644
--- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
+++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml
@@ -607,6 +607,23 @@
binaries, use the p4d package instead.
+
+
+ The openssl-extension for the PHP
+ interpreter used by Nextcloud is built against OpenSSL 1.1 if
+ is below
+ 22.11. This is to make sure that people
+ using
+ server-side
+ encryption don’t loose access to their files.
+
+
+ In any other case it’s safe to use OpenSSL 3 for PHP’s openssl
+ extension. This can be done by setting
+
+ to false.
+
+
The coq package and versioned variants
diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md
index 583480bec0204..bc7f86bf5526e 100644
--- a/nixos/doc/manual/release-notes/rl-2211.section.md
+++ b/nixos/doc/manual/release-notes/rl-2211.section.md
@@ -196,6 +196,13 @@ Available as [services.patroni](options.html#opt-services.patroni.enable).
- The `p4` package now only includes the open-source Perforce Helix Core command-line client and APIs. It no longer installs the unfree Helix Core Server binaries `p4d`, `p4broker`, and `p4p`. To install the Helix Core Server binaries, use the `p4d` package instead.
+- The `openssl`-extension for the PHP interpreter used by Nextcloud is built against OpenSSL 1.1 if
+ [](#opt-system.stateVersion) is below `22.11`. This is to make sure that people using [server-side encryption](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html)
+ don't loose access to their files.
+
+ In any other case it's safe to use OpenSSL 3 for PHP's openssl extension. This can be done by setting
+ [](#opt-services.nextcloud.enableBrokenCiphersForSSE) to `false`.
+
- The `coq` package and versioned variants starting at `coq_8_14` no
longer include CoqIDE, which is now available through
`coqPackages.coqide`. It is still possible to get CoqIDE as part of
diff --git a/nixos/modules/services/web-apps/nextcloud.nix b/nixos/modules/services/web-apps/nextcloud.nix
index 04599884f139c..da621573f2a26 100644
--- a/nixos/modules/services/web-apps/nextcloud.nix
+++ b/nixos/modules/services/web-apps/nextcloud.nix
@@ -13,7 +13,12 @@ let
phpPackage = cfg.phpPackage.buildEnv {
extensions = { enabled, all }:
(with all;
- enabled
+ # disable default openssl extension
+ (lib.filter (e: e.pname != "php-openssl") enabled)
+ # use OpenSSL 1.1 for RC4 Nextcloud encryption if user
+ # has acknowledged the brokeness of the ciphers (RC4).
+ # TODO: remove when https://github.com/nextcloud/server/issues/32003 is fixed.
+ ++ (if cfg.enableBrokenCiphersForSSE then [ cfg.phpPackage.extensions.openssl-legacy ] else [ cfg.phpPackage.extensions.openssl ])
++ optional cfg.enableImagemagick imagick
# Optionally enabled depending on caching settings
++ optional cfg.caching.apcu apcu
@@ -80,6 +85,40 @@ in {
options.services.nextcloud = {
enable = mkEnableOption (lib.mdDoc "nextcloud");
+
+ enableBrokenCiphersForSSE = mkOption {
+ type = types.bool;
+ default = versionOlder stateVersion "22.11";
+ defaultText = literalExpression "versionOlder system.stateVersion \"22.11\"";
+ description = lib.mdDoc ''
+ This option enables using the OpenSSL PHP extension linked against OpenSSL 1.1
+ rather than latest OpenSSL (≥ 3), this is not recommended unless you need
+ it for server-side encryption (SSE). SSE uses the legacy RC4 cipher which is
+ considered broken for several years now. See also [RFC7465](https://datatracker.ietf.org/doc/html/rfc7465).
+
+ This cipher has been disabled in OpenSSL ≥ 3 and requires
+ a specific legacy profile to re-enable it.
+
+ If you deploy Nextcloud using OpenSSL ≥ 3 for PHP and have
+ server-side encryption configured, you will not be able to access
+ your files anymore. Enabling this option can restore access to your files.
+ Upon testing we didn't encounter any data corruption when turning
+ this on and off again, but this cannot be guaranteed for
+ each Nextcloud installation.
+
+ It is `true` by default for systems with a [](#opt-system.stateVersion) below
+ `22.11` to make sure that existing installations won't break on update. On newer
+ NixOS systems you have to explicitly enable it on your own.
+
+ Please note that this only provides additional value when using
+ external storage such as S3 since it's not an end-to-end encryption.
+ If this is not the case,
+ it is advised to [disable server-side encryption](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/encryption_configuration.html#disabling-encryption) and set this to `false`.
+
+ In the future, Nextcloud may move to AES-256-GCM, by then,
+ this option will be removed.
+ '';
+ };
hostName = mkOption {
type = types.str;
description = lib.mdDoc "FQDN for the nextcloud instance.";
@@ -649,6 +688,23 @@ in {
++ (optional (versionOlder cfg.package.version "23") (upgradeWarning 22 "22.05"))
++ (optional (versionOlder cfg.package.version "24") (upgradeWarning 23 "22.05"))
++ (optional (versionOlder cfg.package.version "25") (upgradeWarning 24 "22.11"))
+ ++ (optional cfg.enableBrokenCiphersForSSE ''
+ You're using PHP's openssl extension built against OpenSSL 1.1 for Nextcloud.
+ This is only necessary if you're using Nextcloud's server-side encryption.
+ Please keep in mind that it's using the broken RC4 cipher.
+
+ If you don't use that feature, you can switch to OpenSSL 3 and get
+ rid of this warning by declaring
+
+ services.nextcloud.enableBrokenCiphersForSSE = false;
+
+ If you need to use server-side encryption you can ignore this waring.
+ Otherwise you'd have to disable server-side encryption first in order
+ to be able to safely disable this option and get rid of this warning.
+ See on how to achieve this.
+
+ For more context, here is the implementing pull request: https://github.com/NixOS/nixpkgs/pull/198470
+ '')
++ (optional isUnsupportedMariadb ''
You seem to be using MariaDB at an unsupported version (i.e. at least 10.6)!
Please note that this isn't supported officially by Nextcloud. You can either
diff --git a/nixos/modules/services/web-apps/nextcloud.xml b/nixos/modules/services/web-apps/nextcloud.xml
index a0b69dbd606ce..ca57692fc16a8 100644
--- a/nixos/modules/services/web-apps/nextcloud.xml
+++ b/nixos/modules/services/web-apps/nextcloud.xml
@@ -170,6 +170,20 @@
+
+
+ Server-side encryption
+
+ Nextcloud supports server-side encryption (SSE).
+ This is not an end-to-end encryption, but can be used to encrypt files that will be persisted
+ to external storage such as S3. Please note that this won't work anymore when using OpenSSL 3
+ for PHP's openssl extension because this is implemented using the legacy cipher RC4.
+ If is above22.05,
+ this is disabled by default. To turn it on again and for further information please refer to
+ .
+
+
+
diff --git a/nixos/tests/nextcloud/basic.nix b/nixos/tests/nextcloud/basic.nix
index eb37470a4c7bb..a475049e7b264 100644
--- a/nixos/tests/nextcloud/basic.nix
+++ b/nixos/tests/nextcloud/basic.nix
@@ -37,6 +37,8 @@ in {
"d /var/lib/nextcloud-data 0750 nextcloud nginx - -"
];
+ system.stateVersion = "22.11"; # stateVersion >=21.11 to make sure that we use OpenSSL3
+
services.nextcloud = {
enable = true;
datadir = "/var/lib/nextcloud-data";
@@ -99,6 +101,10 @@ in {
# This is just to ensure the nextcloud-occ program is working
nextcloud.succeed("nextcloud-occ status")
nextcloud.succeed("curl -sSf http://nextcloud/login")
+ # Ensure that no OpenSSL 1.1 is used.
+ nextcloud.succeed(
+ "${nodes.nextcloud.services.phpfpm.pools.nextcloud.phpPackage}/bin/php -i | grep 'OpenSSL Library Version' | awk -F'=>' '{ print $2 }' | awk '{ print $2 }' | grep -v 1.1"
+ )
nextcloud.succeed(
"${withRcloneEnv} ${copySharedFile}"
)
@@ -108,5 +114,6 @@ in {
"${withRcloneEnv} ${diffSharedFile}"
)
assert "hi" in client.succeed("cat /mnt/dav/test-shared-file")
+ nextcloud.succeed("grep -vE '^HBEGIN:oc_encryption_module' /var/lib/nextcloud-data/data/root/files/test-shared-file")
'';
})) args
diff --git a/nixos/tests/nextcloud/default.nix b/nixos/tests/nextcloud/default.nix
index 7dbdff9882387..b8d3ba75b51a9 100644
--- a/nixos/tests/nextcloud/default.nix
+++ b/nixos/tests/nextcloud/default.nix
@@ -8,6 +8,10 @@ with pkgs.lib;
foldl
(matrix: ver: matrix // {
"basic${toString ver}" = import ./basic.nix { inherit system pkgs; nextcloudVersion = ver; };
+ "openssl-sse${toString ver}" = import ./openssl-sse.nix {
+ inherit system pkgs;
+ nextcloudVersion = ver;
+ };
"with-postgresql-and-redis${toString ver}" = import ./with-postgresql-and-redis.nix {
inherit system pkgs;
nextcloudVersion = ver;
diff --git a/nixos/tests/nextcloud/openssl-sse.nix b/nixos/tests/nextcloud/openssl-sse.nix
new file mode 100644
index 0000000000000..7595ee2c67e31
--- /dev/null
+++ b/nixos/tests/nextcloud/openssl-sse.nix
@@ -0,0 +1,105 @@
+args@{ pkgs, nextcloudVersion ? 25, ... }:
+
+(import ../make-test-python.nix ({ pkgs, ...}: let
+ adminuser = "root";
+ adminpass = "notproduction";
+ nextcloudBase = {
+ networking.firewall.allowedTCPPorts = [ 80 ];
+ system.stateVersion = "22.05"; # stateVersions <22.11 use openssl 1.1 by default
+ services.nextcloud = {
+ enable = true;
+ config.adminpassFile = "${pkgs.writeText "adminpass" adminpass}";
+ package = pkgs.${"nextcloud" + (toString nextcloudVersion)};
+ };
+ };
+in {
+ name = "nextcloud-openssl";
+ meta = with pkgs.lib.maintainers; {
+ maintainers = [ ma27 ];
+ };
+ nodes.nextcloudwithopenssl1 = {
+ imports = [ nextcloudBase ];
+ services.nextcloud.hostName = "nextcloudwithopenssl1";
+ };
+ nodes.nextcloudwithopenssl3 = {
+ imports = [ nextcloudBase ];
+ services.nextcloud = {
+ hostName = "nextcloudwithopenssl3";
+ enableBrokenCiphersForSSE = false;
+ };
+ };
+ testScript = { nodes, ... }: let
+ withRcloneEnv = host: pkgs.writeScript "with-rclone-env" ''
+ #!${pkgs.runtimeShell}
+ export RCLONE_CONFIG_NEXTCLOUD_TYPE=webdav
+ export RCLONE_CONFIG_NEXTCLOUD_URL="http://${host}/remote.php/webdav/"
+ export RCLONE_CONFIG_NEXTCLOUD_VENDOR="nextcloud"
+ export RCLONE_CONFIG_NEXTCLOUD_USER="${adminuser}"
+ export RCLONE_CONFIG_NEXTCLOUD_PASS="$(${pkgs.rclone}/bin/rclone obscure ${adminpass})"
+ "''${@}"
+ '';
+ withRcloneEnv1 = withRcloneEnv "nextcloudwithopenssl1";
+ withRcloneEnv3 = withRcloneEnv "nextcloudwithopenssl3";
+ copySharedFile1 = pkgs.writeScript "copy-shared-file" ''
+ #!${pkgs.runtimeShell}
+ echo 'hi' | ${withRcloneEnv1} ${pkgs.rclone}/bin/rclone rcat nextcloud:test-shared-file
+ '';
+ copySharedFile3 = pkgs.writeScript "copy-shared-file" ''
+ #!${pkgs.runtimeShell}
+ echo 'bye' | ${withRcloneEnv3} ${pkgs.rclone}/bin/rclone rcat nextcloud:test-shared-file2
+ '';
+ openssl1-node = nodes.nextcloudwithopenssl1.config.system.build.toplevel;
+ openssl3-node = nodes.nextcloudwithopenssl3.config.system.build.toplevel;
+ in ''
+ nextcloudwithopenssl1.start()
+ nextcloudwithopenssl1.wait_for_unit("multi-user.target")
+ nextcloudwithopenssl1.succeed("nextcloud-occ status")
+ nextcloudwithopenssl1.succeed("curl -sSf http://nextcloudwithopenssl1/login")
+
+ with subtest("With OpenSSL 1 SSE can be enabled and used"):
+ nextcloudwithopenssl1.succeed("nextcloud-occ app:enable encryption")
+ nextcloudwithopenssl1.succeed("nextcloud-occ encryption:enable")
+
+ with subtest("Upload file and ensure it's encrypted"):
+ nextcloudwithopenssl1.succeed("${copySharedFile1}")
+ nextcloudwithopenssl1.succeed("grep -E '^HBEGIN:oc_encryption_module' /var/lib/nextcloud/data/root/files/test-shared-file")
+ nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file | grep hi")
+
+ with subtest("Switch to OpenSSL 3"):
+ nextcloudwithopenssl1.succeed("${openssl3-node}/bin/switch-to-configuration test")
+ nextcloudwithopenssl1.wait_for_open_port(80)
+ nextcloudwithopenssl1.succeed("nextcloud-occ status")
+
+ with subtest("Existing encrypted files cannot be read, but new files can be added"):
+ nextcloudwithopenssl1.fail("${withRcloneEnv3} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file >&2")
+ nextcloudwithopenssl1.succeed("nextcloud-occ encryption:disable")
+ nextcloudwithopenssl1.succeed("${copySharedFile3}")
+ nextcloudwithopenssl1.succeed("grep bye /var/lib/nextcloud/data/root/files/test-shared-file2")
+ nextcloudwithopenssl1.succeed("${withRcloneEnv3} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file2 | grep bye")
+
+ with subtest("Switch back to OpenSSL 1.1 and ensure that encrypted files are readable again"):
+ nextcloudwithopenssl1.succeed("${openssl1-node}/bin/switch-to-configuration test")
+ nextcloudwithopenssl1.wait_for_open_port(80)
+ nextcloudwithopenssl1.succeed("nextcloud-occ status")
+ nextcloudwithopenssl1.succeed("nextcloud-occ encryption:enable")
+ nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file2 | grep bye")
+ nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file | grep hi")
+ nextcloudwithopenssl1.succeed("grep -E '^HBEGIN:oc_encryption_module' /var/lib/nextcloud/data/root/files/test-shared-file")
+ nextcloudwithopenssl1.succeed("grep bye /var/lib/nextcloud/data/root/files/test-shared-file2")
+
+ with subtest("Ensure that everything can be decrypted"):
+ nextcloudwithopenssl1.succeed("echo y | nextcloud-occ encryption:decrypt-all >&2")
+ nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file2 | grep bye")
+ nextcloudwithopenssl1.succeed("${withRcloneEnv1} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file | grep hi")
+ nextcloudwithopenssl1.succeed("grep -vE '^HBEGIN:oc_encryption_module' /var/lib/nextcloud/data/root/files/test-shared-file")
+
+ with subtest("Switch to OpenSSL 3 ensure that all files are usable now"):
+ nextcloudwithopenssl1.succeed("${openssl3-node}/bin/switch-to-configuration test")
+ nextcloudwithopenssl1.wait_for_open_port(80)
+ nextcloudwithopenssl1.succeed("nextcloud-occ status")
+ nextcloudwithopenssl1.succeed("${withRcloneEnv3} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file2 | grep bye")
+ nextcloudwithopenssl1.succeed("${withRcloneEnv3} ${pkgs.rclone}/bin/rclone cat nextcloud:test-shared-file | grep hi")
+
+ nextcloudwithopenssl1.shutdown()
+ '';
+})) args
diff --git a/pkgs/development/interpreters/php/generic.nix b/pkgs/development/interpreters/php/generic.nix
index d1b7c68295578..ae59bf349a9cd 100644
--- a/pkgs/development/interpreters/php/generic.nix
+++ b/pkgs/development/interpreters/php/generic.nix
@@ -91,7 +91,7 @@ let
[ ]
allExtensionFunctions;
- getExtName = ext: lib.removePrefix "php-" (builtins.parseDrvName ext.name).name;
+ getExtName = ext: ext.extensionName;
# Recursively get a list of all internal dependencies
# for a list of extensions.
diff --git a/pkgs/top-level/php-packages.nix b/pkgs/top-level/php-packages.nix
index 0b9f4237327b0..af3bb5451025a 100644
--- a/pkgs/top-level/php-packages.nix
+++ b/pkgs/top-level/php-packages.nix
@@ -71,16 +71,17 @@ lib.makeScope pkgs.newScope (self: with self; {
# will mark the extension as a zend extension or not.
mkExtension = lib.makeOverridable
({ name
- , configureFlags ? [ "--enable-${name}" ]
+ , configureFlags ? [ "--enable-${extName}" ]
, internalDeps ? [ ]
, postPhpize ? ""
, buildInputs ? [ ]
, zendExtension ? false
, doCheck ? true
+ , extName ? name
, ...
}@args: stdenv.mkDerivation ((builtins.removeAttrs args [ "name" ]) // {
pname = "php-${name}";
- extensionName = name;
+ extensionName = extName;
outputs = [ "out" "dev" ];
@@ -103,7 +104,7 @@ lib.makeScope pkgs.newScope (self: with self; {
cdToExtensionRootPhase = ''
# Go to extension source root.
- cd "ext/${name}"
+ cd "ext/${extName}"
'';
preConfigure = ''
@@ -139,7 +140,7 @@ lib.makeScope pkgs.newScope (self: with self; {
runHook preInstall
mkdir -p $out/lib/php/extensions
- cp modules/${name}.so $out/lib/php/extensions/${name}.so
+ cp modules/${extName}.so $out/lib/php/extensions/${extName}.so
mkdir -p $dev/include
${rsync}/bin/rsync -r --filter="+ */" \
--filter="+ *.h" \
@@ -414,6 +415,16 @@ lib.makeScope pkgs.newScope (self: with self; {
configureFlags = [ "--with-openssl" ];
doCheck = false;
}
+ # This provides a legacy OpenSSL PHP extension
+ # For situations where OpenSSL 3 do not support a set of features
+ # without a specific openssl.cnf file
+ {
+ name = "openssl-legacy";
+ extName = "openssl";
+ buildInputs = [ openssl_1_1 ];
+ configureFlags = [ "--with-openssl" ];
+ doCheck = false;
+ }
{ name = "pcntl"; }
{ name = "pdo"; doCheck = false; }
{