Furyu
[フリュー公式]

Tech Blog

フリュー株式会社の技術ブログです

2018年10月31日

Kayo

sudo: ruby: コマンドが見つかりません。。。

みなさん、こんにちは。ピクトリンク事業部インフラ課の藤本佳世です。

最近、サーバのリプレース作業の一環として、バッチスクリプトの移行作業を実施しています。この作業中、「sudo: ruby: コマンドが見つかりません」問題に出くわしたので、対処方法をシェアしたいと思います。

問題

フリューでは、rundeckを使って日次・月次のバッチを実行しています。

新しく構築した環境(以下、新サーバとします)に、従来通りの手順でスクリプトを実行しようとしたところ、エラーが出てしまいました。

今までは問題なく実行できていたのに、なぜ……?

対応策

sudoにオプションiをつけて解決しました。

詳細

エラーになっているexample.shの52行目を確認すると、rubyスクリプトを実行する記述がありました。

エラーの原因は、このrubyコマンドを実行した際、rubyコマンドが見つかりませんというエラーのようです。

実際に新サーバにsshログインし、rubyコマンドがないのかバージョン確認で検証してみました。

やはり、「ruby:コマンドが見つかりません」が出力されました。

旧サーバで実施すると問題ありませんでした。

rootで実施すると問題ありませんでした。

原因は、sudo経由で実行した場合、環境変数が引き継がれない...という問題でした。

もう少し詳しく説明すると

sudo はrootや他のユーザの権限でコマンドを実行することができますが、sudoの設定(/etc/sudoers)によっては、環境変数が引き継がれなかったり、上書きされる設定になっている事があります。

こちらは/etc/sudoersファイルの一部を切り取ったものです。

env_resetが設定されていてますが、これはsudoが実行された際、環境変数がsecure_pathの設定値に上書きされてしまいます。
またenv_keepにPATHがないためにPATHが引き継がれません。

上記のように、/etc/sudoersに追加することで、PATHを引き継ぐことができますが、
今回、私はsudoにオプション-iをつけて対応しました。オプション-iとは、何でしょうか?

こういう時は、–helpコマンドで調べると便利です。

では、 -i  オプションの効果を踏まえて、ruby の設定が環境変数のPATHに設定されているかを見てみましょう。

sudoだと環境変数のPATHが通っていません。
オプション-iを付けることにより、この問題を解消することができます。

補足

sudo のオプションに-Eがあります。

これも環境変数を維持してくれるものになりますが、これでは問題を解決することができませんでした。
原因は不明なので、こちらに関してはもう少し調査する予定です。

最後に

フリューでは、全ユーザにsudo実行できる権限を付与するかわりにrootでのシェル操作を禁止しています。

【理由】

  • セキュリティ向上のため
  • rootコンソールでシェル操作をすると、「誰」が「何」を操作したのか解りにくくなるため
  • sudoを使用してのroot権限での操作はログに残るので追跡調査が可能になるため

 

今回のように、sudoを使っているといくつかの問題に出くわすことがあります。
しかし、セキュリティを担保するためには、rootで直接実行するよりもsudoを使うよう習慣付けるのが望ましいです。
そのためにも、今回のようにオプションを調べて対応することが、今後も大切になりそうです。


2018年10月16日

awata

ansible で become_user が失敗した時の対応

はじめまして。こんにちは。
ピクトリンク事業部インフラ課の粟田です。

今回の内容を書くに至った経緯

ansibleを社内で利用している事は他の記事を参照してもらえればわかると思いますが、今回そんな運用の中で発生した問題とその解決方をメモとして残しておこうという次第です。

ついでに周りからのなんか書いて投稿しろ、という感じだったりします。

 

発生した問題

ユーザ管理とsudoの権限設定にはldapを使用している環境になります。

実際にログインした状態で

などは実行できます。

また、ansibleを実行する際に、ansible_ssh_userにrootを基本的には使用しないのが運用ルールとしてあります。

どのサーバにもrootでログインしようとする人が居るので、これは禁止すべきでしょ、普通。

この状態で、以下の様なplaybookを実行するとエラーになりました。

エラー内容はこう(あまりにも見難かったのでjqで整形してあります)

become_userを記載しない場合には問題なく実行完了するので、油断してたんですが、実際にログインして、コマンドを実行してみました。

ようは、

  • ansibleでログインする際のユーザは一般ユーザ
  • 一般ユーザでもsudoできる
  • sudo -u 別ユーザ コマンド が実行できない

という部分がポイントです。

そんな環境そうそうないでしょうけど…

解決方法

  • 今更ldapの設定を変更して失敗したら影響範囲が大きいのでとっても億劫
  • 一部バッチ処理でもsudoしてるのがあるのでldapいじりたくないな
  • とりあえず、運用としてansibleユーザだけなんとかできれば良い

という事で、ansibleユーザのsudoの権限を単純に解決することにしました。

としてローカルで作成したファイルをansibleのcopyモジュールでリモートの/etc/sudoers.d以下に配置するという最も単純な手法で解決としました。

あとがき

ldapサーバ作った時にもうちょっと検証しておけば…

内輪ネタは削除された…