我使用easy rsa(https://github.com/OpenVPN/easy-rsa)来构建我的小ca及其客户端/服务器。由于它仅用于学习目的,我正在考虑进行一些自动化。通常我可以创建客户端输入所需的文件:
./easyrsa build-client-full client
但当我需要~500个不同的客户端文件时呢? cp
这不是我想要的。
我试着写一个小的bash脚本来帮助自己:
#!/bin/bash
clients=3
pass=randompass
capass=castrongpassword
for i in `seq 1 $clients`
do
./easyrsa build-client-full test$i $pass $pass $capass
done
但它只是“不起作用”。当我在终端中构建我的客户端文件时,我必须提供2个客户端密码和ca密码。主要问题是我不知道在脚本中如何传递它 - 这可能吗?我的脚本给了我Ignoring unknown command option:
作为输出。
答案 0 :(得分:7)
通过easyrsa源代码阅读,似乎build-client-full
命令只接受一个参数:name
。因此,您获得的错误仅仅是因为它不知道如何处理您在命令行上添加的密码。我想该程序会以交互方式要求您提供这些密码,因此必须通过stdin
将它们提供给程序。
easyrsa
注意:OpenSSL(easyrsa
的后端)不会通过stdin
收听
默认。要做到这一点,我们必须添加"-passout stdin"
(因为它是一个
密码保存在输出文件中)到OpenSSL命令行。或者,如果密码保存在文件中,可以添加"-passout file:passfile"
passfile'. To make
it harder,
easyrsa`没有简单的方法来添加参数
OpenSSL命令。因此,我们必须以某种方式更改源代码。
但是,这很容易。
为了能够使用以下替代方案,请将其添加到gen_req
easyrsa
定义后local opts=
的函数:
gen_req() {
....
local opts=
opts="-passout stdin" # ADD THIS LINE
# Alternatively: opts="-passout file:passfile"
....
}
此外,似乎OpenSSL首先关闭了stdin
流
使用(在gen_req
中),因此它也不能用于与CA签名
证书(sign_req
)。我们可以告诉OpenSSL从文件中读取而不是
从stdin
读取(也可用于上述内容)
sign_req() {
local crt_type="$1" opts=
opts="-passin file:capassfile" # ADD THIS LINE (also: create capassfile)
...
}
(注意:以下解决方案主要是为了将来参考,如果不涉及多次调用OpenSSL ......)
通过stdin传递密码的一种方法是启动子shell,然后将其传递给easyrsa,这将模拟您手动完成的实际按键。您的示例将如下所示:
#!/bin/bash
clients=3
pass=randompass
#capass=castrongpassword # (create the file 'capassfile' instead)
for i in `seq 1 $clients`
do
(echo $pass; echo $pass) | ./easyrsa build-client-full test$i
done
您可以将(echo $pass; echo ...)
更改为
printf '%s\n' $pass $pass | ./easyrsa build-client-full test$i
或
echo -e "$pass\n$pass" | ./easyrsa build-client-full test$i
取决于您认为最具可读性的内容。
上述替代方案的缺点是密码会出现在流程列表中(例如ps
),因此从安全角度来看,如果您是共享的话,坏主意框。更好的方法是使用密码创建一个文件,如下所示:
randompass
randompass
然后,只需编写:
,即可在上面的循环中调用easyrsa...
for i in `seq 1 $clients`
do
./easyrsa build-client-full test$i <passfile
done
其中passfile
是包含密码的文件。当然,这假定您拥有所有文件的相同密码。
答案 1 :(得分:0)
通过一些步骤并使用openssl 1.1.1h&easyrsa3,我尝试了类似的解决方案,该解决方案允许选项ViewModel
和/或ViewModel
在文件-passin stdin
中的函数sign_req()第#834行上对该选项进行硬编码。将-passout file:passfile
更改为easy-rsa/easyrsa3/easyrsa
使用此功能来创建单个客户端证书,
opts=""
一个简单的调用将创建一个客户条目
opts="-passin stdin"
在您的for循环中使用密码进行迭代,并将其传递给函数,瞧!完成了。
#function gen_full_client
gen_full_client() {
CN=$1
OVERWRITE=$2
#Generate client using cn and sign it
if [ -f "$EASYRSA_DIR/pki/private/$CN.key" ]; then
cat <<-EOF | sudo $EASYRSA gen-req $CN nopass
$OVERWRITE
$CN
EOF
else
cat <<-EOF | sudo $EASYRSA gen-req $CN nopass
$CN
EOF
fi
#give it some time
sleep 2
CA_PASSWORD=$3
#Generate client using cn and sign it
if [ -f "$EASYRSA_DIR/pki/private/$CN.key" ]; then
#cat <<-EOF | sudo $EASYRSA opts="-passout stdin" build-client-full $CN
cat <<-EOF | sudo $EASYRSA sign-req client $CN
yes
$(echo $CA_PASSWORD)
EOF
fi
}