2009-07-29
特定のサーブレットのみをIPでアクセス制限
今回は、Tomcatのみで実装されたWebAPサーバを使ったWebシステムにおいて、特定のサーブレットのみにアクセス制御をかけたい、という時の話。前提構成として、クライアントからサーバまでの経路上にL7レベルのフィルタを行う機器がなく、またApache-Tomcat連携構成への変更はせずTomcatのみの構成を変えないことが制約。さて、どうするか。
1つのアプリケーション全体へのアクセス制限であれば、オーソドックスにTomcatのRemoteAddrValveを使えば簡単に実装できる。が、この方式では、アクセス制限は特定のサーブレットだけではなくアプリケーション全体に制限がかかってしまいNG。参考までに、この場合の実装方法はこんな感じ。
${CATALINA_BASE}/conf/[Engine]/[Host]/context.xml <Context path="/app01/servlet01" docBase="/<ファイルシステム上のパス>" debug="0" privileged="true" > <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192.168.100.*" /> </Context>
次に試した方法は、サーブレットの実行に認証をかける方法。が、この場合には当然ながらBASIC/FORM/DIGEST認証などの認証方式で対話的に認証情報の入力を求められる。実は今回作業対象としているサーブレットは、バッチによる自動実行もしたかったので、ちょっと厳しい。対話型認証のため、インターネットユーザが認証をブルートフォースアタック攻撃(総当り)で突破できる可能性がある点も考慮し、この方法も残念ながらNG。
で、最後に考えたのが、Javaでアクセス制限の機能を自作(既にこの時点でインフラだけで対処することを諦めてますが)する方法。自作機能のソース(IpAddressFilter.java)はこんな感じ。
import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class IpAddressFilter implements Filter { private FilterConfig config; private String allow_ip; /* パスに対してアクセス制限を行う */ public final void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { final String ip_address = ((HttpServletRequest) request).getRemoteAddr(); if (!ip_address.startsWith(allow_ip)) { ((HttpServletResponse) response).sendError(HttpServletResponse.SC_FORBIDDEN); } else { chain.doFilter(request, response); } } public final void init(FilterConfig filterConfig) throws ServletException { this.config = filterConfig; this.allow_ip = config.getInitParameter("allowIP"); } public final void destroy() { this.config = null; this.allow_ip = null; } }
上記javaファイルをコンパイルし、生成された.classファイルを${CATALINA_BASE}/lib/に配備。あとはアプリのweb.xmlで当該サーブレットのFilter定義に設定すれば解決。以下の例では、docBaseが/usr/local/tomcat/webapps/app01/の場合の設定例。/usr/local/tomcat/webapps/app01/WEB-IN/web.xml
に以下の設定を追記する。
<filter> <filter-name>Allow Local Network Access</filter-name> <filter-class>IpAddressFilter</filter-class> <init-param> <param-name>allowIP</param-name> <param-value>192.168.100.</param-value> </init-param> </filter> <filter-mapping> <filter-name>Allow Local Network Access</filter-name> <servlet-name>TestServlet</servlet-name> </filter-mapping> <filter-mapping> <filter-name>Allow Local Network Access</filter-name> <url-pattern>/servlet01</url-pattern> --> </filter-mapping>
- 42 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GGLJ_jaJP173JP174&q=mysql+レプリケーション+マルチマスタ
- 40 http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla:ja:official&q=vmware+esxi+4.0+usb+dd+for+windows&btnG=検索
- 20 http://www.google.com/search?hl=ja&lr=lang_ja&ie=UTF-8&oe=UTF-8&q=Disabling+IPv4+packet+forwarding:++net.ipv4.ip_forward+=+0&num=50
- 12 http://www.google.co.jp/search?client=firefox-a&rls=org.mozilla:ja:official&channel=s&hl=ja&q=rpm+arch&lr=&btnG=Google+検索
- 10 http://74.125.153.132/search?q=cache:w2vruF2HNhMJ:d.hatena.ne.jp/shibainu55/20080810/1218464434+apache+mpm+確認&cd=2&hl=ja&ct=clnk&gl=jp
- 10 http://www.google.co.jp/search?hl=ja&lr=lang_ja&client=firefox-a&rls=org.mozilla:ja:official&hs=SGF&q=vmware+bonding&revid=476840476&ei=aaNwSq7dJMGMkAWM85nFBQ&sa=X&oi=revisions_inline&resnum=0&ct=broad-revision&cd=6
- 9 http://images.google.co.jp/imgres?imgurl=http://f.hatena.ne.jp/images/fotolife/s/shibainu55/20080812/20080812095231.png&imgrefurl=http://d.hatena.ne.jp/shibainu55/20080811/1218464434&usg=__Ya6sP8WU3GSvOtJOwSLUUX9e5Ck=&h=306&w=628&sz=33&hl=ja&start=222&tbn
- 9 http://www.google.co.jp/search?hl=ja&client=firefox-a&channel=s&rls=org.mozilla:ja:official&hs=Crh&q=ZABBIX 初期パスワード&btnG=検索&lr=
- 8 http://www.google.co.jp/search?q=centos+リポジトリ&sourceid=navclient-ff&ie=UTF-8&rlz=1B3GGGL_jaJP244JP244&aq=t
- 7 http://hatenadiary.g.hatena.ne.jp/keyword/表組みをつくる(表組み記法)