0

I'm new on the web server world, so please bear with me.

I'm trying to build my own API for mobile application using Ubuntu, Nginx and Lumen.

Everything was going fine till I came to upload images from the mobile app to my web server and save the URL in the mysql database backend.

Let's assume my project folder is named TestProject and I want to save the images under Testproject/public/Images/user_id/img.png.

What permissions should I use to make only the web server able to write the folders and images, and anybody else can only read the images via URL request only?

Update to clarify :

My major concern is the security (I don't want any to delete, add or execute files on my server) so to be more clear my scenario is as follows:

  • Mobile app user sends the images and user_id (to be used as sub folder name) via http/https post request.
  • On server side PHP-Lumen code will receive the images and save them under Testproject/public/Images/user_id/img.png (as I mentioned before, this step should be done only by the web server user; now I have only root) and then save the image's URL in MySQL database.
  • All mobile app users can read all the images via url (in mobile app reads mean download via http/https request).

My suggested solution :

Creating a new super user and make it the owner of all project folders and give it the permissions to read and write folders and files (which I don't know how to do) and give world the permission to only read all files inside the /images folder (which I also don't know how to do).

5
  • By "URL only" (yes I tweaked it a little to be URL request only, but same difference) do you mean that you also do not want non-webserver users on the server itself to be able to see the files as well? (Which would include your user, but would NOT include the root user because root is god and can essentially view all the system files without problem anyways)
    – Thomas Ward
    Jan 2, 2018 at 1:22
  • see if the answer I wrote here which is for Apache2 (but can be applied for NGINX without much issue) helps you - just revise /var/www/html from that answer to whatever filepath is on your system. And do not run this out of your home dir...
    – Thomas Ward
    Jan 2, 2018 at 1:46
  • 1
    The problem I see is the web server runs as www-data and I don't see any way to give www-data rw and ro access to a file at the same time.
    – Panther
    Jan 2, 2018 at 3:40
  • "Creating a new super user and make it the owner of all project folders and give it the permissions to read and write folders and files" ABSOLUTELY NOT from a security perspective. You will be adding a massive security hole to your environment, so DO NOT attempt this.
    – Thomas Ward
    Jan 2, 2018 at 18:27
  • "give world the permission to only read all files inside the /images folder " This is doable. If you were to read my answer I wrote and linked here for Apache2 but adapted it for your NGINX project, it'd work perfectly fine for what you need, giving the web server access to things (this is www-data, you do NOT need to have a new superuser for this step, just give www-data access to read and write and traverse in files/directories), and restrict it so that the /images folder is readable by everyone but not writable except by www-data.
    – Thomas Ward
    Jan 2, 2018 at 18:28

2 Answers 2

3

From what I can tell (and it's almost impossible to determine what you're really trying to solve/achieve - if anything it's probably an XY problem case), what you're trying to do is make it so that the webserver can read/write folders and files, but that the 'endpoint' that you've got for clients can only read data. You can't have it both ways without spinning two completely separate webservers with completely different permission sets. As was said in another answer, that doesn't protect you from having your main read/write webserver protected from attack.


From my interpretation, what you seem to want is to only let the webserver and the corresponding backend handle access to files and serving URLs for the endpoint clients to actually load (for images, etc.). That's not more than the basic webserver permissions that I touched upon in another answer. which I linked in comments (and below at the end of this answer.)


This is a summary of the steps you need to get a basic webserver filesystem permissions structure for this. You shouldn't have to do much more than this. If you do, then that's up to how you write your backend to handle permissions, and is beyond the scope of what's answerable here.

Step 1: Put the project directory in a web-server-accessible location, such as a folder under /var/www/ for the site name.

sudo mkdir /var/www/PROJECTDIR

Step 2: Put all your project files in there (as the root user to begin with).

Step 3: Change directory structure ownership for the new directory to www-data:www-data for the webserver.

sudo chown -R www-data:www-data /var/www/PROJECTDIR

Step 4: Give www-data user/group read/write/execute privileges for all directories, and read/write privileges for all files, within the project directory.

sudo find /var/www/PROJECTDIR -type d -exec chmod 770 {} \;
sudo find /var/www/PROJECTDIR -type f -exec chmod 660 {} \;

Step 5: You're done.

You don't seem to need any other user accounts on the system itself (non-root users, other system users, etc.) to be able to see anything within the subdirectories here, so the above will accomplish that.

You also don't seem to need any special permissions, because it's up to the backend you've written to properly handle whether a given request should in turn return a given URL for a given image on the system. If it doesn't have this type of permissions handling, that's an issue for your individual backend, not an NGINX issue, and not a system filepermissions issue.

Note though that as I said above, this is the same set of instructions from the other answer that does basically the same stuff.

2
  • Thanks for your answer man this is exactly what i was looking for, and I'm sorry if i didn't make it clear from the first place
    – Ali Adil
    Jan 4, 2018 at 10:36
  • 1
    A simpler command to set the access permissions recursively would be: sudo chmod -R ug=rwX,o= /var/www/PROJECTDIR. Jan 22, 2018 at 23:45
1

These two requirements are superficially contradictory:

What permissions should I use to make only the web server able to write the folders and images, and anybody else can only read the images via URL request only?

The web server process is both responsible for the reception, organisation and storage of new images and for their later retrieval. It needs write privileges to perform the first task. The only way around that is to run separate web servers for storage and retrieval with different privileges, however I'm not sure what you hope to gain through this: an attacker can still attack the image upload server which has write privileges.

2
  • As i mentioned I'm new with web servers, All what i need is (like a CMS for example) not make my Images folder public for any one and all API users requests can read the images via URLs but i don't know how to accomplish that
    – Ali Adil
    Jan 2, 2018 at 17:52
  • 1
    @AliAdil SOunds like an XY Problem. Also sounds to me like you should not be attempting your project with a web server without more understanding of the corresponding Linux filesystem and its permission handling. But that's my opinion as a system administrator, not as a site moderator.
    – Thomas Ward
    Jan 2, 2018 at 18:48

Not the answer you're looking for? Browse other questions tagged .