Існує кілька варіантів зберігання паролів та інших секретів, які програма Python повинна використовувати, зокрема програма, яка повинна працювати у фоновому режимі, де вона не може просто попросити користувача ввести пароль.
Проблем, яких слід уникати:
- Перевірка пароля для контролю джерела, де його можуть побачити інші розробники або навіть громадськість.
- Інші користувачі на цьому ж сервері читають пароль із конфігураційного файлу або вихідного коду.
- Маючи пароль у вихідному файлі, де інші можуть побачити його через ваше плече, поки ви редагуєте його.
Варіант 1: SSH
Це не завжди варіант, але, мабуть, найкращий. Ваш приватний ключ ніколи не передається по мережі, SSH просто запускає математичні обчислення, щоб довести, що у вас є правильний ключ.
Для того, щоб це працювало, вам потрібно наступне:
- База даних або те, до чого ви отримуєте доступ, має бути доступним SSH. Спробуйте шукати "SSH" та будь-яку послугу, до якої ви отримуєте доступ. Наприклад, "ssh postgresql" . Якщо це не є функцією у вашій базі даних, перейдіть до наступного варіанту.
- Створіть обліковий запис для запуску служби, яка здійснюватиме виклики до бази даних, та генерувати ключ SSH .
- Або додайте відкритий ключ до служби, яку ви збираєтесь викликати, або створіть локальний обліковий запис на цьому сервері та встановіть там відкритий ключ.
Варіант 2: Змінні середовища
Це найпростіший варіант, тому, можливо, це гарне місце для початку. Це добре описано в додатку Дванадцять факторів . Основна ідея полягає в тому, що ваш вихідний код просто витягує пароль або інші секрети зі змінних середовища, а потім ви налаштовуєте ці змінні середовища в кожній системі, де ви запускаєте програму. Це також може бути приємним штрихом, якщо ви використовуєте значення за замовчуванням, які будуть працювати для більшості розробників. Ви повинні збалансувати це проти того, щоб зробити ваше програмне забезпечення "безпечним за замовчуванням".
Ось приклад, який витягує сервер, ім’я користувача та пароль із змінних середовища.
import os
server = os.getenv('MY_APP_DB_SERVER', 'localhost')
user = os.getenv('MY_APP_DB_USER', 'myapp')
password = os.getenv('MY_APP_DB_PASSWORD', '')
db_connect(server, user, password)
Шукайте, як встановити змінні середовища у вашій операційній системі, та розгляньте можливість запуску служби під її власним обліковим записом. Таким чином, у вас немає конфіденційних даних у змінних середовища, коли ви запускаєте програми у власному обліковому записі. Налаштовуючи ці змінні середовища, подбайте про те, щоб інші користувачі не могли їх прочитати. Наприклад, перевірте дозволи файлів. Звичайно, будь-які користувачі з дозволом адміністратора зможуть їх прочитати, але це не допоможе.
Варіант 3: Файли конфігурації
Це дуже схоже на змінні середовища, але ви читаєте секрети з текстового файлу. Я все ще вважаю змінні середовища більш гнучкими для таких речей, як інструменти розгортання та сервери безперервної інтеграції. Якщо ви вирішите використовувати файл конфігурації, Python підтримує кілька форматів у стандартній бібліотеці, таких як JSON , INI , netrc та XML . Ви також можете знайти зовнішні пакети, такі як PyYAML та TOML . Особисто я вважаю, що JSON та YAML найпростіші у використанні, а YAML дозволяє коментувати.
Три речі, які слід врахувати з файлами конфігурації:
- Де файл? Можливо розташування за замовчуванням, наприклад
~/.my_app
, і параметр командного рядка для використання іншого розташування.
- Переконайтеся, що інші користувачі не можуть прочитати файл.
- Очевидно, не прив'язуйте файл конфігурації до вихідного коду. Можливо, вам захочеться закріпити шаблон, який користувачі можуть скопіювати у свій домашній каталог.
Варіант 4: Модуль Python
Деякі проекти просто вкладають свої секрети в модуль Python.
db_server = 'dbhost1'
db_user = 'my_app'
db_password = 'correcthorsebatterystaple'
Потім імпортуйте цей модуль, щоб отримати значення.
from settings import db_server, db_user, db_password
db_connect(db_server, db_user, db_password)
Одним із проектів, який використовує цю техніку, є Django . Очевидно, що вам не слід виконувати зобов'язання settings.py
щодо керування джерелом, хоча, можливо, ви захочете створити файл із назвою, settings_template.py
який користувачі можуть копіювати та модифікувати.
Я бачу кілька проблем із цією технікою:
- Розробники можуть випадково передати файл у вихідний контроль. Його додавання
.gitignore
зменшує цей ризик.
- Частина вашого коду не знаходиться під контролем джерела. Якщо ви дисципліновані і вводите тут лише рядки та цифри, це не буде проблемою. Якщо ви почнете писати тут класи фільтрування журналів, зупиніться!
Якщо у вашому проекті вже використовується цей прийом, легко перейти до змінних середовища. Просто перемістіть усі значення параметрів до змінних середовища та змініть модуль Python на читання з цих змінних середовища.