【问题标题】:Attempt to write a readonly database - Django w/ SELinux error尝试编写只读数据库 - 带有 SELinux 错误的 Django
【发布时间】:2014-01-30 00:17:37
【问题描述】:

我有一个 CentOS 服务器,上面有 Apache、Django、Django CMS 和 mod_wsgi。我的 Django 项目文件存储在 /srv 目录中,出于安全原因,我打开了 SELinux。

我已经成功地将 Django-CMS 集成到 Django 中,当我访问本地 IP 时,我看到了我的页面。但是,当我尝试访问 /admin(我可以开始使用 CMS 功能)时,我得到了DatabaseError at /admin/ attempt to write a readonly database

好的。

所以,由于我的项目文件夹中有一个.sqlite 文件,我在上面运行了一个ls -l,它返回:

-rw-r--r--.  1 root root 133120 Jan 5 11:53   DATABASE.sqlite

好的,所以我认为 Apache 可能由于某些权限原因无法读取该文件,所以在对 Stackoverflow 上的类似问题进行了大量研究之后,我运行了:

> chmod 664 DATABASE.sqlite
> chown apache /srv/mysite
> chown apache /srv/mysite/DATABASE.sqlite

现在,ls -l 输出显示为:

-rw-rw-r--.  1 apache root 133120 Jan 5 11:53  DATABASE.sqlite

不幸的是,在我的 Django 应用程序上尝试访问 /admin 时,我仍然遇到同样的错误。任何帮助将不胜感激!可能与 SELinux 权限有关,但我不知道从哪里开始诊断正在发生的权限问题。

编辑:

我跑了

> chown apache:apache /srv/mysite
> chown apache:apache /srv/mysite/DATABASE.sqlite

快速ls -l 显示mysite 目录和.sqlite 文件的所有者现在是apache。但是,在尝试访问 /admin 页面时,我仍然会遇到错误。我chmoded /srv/mysite 目录到 757 和 DATABASE.sqlite 文件到 756,因为这是我能做的最好的事情来获得锻炼的权限。有人告诉我这是一个安全风险,但我似乎无法弄清楚如何给予它更少的权限并通过unable to read/open database file 错误获得通过。是因为 SELinux 吗?

仅供参考,我在 CentOS 的普通用户帐户下操作,每当我需要提升权限时使用 sudo:

[noblerare@localhost ]$

【问题讨论】:

    标签: django sqlite selinux


    【解决方案1】:

    您必须向存储您的 sqlite 数据库的目录添加写入权限。所以运行chmod 664 /srv/mysite 应该会有所帮助。

    这是一个安全风险,因此更好的解决方案是将数据库的所有者更改为www-data

    chown www-data:www-data /srv/mysite
    chown www-data:www-data /srv/mysite/DATABASE.sqlite
    

    【讨论】:

    • 我最终为 /srv/mysite 做了 755,为 DATABASE.sqlite 做了 756。这是安全风险吗?如果我将其更改为其他任何内容,则会出错。
    • 感谢您的编辑。因为我在 CentOS 系统上,所以我使用 apache 而不是 www-data 运行 chown。无论如何,现在/srv/mysiteDATABASE.sqlite 的所有者是apache。但不管怎样,如果我将“所有人”权限更改为小于读/写/执行或读/写的权限,我就会出错。
    • 不幸的是,它对我没有用 - 仍然无法打开,甚至无法再 cd 到数据库目录 bc 权限:(
    【解决方案2】:

    简而言之,就是写入sqlite数据库的应用程序没有写入权限。

    这可以通过三种方式解决:

    1. 使用 chown 向用户授予 db.sqlite3 文件及其父目录的所有权(因此也可以写入)(例如:chown username db.sqlite3
    2. 以 root 用户身份运行网络服务器(通常是 gunicorn)(在运行 gunicorn 或 django runserver 之前运行命令 sudo -i
    3. 通过运行命令chmod 777 db.sqlite3(危险选项)允许对所有用户进行读写访问

    永远不要选择第三个选项,除非您在本地机器上运行网络服务器,或者数据库中的数据对您来说根本不重要。

    第二个选项也不推荐。但是,如果您确定您的应用程序不受代码注入攻击的影响,您可以选择它。

    【讨论】:

      【解决方案3】:

      这个问题是由 SELinux 引起的。在像你一样设置文件所有权之后,我遇到了这个问题。 audit2why(1) 工具可用于从日志中诊断 SELinux 拒绝:

      (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
      

      果然,运行sudo setsebool -P httpd_unified 1 解决了这个问题。

      查看httpd_unified 的用途,我遇到了fedora-selinux-list post,它解释说:

      这个布尔值默认是关闭的,打开它会允许所有的httpd 可执行文件具有对标有 http 文件的所有内容的完全访问权限 语境。将其关闭可确保一项 httpd 服务不能 干扰他人。

      因此,打开 httpd_unified 可以规避默认行为,该行为会阻止同一服务器上的多个 httpd 实例 - 都以用户 apache 的身份运行 - 弄乱彼此的东西。

      就我而言,我只运行了一个httpd,所以我可以打开httpd_unified。如果你不能做到这一点,我想需要一些更细粒度的标签。

      【讨论】:

      • 这解决了我的问题。连续两天为此苦苦挣扎。即使在向 /var/ 授予 777 权限(这有点破坏性)之后,我也无法修复它。非常感谢!
      • @AakashRayate 一样!我觉得我在整个文件夹上做了太多的 777。
      【解决方案4】:

      我遇到了这个问题,我通过在 mysite 文件夹中创建一个目录来保存我的 db.sqlite3 文件来解决它。所以我做了/home/user/src/mysite/database/db.sqlite3。在我的 django 设置文件中,我更改了我的

       DATABASES = {
      'default': {
          'ENGINE': 'django.db.backends.sqlite3',
          'NAME': "/home/user/src/mysite/database/db.sqlite3" ,
      }}
      

      我这样做是为了让 Django 知道我将我的数据库存储在基本目录的子目录中,在我的例子中是 mysite。现在您需要授予 apache 能够读写数据库的权限。

      chown user:www-data database/db.sqlite3
      chown user:www-data database 
      chmod 755 database
       chmod 755 database/db.sqlite3
      

      这解决了我的问题。这是不同权限的列表。您可以使用选择适合您的那一款 但避免使用 777 和 666

      -rw-------- (600) -- 只有用户有读写权限。

      -rw-r--r-- (644) -- 只有用户有读写权限;该组和其他人只能阅读。

      -rwx------ (700) -- 只有用户有读、写和执行权限。

      -rwxr-xr-x (755) -- 用户有读、写和执行权限;该组和其他人只能读取和执行。

      -rwx--x--x (711) -- 用户有读、写和执行权限;该组和其他人只能执行。

      -rw-rw-rw- (666) -- 每个人都可以读写文件。坏主意。

      -rwxrwxrwx (777) -- 每个人都可以读、写和执行。另一个坏主意。

      以下是一些常用的目录设置:

      drwx------ (700) -- 只有用户可以读,写这个目录。

      drwxr-xr-x (755) -- 每个人都可以读取目录,但其内容只能由用户更改。

      这里是一篇文章的链接,可以[了解更多][1]

      [1]:http://ftp.kh.edu.tw/Linux/Redhat/en_6.2/doc/gsg/s1-navigating-chmodnum.htm#:~:text=%2Drwxr%2Dxr%2Dx %20(,and%20others%20can%20only%20execute.

      【讨论】:

        【解决方案5】:

        我在 Ubuntu Server 上遇到了同样的问题。 所以我所做的只是在为 django 激活虚拟环境之前更改为超级用户,然后我运行 django 服务器。 对我来说效果很好。

        先复制粘贴

        sudo su

        如果你有虚拟环境,那就激活它。

        source myvenv/bin/activate

        最后运行你的 django 服务器。

        python3 manage.py runserver

        希望对你有所帮助。

        【讨论】:

          【解决方案6】:

          我遇到了类似的问题。要检查 SELinux 是否是问题所在,可以使用

          检查其运行状态
          sestatus
          

          并使用

          暂时禁用它
          setenforce 0
          

          这至少可以帮助缩小问题范围。

          【讨论】:

          • 这帮助我解决了 Centos 7 中的问题
          【解决方案7】:

          您可以更改acl,而无需触及文件/目录的所有权和权限。

          使用以下命令:

          setfacl -m u:www-data:rwx /home/user/website
          setfacl -m u:www-data:rw /home/user/website/db.sqlite3
          

          【讨论】:

            【解决方案8】:

            您可以将数据库文件的所有者及其文件夹更改为django

            chown django:django /home/django/mysite
            chown django:django /home/django/mysite/my_db.sqlite3
            

            这适用于 DigitalOcean 的 1-Click Django Droplet

            【讨论】:

              【解决方案9】:

              这是我的解决方案:

              root@fiq:/home/django/django_project# chmod 777 db.sqlite3
              root@fiq:/home/django/django_project# cd ..
              root@fiq:/home/django# chmod 777 *
              

              转到<'your_website/admin'>输入用户名和密码..就是这样。

              【讨论】:

              • 非常不安全,您将 777 设置为 DB,因为 SQLite 的数据库是自包含在文件中的,它实际上将 777 提供给您服务器上的任何用户。
              • 那真是个坏主意。
              • 这个答案是个笑话。任何人都不应该这样做。
              猜你喜欢
              • 2014-12-07
              • 2016-03-14
              • 2023-03-09
              • 2021-11-07
              • 2016-08-16
              • 2016-10-20
              • 2011-01-20
              • 1970-01-01
              • 2015-10-27
              相关资源
              最近更新 更多