为 FIPS 140-2 兼容性配置 SSL

联邦信息处理标准 (FIPS) 140 是美国政府由国家标准与技术研究院 (NIST) 制定的一项标准,用于认证密码模块(例如 TLS 网络加密中所使用的模块)。虽然 FIPS 140 合规性主要针对联邦机构及其承包商,但它也用于医疗保健领域,受《健康保险流通与责任法案》(HIPAA) 等法规约束,以保护患者数据。

本指南旨在帮助配置 Neo4j,以符合 FIPS 的方式使用 TLS/SSL 加密。它是 SSL 框架文档的补充,因为许多配置流程和要求是相同的。

先决条件

  • 验证运行 Neo4j 的机器是否具备 FIPS 兼容的硬件和操作系统。目前 Neo4j FIPS 兼容性仅支持 Linux 操作系统

  • 使用 Neo4j Enterprise 5.23.0 或更高版本。

  • 安装并配置非原生身份验证提供程序,例如 LDAP 或 SSO。请参阅身份验证与授权

启用 FIPS SSL 提供程序

Neo4j 中的安全网络是通过 Netty 库提供的,该库同时支持原生 JDK SSL 提供程序和 Netty 支持的 OpenSSL 衍生版本。具体而言,是 Netty 的 Forked Tomcat Native 库,称为 netty-tcnative

netty-tcnative 库有多种变体。然而,为了实现 FIPS 合规性,必须使用动态链接版本的 netty-tcnative,并搭配 FIPS 兼容的 OpenSSL 安装。

动态链接库需要安装以下依赖项[1]

  • Apache Portable Runtime (APR) 库

  • 一个经过 FIPS 认证的 OpenSSL 版本,且安装了 FIPS 提供程序并将其设置为默认值。

有关更多信息,请参阅 Forked Tomcat Native

Netty 提供了一个方便的预构建、静态链接版本的 netty-tcnative(使用 BoringSSL),但它并未经过 FIPS 认证[2]

通过使用动态 netty-tcnative 库变体并结合经过 FIPS 认证的 OpenSSL 安装,Neo4j 的加密操作将由 netty-tcnative 委托给 OpenSSL 执行,从而间接实现 FIPS 兼容性。

安装 Apache Portable Runtime 库

要安装 Apache Portable Runtime 库,请使用操作系统的软件包管理器。

在 Debian/Ubuntu 中,该软件包通常称为 libapr1

在 Debian 或 Ubuntu 中安装 Apache Portable Runtime 库
apt install -y libapr1

在 RedHat Enterprise Linux 中,该软件包通常称为 apr

在 RedHat 中安装 Apache Portable Runtime 库
dnf install -y apr

安装 OpenSSL

有关如何构建和安装 FIPS 兼容 OpenSSL 的说明不在本文档范围内。安装步骤可能因操作系统以及您对 OpenSSL 的其他安全要求而异。

总体而言

  • 有关经过 FIPS 认证的 OpenSSL 版本列表,请参阅 https://openssl-library.org/source/

  • 必须将 FIPS 提供程序安装到 OpenSSL 中。

  • 必须将 OpenSSL 配置为默认使用 FIPS 提供程序。

安装正确的 netty-tcnative

netty-tcnative 动态库的构建版本位于 Neo4j lib 目录下的子文件夹 netty-tcnative 中。

安装 netty-tcnative 动态库:

  1. 找到 Neo4j 的 lib 目录。

    lib 目录的位置取决于安装 Neo4j 的方法。请查看文件位置文档以确定正确路径。

    该位置将在下文中称为 <NEO4J_LIB>

  2. 确保 <NEO4J_LIB> 文件夹中不存在 netty-tcnative-boringssl 库。

    find <NEO4J_LIB> -name "netty-tcnative-boringssl*.jar" -delete
  3. 检查可用的 netty-tcnative 库

    ls -l <NEO4J_LIB>/netty-tcnative

    存在针对 x86_64 和 ARM 64 架构编译的 Linux 和 Fedora Linux 变体。选择与本地机器操作系统和架构匹配的变体。

  4. 使用 ldd 验证依赖项是否安装正确

    验证 netty-tcnative 依赖项已安装
    unzip -d /tmp <NEO4J_LIB>/netty-tcnative/netty-tcnative-*-linux-$(arch).jar
    ldd /tmp/META-INF/native/libnetty_tcnative_linux_*.so
    rm -rf /tmp/META-INF
    验证 Fedora 变体的 netty-tcnative 依赖项已安装
    unzip -d /tmp <NEO4J_LIB>/netty-tcnative/netty-tcnative-*-linux-$(arch)-fedora.jar
    ldd /tmp/META-INF/native/libnetty_tcnative_linux_$(arch).so
    rm -rf /tmp/META-INF

    ldd 命令会显示库依赖项列表以及它们在本地机器上的加载来源。

    • 如果缺少任何依赖项,则必须安装它们,否则 Neo4j 将无法运行。

    • 列出的 libssl.solibcrypto.so 库必须是前述步骤中随 OpenSSL 安装的那些库。

  5. 将经过验证的 JAR 文件复制到 <NEO4J_LIB>

    仅复制一个 JAR 文件。否则,Neo4j 将无法在运行时解析依赖项。如果出现此错误,您将收到类似于以下内容的消息:

    "Failed to load any of the given libraries: [netty_tcnative_linux_x86_64, netty_tcnative_linux_x86_64_fedora, netty_tcnative_x86_64, netty_tcnative]".

生成 SSL 证书和私钥

Neo4j SSL 加密需要 X.509 标准的证书PKCS #8 格式的私钥,两者均需以 PEM 格式编码。

为了实现 FIPS 兼容性,私钥必须使用密码进行保护。

有关详细信息,请参阅 SSL 证书和密钥说明

配置 Neo4j 使用 SSL 加密

SSL 配置在 SSL 框架配置中有详细说明。

本节描述了除了标准非 FIPS 兼容 SSL 配置之外,还必须执行的配置。

  • 以下 FIPS 兼容密码套件组适用于 TLSv1.2:

    • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

    • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

    • TLS_DHE_RSA_WITH_AES_256_GCM_SHA384

    • TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

      它们需要在应用程序或 OpenSSL 设置中进行额外配置。

  • 在使用 TLSv1.3 时,OpenSSL 默认支持以下密码套件:

    • TLS_AES_256_GCM_SHA384

    • TLS_AES_128_GCM_SHA256

      当 OpenSSL 在构建时启用了 FIPS 支持时,这些套件不需要额外配置。

Bolt

  1. 设置 dbms.netty.ssl.provider=OPENSSL

  2. 设置 server.bolt.tls_level=REQUIRED

  3. 遵循关于 如何配置 Bolt 的 SSL 的说明。

  4. 设置额外的 Bolt 配置

    dbms.ssl.policy.bolt.trust_all=false
    dbms.ssl.policy.bolt.tls_level=REQUIRED
    dbms.ssl.policy.bolt.tls_versions=TLSv1.2,TLSv1.3
    dbms.ssl.policy.bolt.ciphers=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256
  5. 按照 SSL 框架 → 使用加密私钥 中的说明配置 dbms.ssl.policy.bolt.private_key_password,以动态地从加密密码文件中读取密码。密码绝对不能以明文形式设置。

HTTPS

本节仅在启用了 HTTPS 时适用。

  1. 遵循关于 如何配置 HTTPS 的 SSL 的说明。

  2. 设置额外的 HTTPS 配置

    dbms.ssl.policy.https.trust_all=false
    dbms.ssl.policy.https.tls_level=REQUIRED
    dbms.ssl.policy.https.tls_versions=TLSv1.2,TLSv1.3
    dbms.ssl.policy.https.ciphers=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256
  3. 按照 SSL 框架 → 使用加密私钥 中的说明配置 dbms.ssl.policy.https.private_key_password,以动态地从加密密码文件中读取密码。密码不得以明文形式设置。

集群内加密

为了实现 FIPS 兼容性,如果您正在运行 Neo4j 集群,则必须启用集群内加密。

  1. 遵循关于 配置集群内通信 SSL 的说明。

  2. 设置额外的集群配置

    dbms.ssl.policy.cluster.enabled=true
    dbms.ssl.policy.cluster.tls_level=REQUIRED
    dbms.ssl.policy.cluster.client_auth=REQUIRED
    dbms.ssl.policy.cluster.tls_versions=TLSv1.2,TLSv1.3
    dbms.ssl.policy.cluster.ciphers=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256
  3. 按照 SSL 框架 → 使用加密私钥 中的说明配置 dbms.ssl.policy.cluster.private_key_password,以动态地从加密密码文件中读取密码。密码绝对不能以明文形式设置。

备份

本节适用于用于执行备份的实例或集群成员。

  1. 遵循关于 配置备份通信 SSL 的说明。

  2. 设置额外的备份配置

    dbms.ssl.policy.backup.enabled=true
    dbms.ssl.policy.backup.client_auth=REQUIRED
    dbms.ssl.policy.backup.trust_all=false
    dbms.ssl.policy.backup.tls_versions=TLSv1.2,TLSv1.3
    dbms.ssl.policy.backup.ciphers=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_AES_256_GCM_SHA384,TLS_AES_128_GCM_SHA256
  3. 按照 SSL 框架 → 使用加密私钥 中的说明配置 dbms.ssl.policy.backup.private_key_password,以动态地从加密密码文件中读取密码。密码绝对不能以明文形式设置。