astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

無線LANアクセスポイントのリソース状況を可視化した話

こんにちは。開発部のtorigakiです。 弊社では無線LANアクセスポイントにYamaha WLXシリーズを使用しているのですが、最近社内のwifi環境が不調になることがあります。

そこで何が原因なのか探るためアクセスポイントのリソース使用状況を可視化することを試みました。

WLXシリーズにはWebUIが用意されており、CPUやメモリ使用状況などブラウザから確認することもできるのですが、このWebUI上からでは過去の状況を把握することができず、不調になったときの状況がわからないため、定期的にリソース情報を取得し、グラフ化して時系列で状況を把握することができるようにしましたので、今回はそのお話をさせていただければと思います。

リソース情報を取得する

無線アクセスポイントからリソース情報を取得する方法は色々あるかと思いますが、今回はtelnetとexpectを組み合わせて、定期的にアクセスポイントにログインして情報を収集する方法にしました。

以下は情報を収集するスクリプトの例です。 「IP」にはリソース取得対象のアクセスポイントのIPアドレスを指定します。

#!/bin/bash

expect -c "
set timeout 5
spawn telnet ${IP}
expect Password:\  ; send \"XXXXX\n\"
expect \"> \" ; send \"show environment\n\"
expect \"> \" ; send \"exit\n\"
" > ${IP}_log

WLXシリーズは、showコマンドにて様々な情報をとることができます。 「show environment」を実行すると、以下のような結果が得られます。

CPU:  20%(5sec)  31%(1min)  36%(5min)    メモリ: 40% used
ファームウェア: internal  設定ファイル: 0
起動時刻: 2019/04/11 13:33:03 +09:00
現在の時刻: 2019/04/12 16:47:14 +09:00
起動からの経過時間: 1日 03:14:11
セキュリティクラス レベル: 1, FORGET: ON, TELNET: OFF
筐体内温度(℃): 47
電源: PoE
連携状態: RT連携

上記の結果をテキストファイルに保存し、必要な情報を抜き出します。 今回の場合、CPU、メモリ、筐体温度の情報を抜き出しています。

抜き出した情報を可視化する方法

使用したツール

リソース状況を可視化するツールとして、今回はInfluxDBGrafanaを使用しました。

ツールをインストールしたOSは「Ubuntu 18.04.2 LTS」です。

InfluxDB

InfluxDBはオープンソースの時系列データベースで、ログなどの時間を軸とした連続したデータを蓄積、検索することを得意としているデータベースです。

以下はインストール例です。 設定はデフォルトのままです。

wget https://dl.influxdata.com/influxdb/releases/influxdb_1.7.4_amd64.deb
sudo dpkg -i influxdb_1.7.4_amd64.deb

systemctl start influxdb

Grafana

Grafanaはデータ時系列の分析用ダッシュボードのツールです。

以下はインストール例です。 設定はデフォルトのままです。

wget https://dl.grafana.com/oss/release/grafana_6.0.2_amd64.deb 
sudo dpkg -i grafana_6.0.2_amd64.deb 

systemctl start grafana-server

InfluxDBにデータをインサートする

無線アクセスポイントから取得した情報(CPU、メモリ、筐体温度)をInfulxDBにインサートしていきます。 インサート方法はcurlコマンドを使用しました。

以下はインサートスクリプトの例です。 「TAG」に無線アクセスポイントのIPアドレス、「TIME」に情報を取得した時間をunixtimeに変換して入れています。 「DB」はInfluxDBに予め作成したDB名が入ります。

# CPU
curl -o /dev/null -s -i -XPOST "http://localhost:8086/write?db=${DB}&precision=s" 
 --data-binary "${TAG}_cpu,ip=${TAG} cpu=${CPU} ${TIME}"

# MEM
curl -o /dev/null -s -i -XPOST "http://localhost:8086/write?db=${DB}&precision=s" 
 --data-binary "${TAG}_mem,ip=${TAG} mem=${MEM} ${TIME}"

# Temperature
curl -o /dev/null -s -i -XPOST "http://localhost:8086/write?db=${DB}&precision=s"  
 --data-binary "${TAG}_temp,ip=${TAG} temperature=${TEMP} ${TIME}"

上記を実行すると、InfluxDBには以下のようにインサートされます。

# テーブル一覧
> show measurements;
name: measurements
name
----
192.168.11.101_cpu
192.168.11.101_mem
192.168.11.101_temp

# データ内容
> select * from "192.168.11.101_cpu" limit 10;
name: 192.168.11.101_cpu
time                cpu ip
----                --- --
1553585400000000000 57  192.168.11.101
1553585700000000000 52  192.168.11.101
1553586000000000000 60  192.168.11.101
1553586300000000000 52  192.168.11.101
1553586600000000000 54  192.168.11.101
1553586900000000000 61  192.168.11.101
1553587200000000000 54  192.168.11.101
1553587500000000000 68  192.168.11.101
1553587800000000000 61  192.168.11.101
1553588100000000000 53  192.168.11.101
>

1分ごとに取得しているので、DBには1分ごとの情報がインサートされていきます。 各IPアドレスごとに、CPU、MEM、TEMPのテーブルが作成されデータがインサートされていきます。

Grafnaで可視化する

Grafanaにブラウザでアクセスし、グラフを作成します。

InfluxDBからデータを取得するクエリですが、以下のように指定します。 以下はCPUステータスを取得する場合の例です。

select cpu  from /.*_cpu.*/ where $timeFilter order by asc

上記のように、ワイルドカードを指定することにより、IPアドレスごとに作成したテーブル情報を一括で取得することが可能です。 このクエリを実行できるようにするために、InfluxDBにはテーブル名にIPアドレスを入れて、CPUステータスだけを入れるテーブル、メモリステータスだけを入れるテーブルという感じでインサートしていくことがポイントとなります。

実際にGrafanaで作成したグラフが以下になります。

f:id:astamuse:20190415124459p:plain

munin等の場合、1つグラフに1の機器のグラフしか作成できませんが、Grafanaでは複数機器の値を一括で取得すると、1つのグラフに複数機器の状態を重ねて表示できるところができるので便利です。

まとめ

今回は無線LANアクセスポイントのリソース状況を可視化するあたり工夫した点について紹介させていただきました。 少しでも無線LANアクセスポイントの運用されている方のお役に立てれば幸いです。

弊社では引き続きエンジニア・デザイナーを募集中ですので、ご興味のある方は下からご応募いただければと思います。

JDK12で変わったswitchに触れてみる。

お久しぶりです。開発部のyanagitaです。
4月に入り新社会人になられた方や新しい職場に移られた方、多くの職場で新たな出会いがあったのではないでしょうか?
アスタミューゼでは事業拡大に伴い、多くのエンジニア&デザイナーとの出会いを求めてます!

話を戻して、
今回は2019/03/19に正式リリースされたJDK12のswitchの新機能に触ってみたい思います。

switch文の新機能

switch文の新機能は大きく3つあります。

  • case句の複数条件の表記改善
  • break句の省略
  • switch文の式として利用

その前に

今回JDK12で公開されたswitch文の新機能はすべてプレビュー機能に分類されます。 switchの新機能を含むソースコードのコンパイル、実行、jshell上でプレビュー機能を使用するには--enable-previewオプションをつけてあげる必要があります。

コンパイル時

$ javac --enable-preview -source 12 Sample.java

コンパイル時は "--enable-preview" に合わせて "-source 12" が必要になります。(12はjdkバージョン)

実行時

$ java --enable-preview Sample

jshell起動時

$ jshell --enable-preview

※ 本記事ではjavaコマンドでjavaファイルを直接実行します。

case句の複数条件の表記改善

これまでswitch文で複数条件をマッチさせる場合、case句を条件分宣言する必要がありました。
慣れてしまうとそういうものだと思ってしまいますが、条件が増えてくるとcase句を多量に書かなくてはならず、スマートな記述が出来ていませんでした。
■ 従来のswitch文

public class SwitchSample {
    public static void main(String args[]) {
       switch (args[0]) {
           case "red" :  // マッチ条件だけcase句を記述する
           case "green" :
           case "blue" : System.out.printf("%sは色です。\n", args[0]); break;
           default : System.out.printf("条件に一致しません。[%s]\n", args[0]); break;
       }
    }
}

実行結果

$ java SwitchSample.java red
$ redは色です。
$ java SwitchSample.java blue
$ buleは色です。
$ java SwitchSample.java cat
$ 条件に一致しません。[cat]

新機能では、複数条件を1つのcase句にカンマ区切りで定義することが出来ます。

■ 新機能で書いたswitch文

public class SwitchSample {
    public static void main(String args[]) {
       switch (args[0]) {
           // マッチ条件をカンマ区切りで記述する
           case "red", "green", "blue" : System.out.printf("%sは色です。\n", args[0]); break;
           default : System.out.printf("条件に一致しません。[%s]\n", args[0]); break;
       }
    }
}

実行結果

$ java --enable-preview --source 12 SwitchSample.java red
$ redは色です。
$ java --enable-preview --source 12 SwitchSample.java blue
$ buleは色です。
$ java --enable-preview --source 12 SwitchSample.java cat
$ 条件に一致しません。[cat]

行数も減り、だいぶスッキリしました。

break句の省略

これまで条件にマッチしたcase句のみを実行する場合、case句の終わりにbleak句を記述してあげる必要がありました。新機能ではこのbreak句を省略することが可能になります。
省略する際は、これまでのcase 条件 :と記述していたところをcase 条件 ->とcase句の締めを「:」から「->」変更します。
■ 新機能で書いたswitch文

public class SwitchSample {
    public static void main(String args[]) {
       switch (args[0]) {
           case "red", "green", "blue" -> System.out.printf("%sは色です。\n", args[0]); // break; ← 省略
           default -> System.out.printf("条件に一致しません。[%s]\n", args[0]);  // break; ← 省略
       }
    }
}

ここで2点注意があります。

  1. break句の省略形式(case 条件 ->)と従来のcase句の形式を混在させたswithc文はコンパイルエラーとなるため、break句の省略を採用した場合はすべてのcase句でbreak省略形式で記述する必要があります。
  2. break句の省略形式で記述した場合、switch文内でreturnを使用することはできずコンパイルエラーとなります。

2はあまりないケースだと思いますが、修正される場合はお気をつけください。

switch文の式として利用

Scalaなどでifやmatchなど使っていると値を戻すことが当たり前になっているので、久しぶりにjavaに触れるとswitch文の手前で変数宣言をしてあげる必要があり、改めて面倒に感じることが多かったのですが、新機能ではswitch文を処理結果を返す式として扱うことができるようになります。

■ 従来のswitch文

public class SwitchSample {
    public static void main(String args[]) {
        String result = null; // switch文より前で値を受け取る変数を宣言する必要がありました。
        switch (args[0]) {
            case "red" :
            case "green" :
            case  "blue" : result = String.format("%sは色です。\n", args[0]); break;
            default : result = String.format("条件に一致しません。[%s]\n", args[0]); break;
        }
        System.out.print(result);
    }
}

■ 新機能で書いたswitch文

public class SwitchSample {
    public static void main(String args[]) {
        // switch文内の処理結果を受け取れるようになります。
        String result = switch (args[0]) {
            case "red" :
            case "green" : 
            case "blue" : break String.format("%sは色です。\n", args[0]); 
            default : break String.format("条件に一致しません。[%s]\n", args[0]);
        }; // ← switch文が式扱いになるため、「;」で終わること
        System.out.print(result);
    }
}

従来の記述に比べ、switch文が式化したことで変数への代入が一箇所にまとまり代入漏れが減るように感じます。
ここでは注意が3点あり、

  1. 値を返すのは「return 値」ではなく、「break 値」になります。returnを使用するとコンパイルエラーになります。
  2. 戻す型は、switch文から代入する変数の型のみとなります。それ以外の型になっているとコンパイルエラーとなります。
  3. 例のコメントアウトにもありますが、switch文を式として扱うため、switch文の終わりに「;」が必要となります。

全機能使用すると

■ switchの新機能を全部盛り込むと

public class SwitchSample {
    public static void main(String args[]) {
        // 従来の複数マッチ 
        String result = switch (args[0]) {
            case "red", "green", "blue" -> String.format("%sは色です。\n", args[0]);
            default -> String.format("条件に一致しません。[%s]\n", args[0]);
        };
        System.out.print(result);
    }
}

switch文がすごいスッキリしたと思います。個人的には式対応したことはすごく嬉しいです。

おまけ

従来のswitch文と新機能のswitch文で処理速度を比較してみました。
が!差は全くありませんでした。ネタにならず・・・

最後にもう一度

アスタミューゼではたくさんのエンジニア&デザイナをまだまだまだ募集しています。 気になる方は下からご応募下さい!新しい出会いをメンバー一同お待ちしてます!

Linuxでユーザアカウントを無効化するエトセトラ

f:id:astamuse:20190326183431p:plain

こんにちは。並河(@namikawa)です。

すっかり春に近づきつつあり、肌寒い日と陽気な日が入り乱れる近頃ですが、ヒノキ花粉のファーストパンチにやられてしまい、著しく生産性が低下しているここ2〜3日です。

さて、例によって今回もLinux運用環境での小ネタを書いておこうかと思いますが、今日はLinuxサーバでアカウントを残しつつ、アクセスは無効化したい時などの話題です。

今更感がある話題でもありますが、改めて備忘録的に書いておきたいと思います。

試した環境とか背景とか

Linuxでもディストリビューションによって、挙動に若干の差異があるかもしれないので、記載しておきますが、今回、"Ubuntu 18.04 LTS" を使って、試してみました。

会社やプロジェクトでサーバを運用していると、どうしてもプロジェクトから抜けたメンバーや退職者などで、ユーザを削除・無効化など棚卸ししたくなるケースが出てくると思います。

そんな場合に、素直にユーザ削除(userdel)できればよいのですが、事情によってはそのアカウントをしばらく残しておきたい等もあるかと思いますので、そんな場合どうしたらよいのか、が今回のお題です。

あと、普段はあまり使わないですが、わかりやすくするために、今回はあえてSSHでのパスワード認証を許可(PasswordAuthentication yes)しています。

アカウントをロックする

一番簡単なのは、アカウントをロックしちゃうことでしょうか。

メンバーがプロジェクトに戻ってきた場合などでも、簡単に戻せます。

実行は以下のように passwd コマンドを使うと簡単です。

( testuser は対象のユーザ名です )

# passwd -l testuser

確認は、以下の通りで、2列目が "L" になっていれば Lock されたことを意味します。

# passwd -S testuser
testuser L 03/22/2019 0 99999 7 -1

他、/etc/shafow のパスワードフィールドの先頭にアスタリスク(!)が2つ付いていると Lock を意味します。

ログインシェルを無効にする

あまりメンバーのアカウントをシステムアカウント的に使うことはないかと思うのですが、やむを得ない事情でプロセスの起動アカウントとして使いたいが、ログインはさせたくない、といったこともあるでしょう。(無いようにはしたいですが...)

そういった場合は、ログインシェルを無効なものに変更することで、ログインできなくすることもできます。

この話をし始めると、よく /bin/false/sbin/nologin のどちらを使うのかという議論になります。

で、細かい違いはあれど、 /etc/shells で定義されたものがログインシェルとして正当なプログラムと扱われるわけで、今回テストしている環境である Ubuntu 18.04 LTS では、 /etc/shells に上記2つはどちらも含まれていませんでした。

ちなみに最近の Ubuntu では /sbin/nologin ではなく /usr/sbin/nologin にプログラムが存在します。

/usr/sbin/nologin

# usermod -s /usr/sbin/nologin testuser

設定はこんな感じで実施。

$ sudo su - testuser
This account is currently not available.

su しようとすると not available と警告が出て、suできない感じです。

$ ssh testuser@servername
testuser@servername's password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-1028-gcp x86_64)

・・・・・

Last login: Fri Mar 22 12:50:33 2019 from 122.219.65.217
This account is currently not available.
Connection to servername closed.

リモートから ssh で接続しようとしても同様の表示。ただし motd のメッセージが出力されます。 (こちらについての対応は後述。)

/bin/false

# usermod -s /bin/false testuser

先ほど同様、こんな感じで設定できます。

$ su - testuser
Password:

パスワード入力するもログインはできません。

$ ssh testuser@servername
testuser@servername's password:
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-1028-gcp x86_64)

・・・・・

Last login: Fri Mar 22 12:49:16 2019 from 122.219.65.217
Connection to servername closed.

リモートから ssh で接続しようとしても motd のメッセージが表示された後に切断されます。

motd のメッセージが表示されないようにする

これについては man 1 login を読むと以下の記載があります。

   $HOME/.hushlogin
      Suppress printing of system messages.

ホームディレクトリ配下に .hushlogin という空ファイルを作っておくと、システムメッセージの抑制ができます。

# sudo -u testuser touch /home/testuser/.hushlogin

というわけで、該当ユーザ配下に touch でファイルを置いて、、、

$ ssh testuser@servername
testuser@servername's password:
Connection to servername closed.

試してみると、表示されなくなりました。ここまではやっておいた方が良さそうです。

さいごに

最後に、毎度で恐縮なPRタイムですが、弊社ではエンジニア・デザイナーを絶賛大募集しておりますので、少しでも気になれば、カジュアルにランチでもしながらお話ししましょうー!

弊社は、最近オフィスの引っ越しを行ったのですが、オフィスビルの隣には有名なカレー屋(ボンディ)さんがありますので、美味しいカレーでも食べながら是非!

少しでもご興味があればお手数ですが (@namikawa) まで気軽にDM等いただければと思います。

それでは!=͟͟͞͞(๑•̀=͟͟͞͞(๑•̀д•́=͟͟͞͞(๑•̀д•́๑)=͟͟͞͞(๑•̀д•́

@namikawa が書いた過去記事)

Copyright © astamuse company, ltd. all rights reserved.