#python #python-3.x #ftp #credentials #python-module
Вопрос:
Привет, я новичок в сообществе и новичок в Python, опытный, но плохо разбираюсь в других языках высокого уровня, поэтому мой вопрос прост.
Я сделал простой скрипт для подключения к частному ftp-серверу и получения с него ежедневной информации.
from ftplib import FTP
#Open ftp connection
#Connect to server to retrieve inventory
#Open ftp connection
def FTPconnection(file_name):
ftp = FTP('ftp.serveriuse.com')
ftp.login('mylogin', 'password')
#List the files in the current directory
print("Current File List:")
file = ftp.dir()
print(file)
# # #Get the latest csv file from server
# ftp.cwd("/pub")
gfile = open(file_name, "wb")
ftp.retrbinary('RETR ' file_name, gfile.write)
gfile.close()
ftp.quit()
FTPconnection('test1.csv')
FTPconnection('test2.csv')
Вот и весь сценарий, он передает мои учетные данные, а затем вызывает функцию FTPconnection для двух разных файлов, которые я извлекаю.
Затем в моем другом скрипте, который их обрабатывает, есть инструкция import, поскольку я пытался вызвать этот скрипт как модуль, то, что делает мой импорт, это просто подключение к FTP-серверу и получение информации.
import ftpconnect as ftpc
Это другой скрипт на Python, который выполняет обработку.
Это работает, но я хочу его улучшить, поэтому мне нужны некоторые рекомендации о том, как это сделать, потому что в Spyder 4.1.5 я получаю предупреждение «Модуль ftpconnect вызывается, но не используется»… так что, вероятно, мне здесь чего-то не хватает, я разрабатываю на macOS с использованием Anaconda и Python 3.8.5.
Я пытаюсь создать приложение, чтобы автоматизировать некоторые задачи, но я не смог найти ничего о модулях, которые помогли бы мне улучшить код, в нем просто говорится, что вам нужно импортировать любое имя файла .py, которое вы использовали, и это будет считаться модулем … и мой последний вопрос: как вы обычно можете защитить личную информацию(учетные данные ftp) от раскрытия? Это не имеет никакого отношения к защите моего кода, кроме учетных данных.
Комментарии:
1. Обычно импорт модуля просто определяет функции и переменные, а скрипт, который его импортирует, вызывает функции. Это необычно для импорта модуля, чтобы фактически выполнять всю работу, такую как передача файлов. Ваша среда разработки предполагает, что это так, поэтому она предупреждает, когда не видит, что вы никогда не вызываете ни одну из импортированных функций.
2. хорошо @Barмар, спасибо за понимание, как можно повысить ваш ответ? так что я больше ничего не могу сделать, так будет ли это работать, если вместо вызова функций на ftpconnect.py скрипт для вызова их в том, который я использую для обработки, тогда как я могу защитить личную информацию? Этих учетных данных будет достаточно для использования разрешений Unix или существует другая распространенная практика?
3. Мой комментарий касался только
Module ftpconnect called but unused
предупреждения, ничего о хранении учетных данных.4. Вы решаете эту проблему, вызывая
ftpc.FTPconnection('test1.csv')
скрипт, который импортирует.
Ответ №1:
Существует несколько вариантов хранения паролей и других секретов, которые должна использовать программа на 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)
Посмотрите, как задать переменные среды в вашей операционной системе, и подумайте о запуске службы под собственной учетной записью. Таким образом, у вас не будет конфиденциальных данных в переменных среды, когда вы запускаете программы в своей учетной записи. Когда вы настроите эти переменные среды, будьте особенно осторожны, чтобы другие пользователи не могли их прочитать. Например, проверьте права доступа к файлам. Конечно, любые пользователи с правами суперпользователя смогут их прочитать, но с этим ничего не поделаешь. Если вы используете systemd, посмотрите на сервисный модуль и будьте осторожны при использовании EnvironmentFile
вместо Environment
любых секретов. Environment
значения могут быть просмотрены любым пользователем с systemctl show
помощью .
Вариант 3: Файлы конфигурации
Это очень похоже на переменные среды, но вы читаете секреты из текстового файла. Я все еще нахожу переменные среды более гибкими для таких вещей, как инструменты развертывания и серверы непрерывной интеграции. Если вы решите использовать файл конфигурации, Python поддерживает несколько форматов в стандартной библиотеке, таких как JSON, INI, netrc и XML. Вы также можете найти внешние пакеты, такие как PyYAML и TOML. Лично я нахожу JSON и YAML самыми простыми в использовании, а YAML допускает комментарии.
Три вещи, которые следует учитывать при работе с файлами конфигурации:
- Где файл? Возможно , расположение по умолчанию, например
~/.my_app
, и опция командной строки для использования другого местоположения. - Убедитесь, что другие пользователи не могут прочитать файл.
- Очевидно, что не фиксируйте файл конфигурации в исходном коде. Возможно, вам захочется зафиксировать шаблон, который пользователи могут скопировать в свой домашний каталог.
Вариант 4: Модуль Python
Некоторые проекты просто помещают свои секреты прямо в модуль Python.
# settings.py
db_server = 'dbhost1'
db_user = 'my_app'
db_password = 'correcthorsebatterystaple'
Затем импортируйте этот модуль, чтобы получить значения.
# my_app.py
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 для чтения из этих переменных среды.
Комментарии:
1. Вау, спасибо вам за эту информацию @kinshukdua, да, я тоже изучаю Django, и я подумывал об этом, когда приложение станет более зрелым и сможет работать онлайн, но на этих ранних стадиях я просто разрабатывал локально, но мне было любопытно, как защитить учетные данные, так что эта информация отличная, я никогда не рассматривал возможность использования переменных среды, потому что я еще даже не касался модулей sys или os(примерно только что использовал их дважды) … На этом раннем этапе все находится в одном каталоге, и я больше сосредоточен на улучшении кода, но приятно знать, что это можно сделать таким образом.
2. Нет проблем! Пожалуйста, поддержите или выберите его в качестве ответа, если он решил вашу проблему, чтобы люди, которые будут искать его в будущем, могли его найти. Счастливого Кодирования!
3. Ну, это было именно то, что я пытался сделать, но так как модуль-это просто еще один файл .py, я подумал, что вы могли бы усложнить его, например, зашифровать и расшифровать, или использовать что-то вроде PDO в MySQL, я помню, что в php именно это делалось с включениями, но Python похож на базовый, более открытый, поэтому я провел некоторое исследование и не смог найти ничего подобного. @kinshukdua