私はいくつかのベストプラクティスを聞きたいと思っています...
いくつかの異なる本番サーバー(データベースなど)と対話するWebアプリケーションを想定しています...データベースパスワードを含む構成ファイルをソース管理(git、svnなど)に保存する必要がありますか?
そうでない場合、アプリケーションがアクセスする必要のあるサーバーデータベース(または他の関連する)パスワードを追跡するための最良の方法は何ですか?
編集:より多くの議論を促し、より多くの人々がベストプラクティスと考えるものを聞くための報奨金を追加しました。
ここには単一の「銀の弾丸」の答えはなく、すべて詳細に大きく依存します。
まず、すべてのソースコードを個別のリポジトリの構成から分離するためのベストプラクティスを検討します。したがって、ソースコードはソースコードのままですが、インストールまたは展開(構成、パスワードなどを含む)はまったく別のものです。このようにして、開発者のタスクをシステム管理者のタスクからしっかりと分離し、最終的に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のみ)があります。
それらが接続され、完全に機能するために何が必要ですか?
ここには2つの異なる「タイプ」の情報があることに注意してください。IP/ホスト名は固定されたものであり、それらを一度だけ割り当てることをお勧めします。一方、ログインとパスワード(およびデータベース名)は、ここでは純粋に接続を目的としています-MySQLが実際に接続しているPHPアプリケーションであることを確認するためです。したがって、私の推奨事項ここでは、これら2つの「タイプ」を分割します。
最後の最も難しい質問はここに残っています:デプロイメントパッケージを作成する方法は?利用可能な複数の手法があり、2つの主な方法は次のとおりです。
上記の例では、次のようなパッケージを作成します。
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サーバーに依存し、次のようなインストール後のスクリプトが含まれます。/etc/my-php-application/config.inc.php
_で生成されたものと同じログインとパスワード)最終的には、_generate-packages && ssh-all apt-get dist-upgrade
_のような単一のコマンドを使用してデプロイメントをアップグレードするという利点がもたらされるはずです。また、アプリケーション間パスワードはどこにも保存せず、更新のたびに再生成されます。
この非常に単純な例は、ここで使用できる多くの方法を示していますが、最終的には、ここでどちらのソリューションが優れているか、どれがやり過ぎかを判断するのはあなた次第です。ここに、または別の質問として詳細を入力する場合は、喜んで詳細を説明します。
パスワードをプレーンテキストどこにでも(CEO、CFO、CIOだけがアクセスできる誰かの頭蓋骨またはロックされた金庫以外)に保存してはならないという点は別として(そして3つのキーすべてを一度に必要とします))、製品に必要なすべてをソース管理に保存する必要がありますビルド。
つまり、ソースだけでなく、ビルドマシンの仕様、コンパイラオプション、コンパイラ自体なども意味します。
物理ハードウェアをチェックインする方法を見つけることができれば、それも行います:-)
ビルドプロセス自体によって再現できるもの、またはソフトウェアをビルドするのではなくrunningのためのもの(パスワードなど)は、通常、ソースに属していません制御しますが、一部のショップは、実行可能ファイル、生成されたドキュメントなどに対してそれを行い、インストールのために特定のリリースをすばやく取得できるようにします。
パスワードはソース管理に保存しないでください。まったく。これまで。 秘密を秘密にする方法 を参照してください
パスワード、サーバー名などは、サーバー管理者によって実行される展開構成の一部です。この手順を文書化し、文書化された手順を管理下に置くことが不可欠です。
または、sysadminが構成を実行するために実行するスクリプトによって展開構成を実行し、スクリプトの実行中にsysadminに必要な情報を提供するように要求することもできます。この場合も、このスクリプトはバージョン管理下に置く必要があります。
サーバー構成以外のすべては、ソース管理下にある必要があります。
サーバー構成をソース管理に保存することは、展開の邪魔になり、小さな災害を引き起こす可能性があるため、一般的には悪い考えです(たとえば、ソース管理から展開されたテストバージョンがライブサービスと通信していることに誰かが気付いていない場合)。
これらの構成ファイルは常にwebrootの外部に保管してください。
信頼できる接続はオプションであり、既知のIPアドレスがそのサービスの構成によってサービスに接続できるようにします。
一般的に、私はpaxdiabloに同意します。可能な限りすべてをソース管理下に置きます。これには、データベース資格情報を含む本番構成ファイルが含まれます。
サーバーがクラッシュし、バックアップが不良であることが判明し、そのサーバーをバックアップする必要がある状況について考えてみてください。あなたとあなたの顧客(または上司)は、サイトをソース管理に展開するために必要なすべてのものがあることは大きなプラスであることに間違いなく同意すると思います。
継続的インテグレーション(別のベストプラクティス)を使用してソースから簡単にデプロイ可能なパッケージを構築する場合は、構成ファイルをソース管理下に置く必要があります。
また、ほとんどの場合、ソース管理アクセス権を持つ開発者は本番データベースサーバーに直接アクセスできないことを考慮してください。本番パスワードは彼らにとって役に立たない。
間違った人があなたのソースにアクセスした場合でも、パスワードを害するために本番サーバーにアクセスする必要があります。したがって、本番環境が適切に保護されている場合、ソース管理におけるパスワードのセキュリティリスクは非常に限定されます。
この質問は、情報の所有権、信頼、組織に関するものだと思います。システムパスワードを開示や誤用から保護するために、組織のどの部分を信頼しますか?
私は彼らがビジネスの責任者によって管理されている組織にいました。また、作成や使用などのプロセスを所有する運用チームに委任されている場合もあります。
最も重要なことは、システムパスワードにアクセスできるユーザーが組織内で明確に定義されていることです。その後、パスワードを保護するための適切な技術的解決策を決定できます。
いいえ。本番パスワードはサーバー上で直接構成する必要があります。展開中に適切なプロパティファイルを変更するには、展開チーム/担当者向けの展開手順を作成する必要があります。
PHPのSubversionリポジトリでは、パスワードを含む構成ファイルはconfig.php.sample
としてチェックインされ、何を提供する必要があるかについてのヒントがあり、依存するスクリプトではconfig.php
が同じ場所に存在する必要があります。
リポジトリは、「偶発的な」追加やチェックインを回避するために、そのディレクトリのconfig.php
を無視するように構成されています。
ソースコードのパスワードに関する問題:
私が最もうまく機能することがわかったのは、デプロイメント固有のデータに適切なデフォルトとプレースホルダーを組み合わせて使用する構成をチェックインすることです。私たちのアプリは常に、変数のオーバーライドを許可するシステム構成を探します。これにより、実稼働マシンはそのデプロイメントに適した構成を持つことができます。
注:管理者として機能するときは、常にコードとは別に構成を管理します(正当な理由があります)。
パスワードを入力するには、ビルドスクリプト(私の場合はPhing)を使用するのが最善の方法であることがわかりました。
サンプル構成ファイルは、確かに、バージョン管理下に置きます。ただし、通常、サーバーアドレスやパスワードなどの実際のアクセスデータでは使用できません。もっと何かのような
#program.conf # #$ myprogのmysqlオプション # #SERVER_ADDR = 127.0.0.1 # SERVER_USER = mysql #SERVER_PASSWD = abcdef
メインの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'
パスワードやその他のアクセスの詳細(データベースなど)を含む重要な構成ファイルは常に除外します。これは純粋にベストプラクティスです。さらに、そのソース管理とバージョン管理に加えて、通常は複数のユーザーにサービスを提供し、すべてのユーザーが同じデータベースの詳細や同じサーバー構成(ドメインなど)で動作するわけではありません。この目的のために、構成ファイルは除外されたままにする必要があります。沢山。
適切なビルドプロセスがない場合、私はこの戦略を使用しています(PHPアプリの場合):
/etc/companyname
_その中に、2つのファイルを配置します。
_<?php // env.php
return 'prod';
_
_<?php // appname-prod.php
return array(
'db' => array( /* credentials */ ),
/* other Host-specific conf data */
);
_
PHPプロセスでのみ両方のファイルを読み取り可能にする
これで、アプリの構成ファイルは次のようになります。
_<?php // config.php
$env = (require "/etc/companyname/env.php");
$creds = (require "/etc/companyname/appname-{$env}.php");
_
これが適切な場所にあると、環境は使用される資格情報を定義し、事前構成された環境間でコードを移動できます(そして、_$env
_でいくつかのオプションを制御できます)。もちろん、これはサーバー環境変数を使用して実行できますが、これはa)セットアップが簡単で、b)サーバー上のすべてのスクリプトに資格情報を公開しません(phpinfo()
)。
PHPの外で読みやすくするために、資格情報ファイルをJSONなどにして、パフォーマンスのわずかな低下に耐えることができます(APCはそれらをキャッシュしません)。