配置tomcat限制指定IP地址访问后端应用
1. 场景
后端存在N个tomcat实例,前端通过nginx反向代理和负载均衡。
tomcat1 tomcatN
| |
| |
-----------------
|
nginx
2. 需求
为了保护后端应用,tomcat实例只允许前端nginx服务器IP访问,其他任何地址的访问都被拒绝。
3. 实现
编辑${TOMCAT_HOME}/conf/server.xml,添加org.apache.catalina.valves.RemoteAddrValve配置,如下所示:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- SingleSignOn valve, share authentication between web applications Documentation at: /docs/config/valve.html --> <!-- <Valve className="org.apache.catalina.authenticator.SingleSignOn" /> --> <!-- Access log processes all example. Documentation at: /docs/config/valve.html Note: The pattern used is equivalent to using pattern="common" --> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <!-- 限制指定IP地址访问Tomcat --> <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127.0.0.1" deny=""/> </Host>
4. 原理
(1)概述
在tomcat中存在一个与容器关联的组件Valve,该组件用于处理request请求。源码注释为:
详见tomcat请求处理时序图:http://tomcat.apache.org/tomcat-8.5-doc/architecture/requestProcess/request-process.png。
因此,我们可以通过添加指定Valve实现,用于在处理request请求时实现相应功能。
例如:在这里通过在<Host>元素中添加org.apache.catalina.valves.RemoteAddrValve实现限制指定IP地址访问应用程序。
(2)Valve类图
(3)源码解读
org.apache.catalina.valves.RemoteAddrValve实现Valve处理request请求接口:
@Override public void invoke(Request request, Response response) throws IOException, ServletException { String property; if (addConnectorPort) { property = request.getRequest().getRemoteAddr() + ";" + request.getConnector().getPort(); } else { property = request.getRequest().getRemoteAddr(); } process(property, request, response); }
org.apache.catalina.valves.RequestFilterValve process实现:
protected void process(String property, Request request, Response response) throws IOException, ServletException { if (isAllowed(property)) { getNext().invoke(request, response); return; } if (getLog().isDebugEnabled()) { getLog().debug(sm.getString("requestFilterValve.deny", request.getRequestURI(), property)); } // Deny this request denyRequest(request, response); }
public boolean isAllowed(String property) { // Use local copies for thread safety Pattern deny = this.deny; Pattern allow = this.allow; // Check the deny patterns, if any if (deny != null && deny.matcher(property).matches()) { return false; } // Check the allow patterns, if any if (allow != null && allow.matcher(property).matches()) { return true; } // Allow if denies specified but not allows if (deny != null && allow == null) { return true; } // Deny this request return false; }
作者:编程随笔
出处:http://www.cnblogs.com/nuccch/
声明:本文版权归作者和博客园共有,欢迎转载,但请在文章页面明显位置给出原文连接。