Представьте - есть ли шанс ввести фразу-пароль через bash-скрипт?
Я использую "preppro" для получения последних пакетов Debian из моего локального репозитория, который отлично работает вручную.
Теперь мне нужно автоматизировать этот процесс с помощью задания cron, но пароль для переиздания представляет собой приглашение.
Есть ли возможность отправить пароль через скрипт bash? Не удалось найти что-либо на справочной странице
4 ответа
Мне нужно было то же самое, и я искал решение. Помимо бега gpg-agent
, который будет запрашивать пароль только один раз (например, во время загрузки) и кэшировать его для следующего использования, я ничего не нашел.
Проблема заключается в том, как взаимодействовать с интерактивными сценариями, которые запрашивают ввод данных пользователем из stdin. Ожидайте (apt-get install expect
) решает именно это.
Это скрипт, который я написал и сохранил в /usr/local/bin/Pointpro_expect:
#!/usr/bin/expect -f
set timeout 2
set passphrase "mysupersecretpassword"
spawn reprepro -b [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3]
expect {
"*passphrase:*" {
send -- "$passphrase\r"
}
}
expect {
"*passphrase:*" {
send -- "$passphrase\r"
}
}
interact
Вы можете запустить его так:
reprepro_expect [path_to_repository] [command] [distribution] [package_name]
Например:
Добавить новый пакет:
reprepro_expect /var/www/myrepo includedeb wheezy mypackage_0.1-1_all.deb
Удалить пакет
reprepro_expect /var/www/myrepo remove wheezy mypackage
Безопасность: так как пароль к вашему секретному ключу хранится в скрипте, я рекомендую chown
это пользователю, под которым он будет использоваться и chmod
до 500. Почему пароль не передается в качестве еще одного аргумента? Потому что он будет храниться в ~/.bash_history и будет отображаться в ps axu
во время выполнения.
Как уже упоминалось в других ответах, expect
может решить эту проблему. Я закончил с чем-то вроде этого, кроме как reprepro.exp
и сделать его исполняемым с chmod 755 reprepro.exp
#!/usr/bin/expect -f
set timeout 5
set passphrase "$env(SIGNING_PASSWORD)"
# Call reprepro with variable length arguments, so that this script
# takes the same arguments as the original program
spawn reprepro {*}$argv
expect {
timeout {send_error "\nFailed to get password prompt\n";
exit 1}
"Please enter passphrase*" {send -- "$passphrase\r";
send_user " *** entering passphrase ***";
exp_continue}
}
# Get the pid, spawnid, oserr and exitcode from the spawned reprepro command
set returnvalues [wait]
# Extract the reprepro exit code
set exitcode [lindex $returnvalues 3]
# Exit with the exitcode from reprepro (0 on success)
exit $exitcode
Имея один expect
утверждение означает, что это также будет работать (то есть не сбой), если пароль неверный. Затем gpg запросит кодовую фразу три раза, и представьте, что код возврата не равен 0.
Вы можете экспортировать переменную среды SIGNING_PASSWORD
в вашем.bashrc или замените его в скрипте реальным паролем или сделайте что-нибудь еще. Используйте соответствующий уровень безопасности, который вам нужен.
Мой рабочий код. Я повторяю сценарий внутри другого сценария bash в файл и затем открываю его.
#!/usr/bin/expect -f
set timeout 5
spawn reprepro -v -b $SCRIPT_DIR/repository/ubuntu includedeb $UBUNTUVERSION $DEBFILE
expect {
timeout {send_error \"\\nFailed to get password prompt\\n\";
exit 1}
\"Pass*\" {send -- \"$KEYPASSWD\\r\";
send_user \" *** entering passphrase ***\";
exp_continue}
}
# Get the pid, spawnid, oserr and exitcode from the spawned reprepro command
set returnvalues [wait]
# Extract the reprepro exit code
set exitcode [lindex $returnvalues 3]
# Exit with the exitcode from reprepro (0 on success)
exit $exitcode
Не забудьте запустить команду
update-alternatives --set pinentry /usr/bin/pinentry-tty >/dev/null || gpg-connect-agent reloadagent /bye >/dev/null
, поэтому reprepro не хочет открывать графический ввод пользователя!
Этот ответ предназначен для недоступных пользователей.
У меня была та же проблема, я создал фиктивный файл, зашифровал его и использовал
gpg-agent
чтобы кэшировать пароль, как предлагает mkudlacek, но с модулем ожидания ansible. Я использовал следующие задачи:
- name: create test.txt, created a dummy file
file:
path: /test.txt
state: touch
mode: u=rw,g=rw,o=rw #!!! just for testing purposes
- name: encrypt file
expect:
command: gpg --pinentry-mode loopback --sign /test.txt
responses: 'Enter passphrase:': '{{ your_pw }}'
timeout: 60
Теперь вы можете добавить пакеты репрезентации через отдельную задачу и удалить файл test.txt.