Есть много плагинов на веб браузеры, которые умеют генерировать ПИН для вашего MFA. Так же, имеется большое количество ПО на мобильные девайсы, но как по мне, лучше заюзать терминал.
Скрипт для генерации OTP для AWS при использовании MFA в Unix/Linux
Возможно, кто-то генерирует OTP для своих нужд токены для входа на сервер. У меня используеться — AWS сервис и на нем установлен MFA, по этому — нужно каждый раз генерировать токен.
Полезное чтиво:
Установка pip/setuptools/wheel в Unix/Linux
Собственно, я взял и написал скрипт для этой задачи:
# vim get_OTP.py
Выглядит он следующим образом:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import configparser
import argparse
import pyotp
import os
class Bgcolors:
def __init__(self):
self.get = {
'HEADER': '\033[95m',
'OKBLUE': '\033[94m',
'OKGREEN': '\033[92m',
'WARNING': '\033[93m',
'FAIL': '\033[91m',
'ENDC': '\033[0m',
'BOLD': '\033[1m',
'UNDERLINE': '\033[4m'
}
def get_acc_names(db_file):
# db_file = '/Users/captain/.aws/credentials'
if db_file is '':
print('Please add PATH to .aws/credentials file inside this script(db_file variable)')
print('For help, use: script_name.py -h')
exit(1)
config = configparser.ConfigParser()
config.sections()
config.read(db_file)
return config.sections()
def get_creds_from_acc_name(acc_name, db_file):
if db_file is '':
print('Please add PATH to .aws/credentials file inside this script(db_file variable)')
exit(1)
config = configparser.ConfigParser()
config.sections()
config.read(db_file)
if acc_name in config:
if 'aws_access_key_id' in config[acc_name]:
aws_access_key_id = config[acc_name]['aws_access_key_id']
else:
print('Please add aws_access_key_id to %s file for [%s] account' % (db_file, acc_name))
exit(1)
if 'aws_secret_access_key' in config[acc_name]:
aws_secret_access_key = config[acc_name]['aws_secret_access_key']
else:
print('Please add aws_secret_access_key to %s file for [%s] account' % (db_file, acc_name))
exit(1)
if 'region' in config[acc_name]:
region = config[acc_name]['region']
else:
print('Please add region to %s file for [%s] account' % (db_file, acc_name))
exit(1)
if 'mfa_authorisation_key' in config[acc_name]:
mfa_authorisation_key = config[acc_name]['mfa_authorisation_key']
else:
print('Please add mfa_authorisation to %s file for [%s] account' % (db_file, acc_name))
exit(1)
else:
print('Please add [%s] account to %s' % (acc_name, db_file))
print(('EXAMPLE:\n'
' [%s]\n'
' aws_access_key_id = XXXXXXXXXXXXXXXXXXXXXXXX\n'
' aws_secret_access_key = YYYYYYYYYYYYYYYYYYYYYYYY\n'
' region = us-east-1\n'
' mfa_authorisation_key = ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\n'
' ') % acc_name)
print(Bgcolors().get['HEADER'], 'You can use the following ones:', Bgcolors().get['ENDC'],
Bgcolors().get['OKGREEN'], get_acc_names(db_file), Bgcolors().get['ENDC'])
exit(1)
return aws_access_key_id, aws_secret_access_key, region, mfa_authorisation_key
def generate_token(acc_name, db_file):
account_creds = get_creds_from_acc_name(acc_name, db_file)
totp = pyotp.TOTP(account_creds[3])
print("Current OTP for %s:" % acc_name, Bgcolors().get['OKGREEN'], totp.now(), Bgcolors().get['ENDC'])
return generate_token
def generate_token_without_output(acc_name, db_file):
account_creds = get_creds_from_acc_name(acc_name, db_file)
totp = pyotp.TOTP(account_creds[3])
return totp.now()
def main():
parser = argparse.ArgumentParser(prog='python3 script_name.py -h',
usage='python3 script_name.py {ARGS}',
add_help=True,
prefix_chars='--/',
epilog='''created by Vitalii Natarov''')
parser.add_argument('--version', action='version', version='v1.0.1')
parser.add_argument('--acc', dest='account', help='Account name', default='default')
parser.add_argument('--path', dest='path', help='Path to .aws/credentials file',
default='~/.aws/credentials')
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument('--show-acc', dest='show_acc', help='Show account names', action='store_true')
# group.add_argument('--s', dest='show_acc', help='Show account names', action='store_true')
results = parser.parse_args()
ac_name = results.account
path = os.path.expanduser(results.path)
if path is not None:
if results.show_acc:
print(Bgcolors().get['HEADER'], 'You can use the following ones:', Bgcolors().get['ENDC'],
Bgcolors().get['OKGREEN'], get_acc_names(path), Bgcolors().get['ENDC'])
else:
generate_token(ac_name, path)
else:
print('Please add [--path]')
print('For help, use: script_name.py -h')
exit(0)
if __name__ == '__main__':
main()
Для запуска, можно использовать слкдующую команду:
$ python3 get_OTP.py -h
usage: python3 script_name.py {ARGS}
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
--acc ACCOUNT Account name
--path PATH Path to .aws/credentials file
--show-acc Show account names
created by Vitalii Natarov
Это так званный хелп. Скрипт полностью готов к использованию. У него есть подсказки, которые помогут вам в работе.
Я запускаю его следующим образом:
$ python3 get_OTP.py --acc linux-notes
Current OTP for linux-notes: 199746
PS: У меня используется мой стандартный путь к файлу, его нужно сменить или переопределить:
$ python3 get_OTP.py --path="/Users/captain/.aws/credentials" --acc linux-notes
Еще примеры:
$ python3 get_OTP.py --acc default
Please add mfa_autorisation to /Users/captain/.aws/credentials file
Или:
python3 get_OTP.py --acc default2
Please add [default2] account to /Users/captain/.aws/credentials
EXAMPLE:
[default2]
aws_access_key_id = XXXXXXXXXXXXXXXXXXXXXXXX
aws_secret_access_key = YYYYYYYYYYYYYYYYYYYYYYYY
region = us-east-1
mfa_authorisation_key = ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
You can use the following ones: ['default', 'linux-notes']
На мой взгляд — очень даже интуитивно все.
PS: Нужно установить либу:
# pip3 install pyotp
В моем случае, я использую AWS и добавляю в него нужную строку. Вообще, можно немного видоизменить скрипт и считывать данные с другого файла. Если кому-то потребутся помощь — я срадостью помогу.
Я себе, сделал алиас на эту команду чтобы использование стало еще удобнее. Для этого, стоит открыть:
$ vim ~/.bashrc
И прописать:
alias get_OTP="python3 /Users/captain/Projects/python/pyotp/get_OTP.py"
PS: Конечно, стоит сменить путь к файлу. Но это и так понятно было. Наверное….
После чего, использование будет следующее:
$ get_OTP --acc linux-notes
А на этом, у меня все, статья «Скрипт для генерации OTP при использовании MFA в Unix/Linux» завершена.