使用easy rsa,如何自动化客户端/服务器创建过程

时间:2014-03-14 20:57:00

标签: bash

我使用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:作为输出。

2 个答案:

答案 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 ......)

“一般解决方案”#1:管道

通过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 ...)更改为

,而不是创建子shell
printf '%s\n' $pass $pass | ./easyrsa build-client-full test$i

echo -e "$pass\n$pass" | ./easyrsa build-client-full test$i

取决于您认为最具可读性的内容。

“一般解决方案”#2:stdin重定向

上述替代方案的缺点是密码会出现在流程列表中(例如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

  1. 在文件-passin stdin中的函数sign_req()第#834行上对该选项进行硬编码。将-passout file:passfile更改为easy-rsa/easyrsa3/easyrsa

  2. 使用此功能来创建单个客户端证书,

    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

 }