Операция не допускается при запуске 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
,
4 ответа
Я наконец-то понял. Проблема заключалась в том, что основная группа пользователя развертывания была неправильной. Это должен быть "персонал", но вместо этого он был "развернутым". Это означает, что Unicorn пытается передать права владения новыми рабочими процессами группе, которую он должен использовать, но это может сделать только 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>
Gid - это число после "х".
Если я вас хорошо понимаю, вы пытаетесь запустить службу без sudo
под обычным пользователем. Это не будет работать и выдаст ваши ошибки, подобные тем, которые вы получили. Операция не разрешена. Это верно в большинстве (если не во всех) случаях, потому что любой сервис будет требовать одно или несколько из следующих действий для своей работы:
- Привязка / прослушивание на портах < 1024.
- Чтение файлов, которые не могут быть прочитаны пользователем без полномочий root.
- Запись файла (ов) недоступна для записи не-root.
- и, возможно, больше (я не могу вспомнить).
Я столкнулся с той же проблемой. То, что закончилось тем, что работало для меня, установило следующее в моей конфигурации единорога в after_fork do |server, worker|
блок: (это из конфига github unicorn)
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
Я недавно потерял человека из-за этого. Контекст пытался запустить 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)>'
Обработка базы кода оператором print вокруг строки 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
Примечание: Единорог после крючка выше не работал для меня. Ничего не сработало, кроме этого.