コンピューターのアカウントをSlack上から操作するためのSlack botを公開しました

2020年10月6日

LinuxなどのOSのユーザーアカウントをSlack上で管理するためのSlack botであるsacana(Slackbot As Computer Account maNAger)を公開しました!

sacanaは useradd コマンドと usermod コマンドが導入されていて、ユーザー情報が /etc/passwd に記載されている環境で動作するSlack botです。 Slack上にbotアカウントを作り、そのトークンをsacanaに与えて実行することで、設定したチャンネルを監視し、そのチャンネル上でbotアカウントに特定のメッセージを送ることでそのコンピューターのユーザーアカウントの作成やグループへの参加ができるようになります。 また、付属のsystemdのユニットファイルを使うことでLinux環境ではsystemdによるデーモン化ができます。 詳しい導入方法や使い方はプロジェクトのREADME.mdを御覧ください。

実装の背景

フィックスターズには共用開発機と呼ばれるコンピューターたちがいくつか存在します。 共用開発機は社内に公開されている社員が自由に使える開発環境で、社内勉強会や社員の自己研鑽などで使うことができます。 それぞれNVIDIA TITAN VやAMD Radeon Vega、Intel Xeon Phi Knights Landingといった並列計算用のプロセッサを積んでおり、並列計算はもちろんのこと、普通に高性能CPU・大容量メモリのLinux環境として使うこともできます。また、既にCUDAやOpenCLの開発環境が整っているので、ユーザーアカウントを作ってSSHするだけで開発を始められることもあり、共用開発機はインターンシップで使われることもあります。

さて、この共用開発機ですが、実は以前はユーザーアカウントの管理方法が「sudoersでパスワードが公開されている”ユーザーアカウント作成用ユーザー”でログインし、自分のアカウントを作り、以降は自分のアカウントから操作する」という とても温かみのある方法 で行われていました。 この管理方法は以下のような問題点があります。

  • 毎回の作業が大変
    インターン生の中にはLinuxでの開発経験に乏しい方や、日頃Linuxを使っていてもコマンドラインでユーザーアカウントを作成するのに不慣れな方もいます。 また、大体の人はユーザーアカウントを作ったり特定のグループに参加するのは各開発機に対して1回きりなので、社員も作業内容を忘れがちで、教える度にやり方を調べなおすことが多くありました。 また useraddadduser など同種のコマンドが複数あってベストプラクティスがわからない、オプションを間違えると環境全体に影響を及ぼすコマンドがありそれなりに注意が必要、などの問題もありました。
  • セキュリティ的に結構問題
    sudoersのアカウントのパスワードが社内に公開されている状態なので、その気になれば足が付くことなく共用開発機のデータを消し飛ばすことが可能な状態でした。 基本的には性善説に基づいて問題なく運用されていましたが、人間誰しもミスはしうるので、事故の危険性はあります。
これらの問題を解決するために、Slack上からユーザーアカウントの作成を行えるようにしてはどうか、という話になり、sacanaを実装することになりました。

実装について

sacanaの実装にはRustを用いました。 Rustは従来CやC++で記述されていたようなシステムプログラミングにも適したプログラミング言語で、速度、並行性、および安全性の3つを重要視しています。 フィックスターズの業務では主にCやC++を使うことが多いのですが、本プロジェクトの主要なコントリビューターの1人であるtoru.fukayaなど、Rustを積極的に学んでいる社員もいます。

sacanaにRustを採用した理由としては、以下の2点が挙げられます。

  1. sacanaはroot権限で長時間動くシステムアプリケーションなので、静的により多くの点について 安全性 を保証できるRustは魅力的だった
  2. Slackとの通信にHTTPやWebsocketを使う必要があったが、Rustはこうした Web系のプログラムも比較的簡単に記述できる (と聞いていた)
こうしたRustの特徴は実際に本プロジェクトに大きく貢献し、致命的なバグを生むこともほとんど無く¹、Rust自体やSlack APIのキャッチアップも込みで2週間ほどでとりあえず動くところまで持っていくことができました。

また、開発者の個人的な動機として、

  1. Webプログラミングが必要だが、動的型付けは嫌い
  2. Rustについて、良さそうな言語に見えるし、良い言語だという話も聞くが、実用的なアプリケーション開発を行うためにRustを使ってみたことがまだ無かった
といった理由もありました。

実際にRustを使ってみた感想ですが、日頃C++を使っている身からすると、まともなパッケージマネージャがあるというのは特筆すべきポイントの1つでしょう。 簡単な操作で便利なライブラリがすぐ使えるようになる、というのはプロトタイピングを容易にしてくれます。 特にHTTPを叩くライブラリについては reqwest という非常に使いやすいクレートがあり、こうしたeasyで定番のネットワークライブラリが揃っているのはとても素晴らしいと思います²。 またコンパイラが厳しいのも安心感があり、好印象でした。 最初は型合わせゲーム(主に文字列借用周り)で時間を溶かしましたが、逆にコンパイラの指示に従っておけばとりあえず問題なく動くプログラムが書けるという印象です。 他にもパターンマッチや std::result::Result が広く採用されている点など、非常に記述しやすい言語だと感じました。

一方で、Rustネイティブでない身からするとパフォーマンスやRustとしてより良い書き方を意識しながらプログラムを書くのは大変でした。 例えば文字列に関して、性能を気にしない限りとりあえず std::string::String を使っておけば動くプログラムは書けるのですが、「ここの戻り値型は &'static str でいける」などの判断は('static の存在を思い出すのも含めて)中々難しかったです。 また、C++のそれとは異なる概念であるイテレータや、便利なクレート(failure とか)、 if let やHRTBなど、知らないとどうしようもない知識や文化についても実装しながら追いかける形となってしまい、(C++ネイティブとしては)外国語を学んでいる感覚がつよかったです。 今回はレビュワーとしてRustaceanのtoru.fukayaが就いてくれたので、Rustについて教えてもらったり、より良いコードについて2人で考えたりしながら進めていくことができました。

巷では「Rustは学習コストが高い」と言われていますが、個人的な感想は「便利ライブラリも揃っていて、パフォーマンスやコードの品質を気にせず軽めのツールを作るには楽な言語だが、RustをRustらしく書けるようになるために必要な学習コストは高い」で、これはどの言語でも似たようなものなのではないかなぁと思います³

動作イメージ

弊社内では tech-computers-bot の名前でsacanaを実行しています

動作の様子(プライバシーに配慮し、画像の一部を塗りつぶし加工してあります)

このように、 tech-computers-bot にメンションで create gf1060 と送ることで、ホスト名 gf1060 の端末にそのディスプレイネーム(私であれば yoshiki.imaizumi )のアカウントが作成されます。 join sudo furyx と送ればホスト名 furyxyoshiki.imaizumi アカウントが sudo グループに入れます。 また、各コマンドが成功すると「○」、コマンドが失敗すると「×」といったリアクションを付けてくれます。

他にもcomputer-account-managerへのDMで help コマンドを使うことで使い方の説明を見ることもでき、また ping コマンドで各ホストにおけるbotの動作状況を確認することもできます。 さらに、起動時にSlackにhelloメッセージを送ってくれるので、再起動を掛けたときなどに正しく再起動ができたかの簡易的な確認にも使えます。

今後について

社内では安定して動いているため、基本的にはSlack APIの仕様変更やRustの更新に対する追従など保守作業が主となりますが、社内での運用では必須ではないとして実装が見送られた機能など、実装予定の新機能もいくつかあります。 これからも開発はGitHub上で行っていくので、開発状況についてはGitHubのIssueをチェックしてみてください。 もちろん、みなさまからのIssueやPull Requestも歓迎します。


[1]: 最大のバグは「はじめてのデプロイ時にbotが自分に向けてリプライを送り続ける無限ループを起こしてチャンネルが荒れた」というもので、これはロジックの問題なので流石にRustでもどうしようもなかったです。

[2]: C++だとネットワークライブラリ(Boost.Asio)はセットアップもコーディングもeasyではないので、特にネットワークライブラリに関しては強く感じました(常に細かなハンドリングを行いたいわけではないので、(Boost.Beastを使ったとしても)Boost.Asioはオーバースペック気味だと思っています)

[3]: これはやや生存バイアスっぽい

[4]: というか、元々はtech-computers-botの名で開発されていましたが、公開に先立ち紆余曲折を経てsacanaに出世したという経緯があります(魚だけに(?))

Tags

About Author

Imaizumi Yoshiki

Leave a Comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Recent Comments

Social Media