delyodobrev
delyodobrev

Reputation: 65

Apache doesn't allow to load other files than index.html

Before you ask, I tried to search for similar questions, none of them had precisely my problem.
I'm new at this, and I installed Apache2, PHP5, and MySQL5 on a RasPi running Raspbian.
As needed, I put the index.html in /var/www/html and when I type my Pi's IP alone or followed by /index.html, index.html runs its code properly and all elements appear.

Problem: In addition I put my JS and CSS files in that same folder, as well as a few photos to display.
The browser reads the HTML thoroughly, but doesn't load the thereby linked JS and CSS files nor the images. Putting the files in subfolders also didn't help.
When I type in the IP followed by a /style.css (name of my linked CSS file), I get a 403 Forbidden. The errors log also shows this:

 file permissions deny server access: /var/www/html/photo.jpg, referer: http://192.168.178.120/
 access to /images/dark.jpg denied because search permissions are missing on a component of the path, referer: http://192.168.178.120/


I tried researching this but nothing helped. When my JS and CSS are inside my HTML, everything works fine except the images
Concluded: Apache doesn't allow the browser to load files other than index.html.
Do you know what the issue might be? Is there a specific folder where I should put my other files? Thanks in advance.

Upvotes: 1

Views: 5967

Answers (1)

rickdenhaan
rickdenhaan

Reputation: 11328

Based on the result from ls, your files are not accessible to Apache.

Short answer:

Run the following two commands:

find /var/www/html -type f -exec chmod 644 {} \;

find /var/www/html -type d -exec chmod 755 {} \;

Longer explanation:

pi@raspberrypi:~ $ ls -l /var/www/html
total 2976
-rw------- 1 pi pi     60146 Jul 23 22:11 bnw.jpg
-rw------- 1 pi pi    202851 Jul 23 22:11 color.jpg
-rw------- 1 pi pi    617185 Jul 23 21:27 dark.jpg
-rw------- 1 pi pi   2028727 Jul 23 22:11 effect.jpg
drwx------ 2 pi pi      4096 Jul 23 21:33 images
-rw------- 1 pi pi      2238 Jul 23 22:11 index.css
-rw-r--r-- 1 pi root    1261 Jul 23 22:11 index.html
-rw------- 1 pi pi    108397 Jul 23 22:11 photo.jpg
-rw------- 1 pi pi       538 Jul 23 22:11 script.js
-rw------- 1 pi pi      2238 Jul 23 21:33 style.css

The symbols at the beginning of the line have the following meaning:

d: indicates a directory
r: means the file/directory is readable
w: means the file/directory is writable
x: means the file/directory is executable

-: means none of the above apply

These symbols are grouped as follows:

drwxrwxrwx
       ^^^ apply to all users on the system
    ^^^--- apply to all users in the group that owns the file
 ^^^------ apply to the user that owns the file

Where it says pi pi it's referring to the file's owner: the user pi in the group pi. Your index.html file is an exception, because it's owned by the group root.

That's not really important for now, other than that you need to realise that Apache usually runs as the user www-data in the group www-data. This varies a bit from system to system, but that's the most common. What that means is that for Apache to be able to access a file, it must be made available to either the www-data user or the www-data group (or both).

In your case, the files are owned by the user pi and the group pi (with the exception of index.html, which is owned by the group root. Since Apache is not that user and is most likely not in either of those groups, that means the file permissions for "all users on the system" must be set correctly for Apache to be able to access the file.

As you can see, index.html is set to be readable for all users on the system:

-rw-r--r-- 1 pi root    1261 Jul 23 22:11 index.html
       ^^^ all users on the system may read from this file, but may not write and may not execute the file
    ^^^--- all users in the group "root" may read from this file, but may not write and may not execute the file
 ^^^------ the user "pi" may read from and write to this file, but may not execute the file

All other files, including the images directory, are only accessible to the "pi" user:

-rw------- 1 pi pi   2028727 Jul 23 22:11 effect.jpg
       ^^^ all users on the system may not read from, write to or execute this file
    ^^^--- all users in the group "pi" may not read from, write to or execute this file
 ^^^------ the user "pi" may read from and write to this file, but may not execute it

So for effect.jpg to be made available to Apache, you need to change the file permissions to this:

-rw----r-- 1 pi pi   2028727 Jul 23 22:11 effect.jpg
       ^^^ all users on the system (including Apache) may read from this file

To do that, you use the chmod command. There are two ways to flip that permission:

chmod o+r effect.jpg

chmod 604 effect.jpg

chmod o+r means "add 'r' permission to the 'other users' category" (you'd use u+r or g+r to change the user or group permissions). chmod 604 means "set permissions for the user to 6, group to 0 and others to 4" - where the numbers are a binary sum of the permissions: 1 (executable), 2 (writable), 4 (readable).

Directories need a little more work:

drwx------ 2 pi pi      4096 Jul 23 21:33 images

To allow the file system to actually open a directory and read the files within, it needs to be executable for the user that's trying to access its content. So to allow Apache to read any file from this folder, it will need to have the following permissions:

drwx---r-x 2 pi pi      4096 Jul 23 21:33 images
       ^^^ all users on the system may read from this directory and execute it

To do this, use the same principle:

chmod o+rx images (other users, add readable and executable permissions)

chmod 705 images (set read(4)+write(2)+execute(1) for owner and read(4)+execute(1) for all other users)

Now, although it's not strictly necessary if the owner and group are the same, it is best practice to make sure that the group has the same permissions as the "all other users" category. So instead of giving files 604 (-rw----r--) and folders 705 (drwx---r-x), it's best practice to give them 644 (-rw-r--r--) and 755 (drwxr-xr-x). If you're working in an environment where multiple developers need to be able to modify the files, they should be in the same user group and best practice is to give the group the same permissions as the owner, so 644 (-rw-rw-r--) and 775 (drwxrwxr-x).

Finally, you don't want to have to change all file permissions manually. This particular project seems to be relatively small, but it's still annoying work. Fortunately, we can use the find command to perform a batch update.

find will list the full contents of the given folder, including subfolders, which you can then filter or perform actions on.

find /var/www/html -type f

This will list all entries within /var/www/html or any subfolders that are a regular file.

find /var/www/html -type d

This will list all entries within /var/www/html or any subfolders that are directories.

We can use -exec to tell find to automatically perform a certain command on each file/folder it finds:

find /var/www/html -type f -exec chmod 644 {} \;

The {} is a placeholder where find will put each filename. The \; is needed to inform find that no further arguments for the -exec command will be provided, so we can optionally add other arguments for find itself.

So the above command will fix the permissions for all files, the following command will fix the permissions for all folders:

find /var/www/html -type d -exec chmod 755 {} \;

After that, Apache should have access to all files and folders in /var/www/html. Keep in mind that, every time you create a new file in that folder, you need to check the permissions and fix it if necessary.

Upvotes: 1

Related Questions