Search This Blog

Showing posts with label tomcat. Show all posts
Showing posts with label tomcat. Show all posts

2021-12-10

Apache Tomcat with log4j: Workaround to address CVE-2021-44228 in Tomcat Application Server

Product: Tomcat Application Server
Version: All version
URL: https://www.bleepingcomputer.com/news/security/new-zero-day-exploit-for-log4j-java-library-is-an-enterprise-nightmare/

Apache log4j has a new CVE-2021-44228 vulnerability announced yesterday, which allow remove code executing using LDAP messaging lookup.

BleepingComputer.com shown that existing Apache Log4j can use Java startup parameter "-Dlog4j2.formatMsgNoLookups=true" so this post is to show how to configure Windows Service to configure Tomcat Application Server service to startup with this additional Java startup parmaeter

Procedure

1. Run "cmd" to launch Command Prompt

2. For each of the Tomcat in the machine, cd to its bin directory, e.g. 
cd "D:\SAP\SAP BusinessObjects\tomcat\bin"

3. Type "services.msc" and look for the Tomcat service name from "Services" screen. You need to know its instance name to modify it later

4. The Tomcat instance name is BOEXI40Tomcat in my env

5. Open up Tomcat Windows Service editor screen to modify this Windows Service configuration

tomcat9w //ES/BOEXI40Tomcat

6. You will see following editor screen. If you don't, go back Step 3 to ensure you are specifying the correct Tomcat instance name


7. Click on tab "Java" and you should see a text box labeled "Java Options"


8. Scroll to the bottom and add -Dlog4j2.formatMsgNoLookups=true


9. Click on OK button to save and close it

10. Restart Tomcat application server
10.1. Stop Tomcat: D:\SAP\SAP BusinessObjects\tomcat\bin>runas /user:administrator "net stop BOEXI40Tomcat"

Enter the password for administrator:

Attempting to start net stop BOEXI40Tomcat as user "win2019-tester1\administrator" ...

10.2. Start Tomcat: D:\SAP\SAP BusinessObjects\tomcat\bin>runas /user:administrator "net start BOEXI40Tomcat"

Enter the password for administrator:

Attempting to start net start BOEXI40Tomcat as user "win2019-tester1\administrator" ...

11. Verify the Java parameter is there by checking existing running tomcat9.exe. For this execution, the process ID (PID) is 10312 (Task Manager)

D:\SAP\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\win64_x64\sapjvm\bin>runas /user:administrator "jinfo 10312"
Attaching to process ID 10312, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 8.1.061 10.0.2+000
Java System Properties:

java.vendor = SAP AG
org.apache.xml.security.ignoreLineBreaks = true
catalina.base = D:\SAP\SAP BusinessObjects\tomcat
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
catalina.useNaming = true
........
...cut...
........

VM Flags:
Non-default VM flags: -XX:CICompilerCount=2 -XX:CoreDumpType=null -XX:+EnableDebuggingOnDemand -XX:+HeapDumpOnOutOfMemoryError -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=1073741824 -XX:MaxMetaspaceSize=402653184 -XX:MaxNewSize=357564416 -XX:MaxVMs=1 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=89128960 -XX:NonNMethodCodeHeapSize=5828300 -XX:NonProfiledCodeHeapSize=131303578 -XX:OldSize=179306496 -XX:+PrintGCDetails -XX:-PrintGCID -XX:+PrintOldStyleGC -XX:+PrintOldStyleGCDetails -XX:ProfiledCodeHeapSize=131303578 -XX:+ReduceSignalUsage -XX:+SegmentedCodeCache -XX:ThreadStackSize=1024 -XX:-UseAOT -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseParallelOldGC -XX:-UseSharedSessionStore

Command line:  -Dcatalina.home=D:\SAP\SAP BusinessObjects\tomcat -Dcatalina.base=D:\SAP\SAP BusinessObjects\tomcat -Xrs -XX:MaxMetaspaceSize=384M -Djava.awt.headless=true -XX:+HeapDumpOnOutOfMemoryError -Xloggc:D:\SAP\SAP BusinessObjects\tomcat\logs\tomcat.gc.log -XX:+PrintGCDetails -XX:+UseParallelOldGC -Xloggc:d:\SAP\SAP BusinessObjects\tomcat\logs\tomcat.gc.log -Dfile.encoding=UTF-8 -Dlog4j2.formatMsgNoLookups=true exit abort -Xms256m -Xmx1024m -Xss1024k

12. Done. The new setting is activated.  Test with vulnerability scanner to confirm, as well as fully tested the application functionality before deploy to PROD env

2021-09-07

Apache Tomcat 7-9: JNDI JDBC Connection Pool Configuration

Product: Apache Tomcat
Version: 7.0 - 9.x

Since Apache Tomcat 7, the build-in JNDI/JDBC connection pool manager has 2 options:

1. Apache Common DBCP - class name is org.apache.tomcat.dbcp.dbcp2.BasicDataSource
2. Tomcat's light weight DBCP - recommended setting, and I will refer to it as non-DBCP. Class name is org.apache.tomcat.jdbc.pool.DataSource

Tomcat's jdbc-pool.html page documented various benefits to use Tomcat's light-weight DBCP connection pool manager in their homepage: https://tomcat.apache.org/tomcat-9.0-doc/jdbc-pool.html. In summary, you need to configure extra <Resource> parameter org.apache.tomcat.jdbc.pool.DataSourceFactory to switch to the light-weight driver, else it will be using DBCP.

In Tomcat's jndi-datasource-examples-howto.html homepage, it failed to document this additional factor=org.apache.tomcat.jdbc.pool.DataSourceFactory parameter, and many people are using Common DBCP connection pool manager.

This post going to give clear example how to configure both using MS SQL Server

Using Apache Common DBCP

File: [Tomcat]/conf/context.xml (for global), [Tomcat]/webapps/[webapp]/META-INF/context.xml (for specific webapp)

Example: [Tomcat]/conf/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- The contents of this file will be loaded for each web application -->

<Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <Manager pathname="" />
<Resources cacheMaxSize="512000" />
    <Resource name="jdbc/pc1001DataSource" auth="Container"
      type="javax.sql.DataSource"
  username = "[DB username]"
          password = "[DB user password"
          driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" 
          url="jdbc:sqlserver://[MS SQL Server hostname]:1433;DatabaseName=pc1001"
          maxTotal="100"
  validationQuery="select 1004"
  connectionProperties="sendStringParametersAsUnicode=false"
    />

</Context>

Note: If using tomcat/conf/context.xml, then msjdbc.jar must resides in tomcat/lib directory, else Tomcat will complain ClassNotFound

Using Tomcat Non-DBCP Connection Pool

File: [Tomcat]/conf/context.xml (for global), [Tomcat]/webapps/[webapp]/META-INF/context.xml (for specific webapp)

Example: [Tomcat]/conf/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- The contents of this file will be loaded for each web application -->

<Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <Manager pathname="" />
<Resources cacheMaxSize="512000" />
    <Resource name="jdbc/pc1001DataSource" auth="Container"
      type="javax.sql.DataSource"
  factory = "org.apache.tomcat.jdbc.pool.DataSourceFactory"
  username = "[DB username]"
          password = "[DB user password"
          driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver" 
          url="jdbc:sqlserver://[MS SQL Server hostname]:1433;DatabaseName=pc1001"
          maxTotal="100"
  validationQuery="select 1004"
  connectionProperties="sendStringParametersAsUnicode=false"
    />

</Context>

Note: If using tomcat/conf/context.xml, then msjdbc.jar must resides in tomcat/lib directory, else Tomcat will complain ClassNotFound

Monitoring

I compared the monitoring for both DBCP and non-DBCP connection pool manager using Tomcat 9.0 using Oracle Java 1.8.0_111 on Windows OS.  JConsole.exe (Java Monitoring & Management Console) is capable of monitoring both connection pool manager through its "MBeans" tab.

When comparing how each to monitor both of them, I found that DBCP is updating "MBeans" faster and more accurate than non-DBCP.  Non-DBCP sometimes won't show the detail of the connected connections, i.e. PooledConnect[array], for hours, in other word, it never update it.

The slow, delay, and inconsistency for non-DBCP connection pool make JConsole can't be reliabiliy used to monitor it via this JMX utility.  I didn't write a program to directly grab the JDBC connection pool JMX metrics, which I suspect there could be a delay as well

2021-09-03

Apache Tomcat: Connection Pool Manager - Quick Config to Self Recover After DB Restart

Product: Apache Tomcat
Version: 7, 8, 9

According to following Apache Tomcat documentation, testOnBorrow is off by default:

* Tomcat 7: https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html

* Tomcat 8.5: https://tomcat.apache.org/tomcat-8.5-doc/jdbc-pool.html

* Tomcat 9.0: https://tomcat.apache.org/tomcat-9.0-doc/jdbc-pool.html

However, this document mentioned following that is confusing on how many DB connection pool managers it provides, quote:

Section: Introduction

The JDBC Connection Pool org.apache.tomcat.jdbc.pool is a replacement or an alternative to the Apache Commons DBCP connection pool

Section: How to Use

Usage of the Tomcat connection pool has been made to be as simple as possible, for those of you that are familiar with commons-dbcp, the transition will be very simple. Moving from other connection pools is also fairly straight forward

Section: Inside The Apache Tomcat Container

The Tomcat Connection pool is configured as a resource described in The Tomcat JDBC documentation With the only difference being that you have to specify the factory attribute and set the value to org.apache.tomcat.jdbc.pool.DataSourceFactory

What does this means?  Tomcat 7 onward offers 2 types of DB connection pool manager that you can choose:

1. Apache Common DBCP - full feature and heavy duty connection pool manager. For its default configuration values' documentation, refers to https://commons.apache.org/proper/commons-dbcp/configuration.html, but not Tomcat's documentation. Example of [Tomcat]\conf\context.xml"

<Resource name="jdbc/TestDB"
          auth="Container"
          type="javax.sql.DataSource"
          username="root"
          password="password"
          driverClassName="com.mysql.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/mysql"/>

2. org.apache.tomcat.jdbc.pool - Lightweight DB connection pool manager. context.xml will has additional factory=org.apache.tomcat.jdbc.pool.DataSourceFactory parameter. Example of [Tomcat]\conf\context.xml:

<Resource name="jdbc/TestDB"
          auth="Container"
          type="javax.sql.DataSource"
          factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
          username="root"
          password="password"
          driverClassName="com.mysql.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/mysql"/>

A big different between them is that the default value for testOnBorrow is different, so DBCP will drop broken DB connections, while org.apache.tomcat.jdbc.pool.DataSourceFactory won't:

1. Apache Common DBCP - testOnBorrow=true
2. Tomcat org.apache.tomcat.jdbc.pool.DataSourceFactory - testOnBorrow=false

Out of curiosity, I spin up Tomcat 9.0.21 without specifying "factory" parameter, and used jconsole.exe (Java Console) to check folder "Catalina - DataSource" detail in MBeans tab as shown below:

Clicking on "Attributes" menu on the left, and I can see the actual value of the JNDI/JDBC data source configuration showing testOnBorrow=true by default:

In other word, to configure testOnBorrow in Apache Tomcat using its build-in DBCP JNDI/JDBC connection pool data source, you just need to configure parameter validationQuery into [Tomcat]/conf/context.xml or [Tomcat]/webapp/[app]/META-INF/context.xml <Resource> xml tag.

If you used org.apache.tomcat.jdbc.pool.DataSourceFactory, then jconsole.exe will display additional folder "tomcat.jdbc" at the bottom of MBeans tab as shown below:

2021-09-01

Apache Tomcat: Connection Pool Manager - Self Recover After DB Restart

Product: Apache Tomcat
Version: 6.x - 9.x
Ref: https://commons.apache.org/proper/commons-dbcp/configuration.html

Apache Tomcat 6 and earlier bundled with DBCP 1.3 connection pool manager for many years, which is readily to use by J2EE application as JNDI/DBCP connection pool manager. Tomcat 7.x onward start using its own lighter org.apache.tomcat.jdbc.pool connection pool manager (DBCP2 JAR is still bundled), but continue to use the same configuration parameters as DBCP.

This post going to discuss about non-DBCP connection pool manager, which is org.apache.tomcat.jdbc.pool.

One of the big challenge for many J2EE developers who use this connection pool manager assumes that their application will always get a good working DB connection from the connection pool manager when the DB is bounced.  In reality, they see that their Tomcat application will need to restart after DB maintenance (restart).  Many developers or administrators assume that, by default, the connection pool will auto close and open new DB connection when DB restarted, but it is not.  Some think that Tomcat will close them if let it idle for some time, but it won't close the broken connections.

This post is going to discuss several configurations that can configure connection pool manager to close existing broken DB connections and create new DB connection if DBA/anyone bounce the DB.

Among Apache Tomcat version in last 20+ years, it has connection pool parameters that can be configured without bouncing Tomcat (whenever DB bounced, e.g. Windows OS Update/patch).  Let's start with the simplified state diagram that I drawn by lookup Apache 9's connection pool manager.  It is more involving to create the UML state machine diagram which will be best, as I don't have any tool handy.  I tried to add as many Tomcat parameter as much into the diagram, yet to keep its size small, so it certainly won't contain the entire lifecycle of a connections in the pool


Note: Above diagram doesn't show states involving opening new connections from DB, which could experience long login, invalid password, account locked, remote DB down. On failure, it will not auto login to DB, if you are interested to know

Following are the parameters related to testing and dropping DB connections in the pool

1. testOnBorrow - Immediately re-connect all DB connections. Application will not see broken DB connections, and DB bounce is most likely transparent to the application. Default off

2. testWhileIdle +  minEvictableIdleTimeMillis - When connections in the pool meet long idle condition as defined by minEvictableIdleTimeMillis , it will drop all  (Tomcat 7+) existing broken long idle DB connections. Default off

3. testOnReturn - Continue to borrow broken DB connection to application, but immediately drop it if it is a broken DB connection. Application end will complain DB connection broken in its log, and not able to perform any DB operation. Application will not retry automatically. Default off

Following table illustrate more detail about its behavior:

# Method Application Will See Broken DB Conn Error? How Quickly Close Close One-by-One Close in Chunk CPU Usage
1 testOnBorrow No, if DB is up Immediate, and open new DB connections Yes No High
2 testWhileIdle Yes Controlled by:
timeBetweenEvictionRunsMillis (5 sec)
minEvictableIdleTimeMillis (60 sec)
maxIdle (same as maxActive, i.e. 100)
minIdle (same as initialSize, i.e. 10)
No Yes. Number of connection will be closed equals to value of  numTestsPerEvictionRun Low
3 testOnReturn Yes Immediate Yes No Medium

Note: for testWhileIdle setting, parameter numTestsPerEvictionRun is not used by Tomcat 7 onward (non-DBCP), so it will always closed all broken idle connections

For any of the above self recovered connection pool configuration, parameter "validationQuery" must specify a SELECT statement that is quick, and depends on DB type.  For example:

1. Oracle - select 1 from dual
2. MS SQL Server - select 1

I have encountered DB that could be slow to execute above SQL, and causing no available connections to borrow to the application, and stalled.  So developer/administrator must test running above SQL in  series + 1000 integration or more to measure the time taken as precaution.

If no SELECT statement is specified, DBCP won't auto close existing broken DB connections, and open a new one.

testOnBorrow and testWhileIdle are the most commonly configuration as there are generally 2 groups of people who favor high or low CPU resource.

For those who configure testWhileIdle, there are additional configuration to adjust it to the taste of the administrator to reduce CPU usage:

1. minIdle - default 10, which follows initialSize
2. maxIdle - default 100, which follows maxActive
3. numTestsPerEvictionRun - used by Tomcat 6 or older. Tomcat 7+ doesn't has this setting
4. minEvictableIdleTimeMillis - default 60 sec. The criteria for the DB connections in the connection pool to be considered "idle too long" and will be dropped, regardless they are broken or valid.  If connection not broken, then the connection could remains in the pool by keeping as many as 100 (minIdle)
5. timeBetweenEvictionRunsMillis - default 5 sec.  Eviction frequency (cycle or interval) that will drop broken DB connections in the connection pool

Tomcat 6 and older uses DBCP 1.3, which has additional numTestsPerEvictionRun to slowly drops long idle connections (to reduces CPU usage), so following are additional considerations for various versions:

1. How many broken connections in the pool that would like to close each time: Tomcat 7 will close all broken idle connections. numTestsPerEvictionRun (default 3 by DBCP 1.3 doc) is not used by Tomcat 7+, while Tomcat 6 or older will close 3 connections during each eviction cycle.
1.1. If application opened 1,000 DB connections when DB bounced, then there will be 1,000 broken DB connections in the connection pool.  This Tomcat 6 parameter means each round it will close 3 connections (default), and will take ~ 1,000 / 3 = 333 rounds to close all broken connections in the pool. For Tomcat 7+, it will close all 1000 broken connections (not closed 9990 and keeps 10 per minIdle)
1.2. A lower value will use less CPU as it close less broken connection each eviction round of eviction cycle
1.3. A higher value will use more CPU, so Tomcat 7+ will always use more CPU to close all broken connections
1.4. Broken connections get close one-by-one, even though it is in a batch as this is done by 1 Java eviction thread

2. How long a connection will be considered as "long idle" in order to close them: minEvictableIdleTimeMillis, default is 60 sec
2.1. Broken connection must be sitting in the connection pool without borrow to the application, and no user should use the application, or schedule any job, incoming web service call, background process, that will borrow those broken connection
2.2. If the broken connection not used for more or equals to 30 min, then it will be consider idle, and will pick up (per numTestsPerEvictionRun limit for Tomcat 6 or older, which is 3 idle connections only) by eviction thread to close the broken + idle connection
2.3. Even if a connection is idle more than 30 min (default), if in between the eviction cycle, the broken idle connection borrowed to application (due to batch process, background, or user trigger), then it will needs to wait for 30 min to be considered "idle." Sometimes, it will never idle as the broken connections keep borrow to the application due to user activity
2.4. A lower value will make broken connection to meet "idle" status sooner, but will use higher CPU
2.5. If a connection is idle for 29 min, borrowed to application for 1 sec (error out due to broken DB connection), idle for 29 min, borrow to app for 1 sec, and repeat 24 hr, then that specific connection will not consider "idle." This could be due to schedule batch process that fired every 15 min, or multiple that scheduled every 30 min (overlapping, so effectively < 30 min)

3. How frequent the eviction cycle will run and start closing idle (broken in this case) connections: timeBetweenEvictionRunsMillis, default 5 sec
3.1. A lower value will use more CPU, but will close broken connections that meet "long idle" status sooner (limit to 3 connections each round - numTestsPerEvictionRun).  If numTestsPerEvictionRun is 3, the CPU usage will be lower, but if numTestsPerEvictionRun is very high, and this cycle interval is high, then CPU usage will be very high
3.2. A higher cycle interval will close broken idle connections slower, even after they are in "idle" mode
3.3. If eviction cycle frequency (timeBetweenEvictionRunsMillis) is every 1 min (not applicable for Tomcat 7+) with default to close 3 connections (numTestsPerEvictionRun), then for 1000 broken DB connections, it will take 1000/3 * 1 min = 333 min (5 hr 33 sec) to close all
3.4. If eviction cycle is every 1 min with numTestsPerEvictionRun=100, to close 1000 broken DB connection, it will take 1000/100 * 1min = 10 min
3.5. If eviction cycle is every 5 sec with numTestsPerEvictionRun=10, to close 1000 broken DB connection, it will take 1000/10 * 5 sec = 500 sec (8 min 20 sec)
3.6. If eviction cycle is every 1 sec with numTestsPerEvictionRun=20, to close 1000 broken DB connection, it will take 1000/20 * 1 sec = 50 sec

Last warning is that even Tomcat DBCP2 or non-DBCP connection pool manager can self recovered by closing all the broken DB connections (either immediate, or with delay), this doesn't mean the J2EE application functionality will self recovered without human intervention. For example application functionality that won't self recovered:

1. Schedule job that failed to run earlier will not run again
2. Actively running schedule job will not self recovered after it abort when DB bounced
3. Background messaging/JMS might not self brought up
5. Incoming web services that failed due to loosing of DB connection will need to trigger again from remote server
6. End user might needs to login again and lost the information they entered into the screen

2012-10-11

Tomcat shutdown port 8005 - Remote Shutdown

Product: Tomcat
Version: Any version
File: CATALINA_HOME\conf\server.xml (D:\Internet\Web\tomcat7.0.32\conf\server.xml)

In default Tomcat installation, you will find following line in above global server configuration file

Line 22: <Server port="8005" shutdown="SHUTDOWN">

This configuration allows remote shutdown Tomcat by telnet to port 8005. Something to note

1. Port 8005 is on TCP protocol. This is important for firewall configuration
2. Port 8005 must be available for Tomcat to start. Use "netstate -an | grep 8005 | grep LISTEN" to confirm prior of Tomcat startup
3. The shutdown command is configurable, and case sensitive. In this default configuration (as above), it must be uppercase SHUTDOWN. It can configure to other value if there is a security concern
4. If port number is -1, then remote shutdown is disabled

Following steps illustrate how to shut it down remotely (I will login directly to Tomcat server and shut it down by telnet)

1. Use telnet client to login to localhost or any Tomcat server. For Windows 7, telnet command is removed, so I used PuTTY. The protocol is set to "Raw" as Tomcat shutdown port 8005 will interpret all characters send
2. Once connected, Tomcat gives 10 second to type the shutdown command (SHUTDOWN or other configured shutdown command in server.xml). If no command entered, following error will appear in Tomcat log

Oct 11, 2012 12:29:05 PM org.apache.catalina.core.StandardServer await
WARNING: StandardServer.await: read:
java.net.SocketTimeoutException: Read timed out
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:150)
        at java.net.SocketInputStream.read(SocketInputStream.java:121)
        at java.net.SocketInputStream.read(SocketInputStream.java:203)
        at org.apache.catalina.core.StandardServer.await(StandardServer.java:478)
        at org.apache.catalina.startup.Catalina.await(Catalina.java:766)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:712)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:322)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:451)

Oct 11, 2012 12:29:05 PM org.apache.catalina.core.StandardServer await
WARNING: StandardServer.await: Invalid command '' received


3. Entered "SHUTDOWN" in uppercase to shutdown Tomcat immediately, and telnet session will be terminated
4. If lowercase "shutdown" was entered, then the telnet will terminated, while Tomcat will show following message

Oct 11, 2012 12:32:47 PM org.apache.catalina.core.StandardServer await
WARNING: StandardServer.await: Invalid command 'shutdown' received

Other references:

http://tomcat.apache.org/tomcat-7.0-doc/config/valve.html
- Refers to section "Remote Address Filter" if want to allow or deny remote access to shutdown Tomcat. This will implies make use of Valve className org.apache.catalina.valves.RemoteAddrValve (by IP) or className org.apache.catalina.valves.RemoteHostValve (by hostname)
- Following CATALINA_HOME/conf/Catalina/localhost/manager.xml configuration illustrates to allow login from IP range 192.168.5 only

<Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="192\.168\.5\.\d+" />