Как и у любого пользователя Андроид у меня есть аккаунт в Гугле. А значит, кроме всего прочего, есть аж целых 15 гигабайт облачного хранилища, где можно что-то хранить, на случай всяких внезапных проблем с локальным оборудованием.

Традиционно, для этого используется либо приложение Google Drive, либо веб-интерфейс. Но ни то, ни другое не очень-то удобно на компьютере, особенно когда привык просто работать с произвольными файлами, которые куда-нибудь копируются.
И тем более - плохо подходит для автоматизации.

Второй возникающий вопрос - всё, что хранится не в вашем собственном облачном хранилище - в принципе доступно кому-нибудь не вам. И хорошо, если ваши личные документы читает какой-нибудь бот, для которого вы - всего лишь один из миллиардов анонимусов, хуже если информация утечет куда не надо и попадет кому не нужно.

Вот эти две проблемки попробуем решить.

Для работы с разными облачными системами есть неплохая программа rclone.
У нее много полезных возможностей, в чем-то она напоминает rsync, только умеет работать с разными облаками и протоколами обмена, но в данном случае это не обзор программы, а просто описание подхода в целом.

Итак, установим rclone:

apt install rclone  

Общий принцип следующий: нужно зарегистрировать в программе удаленное хранилище, затем создать локальный каталог, и можно копировать туда‑сюда файлы, синхронизировать их с облаком, или просто загружать и удалять отдельные файлы.

Имеется подробный man, несложный синтаксис команд. Всё это из командной строки, то есть можно легко автоматизировать задачи создания бекапов.

В моем случае — на локальном сервере выделяю каталог, данные из которого будут периодически заливаться на Drive.

Но, учитывая возможность что Google в любой момент может стать недоступным, по разным там причинам, будет еще один сервер, в другом месте, который будет забирать с Drive залитые туда файлы.

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

Настраиваем rclone:

rclone config  
  New remote  
  Назовем его как-то - test1  
  Укажем тип - drive  
  Client id - если уже есть, можно указать свой, если нет - оставляем пустое поле  
  Client secret - соответственно также  
  Scope - 1, full access  
  Service account file - пусто
  Edit advansed config - No
  Use auto config:

Тут возможны два варианта:

  • если rclone запускается на рабочей машине, с установленным браузером — можно ответить Yes — откроется окно браузера, нужно выбрать аккаунт и разрешить приложению доступ к Drive.

  • если rclone запускается на удаленной машине через SSH — нужно ответить No и получить ссылку, которую надо будет открыть с помощью rclone на рабочей машине, чтобы разрешить доступ, получить код, скопировать его и ввести в терминале на удаленной машине.

Configure as Shared Drive — No
Keep this remote — Yes

После настройки в файле ~/.config/rclone/rclone.conf появится запись о настроенном подключении.

В принципе, эту запись можно просто скопировать на другую машину, если надо настроить доступ и там тоже.

Теперь можно копировать файлы, примерно так:

mkdir my_google_drive
rclone copy test1:/ my_google_drive --drive-acknowledge-abuse --update
rclone copy my_google_drive test1:/ --drive-acknowledge-abuse --update
rclone sync my_google_drive test1:/ --drive-acknowledge-abuse --update

Подробно возможные команды расписаны в man rclone. Есть возможность даже примонтировать Drive как диск через FUSE.

То есть, теперь можно просто закидывать файлы в нужный каталог, откуда они будут сами по крону загружаться в облако, а потом где-то на удаленном сервере точно так же сами выгружаться оттуда.
Ну и конечно, будут доступны через Google Drive на мобильном телефоне.

Но это только часть дела. Теперь надо подумать и о безопасности данных.

Зашифровать файл в Линуксе очень просто, для этого можно использовать обычный openssl:

openssl enc -aes-256-ctr -salt -in input.file -out output.file -pbkdf2 -pass stdin

Получим зашифрованный файл output.file.
Расшифровка - с параметром -d:

openssl enc -aes-256-ctr -d -in input.file -out output.file -pbkdf2 -pass stdin

Если же указать -pass file:keyfile - в качестве пароля будет использовано содержимое файла keyfile, что удобно для автоматического шифрования большого количества файлов: если держать keyfile в секретном месте, а в облако выгружать исключительно зашифрованные файлы - расшифровать их будет не очень просто.

То есть, можно создать скрипт, который будет шифровать все файлы в каталоге, перемещать шифрованные в другой каталог, и потом загружать в облако, на хранение.
Для расшифровки понадобится вспомнить пароль, и использованный криптоалгоритм.

Сам по себе openssl при расшифровке не проверяет, правильно ли он расшифровал - если вы ввели неверный пароль, он что-то там "расшифрует", но насколько эти данные соответствуют оригиналу - он не знает.

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

Но для повседневного ручного использования это не очень удобно.
Во‑первых, нужно помнить синтаксис командной строки, во‑вторых — используемый тип шифрования. Отсутствует проверка «тот ли это файл вообще?», отсутствует контроль правильности расшифровки.

Но всё это можно добавить.
Итак, задача — сделать простой инструмент для командной строки, чтобы можно было зашифровать файл и расшифровать его обратно.

Для этого сделаем две команды, encrypt & decrypt, с поддержкой проверки формата зашифрованного файла и контролем корректности расшифровки.

Сначала — encrypt:

#!/bin/bash

MAGICK="enc1"

if [ -f "$1" ] ; then

  echo -n "Enter password: "
  read -s pass1
  echo

  if [ "x$pass1" = "x" ] ; then
    exit 0
  fi

  output="$1.enc"
  echo -n "$MAGICK" > "$output"
  openssl dgst -sha256 -binary "$1" >> "$output"

  echo -n "$pass1" | openssl enc -aes-256-ctr -salt -in "$1" -pbkdf2 -pass stdin >> "$output"
fi

Что он делает? Создается файл.enc, в заголовке которого записывается придуманное MAGIC word — просто 4 байта сигнатуры.

Затем рассчитывается sha256-хеш оригинального файла, и записывается следом в виде 32 байт.

Затем шифруется сам файл, и записывается после заголовка. Готово.

Конечно, можно усложнить, добавить параметр для поддержки ключевого файла или чего‑нибудь еще, но цель была как раз в создании простого и удобного инструмента для шифрования файла по паролю.

Если была бы задача, например, шифровать поток по ключу — проще написать другой, тоже простой в применении скрипт‑фильтр.

А вот с расшифровшиком decrypt сложнее, потому что добавлены проверки:

#!/bin/bash

MAGICK="enc1"

if [ -f "$1" ] ; then

  # проверка сигнатуры
  echo -n "$MAGICK" | cmp -n 4 -s - "$1"
  if [ $? -ne 0 ]; then
    echo "File $1 has unknown format"
    exit 1
  fi

  # проверка "расширения"
  orig=$(echo $1 | grep -oP '[^/]+(?=\.enc$)')
  if [ "x$orig" = "x" ] ; then
    echo "File $1 has unknown format"
    exit 1
  fi

  # проверка наличия файла
  if [ -f "$orig" ] ; then
    msg="File $orig already exists, enter new name or overwrite? "
    echo "$msg"
    read -e -i "$orig" -p "> " orig
    echo
  fi
  if [ "x$orig" = "x" ] ; then
    # пользователь стер название
    exit 0
  fi

  # ввод пароля
  read -s -p "Enter password: " pass1
  echo

  if [ "x$pass1" = "x" ] ; then
    exit 0
  fi

  # создаем временный файл и pipe в локальном каталоге
  tmp_out=$(mktemp -p . )
  tmp_in=$(mktemp -u -p .)

  mkfifo "$tmp_in"

  # забираем шифрованную часть файла
  tail -c +37 "$1" > "$tmp_in" &

  # расшифровка
  echo -n "$pass1" | openssl enc -aes-256-ctr -d -in "$tmp_in" -out "$tmp_out" -pbkdf2 -pass stdin
  rm "$tmp_in"

  # проверка хеша
  openssl dgst -sha256 -binary "$tmp_out" | cmp -n 32 -s --ignore-initial=0:4 - "$1"
  if [ $? -ne 0 ]; then
    echo "Incorrect password"
    rm "$tmp_out"
    exit 2
  fi

  mv "$tmp_out" "$orig"
  exit 0
fi

Во-первых, проверяется наличие MAGIC word — читаем первые 4 байта файла.
Во‑вторых, проверяется «расширение» — оно должно быть.enc, и оно убирается, чтобы получить исходное имя файла. Если имя получилось пустым — считаем, что это неправильный файл.

В третьих, проверяем наличие расшифрованного файла — будем его перезаписывать или создаем новый?

И только потом — расшифровка.

При этом есть нюанс: для рашифровки нужно взять только часть входного файла после заголовка, начиная с 37 байта.

Это несложно сделать, перенаправив данные в stdout, тогда openssl должен получить их через stdin, но stdin уже занят вводом пароля, поэтому данные отправляются через FIFO‑pipe.

Получившийся после рашифровки временный файл проверяется по sha256, и если хеш совпадает с указанным в заголовке — можно считать, что файл расшифрован правильно.

Ну и наконец можно проверить:

encrypt somefile
decrypt somefile.enc

Теперь можно легко и быстро шифровать и расшифровывать файлы, без установки других, специализированных пакетов. Чисто для собственного использования.

Комментарии (0)


  1. dpvpro
    20.09.2025 23:26

    Спасибо за статью, но код, кром двух скриптов, совершенно не отформатирован и сливается в один общий текст, который невозможно воспринимать нормально.

    А по сути. У меня похожее решения для резевного копирования. На Google Drive, средставим rclone, копируются файлы из одной директории первой необходимости.

    Всего у меня существует 4 каталога информации которые реплицируются средствами "synсthing" между 3 устройствами. Сейчас 4-ое устройство на походе.

    Ну и вишенка на торте - резервное копирование всех 4 каталогов каждый день + резервное копирование системы раз в неделю по сети на сервер "rest-server" для "restic". Диск с данными, где хранятся резервные копии, дублируется еще на двух дисках, потому как помимо резервных копий там содержится еще много ценных данных.

    По поводу шифрования. Я не понял зачем писать свои bash скрипты для шифрования одиночных файлов, когда можно использовать готовые крипто контейнеры "LUKS/dm-crypt" для чувствительных данных. Примонтировал, поработал с файлами, отмонтировал. У меня прекрасно работает данная схема.


    1. JBFW Автор
      20.09.2025 23:26

      Контейнер - большой файл. Делать мелкие неудобно, возни много.

      А это - как раз для тех случаев, когда нужно либо что-то само по себе большое (.iso например) закрыть, либо наоборот, небольшое (пару файлов в мегабайт) - ради чего создавать контейнер просто лень.


      1. dpvpro
        20.09.2025 23:26

        Контейнер может быть любого удобного размера.

        А писать скрипт, шифровать единичные файлы и потом помнить где что лежит, не лень))


        1. JBFW Автор
          20.09.2025 23:26

          Ну вот смотрите, ситуация: вам надо сохранить файл "Секретный рецепт сырников.doc", 123 кбайта.

          У вас три варианта:
          1 - encrypt "Секретный рецепт сырников.doc" - пароль для рецептов - upload 123 кб
          2 - открыть криптоконтейнер Bigfile, внести рецепт туда, закрыть - upload 2Гб
          3 - открыть криптоконтейнер для рецептов на 200 Мб, увидеть что в нем не осталось места, создать второй для рецептов еще на 200 Мб, - upload 200 Мб. И еще отдельно придумать каталог, что в каком контейнере лежит, чтобы не искать по разным.

          Как-то так.


          1. dpvpro
            20.09.2025 23:26

            Ваши сценарии очень синтетические. И смахивают на придумывание очередного велосипеда.

            Для того что бы не искать файлы, должен быть подход к хранению файлов и структура хранения файлов.

            У меня в каталоге "первой" необходимости хранится криптоконтейнер "KeePassX". Там хранятся все пароли, и при необходимости, можно туда поместить "секретный рецепт сырников" весом 123Кб. Там есть хорошая структура каталогов, которая позволяет не путаться. Файл весит сейчас 1 мегабайт с учетом зашифрованных вложений. Ну даже если он вырастет до 10Мб в моменте, или даже до 100, я не вижу в этом ничего страшного. Сейчас не та скорость интернета, что бы экономить на спичках. Даже если потенциально оперировать размерами в гигабайты, это спокойно можно пережить. Rclone спокойно загрузит все в фоновом режиме. Это "горячее" хранение информации.

            Теперь о "холодном" хранении.
            Все большие криптоконтейнеры используются редко и хранятся и синхронизируются на трех жестких дисках для отказоустойчивости. Все необходимые диски и данные расположены на домашнем сервере и доступны всегда.

            Подчеркну, ничего крупного шифрованного в облаке не хранится. Но даже если вы хотите идти по пути одиночных шифрованных файлов, то можно сделать зашифрованный архив, который и разместить в облаке. В Линукс этом можо делать хоть в CLI, хоть в GUI. И не надо изобретать велосипеды.


            1. JBFW Автор
              20.09.2025 23:26

              Linux/Unix - это и есть куча велосипедов, где одни и те же задачи можно решить разными инструментами и разными способами )


          1. UnknownUserMax
            20.09.2025 23:26

            В Linux также есть шифрованные ФС - encfs и cryfs. У второй даже в описании прямым текстом заявлена работа с облаками.

            CryFS encrypts your files, so you can safely store them anywhere. It works well together with cloud services like Dropbox, iCloud, OneDrive and others. Simple.


  1. tbl
    20.09.2025 23:26

    Вместо того, чтобы считать и прикапывать хэш от дешифрованного контента, лучше считать и прикапывать hmac


  1. propell-ant
    20.09.2025 23:26

    А как вы себе представляете процесс смены ключа шифрования в такой системе? Например, десяток тысяч файлов, под капотом асинхронная отправка в облако, процесс синхроризации сильно растянут во времени...


    1. JBFW Автор
      20.09.2025 23:26

      Никак. Это персональный архив, который не предполагает периодической смены паролей и перешифрования. Более того, никто не обещает что пароли на все файлы одинаковые )

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

      А как еще вы предлагаете менять ключ? Мне правда интересно. Можно перешифровать симметричный ключ, спрятанный в файле - но это всё равно обновление файлов в облаке.

      И в случае криптоконтейнера с возможностью замены ключа - тоже.


  1. UnknownUserMax
    20.09.2025 23:26

    задача - сделать простой инструмент для командной строки, чтобы можно было зашифровать файл и расшифровать его обратно.

    И зачем? rclone умеет сам шифровать файлы. Просто создаём еще одну запись типа crypt, а в remote ссылаемся на облако.


    1. JBFW Автор
      20.09.2025 23:26

      Затем, чтобы они и локально были шифрованные, независимо от rclone.
      Он - транспорт, с дополнительными возможностями, он передает некие данные - вот и пусть передает. Завтра вместо Google Drive будет что-то другое, и другой транспорт окажется лучше - это не должно влиять на данные.

      А готовить данные - локальная задача. Их лучше не объединять.

      Уже был опыт с какой-то вот такой программой (не помню, давно было), позволяла делать шифрованные бекапы в собственное облако Убунты.
      Сначала попал на какой-то баг в программе (иногда не расшифровывались обратно), а потом и облако это отключили.


    1. pvzh
      20.09.2025 23:26

      Поддержу, crypt позволяет прозрачно для пользователя шифровать файлы при выгрузке в облако и дешифровать в исходный вид при скачивании. Удобная вещь!

      File content encryption is performed using NaCl SecretBox, based on XSalsa20 cipher and Poly1305 for integrity. Names (file- and directory names) are also encrypted by default, but this has some implications and is therefore possible to be turned off.


  1. pvzh
    20.09.2025 23:26

    Итак, установим rclone:

    apt install rclone

    Как вариант, раз утилита rclone написана на Go, а значит не требует установки, кроссплатформенная, достаточно скачать свежую сборку и положить один бинарь в .local/bin