Скрытие пароля в скриптах оболочки


23

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

У меня есть один способ: поместить пароль в файл и сделать файл скрытым, и никто не собирается обращаться к файлу (измените права доступа и используйте файл в скрипте при переходе к базе данных).

Ответы:


35

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

Во-вторых , вы должны учитывать не только безопасность учетных данных, но и влияние, если / когда эти учетные данные будут скомпрометированы. У вас не должно быть только одного пароля для всего доступа к базе данных, у вас должны быть разные учетные данные с разными уровнями доступа. Например, у вас может быть один пользователь БД, который может выполнять поиск в базе данных - у этого пользователя должен быть доступ только для чтения. Другой пользователь может иметь право вставлять новые записи, но не удалять их. Третий может иметь разрешение на удаление записей.

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

Эти ограничения должны быть реализованы на стороне DB-сервера системы, так что, даже если клиентская сторона скомпрометирована, ограничения не могут быть изменены от нее. (И, очевидно, сервер БД должен быть защищен брандмауэрами и т. Д. В дополнение к конфигурации БД ...)

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

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

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

В-четвертых , рассмотрим условия, при которых будет выполняться скрипт:

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

Если он запускается с веб-сервера, рассмотрите возможность настройки учетных данных во время запуска веб-сервера. Хорошим примером здесь являются сертификаты SSL - они имеют открытый сертификат и закрытый ключ, а закрытый ключ имеет пароль. Вы можете хранить закрытый ключ на веб-сервере, но вам все равно нужно ввести пароль к нему при запуске Apache. У вас также могут быть учетные данные на каком-либо оборудовании, таком как физическая карта или HSM, которое можно удалить или заблокировать после запуска сервера. (Конечно, недостатком этого метода является то, что сервер не может перезапуститься самостоятельно, если что-то случится. Я бы предпочел это риску взлома моей системы, но ваш пробег может отличаться ...)

Если скрипт запускается из cron, это сложная часть. Вы не хотите, чтобы учетные данные располагались где-то в вашей системе, где кто-то мог бы получить к ним доступ, но вы хотите, чтобы они располагались так, чтобы ваш скрипт мог получить к ним доступ, верно? Ну, не совсем верно. Рассмотрим точно, что делает сценарий. Какие разрешения нужны для базы данных? Можно ли его ограничить, чтобы не имело значения, подключается ли не тот человек с этими разрешениями? Можете ли вы вместо этого запустить скрипт непосредственно на сервере БД, к которому никто другой не имеет доступа, вместо того, чтобы с сервера, на котором есть другие пользователи? Если по какой-то причине, о которой я не могу думать, у вас обязательно должен быть запущен скрипт на небезопасном сервере, и он должен быть в состоянии сделать что-то опасное / разрушительное ... сейчас самое время переосмыслить свою архитектуру.

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

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

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

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


9
Не высокомерный и элитарный вообще. Или я тоже. "Как я могу защитить свои украшения в случае взлома грабителя?" «Положите его в сейф, который закреплен болтами / приварен». «Это слишком много проблем, я просто возьму портативный сейф и повешу ключ на крючке». «Тогда не беспокойтесь, используя сейф». Исключительно разумный совет.
Wildcard

12

Прежде всего, если вы вообще можете что-то изменить, чтобы избежать необходимости хранить пароль внутри или рядом со сценарием, вы должны приложить все усилия для этого. Ответ Дженни Ди содержит много полезных советов на этот счет.

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

. /usr/local/etc/secret-password-here

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


@BasileStarynkevitch ах, но я вижу, что он также говорит " /usr/local/etcможет быть символическая ссылка на /etc/local". Я пропустил это. Так что вы тоже правы, но это МОЖЕТ, так что это необязательно. Но да, это не имеет большого значения и личных предпочтений.
Селада

1
За исключением того, что я выполняю резервное копирование, /etc/ но нет /usr/local/ (который, как я полагаю, может быть восстановлен после сбоя диска)
Василий Старыйнкевич,

Справедливое замечание о резервных копиях
Селада

3

Другие ответы касались того, как , но я рассмотрю вопрос . В зависимости от того, к какой базе данных подключаются ваши пользователи, у вас уже может быть подходящий механизм, который уже используется этими клиентскими программами, и в этом случае обязательно используйте их (я думаю, ~/.mysqlrcили ~/.pgpass).

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

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


1

Ваша идея скрыть пароль в недоступном месте может быть в порядке в зависимости от обстоятельств.

Если информация отдельная, это означает простое редактирование файла, например, во время просмотра кода коллегой не собирается его показывать. Но поймите, что любой, имеющий доступ к вашей учетной записи, может легко найти такой файл. Я использовал подкаталог ~/.sshдля таких целей по той простой причине, что sshжалуется, если права доступа для ~/.sshнедостаточно ограничены.

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

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

Используя GPG :

Немного лучше, но все же не полная защита от атак со стороны пользователя root в вашей системе, - это зашифровать пары имя пользователя / пароль в gpgобщедоступном файле и заставить скрипт получить содержимое файла (возможно, при запросе пароля, если нет кэшируются / истек). Я использую ggp-карту, поэтому, когда я оставляю свой ноутбук рядом, но вытаскиваю карту, доступ невозможен, даже если булавка все еще будет кэширована. По крайней мере, если я запускаю вещь 20 раз за несколько минут, я должен предоставить булавку только один раз.

Безопасность всегда обратно связана с удобством (настройка и использование).


0

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

http://www.kinglazy.com/shell-script-encryption-kinglazy-shieldx.htm

На приведенной выше странице все, что вам нужно сделать, это отправить свой сценарий (вы можете сначала отправить образец сценария для вашего спокойствия). Zip-файл будет создан для вас. Щелкните правой кнопкой мыши ссылку для скачивания и скопируйте предоставленный вами URL. Затем перейдите в окно UNIX и выполните следующие действия.

Установка:

  1. wget ссылка на zip-файл

  2. распаковать недавно загруженный zip-файл

  3. cd / tmp / KingLazySHIELD

  4. ./install.sh / var / tmp / KINGLAZY / SHIELDX- (your-script-name) / home / (your-username) -force

То, что вышеупомянутая команда установки сделает для вас:

  1. Он установит зашифрованную версию вашего скрипта в каталог / var / tmp / KINGLAZY / SHIELDX- (your-script-name).

  2. Ссылка на этот зашифрованный скрипт будет помещена в любой каталог, указанный вами при замене / home / (your-username), - таким образом, он позволит вам легко получить доступ к скрипту без необходимости вводить абсолютный путь.

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

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

НОТА:

Я не верю, что это работает для интерактивных сценариев, которые запрашивают у пользователя ответ. Значения должны быть жестко запрограммированы в скрипте. Шифрование гарантирует, что никто не сможет увидеть эти значения, поэтому вам не нужно об этом беспокоиться.


0

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

Я использую пару ключей gpg без пароля, которые я храню в USB. (Примечание: при экспорте этой пары ключей не используйте --armor, экспортируйте их в двоичном формате).

Сначала зашифруйте свой пароль:

echo -n "pAssw0rd" | gpg --armor --no-default-keyring --keyring /media/usb/key.pub --recipient someone@mail.com --encrypt

Это будет распечатать зашифрованный пароль gpg в стандартном выводе. Скопируйте все сообщение и добавьте его в скрипт:

password=$(gpg --batch --quiet --no-default-keyring --secret-keyring /media/usb/key.priv --decrypt <<EOF 
-----BEGIN PGP MESSAGE-----

hQEMA0CjbyauRLJ8AQgAkZT5gK8TrdH6cZEy+Ufl0PObGZJ1YEbshacZb88RlRB9
h2z+s/Bso5HQxNd5tzkwulvhmoGu6K6hpMXM3mbYl07jHF4qr+oWijDkdjHBVcn5
0mkpYO1riUf0HXIYnvCZq/4k/ajGZRm8EdDy2JIWuwiidQ18irp07UUNO+AB9mq8
5VXUjUN3tLTexg4sLZDKFYGRi4fyVrYKGsi0i5AEHKwn5SmTb3f1pa5yXbv68eYE
lCVfy51rBbG87UTycZ3gFQjf1UkNVbp0WV+RPEM9JR7dgR+9I8bKCuKLFLnGaqvc
beA3A6eMpzXQqsAg6GGo3PW6fMHqe1ZCvidi6e4a/dJDAbHq0XWp93qcwygnWeQW
Ozr1hr5mCa+QkUSymxiUrRncRhyqSP0ok5j4rjwSJu9vmHTEUapiyQMQaEIF2e2S
/NIWGg==
=uriR
-----END PGP MESSAGE-----
EOF)

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


-2
#!/bin/bash
unset username
unset password
unset dbname
echo -n "username:"
read username
echo -n "dbname:"
read dbname
prompt="password:"

    while IFS= read -p "$prompt" -r -s -n 1 char
            do
                    if [[ $char == $'\0' ]]
                            then
                                    break
                    fi
                    prompt='*'
                    password+="$char"
            #       read -s -p "Enter Password: "  pswd
            #       echo -e "\nYour password is: " $pswd
            done

3
Я отступил в вашем коде, может быть, вы могли бы объяснить, что вы пытаетесь сделать?
Архемар

-6

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


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

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

1
Я написал свой ответ сейчас. То, что я пытался получить от вас, было отчасти моим пятым пунктом - когда учетные данные хранятся в памяти, они не полностью защищены от злоумышленника с доступом к серверу. Также, что ваш краткий ответ был не очень полезным, хотя и не неправильным. Я собираюсь указать на это в следующий раз, когда кто-то пожалуется, что мы в ServerFault не так хороши, как люди в Unix / Linux :-)
Дженни Д

2
@JennyD - когда кредит находится в памяти - ему определенно не нужно оставаться там - и это в любом случае очень хорошая причина вместо этого разбирать хэши. Тем не менее, я с радостью представляю стандарты вежливости сообщества как его образец в целом - на самом деле я очень хорошо известен этой чертой.
mikeserv

4
После вашей большой дискуссии я хотел бы упомянуть на случай, если возникнет какое-то недопонимание, что именно я проголосовал, а не Дженни. И причина была не во мнении о том, стоит ли использовать сертификат и личный ключ или пароль, введенный в интерактивном режиме, или делать то, что хочет ОП, или нет. Дело в том, что ответ в его нынешнем виде неправильный: сохранение соленого хэша пароля в качестве учетных данных клиента - это не вещь: соленые хэши - это то, что вы сохраняете в конце соединения, которое проверяет аутентификацию, а не в сторона, которая представляет его.
Селада,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.