Шифрование важных файлов в Git

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

    Я не буду обсуждать согласование описываемого ниже метода с политикой и лицензионным соглашением бесплатных Git-репозиториев (а ля GitHub) — это дело частностей и вашей совести.

    В реализации мы всопользуемся .gitattributes, staging, filters (фильтрами) и главой 7.2 Pro Git Book.


    Вот как мы это будем делать.
    Существуют два важных нам состояния:

    image
    State A.

    image
    State B.

    State A — когда вы сделали выборку (git checkout) и работаете с вашей рабочей копией — в этот момент файлы должны расшифровываться и находиться в читаемом состоянии. Эта фаза контролируется фильтром stage.

    State B — когда изменения ваше рабочей копии готовятся к отправке в репозиторий (git add) — в этот момент файлы должны быть зашифрованы до передачи в хранилище. Эта фаза контролируется фильтром clean.

    Обычно фазы stage & clean используются для чего-то более мирного, например форматирование (indent) исходников по вашим вкусам и причёсывание их под принятые в организации стандарты при обратной отправке.

    Перед отправкой в хранилище (локальное или удалённое) и для получения читаемых секретных файлов проекта необходимо произвести подготовку на машине разработчика.

    Добавляем описание фильтров в ~/.gitconfig:

    [filter "private"]
    clean = ~/git_encode.pl
    smudge = ~/git_decode.pl


    В домашней директории у нас располагаются два скрипта.
    Замените SecurePassword на свой пароль. Выберите на свой вкус метод шифрования из имеющихся в вашей сборке библиотеки OpenSSL. Мы использовали rc5.

    ~/git_encode.pl:

    #!/usr/bin/env perl
    use strict;
    undef $/;
    my $data = <STDIN>;
    my $tmp = "/tmp/git.encode.$$." . rand() . ".tmp";
    local * O;
    open(O,">$tmp");
    print O $data;
    close(O);
    print `openssl enc -rc5 -k SecurePassword -nosalt < $tmp`;
    unlink($tmp);


    ~/git_decode.pl:

    #!/usr/bin/env perl
    use strict;
    undef $/;
    my $data = <STDIN>;
    my $tmp = "/tmp/git.decode.$$." . rand() . ".tmp";
    local * O;
    open(O,">$tmp");
    print O $data;
    close(O);
    print `openssl enc -d -rc5 -k SecurePassword -nosalt < $tmp`;
    unlink($tmp);


    Установите на эти скрипты право исполнения (в командной строке):

    chmod +x ~/git_encode.pl ~/git_decode.pl

    В рабочем каталоге подключаем защиту к необходимым файлам.
    .gitattributes:

    *.m filter=private
    *.h filter=private
    *.c filter=private
    *.cpp filter=private


    Теперь при отправке в хранилище выбранные файлы будут проходить через шифровщик, а при выборке через расшифровщик.
    Чтобы Git не думал каждый раз, что файлы изменились, убедитесь, что шифровщик не «солит» (salted) файлы (используйте опцию -nosalt).
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 26
    • +1
      А как будут выглядеть чейнджсеты? То есть получается как бы работа с бинарными файлами?
      • 0
        Проверил штатный git diff,
        к сожалению да, как двоичные файлы, но, возможно, это можно обойти дополнительными фильтрами.
        В крайнем случае, можно получить копии открытых (расшифрованных) версий файлов и сравнить их в индивидуальном порядке.
        Смысл метода скрыть не всё, а только что-то ну очень секретное.
    • –1
      А не проще TrueCrypt поставить и организовать хранилище на шифрованном разделе?
      • 0
        Да, это подойдёт для сокрытия всего. Но тогда хранилище уже не будет на сервере представлено в виде Bare-репозитория (тогда в этом уже нет смысла).
        Смысл скрыть именно несколько файлов и при этом оставить штатный доступ к Git.
        Если образ диска разместить на сервере — то сколько человек сможет с ним работать одновременно?
        Лично я использовал FUSE + SSHFS и монтировал AES-тома через SSH. Но пока диск у меня, остальные не могут с ним работать безопасно — это плохо кончится. TrueCrypt свободен от этой проблемы?
        • –1
          Если образ диска разместить на сервере, монтировать его и расположить на нем GIT репозитарий, то работа с GIT для всех будет выглядеть абсолютно прозрачно пока диск не размонтируют. Или, может быть, я вас неправильно понял? Может быть, смысл в том, чтобы никто не смог работать с некоторыми конкретными файлами в репозитарии?
          • 0
            Вопрос в том, где этот диск будет смонтирован (возможности TrueCrypt). Допустим, 100 разных человек в разных точках земли, смогут ли смонтировать этот диск и работать с репозиторием, так чтобы целостность данных была в порядке?
            Ограничения этого метода:
            1. Если внутри одной организации — то можно конечно расшарить один смонтированный диск между сотрудниками.
            2. На GitHub такое не пройдёт
            3. Возможна физическая порча репозитория (он уже не сокрыт за сервером, а вот он как локальный)
            • 0
              к сожалению, тогда владельцам хостинга теоретически станут доступны файлы на зашифрованном разделе, пока он смонтирован (т.е. они могут, по крайней мере легко, запустить соответствующий софт на сервере).

              Для предотвращения доступа владельцев сервера к вашим данным есть только два основных направления — усложнение доступа (нестандартные схемы, постоянный контроль софта и т.д.) и дешифровка на клиенте (причем возможен вариант, когда один из надежных клиентов становится временным сервером, а хостинг провайдера используется как простое хранилище). В статье описан второй вариант — в данном случае это наиболее простой и эффективный метод, жаль что ограничивает функционал на стороне клиента. Но первый вариант — не на столько надежен, как второй.

              p.s.
              • +1
                p.s. а если клонировать репозитарий уже от клиента, но без шифрования фильтрами, файлы будут переданы дешифрованными или зашифрованными?
                • 0
                  Расшифрованными они будут только если установлены фильтры,
                  внутри хранилища они лежат в виде двоичного мусора даже на клиенте у которого в рабочей копии открытый файл.
                  Иначе получите двоичный закодированный файл.
        • 0
          Зачем скрипты на перле, если бы одна строка «openssl ...» сработала бы?
          • 0
            Может быть. Процесс эксперимента с фильтрами не сразу привёл к результату. Мне удобнее писать Perl-скрипты, вместо SH-скриптов, поэтому получилось именно так.
            • +1
              На больших файлах print `command`; даст не лучшую производительность, так как будет буферизировать всё в памяти. А запись «секретных» данных лишний раз во временный файл в /tmp вообще противопоказана.
              • 0
                По поводу /tmp — предполагается, что это Ваша машина (клиент).
                Иначе и редактировать файлы на ней не стоит.
                • +2
                  Вы же за машиной не один работаете.

                  Если уж секретный, то в home пишите, а то из tmp его быстро уведут.
                  • 0
                    К счастью, в конкретный текущий момент времени один. Сразу после использования файл удаляется. Но использование tmp в home поддерживаю всё равно.
                    И как тут уже отмечалось, Perl скрипты остались от иследования фильтров.
                    Можно, действительно, обойтись openssl в одну строку без обёртки и без временных файлов.
          • НЛО прилетело и опубликовало эту надпись здесь
            • 0
              Доверие доверием, а подстраховаться никогда не повредит.
              Дополнительное шифрование — это второй уровень защиты.
              К примеру, Вы платите за хостинг и размещаете там репозиторий.
              Насколько Вы доверяете хостеру и местным специалистам, который день и ночь шныряют по SSH?
              Это как замки в квартире — Вы можете их и вовсе не ставить, но тогда…
              А когда Вы их ставите, разве Вы живёте не в скомпроментированном мире?
            • НЛО прилетело и опубликовало эту надпись здесь
              • +1
                Если есть доступ по SSH и Гит на сервере установлен, то никаких проблем возникнуть не должно.
                • НЛО прилетело и опубликовало эту надпись здесь
                  • 0
                    Без рутовых прав нельзя.
                    • +1
                      теоретически, при наличии ssh и установленных зависимостей (некоторые можно самому поставить) можно попытаться установить все необходимое в домашнюю директорию, очень даже может быть что что-нибудь потребуется пересобрать с опцией --preffix=/home/username/ но что то мне говорит что геморою будет намного больше чем стоит любая самая вшивая vps.
                      • +1
                        На самом деле можно.
                        Только не нужно ставить в директории не принадлежащие Вашему пользователю (например, в /usr, /usr/local).
                        Просто переопределите prefix при configure.
                  • 0
                    Не скажу по поводу «заморачиваться», но лично я за практику — попробовать стоит по любому.
                    Из моего опыта — удачно удалось развернуть Git на 301-м тарифе РуЦентра — там в SSH даже gcc есть — сначала собрал nginx, потом git, svn там из коробки идёт.
                  • 0
                    Итак, резюмирую укороченное решение шифрования-дешифрования с возможностью производить diff:
                    Вместо Perl-скриптов и для работы diff в определении фильтра прописываем:

                    [filter "private"]
                    clean = openssl enc -rc5 -k SecurePassword -nosalt
                    smudge = openssl enc -d -rc5 -k SecurePassword -nosalt
                    [diff "private"]
                    textconv = cat


                    Для нужных файлов в .gitattributes:

                    *.h filter=private diff=private

                    При модификации .gitattributes на стороне клиента после клонирования, достаточно выполнить git stash для применения новых настроек фильтра smudge. Чтобы не было недоразумений, не забудьте добавить .gitattributes в хранилище.

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