I have a CentOS server on which I have Apache, Django, Django CMS and mod_wsgi. My Django project files are stored in the /srv
directory and I have SELinux turned on for security reasons.
I've managed to successfully integrate Django-CMS into Django and when I visit the local IP, I see my pages. However, when I try to visit /admin (where I can start making use of the CMS functionality), I get DatabaseError at /admin/ attempt to write a readonly database
.
Okay.
So, since I have a .sqlite
file in my project folder, I ran a ls -l
on it which returned:
-rw-r--r--. 1 root root 133120 Jan 5 11:53 DATABASE.sqlite
Okay, so I figured perhaps Apache couldn't read that file due to some permissions reasons so after a bunch of research on similar problems on Stackoverflow, I ran:
> chmod 664 DATABASE.sqlite
> chown apache /srv/mysite
> chown apache /srv/mysite/DATABASE.sqlite
Now, the ls -l
output reads:
-rw-rw-r--. 1 apache root 133120 Jan 5 11:53 DATABASE.sqlite
Unfortunately, I still get the same error when trying to access /admin on my Django app. Any help would be greatly appreciated! Probably something to do with SELinux permissions but I have no idea where to start in diagnosing what permissions issue is going on.
EDIT:
I ran
> chown apache:apache /srv/mysite
> chown apache:apache /srv/mysite/DATABASE.sqlite
and a quick ls -l
reveals that the owner of the mysite
directory and the .sqlite
file is now apache
. However, I still get errors when trying to visit the /admin
page. I chmod
ed the /srv/mysite
directory to 757 and DATABASE.sqlite
file to 756 because that's the best I can do to get the permissions to work out. I was told that this is a security risk but I can't seem to figure out how to give it less permissions and get pass by unable to read/open database file
errors. Is it because of SELinux?
FYI, I'm operating under a regular user account in CentOS and sudo whenever I need to elevate:
[noblerare@localhost ]$
You have to add writing rights to the directory in which your sqlite database is stored. So running chmod -R u+w /srv/mysite/
should help.
If a server is using custom user (e.g. www-data
) to access the database, the solution could be to change the owner of your database:
chown www-data:www-data /srv/mysite
chown www-data:www-data /srv/mysite/DATABASE.sqlite
In short, it happens when the application which writes to the sqlite database does not have write permission.
This can be solved in three ways:
db.sqlite3
file and its parent directory (thereby write access also) to the user using chown (Eg: chown username db.sqlite3
)sudo -i
before you run gunicorn
or django runserver
)chmod 777 db.sqlite3
(Dangerous option)Never go for the third option unless you are running the webserver in a local machine or the data in the database is not at all important for you.
Second option is also not recommended. But you can go for it, if you are sure that your application is not vulnerable for code injection attack.
This issue is caused by SELinux. After setting file ownership just as you did, I hit this issue. The audit2why(1)
tool can be used to diagnose SELinux denials from the log:
(django)[f22-4:www/django/demo] ftweedal% sudo audit2why -a
type=AVC msg=audit(1437490152.208:407): avc: denied { write }
for pid=20330 comm="httpd" name="db.sqlite3" dev="dm-1" ino=52036
scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:httpd_sys_content_t:s0
tclass=file permissive=0
Was caused by:
The boolean httpd_unified was set incorrectly.
Description:
Allow httpd to unified
Allow access by executing:
# setsebool -P httpd_unified 1
Sure enough, running sudo setsebool -P httpd_unified 1
resolved the issue.
Looking into what httpd_unified
is for, I came across a fedora-selinux-list post which explains:
This Boolean is off by default, turning it on will allow all httpd executables to have full access to all content labeled with a http file context. Leaving it off makes sure that one httpd service can not interfere with another.
So turning on httpd_unified
lets you circumvent the default behaviour that prevents multiple httpd
instances on the same server - all running as user apache
- messing with each others' stuff.
In my case, I am only running one httpd
, so it was fine for me to turn on httpd_unified
. If you cannot do this, I suppose some more fine-grained labelling is needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With