Linuxでシステム固有の値としてディスクのUUIDを暗号化キーに使う

Linuxでシステムごとに固有の値として、ディスクのUUIDを使う方法です。
暗号化キーに使うことで該当システムでのみ復号化できるようになります。

最近見つけた下記サイトで、暗号化でシステムの UUIDを暗号化キーに使っていました。
システムの UUID取得にはrootが必要なので、一般ユーザでも取得可能なディスクのUUIDを検討してみました。

シェルスクリプトの中に安全にパスワードを埋め込む - Qiita


ディスクのUUID取得方法


ディスクのUUIDは、次のコマンドで確認できます。


ls -l /dev/disk/by-uuid/


結果は次のようになります。日時の後の文字列が UUID です。


$ ls -l /dev/disk/by-uuid/
合計 0
lrwxrwxrwx 1 root root 10  7月 26 10:36 05530a6a-3a1a-4000-a403-35f26d99551f -> ../../sda1
lrwxrwxrwx 1 root root 10  7月 26 10:36 0b0e9ce3-f54b-4c1e-adf9-bb30fa1be2f3 -> ../../sda5
lrwxrwxrwx 1 root root 10  7月 26 10:36 e5032a28-c675-4b12-97f8-c4840c98a04e -> ../../sdb1


複数ディスクやパーティションがある場合、UUIDも複数あります。

ここでは、/(ルート)が存在するディスク(のパーティション)のUUIDを使います。

次のコマンドで取得します。
Ubuntu、CentOS(RAIDなし)、CentOS(RAIDあり)、RaspberryPi で動作OKでした。Windows10のWSLでは取得できません。


cat /proc/cmdline | sed -rne 's/^.+ root=UUID=([^ ]+) .+/\1/p' | grep -e "." || ls -la /dev/disk/by-uuid/ | grep `readlink -f \`cat /proc/cmdline | sed -rne 's/^.+ root=(\/dev\/[^ ]+) .+/\1/p'\` | awk -F / '{ print $3}'` | sed -E 's/^.+ (.+) \-> .+/\1/'

ちょっと複雑ですが、/proc/cmdline から /(ルート)のデバイス名を取得し、ls -la /dev/disk/by-uuid/ の結果と突き合わせて、UUID を取得しています。
/proc/cmdline に UUID が書かれている場合は、そちらを使っています。



暗号化・復号化


2019.8.19
以降のコマンドは Ubuntu の場合のみ動作可能でしたので、Ubuntu , CentOS , RaspberryPi でコマンドを分けました。


取得したUUIDを使っての暗号化です。
下記 DATA が暗号化したいデータで、暗号化パスワードに /(ルート)が存在するディスク(のパーティション)のUUIDを使っています。

Ubuntu の場合

echo DATA|openssl aes-256-cbc -e -base64 -pbkdf2 -k "`cat /proc/cmdline | sed -rne 's/^.+ root=UUID=([^ ]+) .+/\1/p' | grep -e "." || ls -la /dev/disk/by-uuid/ | grep \`readlink -f \\\`cat /proc/cmdline | sed -rne 's/^.+ root=(\/dev\/[^ ]+) .+/\1/p'\\\` | awk -F / '{ print $3}'\` | sed -E 's/^.+ (.+) \-> .+/\1/'`"

CentOS , RaspberryPiの場合

echo DATA|openssl aes-256-cbc -e -base64 -k "`cat /proc/cmdline | sed -rne 's/^.+ root=UUID=([^ ]+) .+/\1/p' | grep -e "." || ls -la /dev/disk/by-uuid/ | grep \`readlink -f \\\`cat /proc/cmdline | sed -rne 's/^.+ root=(\/dev\/[^ ]+) .+/\1/p'\\\` | awk -F / '{ print $3}'\` | sed -E 's/^.+ (.+) \-> .+/\1/'`"



復号化です。
復号化用キーは /(ルート)が存在するディスク(のパーティション)のUUID を使います。
下記の「暗号化の出力結果」に、先の暗号化での出力結果を指定します。
ダブルクォーテーション("")は省略せずに記述して下さい。
別システムで実行しても UUID が異なるので、正常に復号化できません。

Ubuntu の場合

echo "暗号化の出力結果"|openssl aes-256-cbc -d -base64 -pbkdf2 -k "`cat /proc/cmdline | sed -rne 's/^.+ root=UUID=([^ ]+) .+/\1/p' | grep -e "." || ls -la /dev/disk/by-uuid/ | grep \`readlink -f \\\`cat /proc/cmdline | sed -rne 's/^.+ root=(\/dev\/[^ ]+) .+/\1/p'\\\` | awk -F / '{ print $3}'\` | sed -E 's/^.+ (.+) \-> .+/\1/'`"

CentOS , RaspberryPiの場合

echo "暗号化の出力結果"|openssl aes-256-cbc -d -base64 -k "`cat /proc/cmdline | sed -rne 's/^.+ root=UUID=([^ ]+) .+/\1/p' | grep -e "." || ls -la /dev/disk/by-uuid/ | grep \`readlink -f \\\`cat /proc/cmdline | sed -rne 's/^.+ root=(\/dev\/[^ ]+) .+/\1/p'\\\` | awk -F / '{ print $3}'\` | sed -E 's/^.+ (.+) \-> .+/\1/'`"




参考


シェルスクリプトの中に安全にパスワードを埋め込む - Qiita
/dev/root の実デバイスの調べ方 - 仮運用中

この記事へのコメント