How to secure database credentials present in database.yml - ruby-on-rails

How do I secure connection credentials which are used in config/database.yml. How do I secure username, password, host information for my db settings.
local: &local
adapter: mysql2
encoding: utf8
reconnect: false
username: foo
password: bar
host: localhost

You don't. At some point you have to put this stuff in and it has to be in plaintext.
This is usually a problem during deployment where you don't want anyone with read access to the repository to see your deployment servers db configuration.
I worked around that by having a custom capistrano task that copies (or symlinks) a database.yml from the server's home directory into the app.
(So in my repo there is a blank database.yml and it gets overridden whenever I publish a new version by the secret version that's already present on the server)
I wrote about this here:
http://www.tigraine.at/2011/09/25/securely-managing-database-yml-when-deploying-with-capistrano/
As for not sharing this while developing: Simply put database.yml into your .gitignore and it won't get committed

Related

How to configure database.yml for production

I would like to deploy my application via Dokku to a VPS.
Putting together the dokku-postgres documentation and the relative, scarce internet documentation on the matter (one at GitHub), it seems necessary to configure database.yml to use the url environment variable url: <%= ENV['DATABASE_URL'] %>
Since I could not find any other sources of information, I wonder how database.yml should be configured, and how Rails will connect to the postgres service created with Dokku.
For instance, taken for granted that linking url to the DATABASE_URL variable is necessary, will this be enough to establish a connection between my Rails application and the postgres service or would it be still necessary to use a username and a password? In the latter case, what username and password am I expected to use?
Below is how at present my database.yml looks like.
default: &default
adapter: postgresql
encoding: unicode
pool: 5
username: asarluhi
development:
<<: *default
database: fireworks_app_development
test:
<<: *default
database: fireworks_app_test
production:
<<: *default
database: fireworks_app_production
pool: 25
username: fireworks_app
password: <%= ENV['FIREWORKS_APP_DATABASE_PASSWORD'] %>
This file was created as it is (apart from a higher pool size for production) when I created the application. How would you suggest to edit the production section?
The dokku-postgres documentation states that the following (and nothing else) will be set on the linked application by default:
DATABASE_URL=postgres://postgres:SOME_PASSWORD#dokku-postgres-lolipop:5432/lolipop
In place of the lollipop postgres service example, I would use fireworks_app_production to match the name of the database in database.yml
Are username and password still necessary after pointing url to the DATABASE_URL variable? Am I expected to add or remove anything else?
You don't need to worry about the database.yml with dokku, just upload your app to the server, let's use "fireworks" as the name for example on this.
when you upload the first time the app, this is created automatically so you don't need to create it.
then you install the postgres plugin and run
# that will create the container for the database
$ dokku postgres:create fireworks
# and then you link both, the app with the database
$ dokku postgres:link fireworks fireworks
you don't have to worry about anything else, with that dokku will connect this
then you just have to run db:migrate and everything is ready to work!

how to review who accessed the db in production

our contract with a outsourced company fell apart, and they seemed to access the rails console in production. We have a backup, we are able to restore the data. But we need to make sure that who accessed the rails console.
development:
adapter: postgresql
encoding: unicode
database: xxxx-xxx
host: xxx.xx.xx.xx
pool: 5
username: xxxx
password: xxxx
in host if we change the ip, and give the appropriate user name and password, we will be able to connect to production data.
So is there a way, we can see the logs of who accessed the database through console?
ps: SSH into server is not possible as the passwords are changed recently.
So is there a way, we can see the logs of who accessed the database through console?
About the only log where this can be stored is your DB server log (in form of "open new connection from XXX.XXX.XXX.XXX"). That's as far as you can get, I think.
In any case, tracking rails console access doesn't make sense. Rails console can only access data if credentials in database.yml are valid. And if credentials in their database.yml are valid, they don't need the rails console to do all kinds of nasty things to your DB. They can just use psql directly or any other client.
Change DB credentials immediately.

Rails, Postgres, EC2/AWS: Database Config Does Not Specify Adapter Error

I'm trying to connect my Rails app to an EC2 instance that contains a PG database. I've already checked with Navicat that I can connect to the database given the EC2 details. The issue is that when run locally the Rails app can't be viewed; it throws the error "database configuration does not specify adapter". A similar issue is thrown when I try a database migration. I haven't even tried to push this up to my Rails EC2 since it isn't working locally.
My database.yml file looks like this:
production:
adapter: postgresql
encoding: unicode
database: postgres
host: ec2-54-197-115-117.compute-1.amazonaws.com
pool: 10
port: 5432 (have both included and removed this line)
username: a database username for security
password: the password associated with that user
My gem files include the gem pg.
For the database name I just wrote what it had in Navicat, but perhaps there's an official name associated with it I should be using; if so, how would I find it? The host I got from the EC2 details. And the username and password were the ones I set with the postgres database via unix.
Thanks in advance for any insight!
Edit:
Fixed!
Fixed! I had forgotten to create an actual DB after setting up the PG; I changed the name in my database.yml file to reflect the new db name. Also, I needed to set on my Rails app environment directly (I thought Apache did this automatically w/Passenger) with "export RAILS_ENV=production". I thought it was still broken when I restarted my server and nothing had changed, but I just had to restart the console. Hope this helps someone else out too!

Heroku with AWS RDS: Are details in database.yml needed?

We're running a Rails app on Heroku and have it connected to a database on Amazon RDS. It works fine, the security zone is configured and the app is live.
Heroku requires you to provide a Database URL in the format of
mysql2://user:pass#rdsinstance.com/database
Since we're specifying the DB info in the add-on, what do we need to provide in the database.yml file, if anything?
Would the following suffice, or do we need even less than that? Maybe just the adapter name?
production:
adapter: mysql2
encoding: utf8
reconnect: false
pool: 5
Heroku automatically replaces the content of any database.yml file on deploy with the value of the shared database, normally stored in the SHARED_DATABASE_URL config variable.
I don't know if it's save to override that value. If you do it, you should be able to connect to the database from Rails without any additional effort.
If your app is working fine and you are just wondering what you need to write inside the default database.yml file, then you can put in whatever you want, Heroku will replace it in any case on deploy.

Rails 3 - rake tasks to work with multiple database connections

Let's say I have s different database connections...
Right now for the purposes of this example let's only be concerned with development. When I run 'rake db:setup' it only creates development because from the rake task perspective the other connection is another environment. I could pass in the other connection as the RAILS_ENV to create the database. However, the problem comes in with how we've defined our database connections. I'd rather not undo this as it makes management and deployment much easier. What we've done is this...
In our database.yml we've added the following code.
databases_file = File.join(Rails.root.to_s, "config", "databases", "#{Rails.env.to_s}.yml")
IO.read(databases_file) if File.exist?(databases_file)
Then in a databases sub-folder under config we've created the different environment yml files.
So in development.yml we have...
development:
... details ...
logging:
... details ...
Now if I set RAILS_ENV to 'logging' it will never load the file since the file is called development.yml. Thus it will never find the logging connection.
If I consolidate all these settings back into the database.yml file then we're back to not checking in the database.yml into the git repo and having to manually create it on the development machines for new hires and such. We'd also have to change our deploy process to start putting the file in place on the lower environments. (Our production process already supports this)
You could use environment variables to manage these. You could have a single database.yml with things defined such as:
development:
database: ENV['DEVELOPMENT_DATABASE']
And then set the environment variables in your .bashrc/.zshrc.
We have multiple databases and we use branches heavily... so I came up with this solution to create multiple databases and tie their names to the branch being worked on...
# config/database.yml
<%=
databases_file = File.join(Rails.root.to_s, "config", "databases", "#{Rails.env.to_s}.yml")
if Rails.env.development? || Rails.env.test?
branch = ENV['BRANCH'] || `git branch --no-color 2> /dev/null`.chomp.split("\n").grep(/^[*]/).first[/(\S+)$/,1].sub("-", "_")
puts "Using databases for #{branch}"
IO.read(databases_file).gsub!("<branch>", branch) if File.exist?(databases_file)
else
IO.read(databases_file) if File.exist?(databases_file)
end
%>
And then you create a database file for each environment. In the development.yml and test.yml you use the token to let this script look for what it needs to in order to do replacement. So an example file would look like this.
# config/databases/development.yml
development:
adapter: mysql2
host: 127.0.0.1
database: <branch>_dev
username: user
password: pass
versions:
adapter: mysql2
host: 127.0.0.1
database: <branch>_versions
username: user
password: pass
reporting:
adapter: mysql2
host: 127.0.0.1
database: <branch>_reporting
username: user
password: pass
ods:
adapter: mysql2
host: 127.0.0.1
database: <branch>_ods
username: user
password: pass
I then extended the rake tasks to handle multiple databases
This is where most of the work went in. Therefore, I'm going to leave it out of the answer and make you work for it! No actually, it's just a big large mess that I'm not proud of and would love time to fix it, but haven't found any. I don't want to lead anyone down the wrong path but if you have questions just get me a message and I'll be happy to help.

Resources