I have two identical files (file contents are simply asd) with 644 permissions and owned by root:root, one created at 19:24 and the other created at 19:25.

The first file was uploaded via SFTP as root and the other one was created on the server directly by a sudoer. The files were then moved to the document root with one of them named index.html.

If the first file is named index.html, I get a 403-response when visiting my website:


You don't have permission to access /index.html on this server.

However, if the second file is named index.html it is served as expected and I can see asd on the page.

Result of ll when it works: enter image description here

Result of ll when I get 403 Forbidden: enter image description here

I am completely dumbfounded. What is happening here?

  • It is not clear which file is uploaded via SFTP and which one is created by "sudoers". I suggest editing the question to reflect that. – Dragas Dec 3 at 20:12
  • It is probably SELinux. Reset the labels on the objects in the directory. – jww Dec 4 at 5:33

Files have more attributes than ls -l shows. For example, many filesystems have several 'flag' attributes to change the file's behavior (visible in lsattr) and many can store arbitrary data in the form of extended attributes (visible in getfattr).

Linux is also not limited to just three classes of permissions; a file can have a list of users and groups assigned to it – this would be indicated by a plus sign + next to standard permissions, and the whole list would be visible in getfacl.

But in this case here, the dot . next to file permissions indicates that the file has a security context label applied to it, which indicates the file's purpose. You should be able to see this parameter in ls -Z and it's used by "Mandatory Access Control" modules – usually SELinux or sometimes SMACK – to enforce limits on which processes can access it even if the owner has set them to world-readable.

While SELinux can often automatically apply the correct label to files based on what directory they're created in, this does not work when the file was originally created elsewhere and only later moved into the final location. So if you run ls -lZ you'll probably see that the inaccessible file has a completely different label than the rest.

To fix this, you should be able to run restorecon on the file, which will set the correct context according to installed SELinux policy.

  • SELinux was precisely the issue. It had the user_home_t context (since it was uploaded there before being moved to the document root) rather than httpd_sys_content_t. I didn't have this problem on my previous VPS, so I had probably disabled SELinux there (not sure if a good idea or not). – Gendarme Dec 3 at 20:31

The dot after the ACLs means that there are extended rights.

getfacl index.html* should show the difference...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.