Ubuntu18.04サーバーにNginxを使用してphpMyAdminをインストールして保護する方法
序章
多くのユーザーはMySQLのようなデータベースシステムの機能を必要としていますが、MySQLコマンドラインクライアントからのみシステムを操作するにはSQL言語に精通している必要があるため、一部のユーザーにとっては推奨されるインターフェイスではない場合があります。
phpMyAdmin は、ユーザーがPHP開発環境と並行して実行される直感的なWebインターフェイスを介してMySQLと対話できるように作成されました。 このガイドでは、Nginxサーバーの上にphpMyAdminをインストールする方法と、セキュリティを強化するためにサーバーを構成する方法について説明します。
注: phpMyAdminなどのソフトウェアを使用する場合、セキュリティ上の重要な考慮事項があります。phpMyAdminはデータベースサーバー上で実行され、データベースクレデンシャルを処理し、ユーザーがデータベースに対して任意のSQLクエリを簡単に実行できるようにするためです。 phpMyAdminは広く展開されているPHPアプリケーションであるため、攻撃の標的になることがよくあります。 十分な情報に基づいて決定できるように、このチュートリアルで実行できるセキュリティ対策について説明します。
前提条件
このガイドを開始する前に、次のものを利用できるようにする必要があります。
- Ubuntu 18.04 の初期サーバーセットアップガイドで説明されているように、
ufw
で保護されたLEMP(Linux、Nginx、MySQL、PHP)スタックを実行するUbuntu18.04サーバー。 サーバーをまだセットアップしていない場合は、 Ubuntu18.04へのLEMPスタックのインストールに関するガイドに従うことができます。 sudo
権限を持つ非rootユーザーとしてこのサーバーにアクセスします。
phpMyAdminはMySQLクレデンシャルを使用して認証を処理するため、サーバーとクライアント間の暗号化されたトラフィックを有効にするためにSSL/TLS証明書をインストールすることを強くお勧めします。 有効な証明書で構成された既存のドメインがない場合は、 Ubuntu18.04でLet’sEncryptを使用してNginxを保護する方法に関するこのガイドに従うことができます。
警告:サーバーにSSL / TLS証明書がインストールされておらず、続行する場合は、このガイドの手順5で説明されているように、SSHトンネルを介したアクセスの強制を検討してください。
これらの前提条件を満たしたら、ガイドの残りの部分に進むことができます。
ステップ1—phpMyAdminをインストールする
最初に行う必要があるのは、LEMPサーバーにphpMyAdminをインストールすることです。 この目標を達成するために、デフォルトのUbuntuリポジトリを使用します。
サーバーのパッケージインデックスを次のように更新することから始めましょう。
- sudo apt update
これで、phpMyAdminを次のコマンドでインストールできます。
- sudo apt install phpmyadmin
インストールプロセス中に、構成するWebサーバー(ApacheまたはLighttpd)を選択するように求められます。 NginxをWebサーバーとして使用しているため、ここで選択するべきではありません。 tab
、OK
の順に押して、次の手順に進みます。
次に、アプリケーションデータベースの構成にdbconfig-common
を使用するかどうかを確認するメッセージが表示されます。 Yes
を選択します。 これにより、phpMyAdminの内部データベースと管理ユーザーが設定されます。 phpmyadminMySQLユーザーの新しいパスワードを定義するように求められます。 空白のままにして、phpMyAdminにランダムにパスワードを作成させることもできます。
これでインストールは終了です。 Nginx WebサーバーがphpMyAdminファイルを正しく検索して提供するには、インストールファイルからNginxのドキュメントルートディレクトリへのシンボリックリンクを作成する必要があります。
- sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin
これで、phpMyAdminのインストールが機能します。 インターフェイスにアクセスするには、サーバーのドメイン名またはパブリックIPアドレスに移動し、続いてWebブラウザーで/phpmyadmin
に移動します。
https://server_domain_or_IP/phpmyadmin
前述のように、phpMyAdminはMySQLクレデンシャルを使用して認証を処理します。つまり、コンソールまたはAPIを介してデータベースに接続するために通常使用するのと同じユーザー名とパスワードを使用する必要があります。 MySQLユーザーの作成についてサポートが必要な場合は、SQLデータベースの管理方法に関するこのガイドを確認してください。
注: root MySQLユーザーとしてphpMyAdminにログインすることは、重大なセキュリティリスクを伴うためお勧めできません。 このガイドの次のステップで、 rootloginを無効にする方法を説明します。
この時点で、phpMyAdminのインストールは完全に機能しているはずです。 ただし、Webインターフェイスをインストールすることにより、MySQLデータベースサーバーを外部に公開しました。 phpMyAdminの人気と、phpMyAdminがアクセスを提供する可能性のある大量のデータのために、このようなインストールは攻撃の一般的なターゲットです。 このガイドの次のセクションでは、phpMyAdminのインストールをより安全にするためのいくつかの異なる方法を紹介します。
ステップ2—phpMyAdminのデフォルトの場所を変更する
phpMyAdminのインストールを保護するための最も基本的な方法の1つは、見つけにくくすることです。 ボットは、 phpmyadmin 、 pma 、 admin 、mysqlなどの一般的なパスをスキャンします。 インターフェイスのURLを/phpmyadmin
から非標準のものに変更すると、自動スクリプトがphpMyAdminのインストールを見つけてブルートフォース攻撃を試みることがはるかに困難になります。
phpMyAdminのインストールで、実際のアプリケーションファイルが配置されている/usr/share/phpmyadmin
を指すシンボリックリンクを作成しました。 phpMyAdminのインターフェイスURLを変更するには、このシンボリックリンクの名前を変更します。
まず、Nginxドキュメントのルートディレクトリに移動し、そこに含まれるファイルを一覧表示して、行う変更をよりよく理解しましょう。
- cd /var/www/html/
- ls -l
次の出力が表示されます。
Outputtotal 8
-rw-r--r-- 1 root root 612 Apr 8 13:30 index.nginx-debian.html
lrwxrwxrwx 1 root root 21 Apr 8 15:36 phpmyadmin -> /usr/share/phpmyadmin
出力は、このディレクトリにphpmyadmin
というシンボリックリンクがあることを示しています。 このリンク名は任意の名前に変更できます。 これにより、phpMyAdminのアクセスURLが変更され、一般的なエンドポイント名を検索するようにハードコードされたボットからエンドポイントを隠すことができます。
エンドポイントの目的をわかりにくくする名前を選択してください。 このガイドでは、エンドポイントに/nothingtosee
という名前を付けますが、は別の名前を選択する必要があります。 これを実現するために、リンクの名前を変更します。
- sudo mv phpmyadmin nothingtosee
- ls -l
上記のコマンドを実行すると、次の出力が表示されます。
Outputtotal 8
-rw-r--r-- 1 root root 612 Apr 8 13:30 index.nginx-debian.html
lrwxrwxrwx 1 root root 21 Apr 8 15:36 nothingtosee -> /usr/share/phpmyadmin
これで、古いURLにアクセスすると、404エラーが発生します。
https://server_domain_or_IP/phpmyadmin
これで、phpMyAdminインターフェイスが、構成したばかりの新しいURLで使用できるようになります。
https://server_domain_or_IP/nothingtosee
サーバー上のphpMyAdminの実際の場所を難読化することで、自動スキャンや手動のブルートフォース攻撃からインターフェースを保護します。
手順3—ルートログインを無効にする
MySQLおよび通常のLinuxシステムでは、 root アカウントは、システムへの無制限のアクセス権を持つ特別な管理アカウントです。 特権アカウントであることに加えて、それは既知のログイン名であり、ブルートフォース攻撃の明らかな標的になります。 リスクを最小限に抑えるために、ユーザーrootからのログイン試行を拒否するようにphpMyAdminを構成します。 このように、ユーザー root に有効な資格情報を提供しても、「アクセスが拒否されました」というエラーが発生し、ログインが許可されません。
dbconfig-common
を使用してphpMyAdmin設定を構成および保存することを選択したため、現在、デフォルトの構成がデータベースに保存されています。 カスタム設定を定義するには、新しいconfig.inc.php
ファイルを作成する必要があります。
phpMyAdminのPHPファイルは/usr/share/phpmyadmin
内にありますが、アプリケーションは/etc/phpmyadmin
にある構成ファイルを使用します。 /etc/phpmyadmin/conf.d
内に新しいカスタム設定ファイルを作成し、pma_secure.php
という名前を付けます。
- sudo nano /etc/phpmyadmin/conf.d/pma_secure.php
次の構成ファイルには、パスワードなしのログイン(AllowNoPassword
をfalse
に設定)およびルートログイン(AllowRoot
をfalse
に設定)を無効にするために必要な設定が含まれています。
<?php
# PhpMyAdmin Settings
# This should be set to a random string of at least 32 chars
$cfg['blowfish_secret'] = '3!#32@3sa(+=_4?),5XP_:U%%8\34sdfSdg43yH#{o';
$i=0;
$i++;
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['AllowNoPassword'] = false;
$cfg['Servers'][$i]['AllowRoot'] = false;
?>
編集が終わったら、CTRL
+ X
、y
を押して変更を確認し、ENTER
を押してファイルを保存します。 変更は自動的に適用されます。 ここでログインページをリロードしてrootとしてログインしようとすると、 AccessDeniedエラーが発生します。
phpMyAdminのインストールでrootログインが禁止されるようになりました。 このセキュリティ対策は、ブルートフォーススクリプトがサーバー上のrootデータベースパスワードを推測しようとするのをブロックします。 さらに、phpMyAdminのWebインターフェイスにアクセスするための特権の低いMySQLアカウントの使用を強制します。これは、それ自体が重要なセキュリティ慣行です。
##ステップ4—認証ゲートウェイの作成
phpMyAdminのインストールを通常とは異なる場所に隠すと、自動化されたボットがネットワークをスキャンするのを回避できる可能性がありますが、標的型攻撃に対しては役に立ちません。 アクセスが制限されたWebアプリケーションをより適切に保護するには、攻撃者がアプリケーションに到達する前に攻撃者を阻止する方が一般的に効果的です。 このようにすると、一般的なエクスプロイトやブルートフォース攻撃を使用してアクセス資格情報を推測することができなくなります。
phpMyAdminの特定のケースでは、ログインインターフェイスをロックしておくことがさらに重要です。 それを世界に公開し続けることで、攻撃者がデータベースのクレデンシャルを推測するためのブルートフォースプラットフォームを提供します。
phpMyAdminのインストールに認証のレイヤーを追加すると、セキュリティを強化できます。 ユーザーは、phpMyAdminログイン画面が表示される前に、HTTP認証プロンプトを通過する必要があります。 Nginxを含むほとんどのWebサーバーは、この機能をネイティブに提供します。
これを設定するには、最初に認証資格情報を保存するためのパスワードファイルを作成する必要があります。 Nginxでは、crypt()
関数を使用してパスワードを暗号化する必要があります。 すでにサーバーにインストールされているはずのOpenSSLスイートには、この機能が含まれています。
暗号化されたパスワードを作成するには、次のように入力します。
- openssl passwd
使用するパスワードを入力して確認するように求められます。 ユーティリティは、次のような暗号化されたバージョンのパスワードを表示します。
OutputO5az.RSPzd.HE
この値をコピーします。これは、作成する認証ファイルに貼り付ける必要があるためです。
次に、認証ファイルを作成します。 このファイルをpma_pass
と呼び、Nginx構成ディレクトリに配置します。
- sudo nano /etc/nginx/pma_pass
このファイルでは、使用するユーザー名、コロン(:
)、openssl passwd
ユーティリティから受け取ったパスワードの暗号化バージョンを指定します。
ユーザーにsammy
という名前を付けますが、別のユーザー名を選択する必要があります。 ファイルは次のようになります。
sammy:O5az.RSPzd.HE
完了したら、ファイルを保存して閉じます。
これで、Nginx構成ファイルを変更する準備が整いました。 このガイドでは、/etc/nginx/sites-available/example.com
にある構成ファイルを使用します。 phpMyAdminが現在ホストされているWebの場所に関連するNginx構成ファイルを使用する必要があります。 開始するには、テキストエディタでこのファイルを開きます。
- sudo nano /etc/nginx/sites-available/example.com
server
ブロックと、その中のlocation /
セクションを見つけます。 サーバー上のphpMyAdminの現在のパスと一致するように、このブロック内に new location
セクションを作成する必要があります。 このガイドでは、Webルートに対するphpMyAdminの場所は/nothingtosee
です。
server {
. . .
location / {
try_files $uri $uri/ =404;
}
location ^~ /nothingtosee/ {
# Settings for phpMyAdmin will go here
}
. . .
}
このブロック内で、2つの異なるディレクティブを設定する必要があります。認証プロンプトに表示されるメッセージを定義するauth_basic
と、作成したファイルを指すauth_basic_user_file
です。 。
server {
. . .
location ^~ /nothingtosee/ {
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/pma_pass;
}
. . .
}
最後に、このブロックには、新しい場所の定義の前に^~
セレクターがあることに注意してください。 これは、すべての.php
ファイルをキャッチする正規表現として通常定義されるPHPファイルのルールと一致する場合にNginxがアクセスルールをバイパスしないようにするためです。 Nginx構成ファイルでは、正規表現の定義は標準の場所の定義よりも優先されるため、場所の先頭で^~
セレクターを使用しない場合でも、ユーザーは次の方法で認証プロンプトをバイパスできます。ブラウザでhttp://example.com/nothingtosee/index.php
に移動します。
ロケーション定義の先頭にある^~
セレクターは、このロケーションに一致するものが見つかったときに他の一致を無視するようにNginxに指示します。 これは、/nothingtosee/
内のすべてのサブディレクトリまたはファイルがこのルールと一致することを意味します。 ただし、^~
セレクターを使用すると、PHPファイルを解析するための定義がスキップされるため、/nothingtosee
定義内に新しいPHPロケーションブロックを含める必要があります。 これにより、この場所にあるPHPファイルが適切に解析されます。そうでない場合は、ダウンロードコンテンツとしてブラウザーに送信されます。
これは、内部PHPロケーションブロックを追加した後の構成ファイルの外観です。
server {
. . .
location ^~ /nothingtosee/ {
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/pma_pass;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
. . .
}
nothingtosee を、phpMyAdminが見つかる実際のパスに置き換えることを忘れないでください。 PHP-FPMソケットファイルの場所も再確認する必要があります。これは、現在インストールされているPHPのバージョンによって異なります。 この例では、PHP7.2で有効なphp7.2-fpm.sock
を使用します。これは、デフォルトのapt
リポジトリを介してUbuntu18.04にインストールされるバージョンです。
完了したら、ファイルを保存して閉じます。 構成ファイルが有効かどうかを確認するには、次のコマンドを実行します。
- sudo nginx -t
次の出力が期待されます。
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
新しい認証ゲートをアクティブにするには、Webサーバーをリロードする必要があります。
- sudo systemctl reload nginx
これで、WebブラウザでphpMyAdmin URLにアクセスすると、pma_pass
ファイルに追加したユーザー名とパスワードの入力を求められるはずです。
https://server_domain_or_IP/nothingtosee
クレデンシャルを入力すると、標準のphpMyAdminログインページが表示されます。
注:ページの更新が機能しない場合、すでにphpMyAdminを使用している場合は、キャッシュをクリアするか、別のブラウザセッションを使用する必要があります。
このゲートウェイは、セキュリティの追加レイヤーを提供するだけでなく、MySQLログからスパム認証の試行を排除するのに役立ちます。
##ステップ5—暗号化されたトンネルを介したアクセスの設定(オプション)
セキュリティを強化するために、phpMyAdminのインストールを許可されたホストのみにロックダウンすることができます。 Nginx構成ファイルで許可されたホストをホワイトリストに設定できるため、リストにないIPアドレスからの要求はすべて拒否されます。
一部のユースケースではこの機能だけで十分な場合もありますが、主にほとんどの人が静的IPアドレスからインターネットにアクセスしないため、これが常に最良の長期的なソリューションであるとは限りません。 インターネットプロバイダーから新しいIPアドレスを取得するとすぐに、Nginx構成ファイルを新しいIPアドレスで更新するまで、phpMyAdminインターフェイスにアクセスできなくなります。
より堅牢で長期的なソリューションとして、IPベースのアクセス制御を使用して、ユーザーが承認済みIPアドレスまたはSSHトンネリング経由のローカルホスト。 これを設定する方法については、以下のセクションで説明します。
IPベースのアクセス制御とSSHトンネリングを組み合わせると、暗号化されたトンネルを使用してユーザーとサーバー間に安全なチャネルを提供するだけでなく、パブリックインターネット(許可されたIPを除く)からのアクセスを完全にブロックするため、セキュリティが大幅に向上します。
NginxでのIPベースのアクセス制御の設定
Nginxでは、IPベースのアクセス制御は、ディレクティブallow
およびdeny
を使用して、特定のサイトの対応するlocation
ブロックで定義できます。 たとえば、特定のホストからのリクエストのみを許可する場合は、保護するサイトに関連するlocation
ブロック内に、次の2行をこの順序で含める必要があります。
allow hostname_or_IP;
deny all;
必要な数のホストを許可できます。保護するサイトのそれぞれのlocation
ブロック内に、許可されたホスト/IPごとに1つのallow
行を含めるだけで済みます。 ディレクティブは、一致が見つかるか、deny all
ディレクティブが原因でリクエストが最終的に拒否されるまで、リストされているのと同じ順序で評価されます。
ここで、ローカルホストまたは現在のIPアドレスからのリクエストのみを許可するようにNginxを構成します。 まず、ローカルマシンがインターネットへの接続に使用している現在のパブリックIPアドレスを知る必要があります。 この情報を取得するにはさまざまな方法があります。 簡単にするために、ipinfo.ioによって提供されるサービスを使用します。 ブラウザでURLhttps://ipinfo.io/ip を開くか、ローカルマシンから次のコマンドを実行できます。
- curl https://ipinfo.io/ip
次のように、出力として単純なIPアドレスを取得する必要があります。
Output203.0.113.111
これが現在のpublicIPアドレスです。 phpMyAdminのロケーションブロックを構成して、ローカルホストに加えて、そのIPからのリクエストのみを許可します。 /etc/nginx/sites-available/example.com
内のphpMyAdminの構成ブロックをもう一度編集する必要があります。
選択したコマンドラインエディターを使用して、Nginx構成ファイルを開きます。
- sudo nano /etc/nginx/sites-available/example.com
現在の構成にはすでにアクセスルールがあるため、ディレクティブsatisfy all
を使用してIPベースのアクセス制御と組み合わせる必要があります。 このようにして、セキュリティを強化するために現在のHTTP認証プロンプトを保持できます。
編集が完了した後のphpMyAdminNginx構成は次のようになります。
server {
. . .
location ^~ /nothingtosee/ {
satisfy all; #requires both conditions
allow 203.0.113.111; #allow your IP
allow 127.0.0.1; #allow localhost via SSH tunnels
deny all; #deny all other sources
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/pma_pass;
location ~ \.php {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
}
. . .
}
nonethtosee を、phpMyAdminが見つかる実際のパスに置き換え、強調表示されたIPアドレスを現在のパブリックIPアドレスに置き換えることを忘れないでください。
完了したら、ファイルを保存して閉じます。 構成ファイルが有効かどうかを確認するには、次のコマンドを実行します。
- sudo nginx -t
次の出力が期待されます。
Outputnginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
次に、Webサーバーをリロードして、変更を有効にします。
- sudo systemctl reload nginx
IPアドレスは許可されたホストとして明示的にリストされているため、アクセスが妨げられることはありません。 phpMyAdminインストールにアクセスしようとしている他のユーザーは、403エラー(禁止)を受け取るようになりました。
https://server_domain_or_IP/nothingtosee
次のセクションでは、SSHトンネリングを使用してローカルリクエストを介してWebサーバーにアクセスする方法を説明します。 このようにして、IPアドレスが変更された場合でも、phpMyAdminのインターフェイスにアクセスできます。
暗号化されたトンネルを介したphpMyAdminへのアクセス
SSHトンネリングは、暗号化されたチャネルを介してネットワークトラフィックをリダイレクトする方法として機能します。 サーバーへのログインに使用するのと同様のssh
コマンドを実行することにより、ローカルマシンとそのサーバーの間に安全な「トンネル」を作成できます。 特定のローカルポートに着信するすべてのトラフィックは、インターネットに接続する前に、暗号化されたトンネルを介してリダイレクトされ、リモートサーバーをプロキシとして使用できるようになりました。 これは、VPN(仮想プライベートネットワーク)を使用した場合に発生することと似ていますが、SSHトンネリングの設定ははるかに簡単です。
SSHトンネリングを使用して、phpMyAdminを実行しているリモートWebサーバーにリクエストをプロキシします。 ローカルマシンとphpMyAdminがインストールされているサーバーの間にトンネルを作成することで、ローカルリクエストをリモートウェブサーバーにリダイレクトできます。さらに重要なのは、トラフィックが暗号化され、リクエストが[X261Xから送信されたかのようにNginxに到達することです。 ]localhost