Вопрос или проблема
Я пытался запустить скрипт, как указано в https://docs.docker.com/engine/security/rootless/:
$ curl -fsSL https://get.docker.com/rootless | sh
Но скрипт завершился с ошибкой на следующей строке:
curl -L -o docker.tgz "$STATIC_RELEASE_URL"
С сообщением:
Warning: Failed to create the file docker.tgz: Permission denied
curl: (23) Failure writing output to destination
Я сузил проблему до того, что curl
пытается записать в папку tmp
, созданную с помощью mktemp -d
, но не понимаю, почему это не удается.
Некоторый контекст:
$ whoami
thiago
$ uname -a
Linux thiago-acer 5.8.0-55-generic #62~20.04.1-Ubuntu SMP Wed Jun 2 08:55:04 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ mktemp -d
/tmp/tmp.U1nPTN5dlS
$ cd /tmp/tmp.U1nPTN5dlS
$ ls -la
total 8
drwx------ 2 thiago thiago 4096 Jun 17 18:20 .
drwxrwxrwt 25 root root 4096 Jun 17 18:20 ..
После выполнения вышеуказанных команд я попробовал:
# это завершается с той же ошибкой, что и выше
curl https://download.docker.com/linux/static/stable/x86_64/docker-20.10.7.tgz -O
# это работает отлично
curl https://download.docker.com/linux/static/stable/x86_64/docker-20.10.7.tgz -o - > docker-20.10.7.tgz
# это тоже работает
wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.7.tgz
Команда curl -O
также работает, если я пробую ее в другой папке, например, в своей домашней папке.
Буду благодарен за любую помощь.
Я не знаю, сколько людей это поможет, но делюсь на всякий случай, если это поможет кому-то. У меня была ошибка Failure writing output to destination
, но не ошибка Permission denied
.
Это было связано с тем, что моя директория /tmp
была заполнена
$ df -h /tmp
Filesystem Size Used Avail Use% Mounted on
tmpfs 7.8G 7.8G 0 100% /tmp
Очистка моей директории /tmp
разрешила мою проблему.
Это поведение можно объяснить, если по какой-то причине исполняемый файл curl
имел установленный бит setuid в своих разрешениях и принадлежал пользователю, отличному от root
или thiago
.
Как в:
$ ls -ld /usr/bin/curl
-rwsr-xr-x 1 nobody nogroup 260328 Mar 14 16:37 /usr/bin/curl*
curl -o file
будет завершаться с ошибкой, потому что file
будет открыт nobody
, у которого нет прав на запись в эту директорию, в то время как curl -o - > file
будет работать, потому что файл открывается оболочкой, работающей от имени thiago
, а не curl
.
Еще одно возможное объяснение может быть связано с тем, что какой-то apparmor
, SELinux или другая система безопасности MAC отказывает curl
в создании файлов в /tmp
.
Системные или аудиторские журналы должны содержать больше информации в этом случае.
Ответ или решение
Не удается записать файл с помощью curl в директорию /tmp, принадлежащую пользователю
Это распространенная проблема, с которой могут столкнуться пользователи, работающие с инструментами командной строки, такими как curl
. В данном случае, проблема заключается в том, что команда curl
не может создать файл docker.tgz
в временной директории, созданной с помощью mktemp -d
, что вызывает сообщение об ошибке "Permission denied" (Ошибка доступа). Рассмотрим основные причины и решения этой проблемы.
Возможные причины
-
Права доступа на директорию /tmp:
Директория/tmp
, как правило, имеет специальные разрешения. На вашей системе она настроена на использованиеdrwxrwxrwt
, что позволяет любому пользователю записывать туда временные файлы. Однако ваша временная директория, созданная черезmktemp
, имеет праваdrwx------
, что означает, что только владелец может записывать в нее. -
Проблемы с исполняемыми файлами:
Еслиcurl
был скомпилирован с установленным битом setuid и принадлежит пользователю, отличному отroot
или текущего пользователя, это может вызвать проблемы с разрешениями. В результате операции записи могут выполняться от имени другого пользователя с ограниченными правами.Проверьте права на файл
curl
:ls -ld /usr/bin/curl
-
Ограничения безопасности:
Если система использует такие механизмы безопасности, как AppArmor или SELinux, они могут ограничивать доступcurl
к определенным директориям или файлам по различным причинам. Проверьте системные журналы, чтобы выявить возможные ошибки. -
Заполненность директории:
Иногда проблема может возникать, если временная директория/tmp
заполнена. При этом система просто не может выделить достаточно места для нового файла. Проверьте заполненность с помощью:df -h /tmp
Решения проблемы
-
Проверка и настройка прав доступа:
Убедитесь, что в вашей временной директории накладываются корректные права для записи:chmod 700 /tmp/tmp.U1nPTN5dlS
-
Использование команд оболочки:
Если вам нужно записать файл в текущую директорию, попробуйте использовать перенаправление, чтобы избежать проблем с правами доступа:curl -o docker.tgz https://download.docker.com/linux/static/stable/x86_64/docker-20.10.7.tgz
-
Очистка временной директории:
Если/tmp
заполнен, освободите место, удалив неиспользуемые файлы:rm -rf /tmp/*
-
Проверка настроек безопасности:
Убедитесь, что механизмы безопасности, такие как AppArmor или SELinux, не блокируютcurl
. Вы можете временно отключить их и протестировать работуcurl
, наблюдая за системными журналами на предмет ошибок. -
Запуск с повышенными правами:
В некоторых случаях может быть целесообразно запускать команды с использованиемsudo
, чтобы временно получить права администратора:sudo curl -L -o docker.tgz "$STATIC_RELEASE_URL"
Заключение
Проблемы с правами доступа и записью файлов в системных директориях часто имеют простые решения, но могут вызвать значительные затруднения. Главное – внимательно проверять все возможные аспекты, начиная от прав доступа и заканчивая настройками безопасности системы. Следуя приведенным рекомендациям, вы сможете устранить возникнувшую проблему и продолжить работу с Docker.