開いているPostgreSQLポートを保護する方法


29

だから、これは状況です。顧客が自分のPostgreSQLデータベースにアクセスできる世界へのTCPポート5432を開く必要があるようです。

明らかな理由から、最後の最後の手段としてのみ、「いいえ」とは言えません。

最大の問題は何ですか?インフラストラクチャを守るにはどうすればよいですか?

とにかく:なぜそれを世界に公開すべきではないのですか?おそらく、20年前のメンテナンスされていないFTPサーバーよりも安全だと思います。

PS VPNは大丈夫ではありません。いくつかの暗号化は、多分(私は彼に、JDBC接続URL与えることができれば動作しますが)。


4
SSHトンネルはオプションではありませんか?このハウツー記事では、実際にPostgreSQLを例として使用しています。簡単に接続できるように、事前に構成されたSSHクライアントを顧客に提供できます。
ルシファーサム14

@LuciferSamいいえ。dbは、社内で開発された約100の企業マシンのJavaアプリケーションによって使用されます。それらを設定する唯一の方法は、localdb管理にjdbc接続URLを与えることです。他の方法は非常に問題が多いです。

@milkmanアプリは何をしますか?代わりにRESTfulサーバーを照会できますか?もちろん、RESTにSQLを渡すことは何も得られませんが、...それはCRUDであると仮定すると
tedder42

@ tedder42これは、私たちもホストしているユーザーCMSのデータベースを操作します。ソースを変更する権限がありません。

回答:


41

SSLを要求し、SELinuxをオンにし、ログを監視し、現在のPostgreSQLバージョン使用します

サーバ側

SSLが必要

postgresql.confセットssl=onし、(ドキュメントとのコメントを参照してくださいあなたのキーファイルとcertfileには適切にインストールされていることを確認してくださいpostgresql.conf)。

クライアントで特別な設定をせずに、クライアントに証明書を信頼してもらいたい場合は、CAから証明書を購入する必要があります。

pg_hba.confような使用何か:

hostssl theuser thedatabase 1.2.3.4/32 md5

...おそらくユーザーおよび/またはデータベースの「すべて」を使用し、おそらくより広いソースIPアドレスフィルターを使用します。

ログインできるユーザーを制限し、リモートスーパーユーザーのログインを拒否する

可能であれば、ユーザーに「すべて」を許可しないでください。スーパーユーザーのログインの必要性を避けることができれば、リモートでのログインを許可したくありません。

ユーザーの権利を制限する

ログインできるユーザーの権利を制限します。ユーザーCREATEDBまたはCREATEUSER権利を与えないでください。

REVOKEすべてのデータベースのCONNECT権限を取得してからPUBLIC、そのデータベースにアクセスできるはずのユーザー/ロールのみに戻します。(ユーザーをロールにグループ化し、個々のユーザーに直接ではなく、ロールに権限を付与します)。

リモートアクセスを持つユーザーは、必要なDBにのみ接続でき、実際に必要なスキーマ、テーブル、および列に対する権限のみを持つようにしてください。これはローカルユーザーにとっても良い習慣であり、賢明なセキュリティです。

クライアントのセットアップ

PgJDBCで、パラメーターを渡しますssl=true

JDBCドライバーにSSL接続を試行して確立するよう指示するには、接続URLパラメーターssl = trueを追加する必要があります。

...サーバー証明書をクライアントのトラストストアにインストールするか、ユーザーに証明書をインストールさせたくない場合は、Javaの組み込みトラストストアにあるCAのいずれかによって信頼されているサーバー証明書を使用します。

進行中のアクション

今、あなたが最新のPostgreSQLを維持することを確認してください。PostgreSQLには事前認証セキュリティホールが2つしかありませんでしたが、それはゼロ以上であるため、最新の状態を維持してください。とにかく、バグ修正は素晴らしいものです。

アクセスする必要がないことがわかっている大きなネットブロック/リージョンがある場合は、前にファイアウォールを追加します。

接続と切断をログに記録します(を参照postgresql.conf)。実用的な場合はクエリをログに記録します。実用的な場合は、侵入検知システムまたはfail2banなどを前に実行します。postgresを使用したfail2banについては、ここに便利な方法があります

ログファイルを監視します。

ボーナスパラノイア

考慮すべき追加手順...

クライアント証明書が必要

必要に応じpg_hba.confて、サーバーが信頼するX.509クライアント証明書の提示をクライアントに要求するために使用することもできます。サーバー証明書と同じCAを使用する必要はありません。homebrewopenssl CAでこれを行うことができます。JDBCユーザーは、クライアント証明書をJavaキーストアにインポートする必要がkeytoolあり、場合によってはJavaをキーストアでポイントするようにいくつかのJSSEシステムプロパティを構成する必要があるため、完全に透過的ではありません。

インスタンスを隔離する

本当に妄想的になりたい場合は、別のコンテナ/ VMで、または少なくとも別のユーザーアカウントで、必要なデータベースだけで、クライアントのインスタンスを実行します。

そうすれば、PostgreSQLインスタンスが危険にさらされても、それ以上進むことはありません。

SELinuxを使用する

私はこれを言う必要はありませんが、...

RHEL 6または7などのSELinuxをサポートするマシンを実行します。SELinuxをオフにしたり、permissiveモードに設定したりしないでください。強制モードのままにします。

デフォルト以外のポートを使用する

あいまいさだけによるセキュリティは愚かです。賢明なことをやったら、少しあいまいなセキュリティを使用しても、おそらく問題はありません。

デフォルト以外のポートでPgを実行して、自動化された攻撃者の生活を少し難しくします。

前にプロキシを配置する

PostgreSQLの前でPgBouncerまたはPgPool-IIを実行して、接続プールおよびプロキシとして動作させることもできます。そうすれば、実際のデータベースホストではなく、プロキシにSSLを処理させることができます。プロキシは、別のVMまたはマシン上に配置できます。

通常、接続プーリングプロキシの使用は、クライアントアプリケーションに既にプールが組み込まれていない限り、PostgreSQLでは一般的に良いアイデアです。ほとんどのJavaアプリケーションサーバー、Railsなどには、組み込みのプーリングがあります。それでも、サーバー側のプーリングプロキシは最悪の場合無害です。


3
クライアントが静的な$ IPを持っている場合は、ファイアウォールを通過して$ portのみに許可します。
user9517はGoFundMonicaを14

どうもありがとうございました!Pgjdbcにはこのパラメーターがありますが、私は彼にjdbc接続URLのみを与えることができ、それが彼のJavaアプリケーションで動作するかどうかはわかりません(専有的で、紛れもない)。OK、そうでない場合、私は新しい質問をします。詳細な回答ありがとうございます!

1
@lesto実際、VPNを公開すると、1つの制限されたサービスに比べて攻撃対象が大幅に増えると思います。人々は、VPNがリモートマシン上のマルウェアの攻撃チャネルになり、すべての境界セキュリティを突き抜けてネットワークの根幹に到達することを忘れています。インターネットホストと同じくらい有毒であるとして扱うDMZに接続する場合にのみ、それらが受け入れられると思います。
クレイグリンガー14

1
@CraigRinger保護の残りの部分を削除するのではなく、サービスをVPNにカプセル化することを言っている
レスト14

1
@lesto確かに、多くの管理者が残念ながらそうするように、VPNがMagic Security Sauceとして扱われない場合、VPNは有用な追加レイヤーになる可能性があります。
クレイグリンガー14

2

クレイグスの印象的なアクションプランの簡単な拡張:

おそらく、ユーザーは比較的小さなネットワークプロバイダーのセット(たとえば、移動中のモバイルネットワークプロバイダー、自宅からのケーブルネットワーク、職場からの発信IPなど)のみを使用しています。

ほとんどのネットワークプロバイダーには多くのIPがありますが、実際には多くのサブネットはありません。したがって、顧客が使用するネットワークセグメントへのpostgresqlアクセスを制限するiptablesフィルターを指定できます。これにより、ランダムに選択されたネットのトラブルソースの攻撃の可能性が大幅に減少しました。

簡単なサポートシナリオ:

  1. 顧客から「ログインできません」と呼ばれます。
  2. tcpdump -i eth0 -p tcp port 5432彼がどこから来たのか、あなたは命令で知ることができます。
  3. whois 1.2.3.4使用すると、このIPで使用されるIPアドレスを取得できます。例えば、それはすることができます1.2.3.0/24
  4. iptables -A INPUT -s 1.2.3.0/24 -p tcp --dport 5432 -j ACCEPT(またはいくつかの類似した)あなたは彼の新しいサブネットとのTCP接続を許可します。

uif永続的で直感的な宣言可能なiptablesルールセットを提供できる非常に優れたperlスクリプトがあります。(「uif iptables」のGoogle)。


1
興味深いアイデアですが、それは少し壊れやすいように聞こえます。
nishantjr

@nishantjrもちろん、それはスタンドアロンのソリューションではなく、物事を改善する可能性があるだけです。
ペテルはモニカを復活させると14

より実用的なアプローチは、この例を参照くださいする方法については、ホワイトリストの個々のISPおよび/または国にあるかもしれないstackoverflow.com/questions/16617607/...
ヨシップ・ロダン

1

上にリンクされたHOWTOに基づいたPostgreSQLの非常に簡単なFail2ban構成を以下に示しますが、Ubuntuパッケージで実際に動作するように微調整し、別のエラー状態をキャッチし、さまざまなデバッグメッセージをスキップして迅速にします:

/etc/fail2ban/filter.d/local-postgresql.conf

[Definition]

failregex = <HOST>\(\d+\) FATAL:  password authentication failed for .+$
            <HOST>\(\d+\) FATAL:  no pg_hba.conf entry for host .+$

ignoreregex = duration:

/etc/fail2ban/jail.d/local-postgresql.conf

[local-postgresql]
enabled  = true
filter   = local-postgresql
action   = iptables[name=PostgreSQL, port=5432, protocol=tcp]
           sendmail-whois[name=PostgreSQL, dest=root@localhost]
logpath  = /var/log/postgresql/postgresql-9.3-main.log
maxretry = 3

1

Fail2banは強力なツールですが、フィルターがそのまま機能することを信頼しないでください。failregexツールを使用してフィルターをテストし、引用符をエスケープすることを忘れないでください(つまり、「admin」は「admin」になります)。例として、私の/etc/log/postgresql/postgresql-9.3-main.logから次のフィルターfailregex行をテストしてもうまくいきませんでした。

fail2ban-regex '2016-09-20 14:30:09 PDT FATAL:  password authentication failed for user "admin"' '<HOST>\(\d+\) FATAL:  password authentication failed for .+$'

上記は私に与えた

Failregex:合計0

ログ形式に合わせてfailregexを更新する必要がありました。

fail2ban-regex '2016-09-20 14:30:09 PDT FATAL:  password authentication failed for user "admin"' 'FATAL:  password authentication failed for user \"<HOST>\"'

これは私に良い結果をもたらしました。

Failregex:合計1

fail2ban-regexテストは、ログファイル全体に実装することもできます。

fail2ban-regex /var/log/postgresql/postgresql-9.3-main.log /etc/fail2ban/filter.d/postgresql.local

上記により、更新されたfailregexで次の肯定的な結果が得られました。

Failregex:合計169

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.