File permissions for Django: Gunicorn, Nginx, and Static Files - linux

I have a standard ubuntu 14.04 machine. I use it daily under the user mh00h. I'm interested in using this machine as a production server. How do I manage file permissions for Django and Nginx?
Nginx is currently configured to run under the www-data:www-data. This minimizes risk of the rest of a machine being compromised. Django/gunicorn likewise should run under a user other than mh00h. But under what user should gunicorn actually be run under? nobody, correct?
Next: I am storing all of my web development files under /home/mh00h/development. Owned by mh00h. /home/mh00h/development/project1 (plus all dir/files but /media and /static)? Owned by mh00h. I follow django two-scoops best practices to create a project directory with static files inside of it. Of course, Nginx is unable to access /home/mh00h/development/project1/project1/static now because all of those parent directories are owned by mh00h, not www-data (./static is owned by www-data).
To complicate the matter, virtualenvwrapper creates my virtual environments under /home/mh00h/.virtualenvs/.
I am hesitant to fraction away from two scoop's best practices and store /static separately in /var/www, because I want all of these directories to stay nicely packaged together for easy transport off to some other server later. Plus, it makes me messy if I compare myself against how two-scoops did it.
Where should my static files be stored?
Where should django specific files be stored?
What users/groups should be able to access which of 1 and 2?
Where should virtualenvwrapper environments be stored?
What permissions should these locations have?
Thank you.

All files and directories in our production environment are owned by root:root with 755/644 file permissions, unless otherwise required. Some private files (think private keys etc.) are only readable by the user/process that needs them, while still being writable only by root.
As for the project structure: all our projects have a dedicated directory under /srv/www/vhosts.d/. Virtual environments are stored under /srv/www/virtualenvs. It is perfectly possible to store them in your home folder, but I feel this central approach is more in line with the idea of a production server. With the right settings, all virtual envs are also accessible by all users.
Our main project directory contains several scripts (manage.py and several deployment/update scripts) and is further split out into subdirectores: i.e. web contains public files, src contains the source code, and frontend contains the template folder and sass folder. The whole project directory is contained in a git repository, but deployment-specific files (user uploaded files, search indexes, encryption keys) are all in .git-ignore.
Our nginx process runs as www-data. In general each Django project has its own user, and the gunicorn process runs as this user.

Related

Creating a shared directory with nginx file server

I have dozen of log files from my server. I wanted to share them over web server, keeping it as simple as possible. I set up authentication for nginx web server, and tried to create symlinks to log files my Python script is storing in dedicated folder in my home directory. First i tried to set this directory as nginx root, but i learned that it's a bad idea, so i decided to create symlinks in default nginx root directory, but it didn't work either.
I thought that maybe synchronizing files across both folders may work, but that honestly seems like a huge overkill for such a simple task.
How else should i approach this?
By default, nginx will try to prevent you from an insecure setup where you serve files outside of your nginx root. See here for how to fix: https://unix.stackexchange.com/questions/157022/make-nginx-follow-symlinks
Second, you need to ensure that the nginx user can list and read the files. (generally, via group permissions.)
It would actually be much better to store the files under the nginx root, and modify your python program.

A directory structure for Django on Linux

I've got a linux machine that I use solely for (multiple) Django projects. I'm looking for the best place to put everything. Currently I'm using the following directories -
/home/Code/my_project to put the django project itself (ie the code created by start_project)
/home/Code/virtualenvs/my_project_env for the virtualenv
/home/www/my_project for apache logs
On top of this I've been keeping my static root and media root directories within the main project code -
/home/Code/my_project/static_root
/home/Code/my_project/media
The big issue I've hit with this setup is that I'm running out of disk space on /home. I feel that I should at least be keeping my static files in /var somewhere. Should the apps themselves go in /opt?
How should I set this up next time? What can I do about my disk space issues with current apps? (Is this really a sys admin question?)

Preventing user accesing Node.js application code

Assuming a user has access to all files within the public_html directory. Doesn't this mean they could have access the a node.js application code within it? Surely this is a massive security risk.
What is the normal way of handling this? Would you user files permissions to restrict the file, or place the node directory outside of the public_html and reference it somehow? If so, how?
Many thanks for any answers given!!
Yes your server scripts should live outside public_html. Only files that you want to make available to the public should be placed under public_html.
Your node server script can refer to the "./public_html" or "../public_html" folder if it is stored in or above the folder containing the script, or it can even refer to "/path/to/public_html" if it is stored elsewhere on your filesystem.

LAMP: Recommended Directory and File Permissions

My project resides in a shared Linux hosting server. The hosting provider, of course, has already set up the necessary directory and file ownerships relative to other server users. My concern for now is how to setup permissions within my domain so my users can have read access to the files and folders they should have and still let my scripts retain read/write access to it.
Question: What would be the recommended permissions on:
Public files and folders (read only?)
Files where uploaded files from forms are stored
Files and folders where GD and cache files are being written into
Folders where my server-side scripts are stored (I used mainly PHP)
My WWW root folder (where index.php resides)
This is a perfect example of where you need the Principle of Least Privilege. Allow ReadOnly to the webserver's user for RO content, allow writing only to a directory/files that absolutely need to be written. Explicitly deny access to things you don't want people to read (config files, htaccess, anything with paths/ip addresses/passwords), don't allow any extra processing if you're not using it (CGI executables, Server Side Includes).
The best way to do it is to start with deny everything and slowly open thing up as you go. First try serving static content, see what is the minimal amount of Apache directives/modules and filesystem ownerships and permissions to get it working. Then try some RO PHP scripts. Then try some RW PHP scripts. Then DB connectivity, and so on, you get the idea... It's a very tedious processes, and you want to plan ahead the sort of things you want to test; I tend to write long scripts with wget commands trying to do both good and bad things to the server. Make one change, restart, rerun the script, see what changes from the last time. Observe-modify-analyze, until you cant stand looking at it anymore ;)

cgi-bin directory contents: What else can be stored there, apart from the CGI scripts/executables?

What files should/should not be stored in the cgi-bin folder/directory on a web server?
Obviously, executable scripts/files that make up a web application, called from a web browser can be stored there.
But is there a common industry opinion about what else can be stored there?
Is there a very strong reason why nothing else apart than the scripts/executables is allowed there?
My preference is to store all files belonging to an application in the cgi-bin directory/folder, as a subfolder off it - for each application.
For example directory cgi-bin/myapplication would contain:
the cgi scripts/executables
datafiles
configuration files
This simplifies installation and also simplifies the steps to run different versions of a application in parallel, e.g. for trialling a new version.
Concerns about security access to non-script files can be addressed by using the correct user permissions and also Apache .htaccess to control access to the directory and files.
It would seem that popular free applications are in favour of this everything-under-one-directory approach: The versions of bugzilla, the free defect and feature tracking tool, e.g. 3.4.4 are offered in this structure, while earlier versions, e.g. 2.x installed bugzilla components to at least three folders.
Drupal, the powerful and popular free content management system also takes this approach of everything-under-one-directory, albeit doesn't use the cgi-bin folder but the approach is the same.
What are your thoughts?
There is nothing special about the cgi-bin folder. It is like any publicly-accessible web folder that has the "allow-script" flag set (or the equivalent for your web server) - something that has become almost meaningless in the world of PHP/JSP and the likes.
You should only store files that you wish to be public in any folder under your webroot. You probably don't want your data and configuration to be downloadable by any user on the internet, so don't keep them in /cgi-bin
Certain servers may try and execute any file in /cgi-bin if requested. This could cause problems, especially if text or data files are executed as shell script.
Applications like Drupal are intended to be easy for anyone to install, regardless of what permissions they may have on their web-host. This is the main reason it keeps everything together. If you have the ability to put files where you want, it is always a good practise to keep non-public files outside of the webroot. If you must keep them under the webroot, then ensure that you use your server's configuration to deny public access to the non-public files.

Resources