I've got a Django project running on an Ubuntu server. There are other developers who have the ability to ssh into the box and look at files. I want to make it so that the mysql credentials and api keys in settings.py
are maybe separated into a different file that's only viewable by the root user, but also usable by the django project to run.
My previous approach was to make the passwords file only accesible to root:root with chmod 600
, but my settings.py
throws an ImportError
when it tries to import the password file's variables. I read about setuid, but that doesn't seem very secure at all. What's a good approach for what I'm trying to do? Thanks.
Have a look at filesystem ACLs, setfacl manpage.
You can have the files in questioned owned and readable only by the root user, but also allow whatever user the Django code is running as (your user name, apache user, etc) to have read access. Filesystem ACLs allow much more granular access control than standard owner/group/other file permissions
I'd place the password file in a directory with 600 permissions owned by the Django user. The Django user would be able to do what it needed to and nobody else would even be able to look in the directory (except root and Django)
Another thing you could do would be to store it in a database and set it so that the root user and the Django user in the DB have unique passwords, that way only the person with those passwords could access it. IE system root is no longer the same as DB root.
That's exactly what dj-database-url was created for!
Using this package you can store DB information in your user's environment variable. anyone who login from different account won't have access to db details
How to use?
Configure your database in settings.py from DATABASE_URL
(default is optional):
import dj_database_url
DATABASES = {'default': dj_database_url.config(default='postgres://...')}
Then in your shell
$ export DATABASE_URL="postgress://user:password@host/databasename"
$ ./manage.py runserver
This will run the server with the connection you specified, if DATABASE_URL
is not defined then assume the connection passed by the optional default
parameter.
ideally you would put
export DATABASE_URL="postgress://user:password@host/databasename"
inside your .bashrc file inside your home directory so that only you can read it
This is discussed in the SplitSettings page on code.djangoproject.com
. They have several suggestions such as
SECRET_KEY = open(os.path.expanduser('~/.gallery-secret')).read().strip()
where .gallery-secret
is limited to read by django user only (root still gets its way, of course). I prefer an environment variable such as MYAPP_OPTIONS=/etc/opt/myapp/
used with os.path.expandvar
so that the user account doesn't need a home directory and so that developers can point to test credentials easily.