apache2.4 ファイルはどこにあっても適応される

以前の記事でWordPressのログイン画面の前にDigest認証をかけようとしました。

WordPressがインストールされているディレクトリの.htaccessに設定を書き込む方法を紹介しましが,他にもApacheの設定ファイル(httpd.conf)自体に書き込む方法があります。

httpd.confに<Files filename>設定</Files>と記述しますが,この場合,そのファイルがどこのディレクトリにあってもその設定が有効になることを知りませんでした。

<Files "private.html">
Require all denied
</Files>

この場合,private.htmlがどこにあってもアクセスを拒否することができます。パスとか指定しなくて良いんだ。

ただ,/var/web/dirの中のprivate.htmlのみのアクセスを制限したければ<Directory>と<Files>を組み合わせれば良い。

<Directory "/var/web/dir">
   <Files "private.html">
      Require all denied
   </Files>
</Directory>

参考にさせて頂いたサイト

Configuration Sections

Apache2.4 VirtualHostで特定のファイルにアクセス制限

以前の記事でwp-login.phpのみにDigest認証をかける作業を行いました。

通常であれば<Files>に設定を書いておけば有効になりますが,バーチャルホストで複数のWebサイトを運営している場合は訳が違います。

理由はわかりませんが,<Directory>や<Files>が何度設定しても有効になりません。結論,<Location>を使えば良いらしいです。

<Location "/wp-login.php">
   AuthUserFile /etc/httpd/conf/.digestpass    
   AuthName "Digest Auth"    
   AuthType Digest     
   <RequireAny>      
      Require valid-user       
      Require ip xxx.xxx.xxx.xxx
   </RequireAny>
</Location>     

例えば<Location “/private”>と指定すると,URLが/privateで始まるリンクすべてに適応される。以下は例。

http://yoursite.example.com/private,
http://yoursite.example.com/private123, http://yoursite.example.com/private/dir/file.html 

ただ疑問なのは,どうしてVirtualHostで設定すると<Directory>や<Files>の設定が有効にならないのだろうか。

というかそもそも<Directory>と<Location>の違いをよく理解できていない。(そのうち掘ります)

参考にさせていただいたサイト

Configuration Sections

WordPressのログイン画面にBasic/Digest認証をかける

WordPressのログイン画面に辿り着く前にもう一つの認証をつけてみます。完成図はこんな感じになります。

Basic/Digest認証を導入する理由

Basic/Digest認証の導入を検討するに至った理由はいくつかあるので紹介しましょう。

他人のサイトでログインを試せてしまう

特に初期設定から変更していない限り,WordPressのログイン画面は誰でも入れてしまいます。また,複数回ログインを失敗した端末のIPアドレスを拒否する設定を施していない場合,ログインを無限に試することができます。

試しにログインページにアクセスできるWordPressベースの有名サイトを並べてみました。(絶対にログインを試さないでください。)

このようにサイトのURLに + /wp-admin と付け加えるだけでログインページにリダイレクトされてしまう・・・。恐ろしい。

Basic認証ではなく,Digest認証をかけたい

wp-login.phpに認証をかけようと調べていると,Basic認証について紹介している記事は多くありましたが,Digest認証の設定を解説している記事はほとんど見つけられませんでした。

確かにサイトがTLS(SSL)に対応していればBasic認証で送られる情報も暗号化されるはず。つまり,盗聴されても中身は解読されにくいわけで,設定する手間を考えればBasic認証でも十分と考える人もいます。

(そもそもBasic認証もDigest認証も本認証の前に置く,おまけの認証でしかないので。)

しかし,私は雑記帳のネタにはなりそうだから,Digest認証を採用しました。

Basic/Digest認証の設定方法

勉強のためにBasic認証もDigest認証の方法も記録しておきます。流石に本番環境での設定をネタにはできないので,実験用の仮想環境で試した設定方法を載せますね。

まずはBasic認証,Digest認証共通の設定。次にそれぞれの設定を説明していきます。

実験環境

  • CentOS Linux release 7.7.1908 (仮想環境)
  • Apache/2.4.6
  • URL) http://192.168.3.9/blog

.htaccessの有効化

httpd.confの設定で無効になっている場合は有効にしてください。

#AllowOverride None
AllowOverride All

.htaccessはディレクトリ毎の設定をするファイルですが,httpd.confの設定を頻繁に変えたくなかったり,そもそも権限がない人はここに書かなければいけません。

[Basic認証 1] .htpasswdの作成

Basic認証に使うユーザ名とパスワードを保存したファイルを作成します。-cは新しいファイルを作成, -mはパスワードはmd5で保存するというオプションです。

$ cd /etc/httpd/conf
$ sudo htpasswd -c -m .htpasswd <ユーザ名>
 New password:<パスワード>
 Re-type new password:<パスワード>
 Adding password for user user

$ cat .htpasswd
 <ユーザ名>:$apr1$W0W01YDj$U6KIhTJBN54GXUVjzC2Hv1

[Basic認証 2] .htaccessの作成

WordPressのインストールされているディレクトリにある.htaccessを編集して以下を追加します。

<Files wp-login.php>
AuthType Basic
AuthName "Please enter your ID and password" 
AuthUserFile /etc/httpd/conf/.digestpass 
require valid-user
</Files> 

AuthNameは本来領域名ですが認証ボックスに表示されるだけなので何でもOKらしい。

[Digest認証 1].digestpassの作成

Digest認証に使うユーザ名とパスワードを保存したファイルを作成します。<領域名>は任意の文字列でOKです。

$ cd /etc/httpd/conf
$ sudo htdigest -c .digestpass "<領域名>" <ユーザ名>
 Adding password for user in realm <領域名>.
 New password:
 Re-type new password:

$ cat .digestpass
 <ユーザ名>:<領域名>:83b0c7f1eaa530b1252578d43bbc6c70

[Digest認証 2] .htaccessの作成

WordPressのインストールされているディレクトリにある.htaccessを編集して以下を追加します。

<Files wp-login.php>
AuthType Digest 
AuthName "<領域名>"
AuthUserFile /etc/httpd/conf/.digestpass 
require valid-user
</Files>

AuthNameは.digestpassを作成したときの領域名を入力してください。

[Digest認証 3] Digest認証モジュールの有効化

Digest認証を行うために,モジュールの有効化をしなければなりません。私の環境ではデフォルトで有効になってました。

/etc/httpd/conf/httpd.conf
/etc/httpd/conf.modules.d/00-base.conf

上記の設定ファイルどちらかにDigest認証に関する記述があるはずです。私の環境では下。

$ cat 00-base.conf | grep digest
 LoadModule auth_digest_module modules/mod_auth_digest.so

このモジュールがコメントアウトされている場合は外して保存してください。

Apache再起動

すべて設定し終わったらApacheを再起動します。問題がなければOKです。

$ sudo systemctl restart httpd

参考にさせて頂いたサイト

SSHのポート番号くらいは変更すべき

遠隔にあるサーバーの操作はSSHで行うことが一般的だと思います。

自宅にサーバーを立てたり,VPSをレンタルした時に最低限のセキュリティ対策としてSSH経由のrootログイン禁止や不要ポートを塞ぐなどをすると思います。

しかし,SSHのポート番号は初期設定の22番で使っていることが多いと思います。自分もそうでした。ちょっと手間ですが変えたほうがいいかもしれません。

中国IPからの攻撃?

自分はそのまま使っていて中国IPから突っつかれていました。

このブログはレンタルVPS上で運営しています。11月19日に契約してその9日後にログイン失敗の履歴を確認したところ6万回近いログイン失敗のログが残っていました。

# lastb

上記のコマンドでログインの失敗を表示できるので試して見ると面白いです。どのようなユーザ名でログイン試行されているかわかります。(以下,IPは隠しています)

他にもtest, guest, git, admin, ubuntuなどなど色々試されていました。

数が多いので1レコードずつ目は通していませんが,数種類のIPアドレスからのログイン試行でした。いくつか調べてみましたが中国に割り当てられているIPでした。

そもそもrootログイン禁止をしているし,自分が使うときは公開鍵で認証しているので大丈夫だと思います。ただ,気持ち悪いし,余計な負担がサーバーにかかってしまうことは防ぎたい。

結局ポートスキャンされれば,ポート番号の変更なんて意味はないかもしれないが気休め。