Hide or disable Tomcat command line arguments logging - jvm

Our application server (Apache Tomcat Plume) that use jta-managed data source through tomee.xml file should access database server just in secure (HTTPS) mode with two way ssl or client authentication.
So we have to put keystore and truststore plain passwords into setenv.sh or other places in row format. (I m not sure that is the first and last method to do that?) and what happens is tomcat logging mechanism log all these secret information in plain format into log files like catalina.out.
That what (locating raw passwords in config files) is we do not want. Actually we must ( although it s not appear a big threaten while user have access to files, could find real password atleast), encrypt password and use it in environment variables.
Central Question
In other word, how can we set jvm properties and environment variables in encrypted mode?

Re: Hide or disable Tomcat command line arguments logging (the title of this question)
This logging is done by VersionLoggerListener it is possible to configure it, or just remove it from configuration (server.xml).
Re: plaintext passwords handling
This is covered in Tomcat FAQ.
A Vault can be used to store secrets.

Related

Tomcat, hide javax.net.ssl.keyStorePassword from -D options

The application installed on Tomcat (9.0.36.B.RELEASE) connects to an external source using SSL (in this case, IBM MQ). I therefore need to specify a truststore, and password for this truststore.
I got it to work adding this to the JVM_OPTS in setenv.sh:
-Djavax.net.ssl.trustStore=/opt/apps/certs/myapplication.truststore
-Djavax.net.ssl.trustStorePassword=TRUSTSTORE-PASSWORD
-Djavax.net.ssl.keyStore=/opt/apps/certs/myapplication.keystore
-Djavax.net.ssl.keyStorePassword=KEYSTORE-PASSWORD
Classic issue with this, the passwords are visible when I do ps -ef|grep java (runs on RHEL).
I have seen a couple suggestions on how to do this (like Hiding plain text password in JVM startup argumnets. " ps -ef | grep 'javax.net.ssl.keyStorePassword'"). But these change/add code or configuration in the WAR file.
I am looking for a "tomcat" solution. Is there a way to to this within the confines of Tomcat. Changes to the WAR file are difficult to implement, as the application comes from a vendor.
Note: this is not for a connector configuration in web.xml since that would only setup SSL for incoming connections. Here the application is making connections to an external system (so outbound from Tomcat's perspective).
You can add additional properties to $CATALINA_BASE/conf/catalina.properties and they will be sourced during Tomcat's startup. As you are certainly aware, system properties are global to the JVM, so there is no way to restrict this configuration to a single application only: the entire Tomcat server will be affected.
Almost all Java system properties can by set this way, with a few exceptions:
catalina.base and catalina.home (obviously),
the configuration for Tomcat logging,
the configuration for JMX and other tools that start before user code.
Attention: You must check whether the VersionLoggerListener (defined in server.xml) does not have logProps="true", otherwise the values of system properties will be logged. By default only the JVM arguments are logged.

Is there a way to save encrypted password in redis.conf?

I want to add password to Redis.
I interested if there is a way to save encrypted password in redis.conf and not as plain text?
Or a way not to store the password in redis.conf at all?
By default redis.conf atleast until today with its most recent version - 6.0.1 still doesnt support encrypting a password.
While this is a situation is not fully avoidable, at the best, you can automate this by writing a wrapper startup script that would accept password as an argument and bring up the service. And then, once the service is up, ALTHOUGH THIS IS TO BE AVOIDED AND IS NOT RECOMMENDED you can delete the conf file or change the password in that file. and, before the startup of REDIS, you would require to run the startup script again/ re-enter the original password. BUT THIS CAN ADDITIONALY CAUSE PROBLEMS.
Please note -> redis.conf can be secured by linux/OS permissions and thats the best way to do so
No Redis doesn't support encrypted password for auth. You may check the details in official documentation
The password is set by the system administrator in clear text inside the redis.conf file. It should be long enough to prevent brute force attacks.
Additionally;
The AUTH command, like every other Redis command, is sent unencrypted, so it does not protect against an attacker that has enough access to the network to perform eavesdropping.
You may use config set requirepass yourpassword to set password and this will not require a server restart but set it on-fly, but when the server is restarted your previous password(written in conf file)/no password(if it is not set) will be used to authenticate requests.
Well while encryption is till now not an option, Redis 6 introduced ACL (Access Control List) where you can store your SHA256-hashed passwords in the redis.conf file.
Please note that this not an Encryption though!
From redis-cli:
acl setuser yourUser on #951249c8e32817cb0727ba2b1440f008c49c582e5daca4a0bd6d64eed1291a37
From redis.conf
user yourUser on #951249c8e32817cb0727ba2b1440f008c49c582e5daca4a0bd6d64eed1291a37
Additional note:
You may need to disable the default user which does not have a password:
From redis-cli:
acl setuser default off
From redis.conf
user default off

How do you supply your Applications with TLS Certificates centrally in Openshift?

I am currently struggeling with the following tasks. I don't want to include my TLS certificates in my templates because
I don't want to check in credentials in code management while still checking in the templates
I am using multiple Applications with the same Certificate and I don't want to update repos just because I might distribute another certificate
Now my approach is this. I am using Jenkins for my build pipelines. I have a Repo that is used just for certificate management. It will run when updated and distribute the certificate and private key to Openshift Secrets on various clusters.
When running the Template of an application I am retrieving the Information from the secret and setting the values in the route. And here's where things get tricky. I can only use single line values because
Openshift templates will not accept multiline parameters with oc process
Secrets will not store multiline values
So the solution seemed to be easy. Just store the Certificate with \n and set it in the Route like this. However Openshift will not accept single line certificates resulting in the error
spec.tls.key: Invalid value: "redacted key data": tls: found a certificate rather than a key in the PEM for the private key
Now the solution could be to insert the Certificate as multiple lines directly in the template file before processing and applying it to the cluster but that seems a little bit hacky to me. So my Question is
How can you centrally manage TLS Certificates for your applications and set them correclty in the Templates you're applying?
Secrets can be multiple lines. You can create a secret using a certificate file, and mount that secret as a file into your containers. See here for how to create secrets from files:
https://kubernetes.io/docs/concepts/configuration/secret/
Use the openshift command line tool instead of kubectl.
For certificates, there is something called cert-manager:
https://docs.cert-manager.io/en/latest/
This will generate certs as needed. You might want to take a look.
In order to centrally manage TLS Certificates for the applications, you can create a general secret and use it via volume mounting.

Encrypting password for c3p0 ComboPooledDataSource

I currently have a server.xml configuration which has the following in it
<Resource auth="Container"
description="DB Connection"
driverClass="oracle.jdbc.driver.OracleDriver"
maxPoolSize="40"
minPoolSize="2"
aquireIncrement="1"
name="jdbc/FOOBAR"
user="foo"
password="bar"
factory="org.apache.naming.factory.BeanFactory"
type="com.mchange.v2.c3p0.ComboPooledDataSource"
jdbcUrl="path:to:db:port:db" />
I have a requirement to no longer allow the username/password to be in clear text in the server.xml file for obvious reasons.
I've read a bit online and came across How to Secure Tomcat Database Passwords for Java
Encrypt username and password for JNDI in Tomcat Server.xml and many other pages; however, I'm a bit stuck.
I first looked at extendind the BasicDataSourceFactory - but it seems that can't occur due to my using c3p0 CombinedPooledDataSource. I then looked at trying to create a c3p0 datasource wrapper by implementing PooledDataSource, Serializable and Referenceable but that didn't work either.
I read I could move the authentication to the server side by making auth="Container" => auth="Application". However, I'm not sure of how to implemet the rest of the pieces with my using Hibernate.
Any help would be great.
So, this will not be a high-security solution.
But an easy way around this is to make use of the fact that c3p0's "password" property is just a configurable c3p0 property, which can be set in a wide-variety of ways. So, you could create a c3p0.properties file and/or a c3p0-config.xml file, and set the password there. Alternatively, you could make sure that a System property c3p0.password is set when you run the JVM.
If you'll have multiple DataSources with different passwords, you'll need to use c3p0's named config feature, which means a c3p0-config.xml file.
c3p0 config (both c3p0.properties and c3p0-config.xml) files can be stuck at the top-level of a jar file in your application's effective CLASSPATH. (With tomcat, you have to be careful about distinctions between the web-app specific ClassLoader and more widely shared locations.) So, you can have your password embedded in a compressed jar file rather than a plain text file. Obviously, this is not secure: plaintext is just an "unzip" away. But it would prevent the password from being casually greppable and such.
Please see http://www.mchange.com/projects/c3p0/#configuration_files
Good luck!

Best practice for securing sensitive data in plain text file?

Currently I am working on a C linux daemon that takes user input for an SQL connection string, then stores the information into a local conf file (client side). The purpose of the daemon is to submit data to an SQL database at a set interval in that every time the daemon is loaded it will look to the local conf for the SQL connection string. Also by using the command line argument -c, the user can reconfigure the SQL connection string in the event that the information changes. Would anyone be willing to share a way of securing this conf file so that it is not plain text. Keep in mind that I still need to be able to access and read in from the conf file as there is other conf settings present. Thanks in advance guys.
Edit: I do eventually plan to use SSL to submit the data between the client side and the SQL server.
The (only?) way to secure the file is to change its permissions to make it readable only to the user that runs the daemon.
Eg. if you are running the daemon as user 'foo' and group 'foo', you should:
chown foo.foo my-conf-file
chmod 600 my-conf-file
(Or even chmod it to 400 to prevent accidental modification, but I guess in this case you'll lose the -c option functionality).
NOTE: Also remember that it is quite dangerous to pass connection strings on the command line since they will be visible from the process listing!
You could also use some GPG stuff to encrypt the file, but I don't see the point there since then you have to protect the key you use to decript the file, and you get the exact same problem as before.
If you have no place to keep your secrets, cryptography will not help you. If your daemon is somehow able to decode password not using any secret, then anyone can do this too. So you have to rely on system protection, such as file access mode flags to keep keys.