【问题标题】:Waiting subprocess to execute openvpn commands. Sourcing vars issue等待子进程执行 openvpn 命令。采购变量问题
【发布时间】:2016-01-25 12:22:27
【问题描述】:

我在等待从 python 中运行的子进程时遇到问题。我也在这里阅读了大量有关它的信息。很抱歉再次提出这个问题,但我仍然没有解决方案。

我的代码

cmds = "cd /etc/openvpn/easy-rsa && . ./vars && ./clean-all && ./pkitool --initca && ./pkitool --server && ./build-dh"
runCmds = subprocess.Popen(cmds, shell=True)
# run = os.system
# runCmds = run(cmds)
# runCmds.wait()
# runCmds.call() 

工作完美,但我需要它等待子进程结束以运行下一部分代码。注释行对我不起作用。如果我从评论中运行某些东西,我会收到错误

请先获取 vars 脚本(即“source ./vars”).......

有一次,wait() 似乎有效,但一段时间后就无效了。方法call() 运行命令但永远不会结束。为什么方法对我不起作用,尤其是wait()?我建议我的问题是在我的环境中采购 openvpn vars 脚本。请帮帮我!
更新:带有

的控制台日志

设置-x

  [25/Jan/2016 18:30:42]"POST /run-step3-process/ HTTP/1.1" 200 49
+ cd /etc/openvpn/easy-rsa
+ . ./vars
+ pwd
+ export EASY_RSA=/etc/openvpn/easy-rsa
+ export OPENSSL=openssl
+ export PKCS11TOOL=pkcs11-tool
+ export GREP=grep
+ /etc/openvpn/easy-rsa/whichopensslcnf /etc/openvpn/easy-rsa
+ export KEY_CONFIG=/etc/openvpn/easy-rsa/openssl-1.0.0.cnf
+ export KEY_DIR=/etc/openvpn/easy-rsa/keys
+ echo NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys
NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys
+ export PKCS11_MODULE_PATH=dummy
+ export PKCS11_PIN=dummy
+ export KEY_SIZE=1024
+ export CA_EXPIRE=3650
+ export KEY_EXPIRE=3650
+ export KEY_COUNTRY=SS
+ export KEY_PROVINCE=FFFFFFF
+ export KEY_CITY=AAAA
+ export KEY_ORG=GGGG
+ export KEY_EMAIL=qq@qq.yy
+ export KEY_EMAIL=mail@host.domain
+ export KEY_CN=ccccccc
+ export KEY_NAME=changeme
+ export KEY_OU=changeme
+ export PKCS11_MODULE_PATH=changeme
+ export PKCS11_PIN=1234
+ ./clean-all
+ ./pkitool --initca
Using CA Common Name: ccccccc
Generating a 1024 bit RSA private key
.................................++++++
............................................++++++
writing new private key to 'ca.key'
-----
+ ./pkitool --server
Using Common Name: ccccccc
Generating a 1024 bit RSA private key
............++++++
...........................++++++
writing new private key to 'ccccccc.key'
-----
Using configuration from /etc/openvpn/easy-rsa/openssl-1.0.0.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName           :PRINTABLE:'SS'
stateOrProvinceName   :PRINTABLE:'FFFFFFF'
localityName          :PRINTABLE:'AAAA'
organizationName      :PRINTABLE:'GGGG'
organizationalUnitName:PRINTABLE:'changeme'
commonName            :PRINTABLE:'ccccccc'
name                  :PRINTABLE:'changeme'
emailAddress          :IA5STRING:'mail@host.domain'
Certificate is to be certified until Jan 22 18:30:42 2026 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated
+ ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
.....................................+...+..................................................................................................................................+................+..................................++*++*++*

更新 2 我研究了我的代码的行为:

Before run:
1.apache(or localhost)restart
2.etc/openvpn/easy-rsa/keys clean
3.start browser with new incognito window
I give permission for etc/openvpn/easy-rsa/ as 47777

success == generating process run, new keys create
error == “please source ./vars.....”
CN == variable for server name in vars 
wait() == subrpocess.wait() code following string with bash commands

code ALWAYS work as below:

orig vars -> edit -> wait() -> error
orig vars -> edit (without CN, ./pkitool --server SERVER )-> wait() -> error

orig vars -> NONedit ->wait() -> success

orig vars -> edit ->WITHOUT_wait() -> success
edited vars -> edit ->WITHOUT_wait() -> success
edited vars -> edit(without CN, ./pkitool --server SERVER) -> WITHOUT_wait() -> success
orig vars -> edit(WITH_ CN, ./pkitool --server) -> WITHOUT_wait() -> success
edited vars -> edit(WITH_ CN, ./pkitool --server) -> WITHOUT_wait() -> success

我在 python 中编辑变量:

from django.shortcuts import  HttpResponse, HttpRequest
import subprocess
from subprocess import Popen, PIPE
import json
import os.path

def pass3Cmds():
''' run commands on step3  to generate keys and cert in '/etc/openvpn/easy-     rsa/keys'
'''
    cmds = "cd /etc/openvpn/easy-rsa && . ./vars && ./clean-all && ./pkitool --initca && ./pkitool --server && ./build-dh"
    runCmds = subprocess.Popen(cmds, shell=True)


def runStep3Process(request):
    '''collect data from step3 user form and insert 
    them in '/etc/openvpn/easy-rsa/vars'
    '''
    path = '/etc/openvpn/easy-rsa/vars'
    data = json.loads(request.body)

    key_cn = 'export KEY_CN="%s"' % data['key_cn']
    if request.method=='POST' and request.user.is_authenticated():
        with open(path) as varsfile:
            data = varsfile.readlines()
        try:
            data[69] = key_cn +'\n' 
            with open(path, 'w') as newvarsfile:
                newvarsfile.writelines(data)
                pass3Cmds()
                pem = '/etc/openvpn/easy-rsa/keys/dh1024.pem'
                if os.path.exists(pem):
                    return HttpResponse(successMsg2)
                return HttpResponse(dangerMsg)
        except IndexError:
            return HttpResponse(warnMsg2)
     return HttpResponse(warnMsg)

再次:代码完美地与这种方式编辑的变量一起工作,直到我想运行任何代码来等待子进程。如果我运行例如subprocess.wait() 我得到“please source ./vars”错误

问题是:为什么在我的情况下编辑变量会导致错误?

【问题讨论】:

  • 您的代码确实确​​实在相关外壳中使用vars。您确定您实际上已根据文档编辑了 vars 脚本吗?
  • 顺便说一句,我强烈建议从 /dev/null 重定向 stdin。否则,openssl 可能会尝试从它从父 (Python) 进程继承的标准输入文件描述符中进行提示。
  • ...换个方式问:在不涉及 Python 的情况下以交互方式运行相同命令时,是否会得到相同的行为?
  • 当我运行 root@localhost:/etc/openvpn/easy-rsa# bash -x 。 ./vars 它打印 .: .: 是一个目录
  • 不,不是那样的。 cmds = "set -x; cd /etc/openvpn/easy-rsa && . ./vars && ./clean-all && ./pkitool --initca && ./pkitool --server && ./build-dh"

标签: python shell openvpn


【解决方案1】:

您的日志显示进程在./build-dh 中无限期等待。

  1. 正如相关日志消息所示,这是一个缓慢的过程。你不应该期望它是即时的。

  2. 但是,如果您的系统的熵池很低,它不仅会很慢,而且可能是不确定的。考虑使用 rng-tools 包中的 rngd 来使用系统的硬件随机数生成器(假设其 CPU 提供)来填充内核的熵池。


除此之外,你的用法不正确:

./pkitool --server

...不是有效命令:需要提供CN来生成服务器证书,例如:

./pkitool --server server

【讨论】:

  • 我尝试从常用命令字符串中排除 ./build-dh 命令并按顺序添加 runCmds.wait() 但立即出现有关源变量的错误
  • 查看更新——实际上确实检查了 easy-rsa 2.0 并运行了您的确切代码。只复现了一个bug,和vars无关。
  • ./pkitool --server 默认从我之前编辑的变量中获取 CN 值,因此无需运行 --server server 因此在 etc/openvpn/easy-rsa/keys 我有例如1111.crt等
  • 不在我运行的版本中。
  • 我使用的是 2.0 并且确实如此。看来您在回答中的第 2 点是正确的。每次我运行 ./build-dh 它都会持续不同的时间,有时会挂断。您能否提供更多关于第 2 点的详细信息?
【解决方案2】:

我不知道“/etc/openvpn/easy-rsa”,但如果它建立了一个 vpn 连接,程序将在连接保持时挂起。为了终止它,您可以使用超时参数来强制它超时。使用 subprocess.call。

cmds = "cd /etc/openvpn/easy-rsa && . ./vars && ./clean-all && ./pkitool --initca && ./pkitool --server && ./build-dh"
timeout = 60 * 10 # 10 minutes

try:
   ret_code = subprocess.call(cmds, shell=True, timeout=timeout)
   # return_code
except subprocess.TimeoutExpired: 
   # do_something()

call, check_call and check_output 接受超时参数。

【讨论】:

  • 我得到 'module' 对象没有属性 'TimeoutExpired' 错误
  • 根据文档docs.python.org/3/library/…,3.3版新增。
  • 如果我运行 "ret_code = subprocess.call(cmds, shell=True, timeout=timeout)" 而没有 try/exept 我收到 __init__() 得到一个意外的关键字参数 'timeout'
  • stackoverflow.com/questions/1191374/…,其实timeout是python3支持的。
  • 不,它没有建立VPN连接;给定的命令生成 SSL CA 和服务器证书,然后退出。因此,这个答案的前提是不正确的,根本不需要timeout 参数。
【解决方案3】:

导入时间模块并使用time.sleep(amount_of_seconds)

【讨论】:

  • 我尝试 time.sleep,它会暂停,但我再次收到关于采购 vars 的相同错误...
  • 睡眠预设时间无论如何都不是一个可接受的解决方案。这些命令所花费的时间会根据系统 RNG 池中的熵量而有很大差异,因此无法可靠地预测等待时间。
猜你喜欢
  • 1970-01-01
  • 2015-06-13
  • 2020-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 1970-01-01
  • 2011-09-20
相关资源
最近更新 更多