curl не может записать в директорию /tmp, принадлежащую пользователю.

Вопрос или проблема

Я пытался запустить скрипт, как указано в 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" (Ошибка доступа). Рассмотрим основные причины и решения этой проблемы.

Возможные причины

  1. Права доступа на директорию /tmp:
    Директория /tmp, как правило, имеет специальные разрешения. На вашей системе она настроена на использование drwxrwxrwt, что позволяет любому пользователю записывать туда временные файлы. Однако ваша временная директория, созданная через mktemp, имеет права drwx------, что означает, что только владелец может записывать в нее.

  2. Проблемы с исполняемыми файлами:
    Если curl был скомпилирован с установленным битом setuid и принадлежит пользователю, отличному от root или текущего пользователя, это может вызвать проблемы с разрешениями. В результате операции записи могут выполняться от имени другого пользователя с ограниченными правами.

    Проверьте права на файл curl:

    ls -ld /usr/bin/curl
  3. Ограничения безопасности:
    Если система использует такие механизмы безопасности, как AppArmor или SELinux, они могут ограничивать доступ curl к определенным директориям или файлам по различным причинам. Проверьте системные журналы, чтобы выявить возможные ошибки.

  4. Заполненность директории:
    Иногда проблема может возникать, если временная директория /tmp заполнена. При этом система просто не может выделить достаточно места для нового файла. Проверьте заполненность с помощью:

    df -h /tmp

Решения проблемы

  1. Проверка и настройка прав доступа:
    Убедитесь, что в вашей временной директории накладываются корректные права для записи:

    chmod 700 /tmp/tmp.U1nPTN5dlS
  2. Использование команд оболочки:
    Если вам нужно записать файл в текущую директорию, попробуйте использовать перенаправление, чтобы избежать проблем с правами доступа:

    curl -o docker.tgz https://download.docker.com/linux/static/stable/x86_64/docker-20.10.7.tgz
  3. Очистка временной директории:
    Если /tmp заполнен, освободите место, удалив неиспользуемые файлы:

    rm -rf /tmp/*
  4. Проверка настроек безопасности:
    Убедитесь, что механизмы безопасности, такие как AppArmor или SELinux, не блокируют curl. Вы можете временно отключить их и протестировать работу curl, наблюдая за системными журналами на предмет ошибок.

  5. Запуск с повышенными правами:
    В некоторых случаях может быть целесообразно запускать команды с использованием sudo, чтобы временно получить права администратора:

    sudo curl -L -o docker.tgz "$STATIC_RELEASE_URL"

Заключение

Проблемы с правами доступа и записью файлов в системных директориях часто имеют простые решения, но могут вызвать значительные затруднения. Главное – внимательно проверять все возможные аспекты, начиная от прав доступа и заканчивая настройками безопасности системы. Следуя приведенным рекомендациям, вы сможете устранить возникнувшую проблему и продолжить работу с Docker.

Оцените материал
Добавить комментарий

Капча загружается...