Credential distribution/storage across fleets - linux

What are the options for secure password/credential storage on a host and propagation of changes across a fleet of hosts?
An example would be you have fleet of size N and you want to store credentials, such as AWS access keys, on those hosts. The simple approach is to store it in the source code or a config file, but this is bad because it's usually plain text. Also, if you make a change to the credentials you then want them to propagate to all of the hosts in the fleet.
Are there any solutions that would allow for something along these lines?
Credentials credentials = new Credentials();
system.doAction( credentials.getCredential("CredentialKeyId") );
This is assuming a non-Windows fleet.

Are you asking for something similar to NIS? To Kerberos, maybe?

Related

Working with multiple AWS keys in Hadoop environment

What's the workaround for having multiple AWS keys in Hadoop environment? My hadoop jobs will require access to two different S3 buckets (two different keys). Tried with "credential" provider but looks like it's pretty limited. It stores all keys in lower case, as a result I cannot use "s3a" for one job and "s3n" for other job. For example: for s3a, it looks for:
fs.s3a.access.key
fs.s3a.secret.key
And for s3n:
fs.s3n.awsAccessKeyId
fs.s3n.awsSecretAccessKey
But if I create provider with "fs.s3n.awsAccessKeyId", it stores as "fs.s3n.awsaccesskeyid", as a result, during runtime it fails to load the expected key.
As a workaround, I tried to generate two different credential providers and pass as:
--Dhadoop.security.credential.provider.path=key1,key2
But it didn't work togher as both of the keys have fs.s3a.access.key & fs.s3a.secrety.key pair.
I don't want to pass access and secret key using -D option as it's visible. Is there any better way to handle this scenario?
If you upgrade to Hadoop 2.8 you can use the per-bucket configurations to address this problem. Everything in fs.s3a.bucket.$BUCKETNAME is patched into the config for the FS instance for that bucket, overriding any other configs
fs.s3a.bucket.engineering.access.key=AAID..
fs.s3a.bucket.logs.access.key=AB14...
We use this a lot for talking to buckets in different regions, encryption, other things. Works well, so far. Though I would say that.
Special exception: if you encrypt credential secrets in JCECKS files. The docs cover this.

JWT with Node & Passport: Restarting server

I am new to Node and trying to setup Node & Passport to create JWTs upon authentication.
I am hoping to build a "stateless authentication mechanism" to reduce the need of going back and forward to the database.
By going "stateless", if none of the shared secrets or JWT is saved in the DB, I am assuming if the server restarts, all the issued JWTs (logged in users) are invalidated, thereby requiring a new JWT for all users to access protected routes. I do not want the users to log back in each time a server restarts or a new instance is spun.
I believe I can pass in static shared secret(s) to Node environment that I can use each time to generate the same JWTs that doesn't affect server restart.
Questions:
If a good practice is to pass in the shared secrets, where and how should I create this shared secret? and what all shared secret(s) will I have to pass in?
However, if passing in shared secret(s) to Node environment is not a good strategy, I am all ears for suggestions?
Update
I meant shared secrets when I said "key(s)". I'll update the question so it's not confusing.
Actually passing the keys as environment is the recommended way for this kind of applications.
Because the environment is only be visible by the running application and reduces the possibilities of leaking the keys (compared to something like a config file provided with the rest of the application code).
Normally you don't rotate the keys that often, it's usual to rotate them once a month assuming that you control your environment.
But keep in mind that the key is only used to prove that the token was signed by you, normally is good practice to only include a tiny bit of information in the token (for performance reasons). So you still need to go to the database to retrieve extra information about the user itself. You can add all the user information inside the token but keep in mind that the token needs to be sent for each request and that adds overhead.
If you use a process manager like supervisord you can set the environments over there and give the appropriate permissions to the config file to avoid key leakage.
I normally use environments to pass that kind of information to my node applications, I use it for JWT, AWS keys, SMTP credentials, etc. It keeps your code decoupled and avoids possible mistakes like pushing private keys to public code versioning system like github.

How to secure passwords in the Software Development?

how do you secure your passwords in propertie Files?
Encryption / Encoding?
Or do you use a different approach to handle Database User / Passwords for connection Strings?
Thanks for you help!
Update: Thanks for your responses! In this special case we talk about two tier architecture. We have many clients with direct connections to the databases. Propertie Files are on a network share.
For connection strings to database I use mostly jndi connections. And there I can encrypt the passwords: http://tomcat.apache.org/tomcat-6.0-doc/realm-howto.html#Digested_Passwords
you might have a closer look to aspnet_regiis. This commandLine programm has some pretty nice parameters such aus -pef (encrypt) and -pdf (decrypt).
so you may encrypt your complete (or just a port of) xxx.config file while it stays useable for your application.
I think for your usual three-tier web application, the secrecy of your database username and password is not something that you care about too much, because you can control network security. Look at MongoDB for example, where passwords are optional and not supported by all configurations. You need to set your database server to only accept connections from your own application servers anyway.
You have multiple accounts (with associated permissions) mostly to protect yourself from accidents, not to really keep separate people apart from each other.
There is no way end users can connect to the database directly.
So keeping the connection credential in an unencrypted property file on the server is fine. If someone gets to the server, you are already in trouble anyway.
Better keep this file outside of the source repository, though.
I do this by encrypting the connection string .
This can be achieved by creating a separate application to encrypt the connection string.
And using the decrypting code that is embedded in the application itself.

How to verify an application is the application it says it is?

Here's the situation: we have a common library which can retrieve database connection details from a central configuration store that we have setup. Each application uses this library when working with a database.
Basically, it will call a stored procedure and say "I am {xyz} application, I need to connect o " and it will return the connection details for that applications primary database (server, instance, database, user, and password).
How would one go about locking that down so that only application {xyz} can retrieve the passwords for {xyz} databases (there is a list of database details for each application... i just need to secure the passwords)?
The usual way is to have a different config store per app and give each app a different user/password to connect to the config store.
That doesn't prevent anyone from changing the app and replacing the user/password for app X with the values from app Y but it's a bit more secure, especially when you compile this data in instead of supplying it via a config file.
If you want to be really secure, you must first create a secure connection to the store (so you need a DB drivers that supports this). This connection must be created using a secure key that is unique per application and which can be verified (so no one can just copy them around). You will need to secure the executable with hashes (the app will calculate its own hash somehow and send that to the server who will have a list of valid hashes for each app).
All in all, it's not something trivial which you can just turn on with an obscure option. You will need to learn a lot about security and secure data exchange, first. You'll need a way to safely install your app in an insecure place, verify its integrity, protect the code against debuggers that can be attached at runtime and against it running in the virtual machine, etc.
Off the top of my head, try PKI.
Are you trying to protected yourself from malicous programs, and is this a central database that these applications are connecting to? If so you should probably consider a middle layer between your database and application.
I'm not sure this applies to your case, depending on how what your answers to the abovementioned would be, but by the comments it sounds like you are having a similar case to what this question is about.
Securing your Data Layer in a C# Application
The simplest/most straightforward way would be to store the passwords in encrypted format (storing passwords in plaintext is just plain bad anyhow, as recently demonstrated over at PerlMonks) and make each application responsible for doing its own password encryption/decryption. It would then not matter whether an app retrieved another app's passwords, as it would still be unable to decrypt them.
One possibility is to keep the passwords in the database in an encrypted form, and convey the encryption key to the allowed application(s) in a secure connection.Then, only the application with the encryption key can actually get the passwords and not others.

Encrypting 3rd party credentials

I have an application where I need to store 3rd party credentials to services like Amazon S3, FTP, SFTP, etc..
I know that it is possible to access some of those systems without passwords, but that has its own issues. If our customers gave us access to their S3 buckets via ACL we would still need to verify which bucket belongs to which user, same goes for SFTP and ssh key auth.
We will try our best to allow non-password alternatives where possible, but sometimes (FTP) it just won't be possible. Therefor I am looking for advice on how to store this sensitive data in our database (MySql) or elsewhere.
In the past I have read about people using TrueCrypt partitions that automatically unmount, but that would probably require decent intrusion detection. For now I'm interested in simple approaches that lead to reasonable security and can improved upon in the future.
Any advice on the subject would be highly appriciated!
There are a range variety of possibilities and since in my opinion you provide not enough info about the context, i will try to give you an overview from my point of view. I assume that here the most important aspect is confidentiality of your data and and authentication of the users. Integrity and availability of data is much less important.
If you want basic security, you can let MySQL handle it by means of username/password combinations and set access rights on the given account. However, since the access control mechanism of mysql is not fine-grained (you can set access control rules per table only, not per row) this will probably yield a bad database design.
If you want to have a non-password approach, you can give users client-certificates and let them prove their identity by presenting their client certificates (use TLS for that) or let them sign something (note their are dangers because you create a so called signing oracle).
Another approach is to encrypt your data in the database. You can do that by deriving a symmetric key from the password and encrypt the credentials with this data. The catch here is of course that your key derivation protocol should be good and this is not easy to accomplish (so if you choose this, i advice you to take existing key derivation protocols or use a streamcipher). Take a look here for a list of streamcipher http://en.wikipedia.org/wiki/Stream_cipher .
If you care very much for security you can start thinking about fancy solutions like authentication with smartcards, or a time synchronized tamper resistant device for generating acccess codes. However, note that these fancy solutions do not give you free security, implementing such systems if hard and costly (due to development and deployment) however, if done correctly they provide the best security.
Have the user supply a (strong) password when they set up an account (before they provide their passwords). Then encrypt all data for that account within your database using a key derived from a strong hash (SHA256 or something like that) of the user's password. That way if your servers get compromised, no data will be revealed because it is encrypted with the user's password (well, a hash of the user's password) and that password is not stored anywhere on your server.
You need to investigate the use of keystores. TruCrypt is an example of such a keystore, but this is a personal keystore, not intended for service level credentials.
You won't be able to avoid storing their passwords in a format that someone can get access to, the goal is to minimize who can access the information. Putting in the same MySQL as application data is asking for disaster.

Resources