3

I am working on Debian Jessie with Django 1.8, trying to set up Gunicorn to run my Django site. I have made a user called opuser, and made this user the owner of the gunicorn.sock file and of the containing directory:

$ 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 ..

Now if I try to run gunicorn as opuser:

gunicorn myapp.wsgi:application --name myapp_prod --workers 3 
  --bind=unix:/webapps/myapp/run/gunicorn.sock --user opuser 
  --group webapps --log-level=debug

I get:

OSError: [Errno 13] Permission denied: '/webapps/myapp/run/gunicorn.sock'

Why am I getting permission denied, when opuser is the owner of the containing directory?

If I run ls -lash /webapps/myapp/run again I see the following:

   0 srwxrwxrwx  1 anna   anna     0 Sep  1 12:24 gunicorn.sock

It looks like the gunicorn.sock file has really permissive permissions, though it's not being created with the owner I expected.

Here's the full output:

[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'

UPDATE: These are the permissions on the parent directories (which are /webapps and /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

UPDATE 2: If I su to opuser, I can create new files in /webapps/myapp/run okay, but I can't open the gunicorn.sock file in vi without getting a permissions error:

sudo su - opuser
touch /webapps/myapp/run/testfile
vi /webapps/myapp/run/gunicorn.sock

In vi I see ~/run/gunicorn.sock" [Permission Denied].

I guess this is the heart of the problem - but why can't I open it? The problem persists even if I do sudo chown opuser:webapps /webapps/myapp/run/gunicorn.sock and then try to open it again.

UPDATE 3: getfacl output for the file and all containing directories.

$ 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
Richard
  • 263
  • 2
  • 5
  • 11
  • What are the permissions on all the parent directories? – Michael Hampton Sep 01 '15 at 19:34
  • Which user has uid 999? What happens if you delete the socket and try again? – Mark Wagner Sep 01 '15 at 20:03
  • @MichaelHampton I've updated the question, thank you! – Richard Sep 01 '15 at 20:26
  • @MarkWagner `getent` shows that `opuser` is user 999. If I delete the socket and try again, I just get the same error. – Richard Sep 01 '15 at 20:27
  • So confused by this! :( – Richard Sep 01 '15 at 20:45
  • Try `--bind unix:/webapps/myapp/run/myapp.sock` (note the lack of `=`). Note that the socket it is trying to use is `/webapps/myapp/run/gunicorn.sock` which is not what you specified on the command line. – Mark Wagner Sep 01 '15 at 22:24
  • Also, you may want to tell Anna that you broke her app. :) – Mark Wagner Sep 01 '15 at 22:25
  • @MarkWagner well spotted, but I'm afraid it's not that, that's just a typo, now fixed! – Richard Sep 01 '15 at 22:50
  • What is actually causing the permissions error to fire? Is it opuser trying to write to gunicorn.sock? If so maybe I should try switching user to opuser and seeing if I can write to the file? – Richard Sep 01 '15 at 22:51
  • `su opuser -c touch /webapps/myapp/run/testfile` worked correctly? Maybe this user don't have shell? – strangeman Sep 01 '15 at 23:33
  • You might potentially want to find out what that + sign represents for the directory myapp. (+ means there's "some" extended permissions set, off the top of my head, getfacl/setfacl or lsattr/chattr, there may be more.). Combined with what the uid/euid gid/egid is for the process at the point which it fails. Other possible sources; SELinux, or some other security framework will also give you permission denied without it necessarily being visible from i.e. ls. – Kjetil Joergensen Sep 02 '15 at 01:42
  • @strangeman thanks for the suggestion, please see my update. – Richard Sep 02 '15 at 08:35
  • @KjetilJoergensen I'm just running Debian Jessie, with no security frameworks as far as I know. I've updated the question with `getfacl` output for the file and all containing directories. I think the included output shows the uid for the process where it fails, but please let me know if it doesn't. – Richard Sep 02 '15 at 08:42

0 Answers0