Ruby: не удалось найти временный каталог

Я получаю около 500 ошибок в своем приложении Passenger Rails. При просмотре журнала выясняется, что пассажир не может получить доступ к каталогу /tmp. Я проверил, что он есть и имеет RW-доступ к root, а затем попробовал www-data. Что здесь происходит?

 2014-01-14 16:01:16.6573 20624/7fa7c8806700 Pool2/SmartSpawner.h:301 ]: Preloader for /var/www/socialrest_homepage started on PID 20686, listening on unix:/tmp/passenger.1.0.20618/generation-0/backends/preloader.20686
App 20704 stdout: 
[Tue Jan 14 16:01:17 2014] [error] [client 168.215.171.129] Premature end of script headers: 
App 20686 stderr: /usr/local/rvm/rubies/ruby-2.0.0-p353/lib/ruby/2.0.0/tmpdir.rb:34:in `tmpdir': could not find a temporary directory (ArgumentError)
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/utils/tmpio.rb:17:in `new'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/utils/tee_input.rb:99:in `initialize'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/rack/thread_handler_extension.rb:55:in `new'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/rack/thread_handler_extension.rb:55:in `process_request'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/request_handler/thread_handler.rb:141:in `accept_and_process_next_request'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/request_handler/thread_handler.rb:109:in `main_loop'
App 20686 stderr:   from /usr/local/rvm/gems/ruby-2.0.0-p353/gems/passenger-4.0.33/lib/phusion_passenger/request_handler.rb:440:in `block (3 levels) in start_threads'
[ 2014-01-14 16:01:21.0163 20624/7fa7cb242700 Pool2/Pool.h:776 ]: Process (pid=20704, group=/var/www/socialrest_homepage#default) no longer exists! Detaching it from the pool.
App 20720 stdout:

Вот мои текущие права собственности на /tmp и config/environment.rb:

drwxrwxrwx   5 root root 4.0K Jan 14 16:01 tmp

-rwxr-xr-x  1 root root  196 Jan 13 20:06 environment.rb

person Clayton Selby    schedule 14.01.2014    source источник


Ответы (3)


Наиболее важной частью трассировки стека является сообщение об ошибке:

could not find a temporary directory (ArgumentError)

Когда вы указываете Ruby >= 2.0 создать временный файл, он ищет каталог, в котором он может создать файл безопасным способом. Создание временных файлов в каталоге, где любой может заменить файл, пока вы над ним работаете, было бы большой (и распространенной) дырой в безопасности!

У вас есть две возможности:

  • Сообщите ruby, где он может безопасно создавать временные файлы, установив одну из переменных среды TMPDIR, TMP или TEMP в безопасный каталог.

  • Исправьте разрешения для каталога, который ruby ​​все равно пытается использовать. Каталоги, которые Ruby все равно пытается использовать: systempdir ("/tmp") и текущий каталог

Ruby считает каталог безопасным, если он либо недоступен для записи всем, либо имеет установленный липкий бит. (Не путайте закрепленный бит (t) с битом seteuid/setgid (s)!)

Таким образом, вместо установки TMPDIR вы можете либо сделать свой рабочий каталог недоступным для записи всем, либо сделать:

chmod +t /tmp

Страница руководства chmod объясняет использование липкого бита:

[Это] запрещает непривилегированным пользователям удалять или переименовывать файл в каталоге, если они не владеют файлом или каталогом; это называется флагом ограниченного удаления для каталога и обычно встречается в доступных для записи каталогах, таких как /tmp.

Вот что может произойти без липкого бита: https://security.stackexchange.com/questions/9115/can-you-describe-a-real-life-scenario-of-exploiting-sticky-bits/108666#108666

См. также: https://blog.diacode.com/fixing-temporary-dir-problems-with-ruby-2

person hagello    schedule 02.07.2015
comment
Да, это оно. 777 не работает. Если вы сделаете 777 в своем каталоге /tmp, вы можете исправить это с помощью предложенного chmod +t /tmp @hagello. - person Travis Reeder; 16.11.2016

Не уверен, что здесь произошло, но я полагаю, что это как-то связано с разрешениями на папку /tmp. Я думал, что моя папка /tmp была повреждена, поэтому я посмотрел вокруг, чтобы удалить эту папку и восстановить ее (я не был уверен, что эта папка имеет особое значение в том, как она была создана). Я нашел этот источник, в котором предлагалось просто создать папку /tmp, как и любой другой другую папку, а затем выполните chmod 1777 для только что созданной папки.

Итак, вместо того, чтобы удалить мой текущий /tmp, я запустил эту команду chmod, и все заработало.

Что странно для меня, так это то, что я ранее сделал chmod 777, и это привело к тому, что папка не работала. Странный...

person Clayton Selby    schedule 14.01.2014
comment
спасатель жизни. Устраняйте эту проблему только для определенных страниц непосредственно перед началом пользовательского тестирования. Первый результат в bing и сразу решил его. Спасибо, что поделился - person jbagavathi; 06.01.2015
comment
chmod 777 /tmp удаляет липкий бит из каталога. Без липкого бита любой может удалить, переименовать или заменить файл из/в каталоге в любое время. Это серьезная проблема безопасности. - person hagello; 03.07.2015
comment
Объяснение, почему chmod 777 /tmp — плохая идея: security.stackexchange.com/questions/9115/ - person hagello; 15.02.2016

ls -l /

$drwxrwxrw   9 root     root      4096 Jun 26 11:34 tmp

Если вы не видите t в конце столбца разрешений '/tmp'

chmod o+t /tmp
chmod 1777 /tmp    
$ ls -l / 
drwxrwxrwt   9 root     root      4096 Jun 26 11:35 tmp

причина в Устранение временных проблем с каталогами в Ruby 2

person Albert.Qing    schedule 01.08.2015