我有一个Flask应用程序,它有一些加密组件。具体来说,磁盘上有一个加密的密钥,必须在内存中解密才能在Flask应用程序进程中使用。为了解密密钥,在应用程序运行时,系统会提示用户输入带有getpass的密码。
这适用于app.run()
和单个前台Flask WSGI服务器。我们遇到的问题是,当使用uWSGI进行部署时,uWSGI控制器不允许stdin。
理想情况下,我们希望发生的情况类似于当您使用SSL重新启动或启动Apache或Nginx时 - 在服务分叉之前它会在stdin上提示输入密码。
任何帮助将不胜感激!
更新
虽然我们仍然希望使用uWSGI,但由于gunicorn的前叉选项,我们已经转向了gunicorn。此解决方案仍然不理想,特别是因为我们无法添加像UPSTART这样的监控服务。基本上,我们之前运行的脚本使用read
将密码设置为环境变量,并将该环境变量传递给gunicorn应用程序。
#!/bin/bash
NAME="baz" # Name of the application
APPDIR=/var/apps/baz # Application project directory
SOCKFILE=/var/apps/baz/gunicorn.sock # Using a socket
BIND="127.0.0.1:8000" # Using a port
USER="www-data" # User to run as
GROUP="www-data" # Group to run as
WORKERS=1 # How many worker processes
echo "Starting $NAME"
# Collect the passphrase
read -s -p "Enter $NAME passphrase: " PASSPHRASE
echo ""
# Activate the virtual environment
source /var/venvs/baz/bin/activate
export BAZ_SETTINGS="baz.conf.Config"
export BAZ_PASSPHRASE=$PASSPRHASE
# Start Gunicorn
exec gunicorn $NAME:app \
--user $USER --group $GROUP \
--bind $BIND \
--workers $WORKERS \
--chdir $APPDIR \
--env BAZ_PASSPHRASE=$PASSPHRASE \
--daemon
这或多或少是教程Setting up Django with Nginx, Gunicorn, virtualenv, supervisor and PostgreSQL中使用的脚本 - 修改后用于阅读密码并与Flask一起使用。
我们已经检查过以确保BAZ_PASSPHRASE
环境变量在任何环境中都不存在,但这仍然感觉有点吱吱作响,所以我们仍然感谢任何评论,特别是关于uWSGI。
答案 0 :(得分:1)
只需添加--honour-stdin
即可禁用将文件描述符0重新映射到/dev/null
如果您致电--daemonize
,您将失去控制终端,因此您必须在使用--daemonize2
答案 1 :(得分:0)
TL; DR:使用FIFO代替STDIN提供输入
#!/bin/sh FIFO=/tmp/.appfifo rm -f ${FIFO} mkfifo ${FIFO} cat > ${FIFO} # decryt password | /etc/init.d/app start exec gunicorn $NAME:app \ --user $USER --group $GROUP \ --bind $BIND \ --workers $WORKERS \ --chdir $APPDIR \ --env ENCRYPTED_CFG=/etc/app.encrypted.cfg --daemon
以及代码中的某个地方
get_password(file(os.getenv('ENCRYPTED_CFG'),'r').read())