Django - Настройки: чувствительные настройки и различные среды (dev, prod, staging).Каков рекомендуемый способ сделать это - PullRequest
0 голосов
/ 29 марта 2019

Я использую Django версии 2.1.7:

Я прочитал много статей и вопросов по этому поводу.Я нашел людей, использующих различные методы.

Approches used in the general are:
1) setting environmental variables
2) multiple settings
3) load configuration variables from a file like using django-environ etc

Approach 1: Я не буду использовать, потому что я не хочу использовать переменные среды для хранения переменных.

Approach 3: использует стороннюю библиотекуи иногда они могут не поддерживаться больше.Но если есть какой-то стандартный способ сделать это, я в порядке.

Approach 2: Здесь я не уверен, как хранить конфиденциальные данные отдельно.

Так что кто-то может мне помочь в этом отношении.

1 Ответ

0 голосов
/ 29 марта 2019

Я использую комбинацию из всех:

  • При запуске gunicorn как службы в systemd, вы можете установить переменные окружения, используя файл conf в каталоге .service.d:
    [Service]
    Environment="DJANGO_SETTINGS_MODULE=myapp.settings.production"
    Environment="DATABASE_NAME=MYDB"
    Environment="DATABASE_USER=MYUSER"
    Environment="DATABASE_PASSWORD=MYPASSWORD" 
    ...
    
  • Этот файл извлекается из S3 (где он зашифрован) при запуске экземпляра. У меня есть скрипт запуска, использующий aws-cli, который делает это.
  • Чтобы иметь возможность запускать команды управления, например, чтобы перенести вашу базу данных в рабочую среду, вам также понадобятся эти переменные, поэтому, если переменные среды не установлены, я получаю их непосредственно из этого файла. Так что в моих настройках у меня что-то вроде этого:

    def get_env_variable(var_name):
        try:
            return os.environ[var_name]
        except KeyError:
            env = fetch_env_from_gunicorn()
            return env[var_name]
    
    def fetch_env_from_gunicorn():
        gunicorn_conf_directory = '/etc/systemd/system/gunicorn.service.d'
        gunicorn_env_filepath = '%s/gunicorn.conf' % (gunicorn_conf_directory,)
        if not os.path.isfile(gunicorn_env_filepath):
            raise ImproperlyConfigured('No environment settings found in gunicorn configuration')
    
        key_value_reg_ex = re.compile(r'^Environment\s*=\s*\"(.+?)\s*=\s*(.+?)\"$')
        environment_vars = {}
        with open(gunicorn_env_filepath) as f:
            for line in f:
                match = key_value_reg_ex.search(line)
                if match:
                    environment_vars[match.group(1)] = match.group(2)
        return environment_vars
    
    ...
    
    DATABASES = {
        ...
        'PASSWORD': get_env_variable('DATABASE_PASSWORD'),
        ...}
    

    Обратите внимание, что все команды управления, которые я выполняю в своих размещенных экземплярах, мне нужно явно передать --settings=myapp.settings.production, чтобы он знал, какой файл настроек использовать.

  • Различные настройки для разных типов сред. Это связано с тем, что такие вещи, как DEBUG, а также настройки почты, настройки аутентификации и т. Д. ... слишком различаются в разных средах, чтобы использовать один файл настроек. У меня есть default.py настройки в каталоге settings со всеми общими настройками, а затем production.py , например, начинается с from .default import * и просто переопределяет, что это необходимо переопределить как DEBUG = False и другие DATABASES (чтобы использовать вышеупомянутый механизм), LOGGING и т.д ...

При этом возникают следующие угрозы безопасности:

  • Секреты могут прочитать все, у кого есть права доступа ssh и права доступа к каталогу systemd. Убедитесь, что у вас есть экземпляры в VPN и ограничьте ssh доступ к определенным IP-адресам, например. Также я разрешаю ssh только с ключами ssh, но не с именем пользователя и паролем, поэтому нет риска кражи паролей
  • Любой, кто имеет доступ по ssh к каталогу приложения django, может запустить оболочку и from django.conf import settings, чтобы затем прочитать settings. То же, что и выше, должно быть ограничено в любом случае.
  • Файл может прочитать любой, у кого есть доступ к вашему хранилищу (например, S3). Опять же, это может быть легко ограничено.
...