了解后在命令行中使用密码的问题,我需要找到一种为程序提供密码的方法,而不会出现问题(密码不会被记录在某处)。
我有一个 bash 脚本,可以自动从源代码安装整个 LAMP 服务器:Apache、FastCGI、PHP 和 MySQL。这些安装需要密码,尤其是 MySQL。
如何使脚本完全自动化而不泄露密码?
编辑(6 月 9 日,3:55 UTC):
我通过 root 在命令行上使用密码调用 mysql:
root@dor-desktop:/home/dor# PASS=`cat /home/dor/tmpf/pass`
root@dor-desktop:/home/dor# mysql -u root -p"$PASS"
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
(在我们的例子中,PASS =“p4ssw0rd”)
我ps aux | grep mysql
通过我的常规用户(dor)执行,这不显示密码!
(一些)ps
输出是:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 3562 0.0 0.0 34156 2864 pts/0 S+ 05:53 0:00 mysql -u root -px xxxxxx
这怎么可能?
答案1
关于您的更新:
当一个进程启动时,它有一个专门的内存区域,用于存储参数和一个 int 来告诉传递了多少个参数。
MEMORY
argc 2
argv[0] program_name
argv[1] foo
argv[2] bar
MySQL 检查密码是否通过命令行传递-p
,如果将其复制到不可见的新变量,则用x
'es 覆盖该内存区域。
简单来说例如:
argc 2
argv[1] -p
argv[2] p4ssw0rd
new_var = copy(argv[2]);
argv[2] = "xxxxx";
client/mysqladmin.cc
您可以在源代码中找到它:
case 'p':
...
opt_password=my_strdup(argument,MYF(MY_FAE));
while (*argument)
*argument++= 'x'; /* Destroy argument */
运行时ps
,它读取参数 ( argv[N]
) 的内存区域,因此它是xxxx
。
密码在很短的时间内可见,但仅持续几个 CPU 周期。
--init-file
您可以使用特殊选项和过程更新 MySQL 密码。C.5.4.1.2。重置 Root 密码:Unix 系统
mysqld_safe --init-file=/home/me/mysql-init &
编辑:
作为@吉尔斯说,你可以echo
,printf
或使用here
脚本中的文档。
您还可以将其添加到.my.cnf
您的主目录或 (暂时的)归档并使用--defaults-extra-file
选项。(相信您必须尽早在命令行上添加该选项。)还可以选择包括用户。另请注意额外的除非您想使用,否则在选项名称中仅有的该文件作为配置:
[client]
user=foo
password='password!'
shell> chmod 400 my_tmp.cnf
shell> mysql --defaults-extra-file=my_tmp.conf -...
可选地,[client]
分组可以mysqld
跳过配置。
也可以用一个MYSQL_PWD
环境变量,但这应该绝不可以像在Linux 上的文件中列出环境一样使用,在许多ps
实现中。ps -e
/proc/<PID>/environ
tr '\0' '\n' < /proc/<PID>/environ
有关该主题的更多信息这里。
您可能还想看看MySQL 配置实用程序这使您能够将密码存储在主目录中的加密文件中 - .mylogin.cnf
.
答案2
典型的解决方案是从文件或标准输入(或必须作为参数传递的另一个文件描述符)读取密码。
答案3
ftp
某些程序(例如命令行)从 中读取密码/dev/tty
,这是代表进程控制 TTY 的每个进程的特殊文件。这使得程序不会将密码回显到屏幕上,并且可以更加确定密码的来源。
#!/bin/bash
stty -F /dev/tty -echo
read PASSWORD < /dev/tty
echo $PASSWORD