サーバを構築する③ 〜Tomcatの設定〜

次は、Tomcatを入れたいと思います。主にこちらを参考にさせていただきます。

(3/15追記:全体的に整理して、サンプルサーブレットの実行、Basic認証の設定、ApacheとTomcatの連携について追記しました)

<Javaのインストール>

とりあえずまずjavaが入っているか確認。

$ java -version

すると、

java version "1.7.0_45"
OpenJDK Runtime Environment (rhel-2.4.3.3.el6-x86_64 u45-b15)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)

と出たので、とりあえず入っているっぽい。

<Tomcatのインストール>

Tomcatをインストールする前に、実行専用のユーザtomcatアカウントを作成する。Tomcatをroot権限で実行するのはよろしくないらしい。

# useradd -s /sbin/nologin tomcat

-sは、ユーザのログインシェルを指定するオプション。上記の設定にすることで、通常のログインではtomcatユーザを利用できないようにしている。なお、linuxではユーザは少なくとも一つのグループに所属する。現時点で、ユーザtomcatはグループtomcatに所属している(新たにgroupaddでtomcatを作る必要はない)。

次に、Tomcatの公式ページからパッケージをダウンロードする。Download -> Tomcat 7.0で、Coreの.tar.gzをとってくる。今の自分の場合は7.0.52。

$ wget http://ftp.kddilabs.jp/infosystems/apache/tomcat/tomcat-7/v7.0.52/bin/apache-tomcat-7.0.52.tar.gz

ダウンロードしたtar.gzファイルを展開し、/usr/localに移動。ディレクトリのオーナーをtomcatユーザに変更し、tomcatという名前でシンボリックリンクを作成しておく。

# tar xvzf apache-tomcat-7.0.52.tar.gz
# mv apache-tomcat-7.0.52 /usr/local
# cd /usr/local
# chown -R tomcat:tomcat apache-tomcat-7.0.52
# ln -s apache-tomcat-7.0.52 tomcat

chownに-Rオプションをつけると、ディレクトリ以下のファイルやディレクトリの所有者を一括して変更することができる。”tomcat:tomcat”で、所有者と所有グループを一度に変更している。

apache-tomcat-7.0.52の中身について少しだけ触れておくと、binディレクトリの中に、Tomcatの起動と停止に用いる複数のスクリプトが入っている。メインスクリプトはcalalina.sh (Windows用はcatalina.bat)で、Tomcatの起動、停止クラスを起動するためのjavaコマンドを実行する。

Tomcatの実行の前には、いくつか環境変数をセットする必要がある。少なくとも以下の二つはセットする

  • CATALINA_HOME
    • Tomcatのlibディレクトリやコマンド行スクリプトといった、Tomcatの静的な(読み込みのみ)ものが格納されているベースディレクトリを指定する。
  • JAVA_HOME
    • JREではなくJDKを入れている場合。Tomcatが使用するJavaのランタイムやJDKの場所を指定する。

サーバ全体の設定なので、/etc/profileに以下の二つを追記する。

export CATALINA_HOME=/usr/local/tomcat
export JAVA_HOME=/usr/lib/jvm/jre-1.7.0-openjdk.x86_64

最初、JAVA_HOMEで指定すべき場所がわからなかったが、readlinkコマンドでシンボリックコマンドを辿ることで解決。

# readlink $(readlink $(which java))

/etc/profileに書き込んだら、サーバを再起動するか、以下で環境変数を有効にする。

# source /etc/profile

環境変数が有効になっていれば、以下で設定したパスが表示される。

$ echo $JAVA_HOME

TomcatはデフォルトでHTTPサーバソケットのポート番号として8080番を使用するらしいので、/etc/sysconfig/iptablesを編集しておく。

-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 8080 -j ACCEPT

追記したら、

$ /etc/init.d/iptables restart

で有効化。そうしたら、とりあえず/usr/local/tomcatに移動して、

# bin/startup.sh

実行。これでTomcatが起動する。ブラウザで”http://192.168.xxx.xxx:8080/”にアクセスしたら、無事にTomcatのトップページが表示された(少しロード時間はかかったけれど)。Tomcatを停止するときは、

# bin/shutdown.sh

<Tomcatの自動起動設定>

sshdやhttpdのように、tomcatをサービスとして扱えるようにする。手順としては、

  1. 起動スクリプト(tomcat)作成
  2. 上記スクリプトファイルに実行権限を付与して/etc/init.d配下へ
  3. chkconfig –add tomcat で、サービスに追加
  4. chkconfig –level 3 tomcat on でランレベルを設定して、サーバ起動時に自動で立ち上がらせる

起動スクリプトは、こちらの方が書いて下さったものをそのまま利用させていただく。実行権限の変更は、

# chmod 755 tomcat

で。”chkconfig -add tomcat”で正しくサービスに登録されたかは、以下で確認。

# chkconfig --list | grep tomcat
tomcat             0:off    1:off    2:on    3:on    4:on    5:on    6:off

これで見ると、すでにランレベル3で自動的に立ち上がるようになっていた(拝借した起動スクリプトにそう書かれていた模様)ので、特になにもしない。

最後に、テスト。

# service tomcat start

最初これをやったら、

touch: cannot touch `/usr/local/tomcat/logs/catalina.out': 許可がありません
/usr/local/tomcat/bin/catalina.sh: line 385: /usr/local/tomcat/logs/catalina.out: 許可がありません

と出て起動失敗。ls -lで”/usr/local/tomcat/logs”以下のファイルを見ると、なぜか所有者と所有グループがrootになっていたので(後で作られた?)、改めて

# chown -R tomcat:tomcat apache-tomcat-7.0.52

で所有者と所有グループを変更。これで再度service tomcat startをすると、今度はOK。stopもrestartも問題なし。再起動後の自動立ち上がりも問題なし。

ちなみに、yumでインストールした場合には、このあたりのサービス登録まで全部自動でやってくれるので非常にラク。その場合はインストール先のフォルダが変わるので、適宜読み替える。

<Managerウェブアプリの設定>

WARファイルの配備(デプロイ)を簡単にできるように、Managerウェブアプリケーションを使えるようにする。

Managerウェブアプリケーションにログインできるようにするには、$CATALINA_HOME/conf/tomcat-users.xmlを編集して、既存ユーザエントリの最後に以下を追記する。

<role rolename=”manager-gui”/>
<user username=”hogehoge” password=”hugahuga” roles=”manager-gui”/>

Tomcat 7より、rolenemeに指定するのは”manager”ではなく”manager-gui”となる(他にもある)。ユーザ名とパスワードは適宜変える。編集できたら、Tomcatを再起動。その後ブラウザ上から”http://192.168.xxx.xxx:8080/manager/html”にアクセスして、先ほど設定したユーザ名とパスワードでManagerウェブアプリにアクセスできるか確認する。自分の場合はこれでOK。

<WARファイルの配置テスト>

テスト用に手っ取り早くWARファイルがほしいので、Webアプリ作成のフレームワーク「Struts」のサンプルアプリを使う。

ここからExamplesのstruts-1.3.10-apps.zipを落としてきて、解凍。先ほどセッティングしたTomcat Manager画面の”WARファイルの配備”で、解凍したサンプルの中にある”struts-blank-1.3.10.war”を選択すると、サーバ上に配備されてサーブレットが有効になる。サーバの中を覗いてみると、/usr/local/tomcat/webappsの中に、先ほどTomcat Manager画面からアップロードしたstruts-blank-1.3.10.warと、それから自動生成されたstruts-blank-1.3.10フォルダがあることがわかる。

ブラウザで”http://192.168.xxx.xxx:8080/struts-blank-1.3.10/”にアクセスし、Welcomeメッセージが表示されれば、WARファイルの配置のテストはOK。

<Basic認証の設定>

Tomcat単独でも、Apacheと同様にBasic認証をかけることができる。詳しくは以下を参照のこと。

自分でも動作を確認してみる。

まず、アプリのweb.xmlを編集する。先ほど配置(デプロイ)したサンプルの場合は、/usr/local/tomcat/webapps/struts-blank-1.3.10/WEB-INF/の中にある。<web-app>タグ内の、<welcom-file-list>タグの後に、以下を追記する。

  <security-constraint>
    <web-resource-collection>
        <web-resource-name>FOR_TEST</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>TEST_ROLE</role-name>
    </auth-constraint>
  </security-constraint>

  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>TEST_REALM</realm-name>
  </login-config>

  <security-role>
    <role-name>TEST_ROLE</role-name>
  </security-role>

<security-role>は管理用アプリケーションなどからロール名を参照するための項目のため、必須ではない。

続いて、/usr/local/tomcat/conf/tomca-user.xmlの編集。<tomca-users>タグ内に、以下を追記する。

<role rolename=”TEST_ROLE” />
<user username=”hogehoge” password=”hugahuga” roles=”TEST_ROLE” />

usernameとpasswordは適宜変える。roleを先ほどweb.xml内の<security-constraint><auth-constraint><role-name>タグで設定した値と同じにすることで関連付けを行う。

ここまでできたら、Tomcatを再起動。

$ sudo /etc/init.d/tomcat restart

先ほどと同じ”http://192.168.xxx.xxx:8080/struts-blank-1.3.10/”にアクセスし、認証要求と承認を確認。

<ApacheとTomcatの連携>

最後に、ApacheとTomcatを連携させる。具体的には、サーバへのアクセスはすべてApacheがhttps(443番ポート)で受けて、必要に応じてTomcatへ転送し処理結果を受け取る。つまり、Apacheをリパースプロキシとして動作させることになる。

前回、Apacheでhttpsのみ受け付けるようにしたので、それにTomcatをつなげる。/etc/httpd/conf/httpd.confを見ると、初期状態でmod_proxyモジュールはロードされるようになっているので、後はそれを転送するための記述を同ファイルに追加する。

<Location “/struts-blank-1.3.10″>
    ProxyPass ajp://localhost:8009/struts-blank-1.3.10
    ProxyPassReverse ajp://localhost:8009/struts-blank-1.3.10
</Location>

やること自体はこれだけだが、いくつか注意と説明が必要。

まず、Locationの引数(転送元)と、ProxyPassおよびProxyPassReverseの転送先の末尾を確実に一致させること。自分は最初Locationの引数(転送元)に”/struts-blank-1.3.10/”と記述し、転送先の方には”/struts-blank-1.3.10″と記述していたせいで、ブラウザアクセスした際に「リダイレクトループが発生している」と怒られた。”/(スラッシュ)”のあるなしはちゃんと揃えなくてはいけない。なお、同じ名前である必要はない模様。

次に、ajpと8009番ポートについて。ajpはApache Jserv Protocolの略で、TomcatをApacheと連携させる際に使うプロトコル。そして、ajpを用いた通信用に、Tomcatは8009番ポートを開けているらしい(これは、/usr/local/tomcat/conf/server.xmlを見ても確認できる)。TomcatはWebサーバーからAJPのリクエストを受け取り,そのリクエスト情報に基づいてServletを呼び出す、という流れとなる。とりあえず「そういうものなのか」というふうに理解しておく。

最後に「ProxyPassReverseはなぜ必要か?」ということ。それについては、このあたりが詳しそう。

どうやら、リダイレクトが発生したときに、クライアントが直接Tomcatにアクセスしてくることのないようにするために書いておかなくてはならないらしい。

追記したらApacheを再起動して、”https://192.168.xxx.xxx/struts-blank-1.3.10/”にアクセスする。ApacheのSSL設定による証明書の確認と、先ほどTomcatで設定したBasic認証の両方が要求されることを確認。

最後に、Tomcatの8080番ポートを閉じて、直接Tomcatへアクセスできないようにする。/usr/local/tomcat/conf/server.xmlの<Connector port=”8080″>で始まる部分をコメントアウトする。そして、Tomcatを再起動して、”http://192.168.xxx.xxx:8080/struts-blank-1.3.10/”でアクセス不可、”https://192.168.xxx.xxx/struts-blank-1.3.10/”のみでアクセス可となっていることを確認。

以上、おつかれさまでした。

Managerアプリの設定やApacheとの連携については、以下の書籍を参考にさせていただきました。

5年以上前の本になるので少し情報は古いところもありますが、それでも充分役に立ちます。ただ、価格がお高い。。。