レイジーのパスワード

最近、専用サーバーをレンタルしているプロバイダーの1つがハッキングされました。 バックアップは毎日行われるため、被害はごくわずかでした。 一方、 休暇前の眠れぬ夜に数十のアカウントのパスワードを変更することも楽しいアクティビティではありません。



パスワードの変更を自動化するというアイデアは、かなり長い間脳を動かし、いくつかのhabratopicが正しい方向に押し進められました。 アイデアは単純でした-できるだけ頻繁に(たとえば毎日)パスワードを変更し、誰かが2日前に通信からパスワードを取得したとしても、彼とは何もできませんでした。 理想的には、システムは各アカウントの毎日のバックアップの直前にパスワードを生成および変更する必要があります。



言うのは簡単です-Linuxサーバーのパスワードの変更を自動化するために-私はあなたの目にこのバッシュを見たことはありません(もちろん、bashorghを除いて)、私はこの人生で全く異なることをしています。 ただし、タスクを最も単純な手順とGoogleに分割する手法は、たった1晩で問題を解決するのに役立ちました。



ステップ1-たとえば、今日の日付など、何らかの文字列からMD5ハッシュを取得します。



echo -n $(date +%F) | md5sum







ステップ2-この喜びを何らかの変数に割り当てます。すぐに2回する方が良いので、それが長くなることがわかります(それから理由を示します):



a=$(echo -n $(date +%F) | md5sum) && a=${a:0:32}${a:0:32}







ステップ3-結果の64文字の文字列から、たとえば今日の位置番号から27文字を選択します(つまり、今日が8月3日の場合、3番目の位置から開始します) したがって、月の31日に、64文字の文字列(31 + 27 = 58)に収まることが保証されます。 他の番号を選択できます。主なことは、64文字に収まるか、元の文字列を長くすることです。



hs=${a:$(date +%d):27}







次の4番目のステップは、サーバー上のすべてのアカウントのリストを取得することです。 私はこのオプションに満足しました(誰かがより正確なオプションを提供してくれたら感謝します):



cat /etc/passwd | grep "/home" | cut -d: -f1







5番目のステップは最も困難であることが判明しました。結果のユーザーリストの行を繰り返し処理します。 30分の実験の後、次の(中間の)オプションが機能し、ユーザー名とパスワードの空白が表示されました。



lines=($(cat /etc/passwd | grep "/home" | cut -d: -f1))



for i in "${lines[@]}"

do

echo "$i" : $hs

done









このオプションをそのままにしておけば、パスワードを取得するアルゴリズム自体を知ることは大したことではないことは明らかです。 そのため、状況を少し複雑にすることにし、6番目のステップは次のようになりました。



salt="abracadabra"

lines=($(cat /etc/passwd | grep "/home" | cut -d: -f1))



for i in "${lines[@]}"

do

echo "$i" : $hs

s=$salt"$i"$hs

newhash=$(echo -n "$s" | md5sum)

done









つまり、現在の日付から収集されたハッシュにアカウント名と「塩」を追加し、その後、結果からハッシュを再度計算します。 私たちだけが知っている「塩」を追加することで、アルゴリズムの構造を「破壊」し、アカウント名も追加することで、結果ハッシュをそれぞれに対して一意にします。 毎日パスワードを変更するので、私たちは妄想を解き放ち、すべてのパスワードを同じにしません:)



ユーザーにとって便利なパスワード変更コマンドを見つける過程で、bashにはすべての動きが記録されているという言及に出会いました。 実際、.bash_historyファイルは最も無作法な方法で、私の実験の一部を見せてくれました。 したがって、7番目のステップとして、historyコマンドと-cスイッチを検討する必要がありました。



明らかに次のような8番目のステップ:



cmd=`echo "$i":$newhash | chpasswd`

echo $cmd









9番目の最終ステップは、毎日のバックアップを開始する直前に、すべてをまとめてcronに追加することでした。 スクリプトは次のようになりました。



#!/bin/bash

#

# Prep some salt

salt="abracadabra"



# Calculate hash from today's date and add it to itself

a=$(echo -n $(date +%F) | md5sum) && a=${a:0:32}${a:0:32}



# Strip 27 characters starting from the character number of today's day of month

hs=${a:$(date +%d):27}



# Grab users into array

lines=($(cat /etc/passwd | grep "/home" | cut -d: -f1))



# For each user create a new pass with salt + user name + hash

#

for i in "${lines[@]}"

do

s=$salt"$i"$hs

newhash=$(echo -n "$s" | md5sum)

newhash=${newhash:0:27}

# echo "$i" : $salt"$i"$hs : $newhash # print this out if you want to

cmd=`echo "$i":$newhash | chpasswd`

echo $cmd

done

history -c









明らかに目に見える欠点:

-強力なアルゴリズム化、すなわち あなたは頭の中にそのようなパスワードを保持することはできません

-小さい文字と数字のみが使用されます。 検索辞書が小さい

-パスワードの配布では、アカウントを変更してパスワードを変更する必要がない場合があります(どのパスワードをすぐに考えるかはわかりませんが、たとえば、サーバーの1つでPuTTyをプロキシとして使用するためのシェルアカウントがある-このアカウントのパスワードを毎時間変更したくない) 。



利点:

-パスワードは何度でも変更できます(必要に応じて、日付の代わりに日付/時刻を使用し、1分ごとまたは1秒ごとにパスワードを変更できます)

-頻繁な変更と長い長さは、辞書の単純さを補います(小さな文字と数字のみ)

-アルゴリズムと「塩」を知っているため、パスワードは安全性を恐れずに任意のマシンで簡単に生成できます-とにかく、次の日/時間/分:)

-自動化の容易さ、カスタマイズ可能性(いつでもアルゴリズムを自分で調整できます)、およびその結果-多数のアカウントのパスワードを変更する際の大幅な時間の節約。



質問:

-異なるレジスタとサービス文字を使用して、この方法でより複雑なパスワードを生成することは可能ですか?

-この実装には他にどのような欠点がありますか?

-この実装には他にどのような利点がありますか?

-これらの不利な点を補うか、完全に取り除くことができますか(たとえば、一部のアカウントのパスワード変更を無効にするために、ストップリストを作成し、ストップリストにあるアカウントを一般リストから削除できます)?



UPD:最初のコメントは明確化を提案しました。 クライアントはときどき自分のアカウントにログインし(たとえばcPanelで)、証明書のログインではなくログイン/パスワードの方がより快適です。 これらのアカウントのシェルは通常、完全に無効になっています(例外はほとんどありません)。



All Articles