问题描述
我使用easy rsa( https://github.com/OpenVPN/easy-rsa )来建立我的小型ca及其客户端/服务器.由于它仅用于学习目的,因此我正在考虑进行一些自动化.通常,我可以创建客户端键入以下内容所需的文件:
I use easy rsa (https://github.com/OpenVPN/easy-rsa) to build my tiny ca and its clients / servers. Since its just for learning purposes, I was thinking about doing some automatization. Normally I can create files needed by client typing:
./easyrsa build-client-full client
但是当我需要约500个不同的客户端文件时该怎么办? cp
不是我想要的.
but what when I need ~ 500 different client files? cp
its not what I want here.
我试图写一些bash脚本来帮助自己:
I tried to write a little bash script to help myself out:
#!/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密码.主要问题是我不知道该如何在脚本中传递它-可能吗?我的脚本给了我忽略未知命令选项:
作为输出.
But it simply 'does not work'. When I build my client files in terminal I have to give 2 client passwords and the ca password. The main problem is I dont know how on earth pass it within script - is that possible? My script gives me Ignoring unknown command option:
as output.
推荐答案
更新(2020-04-03)
自从我写了第一个答案以来,EasyRSA脚本就进行了一些更改.
Update (2020-04-03)
There has been some changes to EasyRSA script since I wrote the first answer.
- EasyRSA 3.0.6(发布于2019-02-02)添加了
-passin
和-passout
选项,这些选项可以按照我的原始说明正确地将选项传递给OpenSSL回答 - EasyRSA 3.0.7(发布于2020-03-31)增加了通过
EASYRSA_PASSIN
和EASYRSA_PASSOUT
环境变量 提供密码的功能.
- EasyRSA 3.0.6 (released 2019-02-02) added
--passin
and--passout
options which correctly pass the options to OpenSSL as described in my original answer - EasyRSA 3.0.7 (released 2020-03-31) added the ability to supply the passwords through the
EASYRSA_PASSIN
andEASYRSA_PASSOUT
environment variables
通读easyrsa源代码,看来 build-client-full
命令仅采用一个参数: name
.因此,您得到的错误仅仅是因为它不知道如何处理在命令行上添加的密码.我猜想程序会以交互方式询问您这些密码,因此您必须通过 stdin
将它们提供给程序.
Reading through the easyrsa source code, it seems that the build-client-full
command only takes one argument: name
. So, the error that you get is simply because it does not know what to do with the passwords you have added on the command line. I guess that the program asks you for these passwords interactively, so you must supply them to the program via stdin
.
注意:OpenSSL( easyrsa
的后端)不会通过 stdin 来监听默认.为此,我们必须添加-passout stdin"
(因为它是一个密码保存在输出文件中)到OpenSSL命令行.或者,如果密码保存在密码文件"中,则可以添加密码文件:密码文件".使更难的是, easyrsa`没有一种简单的方法来向其中添加参数OpenSSL命令.因此,我们必须以某种方式更改源代码.但是,这很容易.
NOTE: OpenSSL (the backend of easyrsa
) does not listen to stdin
bydefault. To make it do so, we must add "-passout stdin"
(since it is apassword saved in an output file) to the OpenSSL command line. Alternatively, one could add "-passout file:passfile"
if the passwords are kept in the file passfile'. To makeit harder,
easyrsa` does not have an easy way of adding arguments tothe OpenSSL command. Thus, we must change the source code somehow.However, this is easy.
要使用以下替代方法,请将其添加到 gen_req
定义 local opts =
后的 easyrsa
函数:
To be able to use the alternatives below, add this into the gen_req
function of easyrsa
after the definition of 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
读取(也可以用于上面的内容)
Also, it seems that OpenSSL closes the stdin
stream after its firstuse (in gen_req
), so it can't also be used for signing with the CAcertificate (in sign_req
). We can tell OpenSSL to read from a file instead ofreading from stdin
(it may also be used for the above)
sign_req() {
local crt_type="$1" opts=
opts="-passin file:capassfile" # ADD THIS LINE (also: create capassfile)
...
}
(注意:在不涉及多次调用OpenSSL的情况下,下面的解决方案主要保留以备将来参考...)
通过stdin传递密码的一种方法是启动一个子shell,然后将其通过管道传递给easyrsa,这将模拟您手动完成的实际按键操作.您的示例将如下所示:
One way to pass passwords through stdin is to start a subshell and then pipe it to easyrsa, which would simulate the actual keypresses you would have done manually. Your example would then look like this:
#!/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
取决于您发现的可读性最高.
depending on what you find the most readable.
上述替代方法的缺点是密码将出现在进程列表中(例如 ps
),因此从安全角度来看,如果您是密码,则是一个坏主意在一个共享的盒子上.更好的方法是使用密码创建文件,如下所示:
The above alternative has the drawback that the passwords will appear in process listings (such as ps
), and is thus from a security standpoint a bad idea if you are on a shared box. A better way would to create a file with the passwords, like this:
randompass
randompass
然后,您只需编写以下代码即可在上面的循环中调用easyrsa:
Then, you invoke easyrsa in your loop above by simply writing:
...
for i in `seq 1 $clients`
do
./easyrsa build-client-full test$i <passfile
done
其中 passfile
是带有密码的文件.当然,这假定您为所有文件使用相同的密码.
where passfile
is your file with the passwords. This of course assumes that you have the same password for all files.
这篇关于使用Easy rsa,如何自动执行客户端/服务器创建过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!