Назад | Перейти на главную страницу

Операция запрещена при запуске Unicorn

Я создал установку nginx / unicorn / capistrato на Ubuntu (Amazon EC2), следуя в основном это руководство. Я думаю, все настроено так, как должно, но когда я запускаю Unicorn, я получаю (МНОГО) эту ошибку в журнале:

E, [2012-09-08T08:57:20.658092 #12356] ERROR -- : Operation not permitted (Errno::EPERM)
/home/deployer/apps/bridgekalenderen.no/shared/bundle/ruby/1.9.1/gems/unicorn-4.3.1/lib/unicorn/worker.rb:82:in `initgroups'

Я вижу, что это связано с разрешениями пользователя, но я просто не могу понять, что я упустил. Сервер запускается нормально, если я запускаю его с помощью sudo (или, на самом деле, rvmsudo).

У пользователя есть возможности sudo, я несколько раз редактировал приложение chmod, поэтому права доступа к файлам должны быть в порядке. Сокет единорога в / tmp принадлежит пользователю программы развертывания, так что это тоже не должно быть проблемой.

Кто-нибудь знает, где искать?

ОБНОВИТЬ:

Покопавшись, я обнаружил, что все сводится к звонку в Process.initgroups который бросает EPERM. Я проверил это в irb. Я не могу понять, что вызывает ошибку. Пользователь может читать /etc/group.

Если я вас хорошо понимаю, вы пытаетесь запустить службу без sudo под обычным пользователем. Это не сработает и приведет к появлению ошибок, подобных тем, которые вы получили. операция не разрешена. Это верно в большинстве (если не во всех) случаях, потому что любая служба потребует одного или нескольких из следующих действий для выполнения своей работы:

  1. Привязка / прослушивание портов <1024.
  2. Чтение файлов, недоступных для чтения пользователям без полномочий root.
  3. Запись файла (ов), недоступного для записи пользователем без полномочий root.
  4. а возможно и больше (не могу вспомнить).

Я наконец-то понял. Проблема заключалась в том, что основная группа пользователя развертывателя была неправильной. Это должно быть «штат», но вместо «развертывающий». Это означает, что единорог пытается передать право собственности на новые рабочие процессы группе, которую он должен использовать, но это может сделать только root.

На всякий случай, если кому-то еще нужно знать, я изменил основную группу, отредактировав /etc/passwd как это:

deployer:x:1002:50:,,,:/home/deployer:/bin/bash

«50» - это слово «посох». Начнем с 1002 года. Чтобы получить гид группы "персонал", выполните:

cat /etc/group | grep staff

Он скажет что-то вроде:

staff:x:50:<comma separated list of users in this group>

Гид - это число после "х".

Я недавно потерял из-за этого один мужской день. Контекст пытался запустить Unicorn для пользователя с именем apps, и ошибка Errno :: EPERM продолжала нас кусать. Вот трассировка стека:

E, [2018-04-12T20:45:07.277588 #2048] ERROR -- : Operation not permitted (Errno::EPERM)
/apps/cas-seas3/shared/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/worker.rb:143:in `initgroups'
/apps/cas-seas3/shared/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/worker.rb:143:in `user'
/apps/cas-seas3/shared/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:657:in `init_worker_process'
/apps/cas-seas3/shared/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:682:in `worker_loop'
/apps/cas-seas3/shared/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:549:in `spawn_missing_workers'
/apps/cas-seas3/shared/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:563:in `maintain_worker_count'
/apps/cas-seas3/shared/bundle/ruby/2.2.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:293:in `join'
/apps/cas-seas3/shared/bundle/ruby/2.2.0/gems/unicorn-5.4.0/bin/unicorn:126:in `<top (required)>'
/apps/cas-seas3/shared/bundle/ruby/2.2.0/bin/unicorn:23:in `load'
/apps/cas-seas3/shared/bundle/ruby/2.2.0/bin/unicorn:23:in `<top (required)>'

Инструментирование базы кода с помощью оператора печати около строки 143 дало нам следующую отладочную информацию:

user = apps
group=apps
uid=1040
gid=110
whoami=apps
Process.egid = 1001

Это несоответствие между gid и Process.egid вызвало этот блок кода:

if gid && Process.egid != gid
  Process.initgroups(user, gid)
  Process::GID.change_privilege(gid)
end

и вот что стало причиной отказа.

Я наконец проследил это до разницы между GID / EGID, и проблема заключалась в том, что пользователь приложения принадлежал к другой основной группе (admin). Когда я переместил пользователя приложений в группу приложений в качестве основной, это сработало. Это было сделано путем редактирования файла / etc / passwd, который определял учетные записи пользователей ящика.

Другой способ проверить это - использовать sg для ручного запуска единорога с правильной группой с помощью команды sg, например:

bundle exec sg apps -c unicorn -c /apps/cas-seas3/current/config/unicorn.rb -E deployment -D

Если вы обнаружите, что это работает, это очень хороший знак, чтобы изучить настройки вашего пользователя / группы.

Unicorn, кажется, очень чувствителен к настройкам пользователя / группы для проверки / etc / passwd и / etc / group, а также использует эту строку ps для проверки различий в выполняемом процессе Unicorn на предмет различий в UID и GID:

ps -eo uid,gid,egid,args | grep unicorn

Примечание: единорог после крючка выше у меня не сработал. Кроме этого ничего не работало.

Я столкнулся с той же проблемой. Что в итоге сработало для меня, так это установка следующего в моей конфигурации единорога в after_fork do |server, worker| блок: (это из конфигурации единорога github)

  begin
    uid, gid = Process.euid, Process.egid
    user, group = 'deployer', 'staff'
    target_uid = Etc.getpwnam(user).uid
    target_gid = Etc.getgrnam(group).gid
    worker.tmp.chown(target_uid, target_gid)
    if uid != target_uid || gid != target_gid
      Process.initgroups(user, target_gid)
      Process::GID.change_privilege(target_gid)
      Process::UID.change_privilege(target_uid)
    end
  rescue => e
    if RAILS_ENV == 'development'
      STDERR.puts "couldn't change user, oh well"
    else
      raise e
    end
  end