Вопрос контроля изменений конфигурации сервера остро стоит перед любым системным администратором, а если не стоит — то до первого случая, когда нужно откатить изменения, а исходного варианта конфигурации не осталось. Обычно рекомендуется всегда делать резервную копию файлов конфигурации перед их правкой, но все мы люди и часто пренебрегаем этим требованием, поэтому все что может быть автоматизировано — должно быть автоматизировано. В данной ситуации на помощь нам придет утилита etckeeper, которая в связке с системой контроля версий git поможет поставить любые изменения в конфигурации под полный контроль.

При общении с коллегами-администраторами часто можно услышать, что «git — это для программистов», однако это не так. Действительно, git — как система контроля версий, в первую очередь востребована программистами, но она может быть полезна не только лишь им. Так как конфигурационные файлы Linux представляют из себя простой текст, то система контроля версий так и напрашивается для применения, позволяя отслеживать и управлять любыми изменениями.

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

В принципе настроить контроль за /etc при помощи git можно и руками, но это потребует изучения данного продукта хотя бы на базовом уровне. Облегчить ситуацию способна утилита etckeeper, которая берет большинство вопросов на себя.

Все дальнейшие действия мы будем производить в среде Debian 10, затем данная инструкция была проверена на Ubunutu 18.04, в этих системах etckeeper по умолчанию использует git, в более старых системах могут использоваться иные системы контроля версий, которые потребуется изменить на git, о чем будет сказано ниже.

Прежде всего установим необходимые пакеты:

apt install etckeeper git

Сразу при установке будет произведена инициализация локального репозитория системы контроля версий. В первую очередь нам необходимо узнать какая именно система используется. Для этого выполните:

cat /etc/etckeeper/etckeeper.conf | grep ^VCS

Если вы получили в ответ строку:

VCS="git"

то следующие действия можно пропустить. Иначе выполним:

etckeeper uninit

Затем откроем файл /etc/etckeeper/etckeeper.conf и закомментируем текущую строку VCS и раскомментируем VCS=»git». После чего выполним:

etckeeper init

При инициализации в локальный репозиторий попадет текущее состояние директории /etc и начнется отслеживание любых изменений в ней. Но отслеживать мы будем не все файлы, некоторые из них являются вспомогательными или временными и не влияют на конфигурацию системы. Стандартный список таких файлов и директорий перечислен в файле /etc/.gitignore.

etckeeper-001.png

Обратите внимание, что конфигурация по умолчанию подразумевает передачу в репозиторий файлов c хешами паролей, а также SSL и SSH-ключей, если это нежелательно, то дополните данный файл строками:

shadow*gshadow*ssh/ssh_host_*ssl/private/*

Если вы используете Let’s Encrypt и не хотите чтобы ваши сертификаты и ключи попадали в репозиторий, то добавьте следующие строки:

letsencrypt/accountsletsencrypt/archiveletsencrypt/csrletsencrypt/keysletsencrypt/live

После чего следует перестроить кеш репозитория, иначе внесенные в список исключения файлы все равно попадут в первый коммит (коммит — это фиксация изменений в системе контроля версий). Обратите внимание, что все команды git следует выполнять, находясь в корне локального репозитория, т.е. /etc:

cd /etcgit rm -r --cached .git add .

Теперь самое время создать и подключить внешний репозиторий, чтобы все изменения конфигурации копировались за пределы сервера. Среди популярных git-сервисов наиболее известны GitHub, GitLab и Bitbucket, особой разницы в работе с ними нет, в нашем примере будет использоваться GitHub. Для хранения изменений конфигурации создадим в нем приватный репозиторий. Обратите внимание — тип репозитория должен быть обязательно приватным, в противном случае доступ к нему сможет получить каждый, кому станет известен его адрес.

etckeeper-002.png

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

Для доступа к внешнему репозиторию будем использовать аутентификацию по SSH-ключу, это позволит делать коммиты автоматически, без участия администратора. Прежде всего сгенерируем ключевую пару, так как задания cron выполняются от имени суперпользователя, то обязательно повысим свои права до root с помощью sudo или su.

ssh-keygen -t rsa -b 4096

При создании закрытого ключа не устанавливаем парольную фразу (просто нажимаем Enter), это в определенной мере снижает безопасность, но позволяет полностью автоматизировать процесс. В итоге в папке /root/.ssh должно появиться два файла: закрытый ключ id_rsa и открытый id_rsa.pub. Откроем последний и скопируем его содержимое.

Затем перейдем в настройки сервиса GitHub и откроем раздел SSH and GPG keys, в котором добавим новый ключ нажав на кнопку New SSH key. Ключам также стоит давать осмысленные имена, чтобы было понятно для какого из серверов он предназначен. В поле ключа внесите содержимое id_rsa.pub.

etckeeper-003.png

После чего возвращаемся к нашему репозиторию и получаем строку подключения к нему по SSH, выглядеть она будет примерно следующим образом:

git@github.com:login/repo.git

где login — ваш логин на GitHub, а repo — имя репозитория. Для его подключения выполним:

git remote add origin git@github.com:login/repo.git

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

git push -u origin master

Она же выполнит первый коммит зафиксировав текущее состояние директории /etc. Снова откроем /etc/etckeeper/etckeeper.conf и в самом конце откорректируем строки:

PUSH_REMOTE="origin"

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

etckeeper commit "My first commit"

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

etckeeper-004.png

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

Еще одна вечная проблема — это ошибки и опечатки, особенно если вы случайно стерли часть конфига или изменили его и заметили это только при перезапуске службы. Нет проблем — делаем коммит и сравниваем изменения. В принципе git позволяет сравнит текущее содержимое с любым состоянием ветки и без коммита, но это требует определенных знаний, поэтому мы пойдем самым простым путем. В нашем примере мы корректировали файл /etc/hosts и допустили в нем опечатку. После коммита это стало сразу видно:

etckeeper-005.png

Вместо одной пустой строки мы добавили две, одну с записью и вторую с опечаткой (точка), при этом вопрос была ли эта строка в файле раньше и в каком виде больше не стоит, все предельно ясно. Ошибку можно исправить как вручную, так и восстановив предыдущее состояние файла. Это удобно, если нужно разом откатить большое количество изменений. Прежде всего получим список коммитов, для этого выполните:

etckeeper vcs log --pretty=oneline 
etckeeper-006.png

Теперь выберем из списка коммитов тот, который содержит нужную нам версию файлов, это не обязательно должен быть последний коммит, вы можете восстановить и версию из глубины, при этом состояние других файлов затронуто не будет. Нам потребуется хеш коммита, точнее первые семь его цифр. Допустим мы хотим вернуть исходное состояние файла и выберем для этого Initial commit — 6e96fd5. Эти же данные можно получить и через веб-интерфейс внешнего репозитория. Затем выполним:

etckeeper vcs checkout 6e96fd5 /etc/hosts

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

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

etckeeper-007.png

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

Источник