IT办公室的故事 2024-06


图片源自:https://www.pexels.com/

两周前为软件开发组写了一个自动克隆数据库的Ansible Playbook;帮助他们减少对VMware的依赖,从而把数据库弄到亚马逊AWS上。

基本上研发组那边只要填写需要上传的数据库的名称,并将新建立的数据库用户的密码记录到密码管理器里面就可以了。基本上打到80%自动化。

不过就在剩下的20%手动中,还是出现了问题。就是会有人忘记记录新建用户的密码。

好吧,还是不能太相信人类能够100%做自己应该做的事情。

今天我们要继续更新一下原有的Playbook,想办法把密码存到密码管理器中。


经过了几年前Lastpass密码泄露的事故之后,我们立刻放弃Lastpass,并转换到Bitwarden。

Bitwarden的口碑要比Lastpass好一些,起码在Lastpass泄露密码之后。而且购买企业版的Bitwarden还能为每一个用户免费创建一个家庭账户。这一点比别的软件良心一些。

对于寻求自动化,Bitwarden有自己的API和SDK。用户可以自行制作自动储存密码的程序。

研究到这里,我们突然间觉得有点问题。为啥这种编程的事情,研发组不做,而是我们IT运营组来做呢?搞不懂……

Bitwarden有Python的SDK。不过我登录到上次编程的数据库服务器上,才发现:

[awx ~]$ python --version
Python 2.7.5
[awx ~]$

一看到居然还是v2版本的Python,我觉得还是歇菜吧,不费那个劲了。看来还是要回到传统流派,Bash Script来做文章。

幸好Bitwarden有自己的CLI。可以用Bash读取密码记录。

bw get item <item_id>

item_id可以直接在每一个密码记录的网址上查找。

如果想储存一个新密码的话需要先读取密码的模板,然后修改模板中默认的数值,再储存新的密码记录。

bw get template item | jq ".name=\"<记录名称>\" |  .login=$(bw get template item.login | jq '.username="<用户账户>" | .password="用户密码"')" | bw encode | bw create item

CLI成功建立新密码记录之后,会反馈新建记录的item_id。

然后再把密码记录转到共享的收藏夹就可以了。

echo "[\"<收藏夹ID>\"]" | bw encode | bw move <item_id> <总帐号ID>

手动测试结束,下面要把上面的所有指令结合到一起,写道Bash Script中。

既然是防止研发组出错,干脆把自动生成密码的程序也写出来。这样他们也不会编出一个太过简单的密码。

generate_random_string() {
    local random_string
    random_string=$(< /dev/urandom tr -dc 'A-Za-z0-9' | head -c 22)
    echo "$random_string"
}

用上面的方程产生一个22位,由大小写字母和阿拉伯数字组成的随即字符串。这样就可以充当密码了。

不过把刚才手动的几条利用Bitwarden CLI的指令出现了一些问题。手动指令时,身份验证是将会话控制(session)临时储存系统自定义变量来完成的。

不过Bash Script是在当前Shell下的一个子Shell中完成的。无法读取当前Shell西面的自定义变量。

好在,CLI中可以将session填写到指令中,这样就不用担心无法读取自定义变量的问题。

也就是说所有的bw指令中加上--session <会话控制>就可以了。

# Generate password
temp_password=$(generate_random_string)
echo "Test Password: $test_password"

# Generate username and password JSON object
get_credential=$(echo "{\"username\": \"$test_user\", \"password\": \"$temp_password\"}" | jq .)

json_string=$(bw get template item --session "$session_token" | jq ".name=\"$test_record\" | .login=$(bw get template item.login --session "$session_token" | echo $get_credential)" | bw encode | bw create it
em --session "$session_token")
echo "$json_string"

# Retrieve item id from standard output
get_id=$(echo "$json_string" | jq -r '.id')

# Move new bitwardn item to collection
result=$(echo "[\"$BW_COLLECTION_ID\"]" | bw encode | bw move $get_id $BW_ORG_ID --session $session_token)
echo $result

这么一来,一个简单的Bash Script正式完成。再把这段脚本加到Ansible Playbook调用的Bash Script中,一下子就实现了99%自动化。唯一需要手动的部分就是研发部填写数据库的名称。

如果这件事他们再出错,那就开炒鱿鱼了……

姑且,姑且认为他们不会打错数据库的名字。我们又可以继续自己懒,看着研发部手动做事;而我们坐在电脑前悠哉游哉了。