如何在构建派生时访问 CA 证书



我想在运行nix-shell时自动将 CA 证书添加到 Java 密钥库。在以下脚本工作之前:

with import <nixpkgs> {
config.allowUnfree = true;
config.oraclejdk.accept_license = true;
};
let dependencies = rec {
_oraclejdk8 = stdenv.lib.overrideDerivation pkgs.oraclejdk8 (attrs : {
installPhase = ''
${attrs.installPhase}
pems_dir=pems
mkdir "$pems_dir"
echo "split bundled ca-certificates into separate files 'cert.N.pem'
and add them to default keystore"
keytool=$out/bin/keytool
keystore=$jrePath/lib/security/cacerts
pushd "$pems_dir"
awk 'BEGIN {c=0;doPrint=0;} /END CERT/ {print > "cert." c ".pem";doPrint=0;} /BEGIN CERT/{c++;doPrint=1;} { if(doPrint == 1) {print > "cert." c ".pem"} }' < /etc/ssl/certs/ca-bundle.crt
# import certificates
for f in `ls cert.*.pem`; do
alias=`basename $f`
$keytool -import -trustcacerts -noprompt -keystore "$keystore" -alias "$alias" -file "$f" -storepass changeit;
done
popd
'';
});
};
in with dependencies;
stdenv.mkDerivation rec {
name = "env";
buildInputs = [ _oraclejdk8 ];
}

但现在它失败并出现以下错误:

/nix/store/9fx2jfmks2zhvv2kmqgl6rg0fbkc3da0-stdenv-linux/setup: line 1391: /etc/ssl/certs/ca-bundle.crt: No such file or directory

看起来现在无法访问任何现有文件。但实际上这个文件只是一个存储链接:

$ readlink -f /etc/ssl/certs/ca-bundle.crt
/nix/store/w3vw4q9z7s0wig6ng4nv62af1917ynrm-ca-certificates.crt

如何在脚本中访问此文件?

Nix 是一个密封的构建系统,这意味着必须声明所有输入,以便可以跟踪它们。 您可以提取Nixpkgs的证书颁发机构证书集,pkgs.cacert

# CAREFUL, read on!
awk 'BEGIN {c=0;doPrint=0;} /END CERT/ {print > "cert." c ".pem";doPrint=0;} /BEGIN CERT/{c++;doPrint=1;} { if(doPrint == 1) {print > "cert." c ".pem"} }' < ${cacert}/etc/ssl/certs/ca-bundle.crt

但是,在固定加密配置时要小心,因为当它发生变化时,您需要在任何地方更新它。假设您要运行 2 年前的软件版本,是要使用 2 年前的证书还是来自环境的证书运行它?

另一个问题是这些证书应该写在哪里?默认情况下,Keytool 会写入主目录,这是构建沙盒中不存在的目录。

在您的情况下,似乎正确的解决方案不是在沙箱中添加证书,而是返回一个脚本,该脚本将在有意义的上下文中执行此操作。何时何地由您决定,但请确保您从良好的来源获得这些证书。如果你可以假设你的部署总是使用足够最新的Nixpkgs完成的,你可以这样做。否则,您可能最好使用系统中已有的那些/etc.

最新更新