astamuse Lab

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

アクセスログ収集用Elasticsearchの運用話

こんにちは。インフラ・開発部のtorigakiです。

早いもので2回目の投稿となります。

弊社はアクセスログの収集・解析にElasticsearchを使用しているのですが、今回はこのElasticsearchの運用環境について書きたいと思います。

システム構成

Elasticsearch環境は以下となります。

  • GCPの仮想インスタンスで構築
  • Elasticsearchサーバー3台(1クラスタ)+運用管理サーバー1台
  • Elasticsearchサーバー情報(3台)
    • Elasticsearchのバージョンは2.4.6。
OS CPUコア数 メモリ HDD
Ubuntu 16.04.4 8コア           8GB 200GB
  • 運用管理用サーバーはCPU:1コア、メモリ:2GB。

f:id:astamuse:20180717114148p:plain

  • NginxのアクセスログをFluentd経由でElasticsearchに送信。
  • ElasticsearchはKibanaの他にJavaのアプリからも使用しています。
  • Elasticsearchの運用スクリプト(バックアップ等)は運用管理サーバーから実行しています。

運用管理サーバーの役割

Nginxでバランシング

Nginxで以下アクセスをバランシングしています。

  • kibanaへのアクセス
  • Elasticsearchの運用スクリプト(過去データ削除、バックアップ、インデックス作成)

※3台のうちどのノードが落ちたときでもスクリプトを実行できるようにするため、Elasticsearchへのアクセスはバランサーを通すようにしています。

Elasticsearch運用

以下を実行するスクリプトを用意して、cronで定期実行するようしています。

  • index(alias)作成

    • 月末に来月分のindex(alias)を作成します。(例:logstash-2018.XX)
  • 過去データ削除

    • Curatorを使って定期的に削除しています。

Curatorの設定は以下ようにしています。

actions:
  1:
    action: delete_indices
    description: "Delete logstash indices"
    options:
      ignore_empty_list: True
      continue_if_exception: False
      disable_action: False
    filters:
    - filtertype: pattern
      kind: prefix
      value: logstash-
      exclude:
    - filtertype: age
      source: name
      direction: older
      timestring: '%Y.%m'
      unit: days
      unit_count: XXX
      exclude:

「unit_count」に保持日数を設定します。

上記のymlファイルを以下のコマンドでcronで定期実行するように設定します。

/usr/local/bin/curator delete_indices.yml
  • バックアップ
    • elasticsearch-dumpを使ってJSONファイルとして保存し、GCSにアップロードしています。

elasticsearch-dumpを実行するスクリプトは以下のようにして、analyzer、mapping、dataをJSONファイルとして個別に保存し、gzipで圧縮するようにしてあります。

  /usr/local/bin/elasticdump \
    --input=http://localhost:9200/${index} \
    --output=$ \
    --type=analyzer \
    | gzip > ${BACKUP_DIR}/$1/analyzer.json.gz

  /usr/local/bin/elasticdump \
    --input=http://localhost:9200/${index} \
    --output=$ \
    --type=mapping \
    | gzip > ${BACKUP_DIR}/$1/mapping.json.gz

  /usr/local/bin/elasticdump \
    --input=http://localhost:9200/${index} \
    --output=$ \
    --type=data \
    | gzip > ${BACKUP_DIR}/$1/data.json.gz

環境の移設

このアクセスログ収集用Elasticsearchは他環境から移設してきたのですが、移設時の切り替えで行った作業内容について簡単に書きたいと思います。

f:id:astamuse:20180717114448p:plain

事前準備

  • 旧環境と同一のテンプレートを新環境のElasticsearchにインポートしておきます。
  • 新環境のElasticsearchに過去データをコピーしておきます。
    • データコピーにはelasticsearch-dump使用してクラスタ間でダイレクトコピーしました。
  • コピーしたデータがKinbanaで問題なく表示できることを確認しておきます。
  • 新・旧両方のElasticsearchに同一データを送信するためのFluentdのコンフィグファイルを準備しておきます。

作業手順

  1. Fluentdを停止します。
  2. 新環境のElasticsearchに、最新データをコピーします。
  3. Fluentdのコンフィグファイルを新・旧同時送信用のコンフィグに差し替えます。
  4. Fluentdを起動します。
  5. 新・旧のElasticsearchに新規の同一データが送信されていることを確認します。

作業後

  • 1ヶ月は新・旧並行運用して様子を見ます。
  • Javaアプリの接続先を新環境に切り替えます。

まとめ

今回はElasticsearchの運用で工夫した点について紹介させていただきました。

少しでもElasticsearchの運用されている方のお役に立てれば幸いです。

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

Monit+Webhookでslack通知してみる

f:id:astamuse:20180709175656p:plain

お久しぶりです。インフラ・開発部のyanagitaです。
変わらず宮崎からリモートワークを行っております。

弊社ではサービス障害や優先度の高いインシデントの発生時に開発メンバー全員へのメール通知と合わせて、 担当のスケジューリングとエスカレーション機能を持つ外部サービス(https://www.pagerduty.com/)を使用していち早く対応を行っています。
ただ、中にはそれほど優先度の高くないインシデントや限られたメンバーのみで検知したい事があります。
そこで今回はその条件を満たす例として、Monit + Slackのwebhookを利用してSlackに通知する方法を紹介したいと思います。

とりあえず、全体図

f:id:astamuse:20180709175556j:plain 全体図は非常にあっさりしています。
前述したとおり、サーバ内の異常をMonitで検知して、MonitからSlackのWebhookにメッセージを送信するShellをキックする流れとなります。

では、手順を紹介します。

着信Webフックの登録

着信Webフックとは、着信Webフック用のURLに向けてメッセージをPostするだけでSlack上にメッセージを表示することできるインテグレーション用のアプリになります。
まず、着信Webフックの登録に移ります。
※ サインオン前提で進めます。

slack.com

登録はアイコン下の「設定を追加」から行います。ざっと手順は下記の通りです。

  1. メッセージを投稿するチャンネルの選択する。

  2. 以下の項目を他の着信Webフックと被らないよう変更する。
     ・着信Webフック名
     ・アイコン

ここでWebhook URLの値がPost用のURLになりますので取扱いにご注意ください。

通知Shellの実装

Webhook URLをキックするShellを実装します。以下は簡略化したサンプルです。

/opt/slack/SlackNotification.sh

#!/bin/bash

# 着信Webフックで発行したWebhook URL
webHookUrl="https://hooks.slack.com/services/XXXXXXXX/YYYYYYYY/0123456789abcdefg"

# メッセージの情報はjson形式で定義します。
# パラメータの詳細はこちら(https://api.slack.com/docs/message-attachments#when_to_use_attachments)
payload='payload={
  "attachments": [
    {
      "color": "warning",
      "fields": [
        {
          "title" : "サンプル警告タイトル",
          "value" : "サンプル警告メッセージ"
        }
      ]
    } 
  ]
}'

# Webhoookに向けてメッセージ情報をPostします。
curl -s -X POST --data-urlencode "$payload" $webHookUrl

出力結果はこんな感じです。
f:id:astamuse:20180710102626p:plain

メッセージの表示フォーマットは細かくカスタマイズ可能です。気になる方はこちらをご確認ください。

api.slack.com

payloadのメッセージ確認はこちらで行うも事ができます。
Message Formatting | Slack

Monitの設定

Monitではサーバ内の細かいチェックが可能ですが、今回はlogファイルにworningが出力されたタイミングでSlackに通知させたいと思います。
Monitの設定は以下の通りです。

check file sample_notification with path /opt/batch/sample_batch/logs/application.log
    if match "WORN" then exec "/opt/slack/SlackNotification.sh"

check fileで監視ファイルを指定し、3行目のif match句で警告ログを検知させます。検知した際は通知Shellをキックさせるためexec句で通知Shellのパスを指定します。
この時、monitの設定で検知時にメールを送信する設定を入れている場合は、通知をSlackのみに限定したいのでnoalert句でメール通知を停止させます。

check file sample_notification with path /opt/batch/sample_batch/logs/application.log
    noalert xxxxxxxx@test.astamuse.co.jp
    if match "WORN" then exec "/opt/slack/SlackNotification.sh"

以上の工程で簡単にSlackへの通知が可能になります。

最後に

monit+webhookの組み合わせでSlackへの簡単な通知を紹介ました。
通知Shellの実装次第で詳細な情報の通知することもできますし、webhookの追加開発を行えば誰が対応しているかSlack上で共有することも可能です。

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

何気に便利に使えるかもしれない authorized_keys のオプション

f:id:astamuse:20180704111737j:plain

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

関東ではすでに梅雨が明けたということで水不足が心配ではありますが、すっかり気候は夏ですね。夏といえば、海にアイスクリームにラーメンといったところでしょうか。

さて、前回も書いた気がするのですが、近頃はすっかり本業のインフラ職人業が随分と減ってきていて、新鮮な技術ネタがあまりなく、エンジニアとして微妙な立ち位置ですが、せっかくの機会なので1年くらい前に気づいたLinux運用環境での小ネタでも書こうかと思います。

authorized_keys のオプション

authorized_keys は、SSHでログインする場合に、利用する公開鍵を指定しておくファイル(~/.ssh/authorized_keys)になっているのですが、実はオプションをつけることで色々と制約を設けることができます。

何もオプションを指定しない場合は、こういう感じのフォーマットになっているかと思います。

ssh-rsa AAAAB3NzaC1yc2EA........DV3UA/br namikawa@localhost

で、 man sshd とかを眺めると AUTHORIZED_KEYS FILE FORMAT の項目に色々なオプションの説明が書いてあり、使えるオプションとその概要のリストは以下の通りです。

  • cert-authority
    • CA認証局の設定
  • command="command"
    • 実行可能なコマンドの設定
  • environment="NAME=value"
    • 環境変数の設定
  • from="pattern-list"
    • 接続可能なIPアドレス(またはcanonical name)の設定
  • no-agent-forwarding
    • 認証エージェント転送禁止の設定
  • no-port-forwarding
    • ポート転送禁止の設定
  • no-pty
    • 仮想端末の割り当て禁止の設定
  • no-user-rc
    • ~/.ssh/rcの実行禁止の設定
  • no-X11-forwarding
    • X11(画面)転送禁止の設定
  • permitopen="host:port"
    • ssh -L のポート転送先を、指定されたホスト・ポートのみに限定する設定
  • principals="principals"
    • cert-authorityで認証が許可されている principal 一覧の設定
  • tunnel="n"
    • 使用する tun デバイスの設定



細かい説明については、下部に man の抜粋を転載しておきますので、そちらでご確認いただければと思います。

オプションの指定方法

こちらも man にサンプルの記載があるのですが、以下のように指定を行います。 例えば、 from オプションを使って接続元の制限をしたい場合は、以下のように指定します。

from="192.168.10.0/24,*.example.com" ssh-rsa AAAA(以下略)

また、複数の設定を同時に指定したい場合などは、カンマ区切りで以下のように指定します。

from="192.168.10.0/24,*.example.com",no-pty,no-port-forwarding ssh-rsa AAAA(以下略)

このような感じで、公開鍵情報の手前に用意されているオプションを指定することで有効となります。

所感

さて、 authorized_keys も色々とオプションが指定できるんだなー、という感じではあるのですが、ではどういう時に使うのだろうなという点です。

上記のオプションを眺めてわかることは基本的に制約に関する設定になっています。

サーバ管理者がユーザごとに何かしらの制約を課したくて、このやり方でオプションの設定を入れたとしても、ユーザは一度ログインできてしまえば、この設定は変な話、変更できちゃうんですよね。

なので、基本的には、ユーザ自身がオペミス防止などの観点から、必要以上の権限を持たない、もしくは使えなくするように入れる制約となりそうです。

こんな感じで、公開鍵単位で色々と制御できるのは、何かと便利なシーンもあったりするので、頭の片隅に置いておくと役にたつかもしれません。何かのお役に立てれば幸いです。

おまけ

本エントリとは、全く関係のない余談にはなるのですが、このエンジニアブログを始める際に、「企業向けエンジニアブログの作り方」のエントリで書いた通り、持ち回りのターン内でKPI値に沿った優秀エントリに選ばれると、豪華ランチがプレゼントされます。

で、3ターン目に書いた「nginx + ngx_mruby でSSL証明書の動的読み込みを実現して、作業がとても楽になった話」がなんと優秀エントリに選ばれたので、遠慮なく築地で濃厚なうに丼をいただき、大変幸せな気分になりました・・・!

f:id:astamuse:20180704111840j:plain

・・・はい。

最後に、弊社ではエンジニア・デザイナーを絶賛大募集しておりますので、少しでも気になれば、カジュアルにランチでもしながらお話ししましょう。疑問・質問などございましたら、お手数ですが (@namikawa) まで気軽にDM等いただければと思います。

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

@namikawa が書いた過去記事)

参考: man sshd - AUTHORIZED_KEYS FILE FORMAT

AUTHORIZED_KEYS FILE FORMAT
     AuthorizedKeysFile specifies the files containing public keys for public key authentica‐
     tion; if none is specified, the default is ~/.ssh/authorized_keys and
     ~/.ssh/authorized_keys2.  Each line of the file contains one key (empty lines and lines
     starting with a ‘#’ are ignored as comments).  Protocol 1 public keys consist of the
     following space-separated fields: options, bits, exponent, modulus, comment.  Protocol 2
     public key consist of: options, keytype, base64-encoded key, comment.  The options field
     is optional; its presence is determined by whether the line starts with a number or not
     (the options field never starts with a number).  The bits, exponent, modulus, and com‐
     ment fields give the RSA key for protocol version 1; the comment field is not used for
     anything (but may be convenient for the user to identify the key).  For protocol version
     2 the keytype is “ecdsa-sha2-nistp256”, “ecdsa-sha2-nistp384”, “ecdsa-sha2-nistp521”,
     “ssh-ed25519”, “ssh-dss” or “ssh-rsa”.

     Note that lines in this file are usually several hundred bytes long (because of the size
     of the public key encoding) up to a limit of 8 kilobytes, which permits DSA keys up to 8
     kilobits and RSA keys up to 16 kilobits.  You don't want to type them in; instead, copy
     the identity.pub, id_dsa.pub, id_ecdsa.pub, id_ed25519.pub, or the id_rsa.pub file and
     edit it.

     sshd enforces a minimum RSA key modulus size for protocol 1 and protocol 2 keys of 768
     bits.

     The options (if present) consist of comma-separated option specifications.  No spaces
     are permitted, except within double quotes.  The following option specifications are
     supported (note that option keywords are case-insensitive):

     cert-authority
             Specifies that the listed key is a certification authority (CA) that is trusted
             to validate signed certificates for user authentication.

             Certificates may encode access restrictions similar to these key options.  If
             both certificate restrictions and key options are present, the most restrictive
             union of the two is applied.

     command="command"
             Specifies that the command is executed whenever this key is used for authentica‐
             tion.  The command supplied by the user (if any) is ignored.  The command is run
             on a pty if the client requests a pty; otherwise it is run without a tty.  If an
             8-bit clean channel is required, one must not request a pty or should specify
             no-pty.  A quote may be included in the command by quoting it with a backslash.
             This option might be useful to restrict certain public keys to perform just a
             specific operation.  An example might be a key that permits remote backups but
             nothing else.  Note that the client may specify TCP and/or X11 forwarding unless
             they are explicitly prohibited.  The command originally supplied by the client
             is available in the SSH_ORIGINAL_COMMAND environment variable.  Note that this
             option applies to shell, command or subsystem execution.  Also note that this
             command may be superseded by either a sshd_config(5) ForceCommand directive or a
             command embedded in a certificate.

     environment="NAME=value"
             Specifies that the string is to be added to the environment when logging in
             using this key.  Environment variables set this way override other default envi‐
             ronment values.  Multiple options of this type are permitted.  Environment pro‐
             cessing is disabled by default and is controlled via the PermitUserEnvironment
             option.  This option is automatically disabled if UseLogin is enabled.
     from="pattern-list"
             Specifies that in addition to public key authentication, either the canonical
             name of the remote host or its IP address must be present in the comma-separated
             list of patterns.  See PATTERNS in ssh_config(5) for more information on pat‐
             terns.

             In addition to the wildcard matching that may be applied to hostnames or
             addresses, a from stanza may match IP addresses using CIDR address/masklen nota‐
             tion.

             The purpose of this option is to optionally increase security: public key
             authentication by itself does not trust the network or name servers or anything
             (but the key); however, if somebody somehow steals the key, the key permits an
             intruder to log in from anywhere in the world.  This additional option makes
             using a stolen key more difficult (name servers and/or routers would have to be
             compromised in addition to just the key).

     no-agent-forwarding
             Forbids authentication agent forwarding when this key is used for authentica‐
             tion.

     no-port-forwarding
             Forbids TCP forwarding when this key is used for authentication.  Any port for‐
             ward requests by the client will return an error.  This might be used, e.g. in
             connection with the command option.

     no-pty  Prevents tty allocation (a request to allocate a pty will fail).

     no-user-rc
             Disables execution of ~/.ssh/rc.

     no-X11-forwarding
             Forbids X11 forwarding when this key is used for authentication.  Any X11 for‐
             ward requests by the client will return an error.

     permitopen="host:port"
             Limit local ``ssh -L'' port forwarding such that it may only connect to the
             specified host and port.  IPv6 addresses can be specified by enclosing the
             address in square brackets.  Multiple permitopen options may be applied sepa‐
             rated by commas.  No pattern matching is performed on the specified hostnames,
             they must be literal domains or addresses.  A port specification of * matches
             any port.

     principals="principals"
             On a cert-authority line, specifies allowed principals for certificate authenti‐
             cation as a comma-separated list.  At least one name from the list must appear
             in the certificate's list of principals for the certificate to be accepted.
             This option is ignored for keys that are not marked as trusted certificate sign‐
             ers using the cert-authority option.

     tunnel="n"
             Force a tun(4) device on the server.  Without this option, the next available
             device will be used if the client requests a tunnel.

     An example authorized_keys file:

        # Comments allowed at start of line
        ssh-rsa AAAAB3Nza...LiPk== user@example.net
        from="*.sales.example.net,!pc.sales.example.net" ssh-rsa
        AAAAB2...19Q== john@example.net
        command="dump /home",no-pty,no-port-forwarding ssh-dss
        AAAAC3...51R== example.net
        permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-dss
        AAAAB5...21S==
        tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...==
        jane@example.net

Copyright © astamuse company, ltd. all rights reserved.