VirtualHost+mod_proxyで、LAN内のホストを外部へ公開する

目標

ザックリ書くと今はこんな感じです。

 インターネット
    │
 ┌──┴──┐
 │ ルーター │
 └──┬──┘
    ├──────┬─────┬──・・・
┌───┴───┐┌─┴─┐ ┌─┴─┐
│ WEBサーバー  ││ SVN  │ │  PC  │
└───────┘└───┘ └───┘

このSVNのホスト(実態はPCと同じパソコンだったりするわけ)でソース管理していたプログラムを他人にも手伝ってもらって楽したい
ということで、インターネットに放り出す(手伝ってもらえるかは、また別の話^^;)

なので、インターネット経由でSVNが見れるとOKって事
もちろん、今までどおりWEBサーバーは見れたままで

httpd.confを編集

# vi /etc/httpd/conf/httpd.conf
(下のほうにあるNameVirtualHost *:80のコメントを外す)
-#NameVirtualHost *:80
+ NameVirtualHost *:80

virtualhostの設定を追加

# vi /etc/httpd/conf.d/virtual.conf

<VirtualHost *:80>
    ServerName svn.<私のドメイン名>
    <IfModule mod_proxy.c>
        ProxyRequests Off
        ProxyPreserveHost On
        ProxyPass / http://<SVNのIP>/svn/
        ProxyPassReverse / http://<SVNのIP>/svn/
    </IfModule>
</VirtualHost>

<私のドメイン名>には、環境にあったものを設定してください。

で、再読み込みしてアクセスしてみる

# service httpd reload

svn.<私のドメイン名>にアクセス
OK
www.<私のドメイン名>にアクセス
って、svnと同じものが・・・
NGって、orz


もう一度Apacheドキュメントを読んでいたら

メインホストはなくなります

既にあるウェブサーバにバーチャルホストを追加する場合、 既存のウェブサーバに対しても ブロックを作らなければなりません。このバーチャルホストの ServerName と DocumentRoot は、グローバルな ServerName と DocumentRoot と同じものにします。また、このバーチャルホストを設定ファイルの中で 先頭に置いて、デフォルトホストとして動作するようにします。

なるほど
って事で、 NameVirtualHost *:80を生かしたhttpd.confに最低限の設定を追加

#vi /etc/httpd/conf/httpd.conf
(最終行に追加)
<VirtualHost *:80>
   ServerName www.<私のドメイン名>
   DocumentRoot /home/www/html/
</VirtualHost>

で、再度設定反映

# service httpd reload

svn.<私のドメイン名>にアクセス
OK
www.<私のドメイン名>にアクセス
OK
って事で、完了!!だと思ったのだけど、apacheのドキュメントに書かれている

このバーチャルホストを設定ファイルの中で 先頭に置いて、デフォルトホストとして動作するようにします

の一文が非常に気になる。
この設定のままだと、virtual.confの方が先に読めれている。というのは、「Include conf.d/*.conf」が存在するのはLoadModuleの直ぐ下、なのに、Virtualhostの設定はhttpd.confの最後なので、

<VirtualHost *:80>
    ServerName svn.<私のドメイン名>
    <IfModule mod_proxy.c>
        ProxyRequests Off
        ProxyPreserveHost On
        ProxyPass / http://<SVNのIP>/svn/
        ProxyPassReverse / http://<SVNのIP>/svn/
    </IfModule>
</VirtualHost>

の設定は、virtual.confを作るのではなく、httpd.confの一番最後に

<VirtualHost *:80>
   ServerName www.<私のドメイン名>
   DocumentRoot /home/www/html/
</VirtualHost>

<VirtualHost *:80>
    ServerName svn.<私のドメイン名>
    <IfModule mod_proxy.c>
        ProxyRequests Off
        ProxyPreserveHost On
        ProxyPass / http://<SVNのIP>/svn/
        ProxyPassReverse / http://<SVNのIP>/svn/
    </IfModule>
</VirtualHost>

このように書いておくほうが良いようです
でないと、ディフォルトはproxy側になっちゃってるのでどれにもマッチしない条件を記載するにはそちらに記載する必要が出てしまう。
しかも、VirtualHost増えたらどれが先頭だか分からなくなるよね(conf.d/*.confの読み込み順を意識すればわかるかもだけど・・・)、VirtualHostの設定に関しては、httpd.confに書いておくのが無難、という結論でよろしい?

認証をWEBサーバー側で行う

proxyで飛んでいるわけだから、Proxy側で認証すればよいんだけどアクセスの制限をWEBサーバー側でやりたい
別々にいろいろ設定するのは面倒だからねw

Apacheのドキュメント読んでたら数行追加で簡単に実現できた

<VirtualHost *:80>
   ServerName svn.<私のドメイン名>
   <IfModule mod_proxy.c>
      ProxyRequests Off
      ProxyPreserveHost On
      
      <Proxy *>
         AuthName "Access Password"
         AuthUserFile /var/www/.htpasswd
         AuthType Basic
         Require valid-user
      </Proxy>
      
      ProxyPass / http://<SVNのIP>/svn/
      ProxyPassReverse / http://<SVNのIP>/svn/
   </IfModule>
</VirtualHost>


まあ、こんな感じ、もちろんパスワードファイルを作っておかなくてはいけないので、

# htpasswd -c /var/www/.htpasswd <アクセスユーザーID>
New password: <パスワード>
Re-type new password: <パスワード>

って感じでよろしく