我正在使用 Django 1.8 在 Debian Jessie 上工作,试图设置 Gunicorn 来运行我的 Django 网站。我创建了一个名为 的用户,并让该用户成为文件和包含目录的opuser
所有者:gunicorn.sock
$ ls -lash /webapps/myapp/run/
total 8.0K
4.0K drwxrwxrwx 2 opuser users 4.0K Sep 1 12:24 .
4.0K drwxrwxrwx+ 7 opuser users 4.0K Sep 1 10:37 ..
现在如果我尝试以如下方式运行 gunicorn opuser
:
gunicorn myapp.wsgi:application --name myapp_prod --workers 3
--bind=unix:/webapps/myapp/run/gunicorn.sock --user opuser
--group webapps --log-level=debug
我得到:
OSError: [Errno 13] Permission denied: '/webapps/myapp/run/gunicorn.sock'
当 opuser 是包含目录的所有者时,为什么我被拒绝权限?
如果我ls -lash /webapps/myapp/run
再次运行,我会看到以下内容:
0 srwxrwxrwx 1 anna anna 0 Sep 1 12:24 gunicorn.sock
gunicorn.sock
尽管该文件不是由我期望的所有者创建的,但它似乎具有非常宽松的权限。
以下是完整输出:
[2015-09-01 11:18:36 +0000] [9439] [DEBUG] Current configuration:
proxy_protocol: False
worker_connections: 1000
statsd_host: None
max_requests_jitter: 0
post_fork: <function post_fork at 0x7efebefd2230>
pythonpath: None
enable_stdio_inheritance: False
worker_class: sync
ssl_version: 3
suppress_ragged_eofs: True
syslog: False
syslog_facility: user
when_ready: <function when_ready at 0x7efebefc6ed8>
pre_fork: <function pre_fork at 0x7efebefd20c8>
cert_reqs: 0
preload_app: False
keepalive: 2
accesslog: None
group: 999
graceful_timeout: 30
do_handshake_on_connect: False
spew: False
workers: 3
proc_name: myapp_prod
sendfile: True
pidfile: None
umask: 0
on_reload: <function on_reload at 0x7efebefc6d70>
pre_exec: <function pre_exec at 0x7efebefd27d0>
worker_tmp_dir: None
post_worker_init: <function post_worker_init at 0x7efebefd2398>
limit_request_fields: 100
on_exit: <function on_exit at 0x7efebefd2e60>
config: None
secure_scheme_headers: {'X-FORWARDED-PROTOCOL': 'ssl', 'X-FORWARDED-PROTO': 'https', 'X-FORWARDED-SSL': 'on'}
proxy_allow_ips: ['127.0.0.1']
pre_request: <function pre_request at 0x7efebefd2938>
post_request: <function post_request at 0x7efebefd2a28>
user: 999
forwarded_allow_ips: ['127.0.0.1']
worker_int: <function worker_int at 0x7efebefd2500>
threads: 1
max_requests: 0
limit_request_line: 4094
access_log_format: %(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"
certfile: None
worker_exit: <function worker_exit at 0x7efebefd2b90>
chdir: /webapps/myapp/myapp
paste: None
default_proc_name: myapp.wsgi:application
errorlog: -
loglevel: debug
logconfig: None
syslog_addr: udp://localhost:514
syslog_prefix: None
daemon: False
ciphers: TLSv1
on_starting: <function on_starting at 0x7efebefc6c08>
worker_abort: <function worker_abort at 0x7efebefd2668>
bind: ['unix:/webapps/myapp/run/gunicorn.sock']
raw_env: []
reload: False
check_config: False
limit_request_field_size: 8190
nworkers_changed: <function nworkers_changed at 0x7efebefd2cf8>
timeout: 30
ca_certs: None
django_settings: None
tmp_upload_dir: None
keyfile: None
backlog: 2048
logger_class: gunicorn.glogging.Logger
statsd_prefix:
[2015-09-01 11:18:36 +0000] [9439] [INFO] Starting gunicorn 19.3.0
Traceback (most recent call last):
File "/home/anna/.virtualenvs/myapp/bin/gunicorn", line 11, in <module>
sys.exit(run())
File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 74, in run
WSGIApplication("%(prog)s [OPTIONS] [APP_MODULE]").run()
File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 189, in run
super(Application, self).run()
File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/app/base.py", line 72, in run
Arbiter(self).run()
File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 171, in run
self.start()
File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/arbiter.py", line 130, in start
self.LISTENERS = create_sockets(self.cfg, self.log)
File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/sock.py", line 211, in create_sockets
sock = sock_type(addr, conf, log)
File "/home/anna/.virtualenvs/myapp/local/lib/python2.7/site-packages/gunicorn/sock.py", line 104, in __init__
os.remove(addr)
OSError: [Errno 13] Permission denied: '/webapps/myapp/run/gunicorn.sock'
更新:这些是父目录的权限(分别是/webapps
和/webapps/myapp
:
$ ls -lash /webapps/
total 12K
4.0K drwxrwxrwx 3 anna root 4.0K Aug 29 18:21 .
4.0K drwxrwxrwx+ 7 opuser users 4.0K Sep 1 10:37 myapp
更新 2:如果我 su 到opuser
,我可以在 中创建新文件/webapps/myapp/run
,但是我无法gunicorn.sock
在 vi 中打开该文件,否则会出现权限错误:
sudo su - opuser
touch /webapps/myapp/run/testfile
vi /webapps/myapp/run/gunicorn.sock
我vi
明白了~/run/gunicorn.sock" [Permission Denied]
。
我猜这是问题的核心——但为什么我打不开它?即使我打开sudo chown opuser:webapps /webapps/myapp/run/gunicorn.sock
它并再次尝试打开它,问题仍然存在。
更新 3: getfacl 输出文件和所有包含的目录。
$ getfacl /webapps/myapp/run/gunicorn.sock
getfacl: Removing leading '/' from absolute path names
# file: webapps/myapp/run/gunicorn.sock
# owner: opuser
# group: webapps
user::rwx
group::rwx
other::rwx
$ getfacl /webapps/myapp/run/
getfacl: Removing leading '/' from absolute path names
# file: webapps/myapp/run/
# owner: opuser
# group: users
user::rwx
group::rwx
other::rwx
$ getfacl /webapps/myapp/
getfacl: Removing leading '/' from absolute path names
# file: webapps/myapp/
# owner: opuser
# group: users
user::rwx
user:anna:rwx
group::r-x
mask::rwx
other::rwx
$ getfacl /webapps/
getfacl: Removing leading '/' from absolute path names
# file: webapps/
# owner: anna
# group: root
user::rwx
group::rwx
other::rwx