web-dev-qa-db-ja.com

パスワードを含むサーバー/データベース構成ファイルをソース管理に保存する必要がありますか?

私はいくつかのベストプラクティスを聞きたいと思っています...

いくつかの異なる本番サーバー(データベースなど)と対話するWebアプリケーションを想定しています...データベースパスワードを含む構成ファイルをソース管理(git、svnなど)に保存する必要がありますか?

そうでない場合、アプリケーションがアクセスする必要のあるサーバーデータベース(または他の関連する)パスワードを追跡するための最良の方法は何ですか?

編集:より多くの議論を促し、より多くの人々がベストプラクティスと考えるものを聞くための報奨金を追加しました。

51
philfreo

ここには単一の「銀の弾丸」の答えはなく、すべて詳細に大きく依存します。

まず、すべてのソースコードを個別のリポジトリの構成から分離するためのベストプラクティスを検討します。したがって、ソースコードはソースコードのままですが、インストールまたは展開(構成、パスワードなどを含む)はまったく別のものです。このようにして、開発者のタスクをシステム管理者のタスクからしっかりと分離し、最終的に2つの異なるチームを構築して彼らの得意なことを実行できます。

ソースコードリポジトリとデプロイメントリポジトリが別々になっている場合、次の最善策はデプロイメントオプションを検討することです。ここで私が見る最良の方法は、選択したOSに典型的な展開手順を使用することです(つまり、OSのメンテナが行う方法で、選択したOSの自律パッケージを構築します)。

たとえば、Red HatまたはDebianのパッケージ化手順は、通常、外部サイトからソフトウェアのtarballを取得し(ソースコードVCSからソースをエクスポートする)、それを解凍し、コンパイルして、展開の準備をすることを意味します。デプロイメント自体は、理想的には、_rpm -U package.rpm_、_dpkg --install package.deb_、_apt-get dist-upgrade_などのパッケージをインストールする迅速で単純なコマンドを実行することを意味する必要があります(ビルドされたパッケージが適切なリポジトリに移動する場合) getはそれらを見つけることができるでしょう)。

明らかに、このように機能させるには、すべてのアドレスと資格情報を含む、完全に機能する状態のシステムのすべてのコンポーネントのすべての構成ファイルを提供する必要があります。

より簡潔にするために、典型的な「小規模サービス」の状況を考えてみましょう。1つのPHPアプリケーションがnアプリケーションサーバーにデプロイされているApache/mod_phpを実行し、mMySQLサーバーにアクセスします。これらのサーバー(または仮想コンテナ、実際には重要ではありません)はすべて、保護されたプライベートネットワークに存在します。この例を簡単にするために、すべての実際のインターネット接続の前にkhttpアクセラレーター/リバースプロキシー(nginx/lighttpd /など)のクラスターがあると仮定します。 Apache)非常に簡単な構成(転送先の内部IPのみ)があります。

それらが接続され、完全に機能するために何が必要ですか?

  • MySQLサーバー:IP /ホスト名の設定、データベースの設定、ログインとパスワードの提供
  • PHPアプリケーション:IP /ホスト名を設定し、MySQLサーバーのIP、ログイン、パスワード、データベースを記載した構成ファイルを作成します

ここには2つの異なる「タイプ」の情報があることに注意してください。IP/ホスト名は固定されたものであり、それらを一度だけ割り当てることをお勧めします。一方、ログインとパスワード(およびデータベース名)は、ここでは純粋に接続を目的としています-MySQLが実際に接続しているPHPアプリケーションであることを確認するためです。したがって、私の推奨事項ここでは、これら2つの「タイプ」を分割します。

  • IPなどの「永続的な」情報は、一部のVCSに保存する必要があります(ソースコードVCSとは異なります)。
  • 2つのアプリケーション間のパスワードなどの「一時的な」情報は決して保存しないでください。ただし、デプロイメントパッケージの生成中に生成されます。

最後の最も難しい質問はここに残っています:デプロイメントパッケージを作成する方法は?利用可能な複数の手法があり、2つの主な方法は次のとおりです。

  • VCS1からエクスポートされたソースコード+ VCS2からの「永続的な」構成+ VCS3からのビルドスクリプト=パッケージ
  • ソースコードはVCS1にあります。 VCS2は、VCS1の「フォーク」+構成情報+生成可能なビルドスクリプトを本質的に含む分散バージョン管理(gitやhgなど)です。私は個人的にこのアプローチの方が好きです。はるかに短く、最終的には使いやすくなりますが、特にgitまたはhgを習得する必要がある管理者にとっては、学習曲線が少し急になる可能性があります。

上記の例では、次のようなパッケージを作成します。

  • _my-application-php_-これはmod_php、Apacheに依存し、md5(current source code revision + salt)として生成されたMySQLデータベースのIP /ホスト名とログイン/パスワードを含む_/etc/my-php-application/config.inc.php_のような生成されたファイルを含みます。このパッケージは、すべてのnアプリケーションサーバーにインストールされます。理想的には、クリーンにインストールされたOSにインストールでき、手動で操作しなくても完全に機能するアプリケーションクラスターノードを作成できる必要があります。
  • _my-application-mysql_-これはMySQLサーバーに依存し、次のようなインストール後のスクリプトが含まれます。
    • mySQLサーバーを起動し、OSの起動時に自動的に起動することを確認します
    • mySQLサーバーに接続します
    • 必要なデータベースが存在するかどうかを確認します
    • いいえの場合-データベースを作成し、コンテンツでブートストラップし、パスワードでログインを作成します(md5アルゴリズムを使用して_/etc/my-php-application/config.inc.php_で生成されたものと同じログインとパスワード)
    • はいの場合-データベースに接続し、移行を適用してデータベースを新しいバージョンにし、古いログイン/パスワードをすべて削除し、新しいログイン/パスワードのペアを再作成します(ここでも、md5(リビジョン+ソルト)メソッドを使用して生成されます)

最終的には、_generate-packages && ssh-all apt-get dist-upgrade_のような単一のコマンドを使用してデプロイメントをアップグレードするという利点がもたらされるはずです。また、アプリケーション間パスワードはどこにも保存せず、更新のたびに再生成されます。

この非常に単純な例は、ここで使用できる多くの方法を示していますが、最終的には、ここでどちらのソリューションが優れているか、どれがやり過ぎかを判断するのはあなた次第です。ここに、または別の質問として詳細を入力する場合は、喜んで詳細を説明します。

27
GreyCat

パスワードをプレーンテキストどこにでも(CEO、CFO、CIOだけがアクセスできる誰かの頭蓋骨またはロックされた金庫以外)に保存してはならないという点は別として(そして3つのキーすべてを一度に必要とします))、製品に必要なすべてをソース管理に保存する必要がありますビルド

つまり、ソースだけでなく、ビルドマシンの仕様、コンパイラオプション、コンパイラ自体なども意味します。

物理ハードウェアをチェックインする方法を見つけることができれば、それも行います:-)

ビルドプロセス自体によって再現できるもの、またはソフトウェアをビルドするのではなくrunningのためのもの(パスワードなど)は、通常、ソースに属していません制御しますが、一部のショップは、実行可能ファイル、生成されたドキュメントなどに対してそれを行い、インストールのために特定のリリースをすばやく取得できるようにします。

18
paxdiablo

パスワードはソース管理に保存しないでください。まったく。これまで。 秘密を秘密にする方法 を参照してください

パスワード、サーバー名などは、サーバー管理者によって実行される展開構成の一部です。この手順を文書化し、文書化された手順を管理下に置くことが不可欠です。

または、sysadminが構成を実行するために実行するスクリプトによって展開構成を実行し、スクリプトの実行中にsysadminに必要な情報を提供するように要求することもできます。この場合も、このスクリプトはバージョン管理下に置く必要があります。

サーバー構成以外のすべては、ソース管理下にある必要があります

サーバー構成をソース管理に保存することは、展開の邪魔になり、小さな災害を引き起こす可能性があるため、一般的には悪い考えです(たとえば、ソース管理から展開されたテストバージョンがライブサービスと通信していることに誰かが気付いていない場合)。

これらの構成ファイルは常にwebrootの外部に保管してください。

信頼できる接続はオプションであり、既知のIPアドレスがそのサービスの構成によってサービスに接続できるようにします。

11

一般的に、私はpaxdiabloに同意します。可能な限りすべてをソース管理下に置きます。これには、データベース資格情報を含む本番構成ファイルが含まれます。

サーバーがクラッシュし、バックアップが不良であることが判明し、そのサーバーをバックアップする必要がある状況について考えてみてください。あなたとあなたの顧客(または上司)は、サイトをソース管理に展開するために必要なすべてのものがあることは大きなプラスであることに間違いなく同意すると思います。

継続的インテグレーション(別のベストプラクティス)を使用してソースから簡単にデプロイ可能なパッケージを構築する場合は、構成ファイルをソース管理下に置く必要があります。

また、ほとんどの場合、ソース管理アクセス権を持つ開発者は本番データベースサーバーに直接アクセスできないことを考慮してください。本番パスワードは彼らにとって役に立たない。

間違った人があなたのソースにアクセスした場合でも、パスワードを害するために本番サーバーにアクセスする必要があります。したがって、本番環境が適切に保護されている場合、ソース管理におけるパスワードのセキュリティリスクは非常に限定されます。

7

この質問は、情報の所有権、信頼、組織に関するものだと思います。システムパスワードを開示や誤用から保護するために、組織のどの部分を信頼しますか?

私は彼らがビジネスの責任者によって管理されている組織にいました。また、作成や使用などのプロセスを所有する運用チームに委任されている場合もあります。

最も重要なことは、システムパスワードにアクセスできるユーザーが組織内で明確に定義されていることです。その後、パスワードを保護するための適切な技術的解決策を決定できます。

3
8DH

いいえ。本番パスワードはサーバー上で直接構成する必要があります。展開中に適切なプロパティファイルを変更するには、展開チーム/担当者向けの展開手順を作成する必要があります。

1
Jinesh Parekh

PHPのSubversionリポジトリでは、パスワードを含む構成ファイルはconfig.php.sampleとしてチェックインされ、何を提供する必要があるかについてのヒントがあり、依存するスクリプトではconfig.phpが同じ場所に存在する必要があります。

リポジトリは、「偶発的な」追加やチェックインを回避するために、そのディレクトリのconfig.phpを無視するように構成されています。

1
Linus Kleen

ソースコードのパスワードに関する問題:

  • デプロイメントごとに変更するのは難しい(本番環境でソースコードを変更する必要はありません)
  • 開発を行うときに誤って本番データベースを破損する可能性が高くなります
  • セキュリティの問題(ほとんどのショップでは、コード/開発者が製品のパスワードを知る理由はありません)
  • 変更されたパスワードは再デプロイが必要です

私が最もうまく機能することがわかったのは、デプロイメント固有のデータに適切なデフォルトとプレースホルダーを組み合わせて使用​​する構成をチェックインすることです。私たちのアプリは常に、変数のオーバーライドを許可するシステム構成を探します。これにより、実稼働マシンはそのデプロイメントに適した構成を持つことができます。

注:管理者として機能するときは、常にコードとは別に構成を管理します(正当な理由があります)。

1
dietbuddha

パスワードを入力するには、ビルドスクリプト(私の場合はPhing)を使用するのが最善の方法であることがわかりました。

1
Matt Bostock

サンプル構成ファイルは、確かに、バージョン管理下に置きます。ただし、通常、サーバーアドレスやパスワードなどの実際のアクセスデータでは使用できません。もっと何かのような

#program.conf 
#
#$ myprogのmysqlオプション
#
#SERVER_ADDR = 127.0.0.1 
# SERVER_USER = mysql 
#SERVER_PASSWD = abcdef 
1
user502515

メインのsettingsファイルの横にlocal_settingsファイルがある方がいいです。このlocal_settingsはリポジトリに追加すべきではありませんが、このファイルの構造を示すためにsample.local_settingをリポジトリに追加します。

実行時にlocal_settingsが存在する場合、その値はメイン設定ファイルの値を上書きします。

たとえば、Pythonの場合:

settings.py:

log='error.log'
db=lambda:None
db.Host='localhost'
db.user=''
db.password=''

try:
    import local_settings
except ImportError:
    pass

local_settings.py:

from settings import *

db.user='abcd'
db.password='1234'
0
iman

パスワードやその他のアクセスの詳細(データベースなど)を含む重要な構成ファイルは常に除外します。これは純粋にベストプラクティスです。さらに、そのソース管理とバージョン管理に加えて、通常は複数のユーザーにサービスを提供し、すべてのユーザーが同じデータベースの詳細や同じサーバー構成(ドメインなど)で動作するわけではありません。この目的のために、構成ファイルは除外されたままにする必要があります。沢山。

0
Matthew Morek

適切なビルドプロセスがない場合、私はこの戦略を使用しています(PHPアプリの場合):

  1. フォルダを作成する_/etc/companyname_
  2. その中に、2つのファイルを配置します。

    _<?php // env.php
    return 'prod'; 
    _
    _<?php // appname-prod.php
    return array(
      'db' => array( /* credentials */ ),
      /* other Host-specific conf data */
    ); 
    _
  3. PHPプロセスでのみ両方のファイルを読み取り可能にする

これで、アプリの構成ファイルは次のようになります。

_<?php // config.php
$env = (require "/etc/companyname/env.php");
$creds = (require "/etc/companyname/appname-{$env}.php");
_

これが適切な場所にあると、環境は使用される資格情報を定義し、事前構成された環境間でコードを移動できます(そして、_$env_でいくつかのオプションを制御できます)。もちろん、これはサーバー環境変数を使用して実行できますが、これはa)セットアップが簡単で、b)サーバー上のすべてのスクリプトに資格情報を公開しません(phpinfo())。

PHPの外で読みやすくするために、資格情報ファイルをJSONなどにして、パフォーマンスのわずかな低下に耐えることができます(APCはそれらをキャッシュしません)。

0
Steve Clay