Top Description Fields Constructors Methods
org.apache.catalina.valves

public Class RemoteIpValve

extends ValveBase
Class Inheritance
Imports
java.io.IOException, java.net.InetAddress, .UnknownHostException, java.util.ArrayDeque, .Deque, .Enumeration, java.util.regex.Pattern, jakarta.servlet.ServletException, org.apache.catalina.AccessLog, .Globals, org.apache.catalina.connector.Request, .Response, org.apache.juli.logging.Log, .LogFactory, org.apache.tomcat.util.buf.StringUtils, org.apache.tomcat.util.http.MimeHeaders, org.apache.tomcat.util.http.parser.Host

Tomcat port of mod_remoteip, this valve replaces the apparent client remote IP address and hostname for the request with the IP address list presented by a proxy or a load balancer via a request headers (e.g. "X-Forwarded-For").

Another feature of this valve is to replace the apparent scheme (http/https) and server port with the scheme presented by a proxy or a load balancer via a request header (e.g. "X-Forwarded-Proto").

This valve proceeds as follows:

If the incoming request.getRemoteAddr() matches the valve's list of internal or trusted proxies:

Configuration parameters
RemoteIpValve property Description Equivalent mod_remoteip directive Format Default Value
remoteIpHeader Name of the Http Header read by this valve that holds the list of traversed IP addresses starting from the requesting client RemoteIPHeader Compliant http header name x-forwarded-for
internalProxies Regular expression that matches the IP addresses of internal proxies. If they appear in the remoteIpHeader value, they will be trusted and will not appear in the proxiesHeader value RemoteIPInternalProxy Regular expression (in the syntax supported by java.util.regex) 10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}| 169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}| 100\.6[4-9]{1}\.\d{1,3}\.\d{1,3}|100\.[7-9]{1}\d{1}\.\d{1,3}\.\d{1,3}| 100\.1[0-1]{1}\d{1}\.\d{1,3}\.\d{1,3}|100\.12[0-7]{1}\.\d{1,3}\.\d{1,3}| 172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}| 172\.3[0-1]{1}\.\d{1,3}\.\d{1,3}| 0:0:0:0:0:0:0:1|::1
By default, 10/8, 192.168/16, 169.254/16, 127/8, 100.64/10, 172.16/12, and ::1 are allowed.
proxiesHeader Name of the http header created by this valve to hold the list of proxies that have been processed in the incoming remoteIpHeader proxiesHeader Compliant http header name x-forwarded-by
trustedProxies Regular expression that matches the IP addresses of trusted proxies. If they appear in the remoteIpHeader value, they will be trusted and will appear in the proxiesHeader value RemoteIPTrustedProxy Regular expression (in the syntax supported by java.util.regex)  
protocolHeader Name of the http header read by this valve that holds the flag that this request N/A Compliant http header name like X-Forwarded-Proto, X-Forwarded-Ssl or Front-End-Https X-Forwarded-Proto
protocolHeaderHttpsValue Value of the protocolHeader to indicate that it is an Https request N/A String like https or ON https
httpServerPort Value returned by jakarta.servlet.ServletRequest#getServerPort() when the protocolHeader indicates http protocol N/A integer 80
httpsServerPort Value returned by jakarta.servlet.ServletRequest#getServerPort() when the protocolHeader indicates https protocol N/A integer 443

This Valve may be attached to any Container, depending on the granularity of the filtering you wish to perform.

Regular expression vs. IP address blocks: mod_remoteip allows to use address blocks (e.g. 192.168/16) to configure RemoteIPInternalProxy and RemoteIPTrustedProxy ; as Tomcat doesn't have a library similar to apr_ipsubnet_test, RemoteIpValve uses regular expression to configure internalProxies and trustedProxies in the same fashion as RequestFilterValve does.


Sample with internal proxies

RemoteIpValve configuration:

<Valve className="org.apache.catalina.valves.RemoteIpValve" internalProxies="192\.168\.0\.10|192\.168\.0\.11" remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by" protocolHeader="x-forwarded-proto" />
Request Values
property Value Before RemoteIpValve Value After RemoteIpValve
request.remoteAddr 192.168.0.10 140.211.11.130
request.header['x-forwarded-for'] 140.211.11.130, 192.168.0.10 null
request.header['x-forwarded-by'] null null
request.header['x-forwarded-proto'] https https
request.scheme http https
request.secure false true
request.serverPort 80 443

Note : x-forwarded-by header is null because only internal proxies as been traversed by the request. x-forwarded-by is null because all the proxies are trusted or internal.


Sample with trusted proxies

RemoteIpValve configuration:

<Valve className="org.apache.catalina.valves.RemoteIpValve" internalProxies="192\.168\.0\.10|192\.168\.0\.11" remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by" trustedProxies="proxy1|proxy2" />
Request Values
property Value Before RemoteIpValve Value After RemoteIpValve
request.remoteAddr 192.168.0.10 140.211.11.130
request.header['x-forwarded-for'] 140.211.11.130, proxy1, proxy2 null
request.header['x-forwarded-by'] null proxy1, proxy2

Note : proxy1 and proxy2 are both trusted proxies that come in x-forwarded-for header, they both are migrated in x-forwarded-by header. x-forwarded-by is null because all the proxies are trusted or internal.


Sample with internal and trusted proxies

RemoteIpValve configuration:

<Valve className="org.apache.catalina.valves.RemoteIpValve" internalProxies="192\.168\.0\.10|192\.168\.0\.11" remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by" trustedProxies="proxy1|proxy2" />
Request Values
property Value Before RemoteIpValve Value After RemoteIpValve
request.remoteAddr 192.168.0.10 140.211.11.130
request.header['x-forwarded-for'] 140.211.11.130, proxy1, proxy2, 192.168.0.10 null
request.header['x-forwarded-by'] null proxy1, proxy2

Note : proxy1 and proxy2 are both trusted proxies that come in x-forwarded-for header, they both are migrated in x-forwarded-by header. As 192.168.0.10 is an internal proxy, it does not appear in x-forwarded-by. x-forwarded-by is null because all the proxies are trusted or internal.


Sample with an untrusted proxy

RemoteIpValve configuration:

<Valve className="org.apache.catalina.valves.RemoteIpValve" internalProxies="192\.168\.0\.10|192\.168\.0\.11" remoteIpHeader="x-forwarded-for" proxiesHeader="x-forwarded-by" trustedProxies="proxy1|proxy2" />
Request Values
property Value Before RemoteIpValve Value After RemoteIpValve
request.remoteAddr 192.168.0.10 untrusted-proxy
request.header['x-forwarded-for'] 140.211.11.130, untrusted-proxy, proxy1 140.211.11.130
request.header['x-forwarded-by'] null proxy1

Note : x-forwarded-by holds the trusted proxy proxy1. x-forwarded-by holds 140.211.11.130 because untrusted-proxy is not trusted and thus, we cannot trust that untrusted-proxy is the actual remote ip. request.remoteAddr is untrusted-proxy that is an IP verified by proxy1.

Field Summary

Modifier and TypeField and Description
private boolean
private boolean
private static final Pattern
commaSeparatedValuesPattern

Pattern for a comma delimited string that support whitespace characters

private String
private int
private int
private Pattern
private static final Log
private String
private String
private String
private String
private String
private boolean
private Pattern
Inherited from org.apache.catalina.valves.ValveBase:
asyncSupportedcontainercontainerLognextsm

Constructor Summary

AccessConstructor and Description
public
RemoteIpValve()

Default constructor that ensures ValveBase#ValveBase(boolean) is called with true.

Method Summary

Modifier and TypeMethod and Description
protected static String[]

Returns:

array of String (non null)
commaDelimitedListToStringArray
(String
The string to convert
commaDelimitedStrings
)

Convert a given comma delimited String into an array of String

public String

Returns:

The HTTP header name
getHostHeader
()

Obtain the name of the HTTP header used to override the value returned by Request#getServerName() and (optionally depending on {link isChangeLocalName() Request#getLocalName().

public int
public int
public String

Returns:

Regular expression that defines the internal proxies
getInternalProxies
()

public String

Returns:

The HTTP header name
getPortHeader
()

Obtain the name of the HTTP header used to override the value returned by Request#getServerPort() and (optionally depending on {link isChangeLocalPort() Request#getLocalPort().

public String

Returns:

the protocol header (e.g. "X-Forwarded-Proto")
getProtocolHeader
()

public String

Returns:

the value of the protocol header for incoming https request (e.g. "https")
getProtocolHeaderHttpsValue
()

public String

Returns:

the proxies header name (e.g. "X-Forwarded-By")
getProxiesHeader
()

public String

Returns:

the remote IP header name (e.g. "X-Forwarded-For")
getRemoteIpHeader
()

public boolean

Returns:

true if the attributes will be logged, otherwise false
getRequestAttributesEnabled
()

public String

Returns:

Regular expression that defines the trusted proxies
getTrustedProxies
()

public void
invoke(Request
The servlet request to be processed
request
,
Response
The servlet response to be created
response
)

Implements org.apache.catalina.Valve.invoke.

Perform request processing as required by this Valve.

public boolean
public boolean
private boolean
public void
setChangeLocalName(boolean changeLocalName)

public void
setChangeLocalPort(boolean changeLocalPort)

public void
setHostHeader(String
The HTTP header name
hostHeader
)

Set the name of the HTTP header used to override the value returned by Request#getServerName() and (optionally depending on {link isChangeLocalName() Request#getLocalName().

public void
setHttpServerPort(int
The server port
httpServerPort
)

Server Port value if the protocolHeader is not null and does not indicate HTTP

Default value : 80

public void
setHttpsServerPort(int
The server port
httpsServerPort
)

Server Port value if the protocolHeader indicates HTTPS

Default value : 443

public void
setInternalProxies(String
The proxy regular expression
internalProxies
)

Regular expression that defines the internal proxies.

public void
setPortHeader(String
The HTTP header name
portHeader
)

Set the name of the HTTP header used to override the value returned by Request#getServerPort() and (optionally depending on {link isChangeLocalPort() Request#getLocalPort().

private void
setPorts(Request request, int defaultPort)

public void
setProtocolHeader(String
The header name
protocolHeader
)

Header that holds the incoming protocol, usually named X-Forwarded-Proto.

public void
setProtocolHeaderHttpsValue(String
The header name
protocolHeaderHttpsValue
)

Case insensitive value of the protocol header to indicate that the incoming http request uses SSL.

public void
setProxiesHeader(String
The header name
proxiesHeader
)

The proxiesHeader directive specifies a header into which mod_remoteip will collect a list of all of the intermediate client IP addresses trusted to resolve the actual remote IP.

public void
setRemoteIpHeader(String
The header name
remoteIpHeader
)

Name of the http header from which the remote ip is extracted.

public void
setRequestAttributesEnabled(boolean
true causes the attributes to be set, false disables the setting of the attributes.
requestAttributesEnabled
)

Should this valve set request attributes for IP address, Hostname, protocol and port used for the request?

public void
setTrustedProxies(String
The regular expression
trustedProxies
)

Regular expression defining proxies that are trusted when they appear in the remoteIpHeader header.

Inherited from org.apache.catalina.valves.ValveBase:
backgroundProcessgetContainergetDomainInternalgetNextgetObjectNameKeyPropertiesinitInternalisAsyncSupportedsetAsyncSupportedsetContainersetNextstartInternalstopInternaltoString

Field Detail

changeLocalNameback to summary
private boolean changeLocalName
changeLocalPortback to summary
private boolean changeLocalPort
commaSeparatedValuesPatternback to summary
private static final Pattern commaSeparatedValuesPattern

Pattern for a comma delimited string that support whitespace characters

hostHeaderback to summary
private String hostHeader
httpServerPortback to summary
private int httpServerPort
See Also
setHttpServerPort(int)
httpsServerPortback to summary
private int httpsServerPort
See Also
setHttpsServerPort(int)
internalProxiesback to summary
private Pattern internalProxies
See Also
setInternalProxies(String)
logback to summary
private static final Log log

Hides org.apache.catalina.util.LifecycleMBeanBase.log.

Logger

portHeaderback to summary
private String portHeader
protocolHeaderback to summary
private String protocolHeader
See Also
setProtocolHeader(String)
protocolHeaderHttpsValueback to summary
private String protocolHeaderHttpsValue
See Also
setProtocolHeaderHttpsValue(String)
proxiesHeaderback to summary
private String proxiesHeader
See Also
setProxiesHeader(String)
remoteIpHeaderback to summary
private String remoteIpHeader
See Also
setRemoteIpHeader(String)
requestAttributesEnabledback to summary
private boolean requestAttributesEnabled
See Also
setRequestAttributesEnabled(boolean)
trustedProxiesback to summary
private Pattern trustedProxies
See Also
RemoteIpValve#setTrustedProxies(String)

Constructor Detail

RemoteIpValveback to summary
public RemoteIpValve()

Default constructor that ensures ValveBase#ValveBase(boolean) is called with true.

Method Detail

commaDelimitedListToStringArrayback to summary
protected static String[] commaDelimitedListToStringArray(String commaDelimitedStrings)

Convert a given comma delimited String into an array of String

Parameters
commaDelimitedStrings:String

The string to convert

Returns:String[]

array of String (non null)

getHostHeaderback to summary
public String getHostHeader()

Obtain the name of the HTTP header used to override the value returned by Request#getServerName() and (optionally depending on {link isChangeLocalName() Request#getLocalName().

Returns:String

The HTTP header name

getHttpServerPortback to summary
public int getHttpServerPort()
getHttpsServerPortback to summary
public int getHttpsServerPort()
getInternalProxiesback to summary
public String getInternalProxies()
Returns:String

Regular expression that defines the internal proxies

See Also
setInternalProxies(String)
getPortHeaderback to summary
public String getPortHeader()

Obtain the name of the HTTP header used to override the value returned by Request#getServerPort() and (optionally depending on {link isChangeLocalPort() Request#getLocalPort().

Returns:String

The HTTP header name

getProtocolHeaderback to summary
public String getProtocolHeader()
Returns:String

the protocol header (e.g. "X-Forwarded-Proto")

See Also
setProtocolHeader(String)
getProtocolHeaderHttpsValueback to summary
public String getProtocolHeaderHttpsValue()
Returns:String

the value of the protocol header for incoming https request (e.g. "https")

See Also
RemoteIpValve#setProtocolHeaderHttpsValue(String)
getProxiesHeaderback to summary
public String getProxiesHeader()
Returns:String

the proxies header name (e.g. "X-Forwarded-By")

See Also
setProxiesHeader(String)
getRemoteIpHeaderback to summary
public String getRemoteIpHeader()
Returns:String

the remote IP header name (e.g. "X-Forwarded-For")

See Also
setRemoteIpHeader(String)
getRequestAttributesEnabledback to summary
public boolean getRequestAttributesEnabled()
Returns:boolean

true if the attributes will be logged, otherwise false

See Also
setRequestAttributesEnabled(boolean)
getTrustedProxiesback to summary
public String getTrustedProxies()
Returns:String

Regular expression that defines the trusted proxies

See Also
setTrustedProxies(String)
invokeback to summary
public void invoke(Request request, Response response) throws IOException, ServletException

Implements org.apache.catalina.Valve.invoke.

Doc from org.apache.catalina.Valve.invoke.

Perform request processing as required by this Valve.

An individual Valve MAY perform the following actions, in the specified order:

  • Examine and/or modify the properties of the specified Request and Response.
  • Examine the properties of the specified Request, completely generate the corresponding Response, and return control to the caller.
  • Examine the properties of the specified Request and Response, wrap either or both of these objects to supplement their functionality, and pass them on.
  • If the corresponding Response was not generated (and control was not returned, call the next Valve in the pipeline (if there is one) by executing getNext().invoke().
  • Examine, but not modify, the properties of the resulting Response (which was created by a subsequently invoked Valve or Container).

A Valve MUST NOT do any of the following things:

  • Change request properties that have already been used to direct the flow of processing control for this request (for instance, trying to change the virtual host to which a Request should be sent from a pipeline attached to a Host or Context in the standard implementation).
  • Create a completed Response AND pass this Request and Response on to the next Valve in the pipeline.
  • Consume bytes from the input stream associated with the Request, unless it is completely generating the response, or wrapping the request before passing it on.
  • Modify the HTTP headers included with the Response after the getNext().invoke() method has returned.
  • Perform any actions on the output stream associated with the specified Response after the getNext().invoke() method has returned.
Parameters
request:Request

The servlet request to be processed

response:Response

The servlet response to be created

Annotations
@Override
Exceptions
IOException:
if an input/output error occurs, or is thrown by a subsequently invoked Valve, Filter, or Servlet
ServletException:
if a servlet error occurs, or is thrown by a subsequently invoked Valve, Filter, or Servlet
isChangeLocalNameback to summary
public boolean isChangeLocalName()
isChangeLocalPortback to summary
public boolean isChangeLocalPort()
isForwardedProtoHeaderValueSecureback to summary
private boolean isForwardedProtoHeaderValueSecure(String protocolHeaderValue)
setChangeLocalNameback to summary
public void setChangeLocalName(boolean changeLocalName)
setChangeLocalPortback to summary
public void setChangeLocalPort(boolean changeLocalPort)
setHostHeaderback to summary
public void setHostHeader(String hostHeader)

Set the name of the HTTP header used to override the value returned by Request#getServerName() and (optionally depending on {link isChangeLocalName() Request#getLocalName().

Parameters
hostHeader:String

The HTTP header name

setHttpServerPortback to summary
public void setHttpServerPort(int httpServerPort)

Server Port value if the protocolHeader is not null and does not indicate HTTP

Default value : 80

Parameters
httpServerPort:int

The server port

setHttpsServerPortback to summary
public void setHttpsServerPort(int httpsServerPort)

Server Port value if the protocolHeader indicates HTTPS

Default value : 443

Parameters
httpsServerPort:int

The server port

setInternalProxiesback to summary
public void setInternalProxies(String internalProxies)

Regular expression that defines the internal proxies.

Default value : 10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254.\d{1,3}.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|0:0:0:0:0:0:0:1

Parameters
internalProxies:String

The proxy regular expression

setPortHeaderback to summary
public void setPortHeader(String portHeader)

Set the name of the HTTP header used to override the value returned by Request#getServerPort() and (optionally depending on {link isChangeLocalPort() Request#getLocalPort().

Parameters
portHeader:String

The HTTP header name

setPortsback to summary
private void setPorts(Request request, int defaultPort)
setProtocolHeaderback to summary
public void setProtocolHeader(String protocolHeader)

Header that holds the incoming protocol, usually named X-Forwarded-Proto. If null, request.scheme and request.secure will not be modified.

Default value : X-Forwarded-Proto

Parameters
protocolHeader:String

The header name

setProtocolHeaderHttpsValueback to summary
public void setProtocolHeaderHttpsValue(String protocolHeaderHttpsValue)

Case insensitive value of the protocol header to indicate that the incoming http request uses SSL.

Default value : https

Parameters
protocolHeaderHttpsValue:String

The header name

setProxiesHeaderback to summary
public void setProxiesHeader(String proxiesHeader)

The proxiesHeader directive specifies a header into which mod_remoteip will collect a list of all of the intermediate client IP addresses trusted to resolve the actual remote IP. Note that intermediate RemoteIPTrustedProxy addresses are recorded in this header, while any intermediate RemoteIPInternalProxy addresses are discarded.

Name of the http header that holds the list of trusted proxies that has been traversed by the http request.

The value of this header can be comma delimited.

Default value : X-Forwarded-By

Parameters
proxiesHeader:String

The header name

setRemoteIpHeaderback to summary
public void setRemoteIpHeader(String remoteIpHeader)

Name of the http header from which the remote ip is extracted.

The value of this header can be comma delimited.

Default value : X-Forwarded-For

Parameters
remoteIpHeader:String

The header name

setRequestAttributesEnabledback to summary
public void setRequestAttributesEnabled(boolean requestAttributesEnabled)

Should this valve set request attributes for IP address, Hostname, protocol and port used for the request? This are typically used in conjunction with the AccessLog which will otherwise log the original values. Default is true. The attributes set are:

  • org.apache.catalina.AccessLog.RemoteAddr
  • org.apache.catalina.AccessLog.RemoteHost
  • org.apache.catalina.AccessLog.Protocol
  • org.apache.catalina.AccessLog.ServerPort
  • org.apache.tomcat.remoteAddr
Parameters
requestAttributesEnabled:boolean

true causes the attributes to be set, false disables the setting of the attributes.

setTrustedProxiesback to summary
public void setTrustedProxies(String trustedProxies)

Regular expression defining proxies that are trusted when they appear in the remoteIpHeader header.

Default value : empty list, no external proxy is trusted.

Parameters
trustedProxies:String

The regular expression