コーディング規約案

2021/07/24 09:06 OS別::Linuxその他::シェル

シェルコマンド言語 コーディング規約案

いろいろな考え方があり、それぞれのプロジェクトで最適解が異なります。
規約のたたき台として、まずは作成しました。
参考の一助になれば幸いです。
ここでは、自分が使いやすい規約にしてみました。
臨機応変に変更してください。

Google Shell guide といったものも存在します。
https://google.github.io/styleguide/shellguide.html


プロジェクトにおけるシェルコマンド言語を利用したスクリプトは、視認性やメンテナンス性の向上を目的として、次の規約に則り作成すること。

汎用性の考慮

UNIX として共通の仕様である POSIX に規定された範囲でのコーディングとし、独自拡張は極力利用しないこと。

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html

また、必要があって利用する場合は、ヘッダに注意事項として記載すること。
[Tips]
たとえば、Linux の for 文で C 言語のような ( i=0 ; i < x ; i++ ) という形式を利用できます。これは便利なのですが bash の独自実装なので汎用性が下がります。

スクリプト

スクリプトは、次の要件を満たすこと。

ファイル名
ファイル名は、英数字 + 拡張子とする。
拡張子
拡張子は、シェルスクリプト単体で実行するものを .sh とする。
また、変数や関数を別途まとめたファイルについては .src とする。
[Tips]
csh / tcsh / fish / bash / dash といった、シェルを複数利用するようなプロジェクトでは、拡張子をそれぞれに合わせた方が良いと思います。
bash しか利用しないことが分かっている環境で、シバンにも bash 指定のみの場合は .sh でも不都合はないと思います。

.src は、内容として bash なのですが source コマンド (ビルトインでは . コマンド) で呼ぶことを意図しています。
実行権限
実行権限は、システムとして特に指定のない限り 610 とする。
[Tips]
権限を 755 や 700 で運用することは多いのですが、セキュリティを考慮すると、権限は最小限にすべきでしょう。
ここでは本番環境を想定していて、作成するユーザと、実行するユーザが異なることを考慮しています。
所有者は、更新できるが実行できない。前提条件を満たさない、不用意な実行を阻止できる。
グループ(実行者)は、更新できないが実行できる。JP1 のような自動実行ユーザのスクリプト改変を阻止できる。

ファイル内容

構成
スクリプトは、次の構成を基本とする。
段落内容備考
ヘッダシバンやスクリプトの目的などを記載する。
変数宣言スクリプトが利用する変数を宣言もしくは指定する。source (.) での指定も可
関数宣言スクリプトが利用する関数を宣言する。source (.) での指定も可
メイン処理スクリプトが目的とする処理を行う。
終了処理一時利用のために展開していたテンポラリファイルの削除などを行う。

文字コード
文字コードは UTF-8 とする。
また、BOM は付与しないこと。
日本語はコメントに限定する。
[Tips]
コメントに日本語を使わない場合は ASCII を指定してもよいです。
むしろ ASCII として認識されるでしょう。
改行コード
改行コードは LF とする。
[Tips]
Windows でスクリプトを書くと、改行コードは考慮から漏れがちです。
Linux や UNIX 上で書くと気にしなくても良いのですが、プロジェクトの進行状況や管理方法次第で、どうしても Windows 端末での開発を行わなければならない状況もあります。
致命的ではない文字コードやインデントも指定するのですから、致命的エラーとなる改行コードは指定しておきましょう。
インデント
インデントは、半角スペース2つとする。
[Tips]
タブ (半角スペース4つもしくは8つ) だと、横に広がりすぎて視認性が悪くなることがあります。
シバン
シバンは、以下の通り bash とする。
#!/bin/bash
[Tips]
シバンとヘッダは、ひとまとめにしてしまっても良いかもしれません。
もしくは、拡張子の指定でシバンも固定することになるでしょう。
ヘッダ
スクリプトの冒頭には、スクリプトの概要を記載する。
項目内容備考
スクリプト名Script nameファイル名称を記載する。
変更Modify変更日・変更者・変更内容を記録する。

以下は、定義する際のサンプル。
項目内容備考
スクリプト名Script nameファイル名称を記載する。
目的Purposeスクリプトの目的を記載する。
引数Option指定可能なオプションを記載する。
変更Modify作成日を記録する。日付と担当者をひとまとめにしてもよい。
作成者Auther作成者を記載する。
更新日Update更新日を記載する。更新内容も併記するとなおよい。
権限Permission実行者や権限を記載する。
サンプル 1
# Script name: example.sh
サンプル 2
# スクリプト名: example.sh
# 目的: スクリプトサンプル
コメント
適宜コメントを記載すること。
コメント内は日本語で記述する。

サンプル
# システム

パラメータ関係

変数名
変数名は、別途定めるプレフィックス/サフィックスを含め、キャメルケースで指定する。
一部の予約された変数名以外は、単語の組み合わせで指定すること。
[Tips]
私がスネークケースよりキャメルケースのほうが読みやすいと感じるタイプなので、キャメルケースを指定しています。
メリット・デメリットを考慮して、規定するのが良いです。

変数名はスクリプト上部にまとめて宣言しておくので、エディタの画面分割機能でコピペすることが前提としてあります。
画面分割は vim でも可能です。
変数名が短くても、何回も手入力していればタイポする可能性は高いです。
プレフィックス
プレフィックスは、変数の用途に応じて次の文字を使用する。
文字用途備考
p汎用パラメータParameter を意図
n数値用パラメータNumber を意図
f0 を真としたフラグ情報Flag を意図
tループで頻繁に書き換える使い捨てパラメータTemporary を意図
iループ用に予約Integer を意図 (while/until での数値ループに使用)
sループ用に予約String を意図(for での文字列ループに使用)
サフィックス
サフィックスは、特定の用途で次の文字列を使用する。
文字用途備考
Path絶対パスでファイル情報を指定する場合に利用
Dirディレクトリ情報の場合に利用文字列の最後は / で終わること。
Nameファイル情報の場合に利用ディレクトリは含めないこと。
Enableフラグ管理など、0 で有効とする場合に利用
サフィックスとしての Disable は、Enable と併用すると混乱を招くことがあるので禁止する。
利用時の指定方法
変数を利用する場合は、ブラケットで括ること。
Exit Status
終了ステータスは、スクリプトの目的が満たされることを正常とし、正常終了した場合に 0 とする。

関数関係

関数は、
関数名
関数名は、別途定めるプレフィックスを含め、キャメルケースで指定する。
一部の予約された関数名以外は、単語の組み合わせで指定すること。
プレフィックス
プレフィックスは、変数の用途に応じて次の文字を使用する。
文字用途備考
fn関数 (ファンクション) であることを示す
テンプレート関数
fnLog
特定のログファイルに、毎回リダイレクトを記述するのは可視性としても悪くなり、ミスも誘発しやすい。
引数としてメッセージをログファイルへ書き込む関数を用意した。

スクリプトの進捗状況を記述する目的で利用すること。

サンプル
fnLog "Sample message"
fnDebug
開発時に利用したデバッグ用メッセージを、メンテナンス時にも再利用できるよう、フラグに応じて出力指定もできる関数を用意した。

デバッグ情報を記述する目的で利用すること。

サンプル
fnDebug "Debug message"
fnErr
シェルスクリプトが標準エラー出力を行うための関数を用意した。

エラー出力を記述する目的で利用すること。

サンプル
fnErr "Standard Error message"
fnErrEnd
存在しなければ即時で終了するための関数を用意した。

引数として、エラー番号と、対象のファイルまたはディレクトリなどを指定すること。

サンプル
[ -d "/etc" ] || fnErrEnd 14 "/etc"
[ -f "/etc/hosts" ] || fnErrEnd 15 "/etc/hosts"
[ -x "/bin/ps" ] || fnErrEnd 13 "/bin/ps"

メイン

オプション解析
getopts を利用した解析を行う。
[Tips]
    • help といったロングオプションを使いたい場合は、getopts ではなく、引数そのものを case で解析するほうがよいと思います。

備考

テンプレート
シェルスクリプト
サンプル
#!/bin/bash
############################################################
# Script name: example.sh
# Modify     : yyyy.mm.dd 名前 初版作成
############################################################

### Parameter and Variable #################################
pCommon=./src/common.src
if [ -f "${pCommon}" ]; then
  . ${pCommon}
else
  echo "${pCommon} not exist."
  exit 1
fi

### Function ###############################################
fnEnd() {
  # スクリプト内で異常終了する際の Exit Status と、メッセージ内容の定義
  nExitStatus=$1
  case "${nExitStatus}" in
     0 ) fnLog "Script ${0##*/} end.";;
     * ) fnErr "Unknown error ($2)"; nExitStatus=1;;
  esac
  exit ${nExitStatus}
}

### Main ###################################################
fnLog "Script ${0##*/} start."

## オプション解析
while getopts h OPT; do
  case ${OPT} in
    h )
      fnDebug "Option h used."
      echo "Usage ${0##*/} [-h]"
      echo " [-h]    help messages."
      fnEnd 0
      ;;
    * )
      fnDebug "Unknown option used."
      fnErrEnd 10 "${OPT}"
      ;;
  esac
done

# xxx 処理


### End ####################################################
fnEnd 0

############################################################
外部ファイル
サンプル
# 共通ファイル (common.src)

### Parameter and Variable #################################

## ディレクトリ
pLogDir="/var/log/script/"

## ファイル
pLogName=$(basename ${0%.*}.log)

## パス
# ログファイル
pLogPath="${pLogDir}${pLogName}"

# ヌルクリア
i=""
s=""

# Exit Status
nExitStatus=0

## フラグ
fDebugEnable=0

### Function ###############################################

# 目的:ログ出力
fnLog() {
  echo "$(date +'%Y/%m/%d %H:%M:%S') $*" >> ${pLogPath}
}

# 目的:デバッグ出力
fnLog() {
  [ "${fDebugEnable}" -eq "0" ] && fnLog "[Debug] $*"
}

# 目的:エラー出力
fnErr() {
  # ログ出力
  fnLog "$*"
  # 標準エラー出力
  echo "$(date +'%Y/%m/%d %H:%M:%S') $*" >&2
}

# 目的: エラー終了
fnErrEnd() {
  nExitStatus=${1}

  # 引数確認
  if [ -z "${nExitStatus}" ]; then
    fnErr "Not argument."
    exit 1
  fi

  case "${nExitStatus}" in
     0 ) fnErr "Function (fnErrEnd) argument error."; nExitStatus=1;;
    10 ) fnErr "Argument error ($2)";;
    11 ) fnErr "Read permission not exist ($2)";;
    12 ) fnErr "Write permission not exist ($2)";;
    13 ) fnErr "Exec permission not exist ($2)";;
    14 ) fnErr "Directory not exist ($2)";;
    15 ) fnErr "File not exist ($2)";;
     * ) fnErr "Unknown error ($2)";;
  esac
  exit ${nExitStatus}
}
||

Zabbix 5.2 on AWS

2021/05/08 17:37 OS別::Linuxその他::技術情報

Zabbix 5.2 on AWS

【注意】まず、このページは個人的な備忘録であり、自分が分かる部分はいろいろとスキップしています。参考にされませぬよう。

例)Zabbix へブラウザでアクセスする方法は、もともと準備していた EC2 インスタンスに SSH でアクセスしてポートフォワードを設定し、xrdp をインストールした EC2 に RDP している。



全体構成

このページでは、Zabbix 5.2 の設定を、公式手順をもとにカスタマイズしています。
https://www.zabbix.com/jp/download

また、フロントエンドとしてのシステム要件は、次のページを参照しています。
https://www.zabbix.com/documentation/current/manual/installation/requirements

公式手順では、サーバを設定 → DB 設定 → Agent 設定という流れになっています。

DB をサーバ上に構築するためにはスマートな流れですが、RDS を利用する場合は DB を先に準備できるので、作業しておきます。

それから、このページでは企業が利用するような手順書としては余計な情報も大量に記載しているので、そのままでは利用できないことに注意してください。
構成概要
以下の構成で、構築します。
Zabbix Server
仕事で AWS クラウドでの構築という手段がとれることを確認するのが目的です。

Zabbix の公式では、Red Hat Enterprise Linux / CentOS / Oracle Linux / Ubuntu / Debian / SUSE Linux Enterprise Server / Raspberry Pi OS / Ubuntu (arm64) に対応しています。

Amazon Linux 2 は、おそらく Cent OS 7 の手順で使えそうに思いましたが、一応 RHEL 8 を選択します。
ハードウェア
クラウド上のインスタンス「AWS EC2 (t2.micro) 」を利用するため、ハードウェアは持ちません。
ソフトウェア
Zabbix 用のサブネットに、次のインスタンスを作ります。
項目内容備考
OSRHEL 8構築時には最新化する
DBMySQLAmazon RDS を利用
アプリZabbix Server 5.2
Zabbix Clientサーバ自身の管理用
PHP 7.3Zabbix フロントエンドで利用
要件として PHP 7.2.5 が求められていますが、RHEL8 はデフォルトで PHP 7.2.4 がインストールされます。
また、PHP 8.0 はサポートされていません。

Zabbix 5.2 のフロントエンドの要件
https://www.zabbix.com/documentation/current/manual/installation/requirements

そのため PHP 7.3 をインストールします。
ネットワーク
Zabbix サーバを置くネットワークのサンプルとして 172.16.10.10 を静的に指定します。

これはプライベートサブネットなので、Web アクセスは外部からインターネット接続で RDP できる EC2 インスタンスから参照します。

実際に確認した方法としては、パブリックサブネットに SSH 通信ができる Linux インスタンスを置いて、ポートフォワードを利用して RDP できるインスタンスからブラウザによって参照しています。

業務として構築する場合は Basic 認証等も検討し、パブリックサブネットに配置しても良いでしょう。
Zabbix Agent
Agent は、以下の構成で構築します。
ハードウェア
  • Amazon Linux 2
サンプルとして、Public subnet に Amazon Linux 2 のインスタンスを作ります。
ソフトウェア
適当なサブネットに、次のインスタンスを作ります。
項目内容備考
OSAmazon Linux 2
アプリZabbix Agent 5.2
Zabbix Clientサーバ自身の管理用
ネットワーク
サンプルとして、パブリックサブネットに構築します。
構成図
このページで作成する Zabbix の構成図を次に示す。
zbx5.2 + rds 構成図
Zabbix 5.2 + RDS (MySQL) 構成図
Zabbix Agent をインストールする Client に ssh で接続する想定です。
また Client には xrdp もインストールして ssh ポートフォワードから RDP しますが、こちらについては目的の動作ではないため割愛します。
作業の流れ
このページは、以下の流れで作業します。
  1. RDS で DB を用意
  2. EC2 で Zabbix Server を用意
  3. Zabbix Server で設定
  4. Zabbix Agent を設定

セキュリティグループの作成

左ペインの「セキュリティ」から「セキュリティグループ」を選択します。

Zabbix Server は 10051 番ポートで Zabbix Agent からのアクセスに応答します。
Zabbix Agent は 10050 番ポートで Zabbix Server からのアクセスに応答します。
RDS 用
基本的な詳細
セキュリティグループの、基本的な詳細を入力します。
項目内容
セキュリティグループ名Zabbix RDS
説明Zabbix DB
VPC(作成した VPN を選択)
説明には、日本語が使えない模様……。
インバウンドルール
RDS は 3306 番ポートで Zabbix Server からのアクセスに応答します。
タイププロトコルポート範囲ソース説明
MYSQL/AuroraTCP3306172.16.10.0/24
アウトバウンドルール
特に制限を設けません。
Zabbix Server 用
基本的な詳細
セキュリティグループの、基本的な詳細を入力します。
項目内容
セキュリティグループ名Zabbix
説明Zabbix Servers Access
VPC(作成した VPN を選択)
説明には、日本語が使えない模様……。

インバウンドルール
Zabbix Server は 10051 番ポートで Zabbix Agent からのアクセスに応答します。
他のサブネットから、Zabbix サーバに Agent の情報を送るための設定します。

タイププロトコルポート範囲ソース説明
カスタム TCPTCP10051172.16.0.0/16Agent による Zabbix サーバへのアクセス
HTTPTCP80172.16.0.0/16Web ブラウザによる Zabbix サーバへのアクセス
HTTPTCP443172.16.0.0/16Web ブラウザによる Zabbix サーバへのアクセス
SSHTCP22172.16.0.0/16SSH による Zabbix サーバへのアクセス

Zabbix Agent 側のセキュリティルールに、TCP/10050 ポートのインバウンドルールを付与してください。
なお、アクセス端末については、パブリックサブネットの Client を想定しています。
アウトバウンドルール
特に制限を設けません。
制限を設ける場合は、次の2点に注意。
Zabbix サーバが Agent に対してアクセスするための TCP/10050
Zabbix サーバが RDS に対してアクセスするための TCP/3306
Zabbix Agent 用
基本的な詳細
セキュリティグループの、基本的な詳細を入力します。
項目内容
セキュリティグループ名Zabbix Agent
説明Zabbix Zagents Access
VPC(作成した VPN を選択)

インバウンドルール
Zabbix Agent は 10050 番ポートで Zabbix Server からのアクセスに応答します。
他のサブネットから、Zabbix サーバに Agent の情報を送るための設定です。

タイププロトコルポート範囲ソース説明
カスタム TCPTCP10050172.16.0.0/16Zabbix Server による Agent へのアクセス
Agent が Linux の場合は TCP/22 を、Windows の場合は TCP/3389 も必要と思われます。
デフォルトでは、セキュリティグループを5つまで同時に適用できるため、分割したほうが良さそうです。
アウトバウンドルール
特に制限を設けません。
制限を設ける場合は、次の2点に注意。
Zabbix サーバが Agent に対してアクセスするための TCP/10050
Zabbix サーバが RDS に対してアクセスするための TCP/3306

ネットワーク構成

VPC の作成
デフォルト VPC を利用する場合は必要ない作業ですが、今回は別途行うものとします。
サンプルとして、上記構成図のとおり 172.16.0.0/16 の VPC を作成します。
サブネットの定義
また、Amazon RDS 用のサブネットを2つ作るものとします。

RDS は、AZ 2つ以上を束ねたマルチ AZ 構成にする必要があります。
なので VPC 作成 → サブネット作成 → サブネットグループに指定 → データベース作成をお行います。

Amazon RDS にて DB を構築したいので、AWS マネジメントコンソールから VPC にアクセスします。
パブリックサブネット
DMZ 用サブネット(Public)
外部と接するサブネットを作成します。
172.16.0.0/24 として話を進めます。

ここには Internet Gateway や NAT Gateway など、インターネット接続を行うためのインスタンスを置くことになります。
Zabbix がインターネットにアクセスする必要があるなら、ここに Zabbix サーバを立てても良いです。

パブリックサブネットの要件となる、Internet Gateway を置きます。
また、プライベートサブネットがインターネットに抜けるために必要な NAT Gateway もここに置きます。
Internet Gateway
省略
NAT Gateway
省略

プライベートサブネットからのインターネット接続を受けて、Internet Gateway でやり取りするものです。
セキュリティグループの設定を忘れず行う必要があります。
プライベートサブネット
RDS 用サブネット A(Private)
VPC で 172.16.1.0/24 のサブネットを作ります。
名前は DB a として進めます。

AZ は a ~ d あるとして、ここでは a を選択します。
RDS 用サブネット B(Private)
VPC で 172.16.2.0/24 のサブネットを作ります。
名前は DB b として進めます。

AZ は a ~ d あるとして、ここでは b を選択します。
Zabbix サブネット(Private)
VPC で 172.16.5.0/24 のサブネット を作ります。
AZ は任意で、名前は Zabbix として進めます。

Zabbix サーバを立てるためのサブネットとしているが、サーバ用に作らなければならないものでは無くて、話を理解しやすくするためのものです。
このサブネット以外に Zabbix サーバを立てても良いです。

RDS

AWS マネジメントコンソールから RDS にアクセスします。
サブネットグループの作成
左ペインのサブネットグループを選択します。

「DB サブネットグループを作成」を押して、作成画面へ。
サブネットグループの詳細
「サブネットグループの詳細」へ入力します。
入力項目サンプル入力内容
名前Zabbix
説明zabbix network subnet
VPC(作成したVPC)
入力イメージを次に示します。
RDS Subnetgroup
サブネットグループの詳細
サブネットを追加
「サブネットを追加」へ入力します。
入力項目サンプル入力内容
アベイラビリティゾーンAZ a と AZ b を選択他にサブネットを作成した AZ があればそれも選択
サブネットRDS 用サブネット「DB a」「DB b」を選択します
入力イメージを次に示します。
Add subnet
サブネットを追加

作成ボタンをクリックして、RDS が利用するサブネットグループを作成します。
データベース
左ペインから「データベース」を選択し、右ペインの「データベースの作成」ボタンをクリックします。
データベース作成方法を選択
標準作成を選択。
標準作成
選択イメージ
エンジンのオプション
MySQL を選択します。
エディションは、MySQL Community のみ。
バージョンは MySQL 8.0.23 で良いです。
MySQL 選択
エンジン選択イメージ
テンプレート
無料利用枠を選択します。
無料利用枠
テンプレートイメージ
設定
項目設定サンプル内容
DBインスタンス識別子zabbix
認証情報の設定
マスターユーザー名任意自動生成してもよい
マスターパスワード任意自動生成してもよい

設定
設定イメージ

Default は狙われやすいのでできれば変更するのが望ましいが、プライベートサブネットで、セキュリティグループでアクセス元を管理する想定、かつサンプルということで admin のまま。

マスターパスワードはブラウザの機能で勝手に入れられているが、本来はブランク……

DB インスタンスサイズ
「db.t2.micro」を選択します。
DB インスタンスサイズ
DB インスタンスサイズイメージ
ストレージ
項目設定サンプル内容
ストレージタイプ汎用(SSD)デフォルトの場合
ストレージ割り当て20 GiBデフォルトの場合
ストレージの自動スケーリング

ストレージ
ストレージイメージ
可用性と耐久性
マルチ AZ 配置
一択です。
可用性と耐久性
可用性と耐久性イメージ
接続
項目内容備考
VPCSample作成した VPC
サブネットグループzabbix作成したサブネットグループ
パブリックサブアクセス可能なしプライベートサブネットに置く想定
VPC セキュリティグループZabbix対応するセキュリティグループは作成済みの想定
既存の VPC セキュリティグループZabbix
アベイラビリティゾーン任意で指定
追加の接続設定
データベースポート3306

接続
接続イメージ

データベース認証
パスワードを選択します。
データベース認証
データベース認証イメージ

追加設定
このタイミングでデータベースを作っておきます。
項目内容備考
データベースの選択肢
最初のデータベース名zabbixZabbix サーバのデフォルト
DB パラメータグループ(変更不可)
オプショングループ(変更不可)
バックアップ
自動バックアップの有効化
モニタリング
拡張モニタリングの有効化
ログのエクスポート
エラーログ
全般ログ
スロークエリログ
メンテナンス
マイナーバージョン自動アップグレードの有効化
メンテナンスウィンドウ〇設定なし
削除保護
削除保護の有効化

追加設定
追加設定イメージ

概算月間コスト
毎月の支払予想額が出ます。
出ないこともあります。
エンドポイント
AWS マネジメントコンソールから RDS にアクセスします。

左ペインから「データベース」を選択して、右ペインに出てくる DB 識別子 zabbix を選択します。

接続とセキュリティにある、エンドポイントをメモしておきます。
これは、Zabbix サーバからアクセスする際に必要です。

Zabbix 5.2 Server

AWS マネジメントコンソールから EC2 にアクセスします。
ユーザーデータ用シェルスクリプトを作成
シェルスクリプトとして、次の内容のテキストファイルを作成します。
ファイル名は zbxsvr.sh として進めます。

なお、改行コードは LF のみとします。
(日本語を含まないので Shift-JIS でも構わない。含める場合は UTF-8 にすること)
#!/bin/bash

# RHEL8 Update
dnf update -y

# Zabbix install
rpm -Uvh https://repo.zabbix.com/zabbix/5.2/rhel/8/x86_64/zabbix-release-5.2-1.el8.noarch.rpm
dnf clean all
dnf install -y mysql zabbix-server-mysql zabbix-web-mysql zabbix-apache-conf zabbix-agent zabbix-web-japanese

# php
dnf install -y php
dnf distro-sync
dnf module reset php
dnf module enable php:7.3
dnf distro-sync

# SElinux
setenforce 0

インスタンスの作成
左ペインから「インスタンス」を選択して、右ペインの「インスタンスを起動」をクリックします。
AMI の選択
サーバとして RHEL8 の x86 を選択します。
AMI の選択
AMI の選択イメージ
インスタンスタイプの選択
タイプ t2.micro を選択します。
インスタンスタイプの選択
インスタンスタイプの選択イメージ
インスタンスの設定
インスタンスの設定
項目内容備考
インスタンス数1
購入のオプション□ スポットインスタンスのリクエスト
ネットワークSample作成した VPC
サブネットZabbix作成したサブネット
自動割り当てパブリック IPサブネット設定を使用(無効)
配置グループ□ インスタンスをプレイスメントグループに追加します。
キャパシティーの予約開く
ドメイン結合ディレクトリディレクトリなし
IAM ロールなし
シャットダウン動作停止
停止 - 休止動作□ 停止動作に休止動作を追加します
終了保護の有効化□ 誤った終了を防止します
モニタリング□ CloudWatch 詳細モニタリングを有効化
テナンシー共有 - 共有ハードウェアインスタンスの実行
Elastic Inference□ Elastic Inference アクセラレーターを追加
クレジット仕様□ 無制限
ファイルシステム

インスタンスの設定
インスタンスの設定イメージ
ネットワークインターフェイス
項目内容備考
デバイスeth0デフォルト
ネットワークインターフェイス新しいネットワークインターフェースデフォルト
サブネットデフォルト
プライマリ IP172.16.10.10EIPを使用しないので、静的に指定します
セカンダリ IP アドレス指定なし
IPv6 IP指定なし

ネットワークインターフェイス
ネットワークインターフェイスイメージ
高度な詳細
ここで zbssvr.sh を利用します。
ここで実行コマンドを記述したファイルをアップロードしておくと、サインインした後に手で入力する必要がなくなります。
項目内容備考
Enclave□ 有効
アクセス可能なメタデータ有効
メタデータのバージョンV1 および V2 (トークンはオプション)
メタデータトークンレスポンスのホップ制限1
ユーザーデータ● ファイルとしてzbssvr.sh を指定
高度な詳細
高度な詳細イメージ
なお、上記スクリプトの利用は NAT Gateway が適切に設定され、インターネット接続できることが条件となります。
ストレージの追加
デフォルトで進めます。
ストレージの追加
ストレージの追加イメージ
タグの追加
任意のタグを設定します。
セキュリティグループの設定
Zabbix サーバ用のセキュリティグループを指定します。
インバウンドルール
最低限、以下のポートが利用できること。
タイププロトコルポート範囲ソース説明
MYSQL/AuroraTCP3306172.16.0.0/16
カスタム TCPTCP10051172.16.0.0/16Agent による Zabbix サーバへのアクセス
HTTPTCP80172.16.0.0/16Web ブラウザによる Zabbix サーバへのアクセス
HTTPTCP443172.16.0.0/16Web ブラウザによる Zabbix サーバへのアクセス
SSHTCP22172.16.0.0/16SSH による Zabbix サーバへのアクセス

確認
ブラウザでの設定
ブラウザで Zabbix サーバにアクセスします。

URL は、次の通りです。
http://(IPアドレス)/zabbix
次の画面が表示されます。
言語選択
言語選択
ここでは、日本語に変更します。
(インストール時に zabbix-web-japanese も指定しているので、日本語を選択可能です)
言語選択 日本語
言語選択 日本語
日本語に変更できたら「次のステップ」を選択します。


次に、前提条件のチェックで、環境に問題ないことを確認します。
前提条件のチェック
前提条件のチェック
全部 OK であれば問題ありません。
「次のステップ」を選択します。

データベースホストに、RDSのエンドポイントを指定します。
また、zabbix ユーザのパスワードも指定します。
データベース接続設定
データベース接続設定
項目内容
データベースホストRDS のエンドポイント
パスワードRDS zabbix ユーザのパスワード

データベース接続設定 入力
データベース接続設定 入力イメージ
「次のステップ」を選択します。
Zabbixサーバーの詳細
Zabbixサーバーの詳細
「次のステップ」を選択します。
GUI設定
GUI設定
タイムゾーンは日本に変更します。
(UTC+09:00) Asia/Tokyo を選択します。
GUI設定 日本時間
GUI設定 日本時間
「次のステップ」を選択します。
インストール事前準備概要
インストール事前準備概要
「次のステップ」を選択します。
インストール終了
インストール終了
「終了」を選択します。
サインイン画面
サインイン画面
サインイン
次のデフォルトアカウントでサインインします。
項目内容
ユーザー名Admin
パスワードzabbix
サインインしたら、パスワードは変更しましょう。

Zabbix Agent

以下は、あとで分割してページを作る予定です。
Amazon Linux 2
リポジトリ登録
Amazon Linux 2 は、CentOS をベースに作成されていると考えられます。
そこで、RHEL7 ベースのリポジトリを登録します。
# yum update
# rpm -ivh https://repo.zabbix.com/zabbix/5.2/rhel/7/x86_64/zabbix-release-5.2-1.el7.noarch.rpm
# yum clean all
Zabbix Agent インストール
登録したリポジトリから、Agent をインストールします。
# yum install zabbix-agent
Zabbix Agent 設定
/etc/zabbix/zabbix_agentd.conf を修正します。
# cp -p /etc/zabbix/zabbix_agentd.conf,_$(date +%Y%m%d)
# vi /etc/zabbix/zabbix_agentd.conf
修正内容は、自分自身のホスト名と、情報を送る Zabbix サーバです。


差分の確認を行います。
# diff /etc/zabbix/zabbix_agentd.conf,_$(date +%Y%m%d)
Zabbix Agent 起動
インストールした Agent を起動および自動起動設定を行います。
# systemctl restart zabbix-agent
# systemctl enable zabbix-agent

その他

下記の登録商標・商標をはじめ、当社サイトに記載している会社名、システム名、製品名は一般に各社の登録商標または商標です。

adiary on RaspPi

Raspberry Pi に adiary をインストールする手順を、メモ程度に公開します。

adiary on Raspberry Pi

前提条件

この手順は、以下の条件がすでに完了していることを前提としています。

・Raspberry Pi 3 Model B へ Raspbian をインストールおよびアップデート済み
・SSH でのアクセスが可能
・DNS にドメイン設定済み

想定する利用者

読み手は CUI での操作が可能で、TCP/IP の基礎知識をもち、ある程度 Linux に慣れていることを想定しています。
そのため、割と不親切*1です。

*1 : 前提条件の「DNS 設定済み」は、それなりにハードルが高いはずです。あとで読み返して「自分が分かれば良い」を目安にしています。

Raspberry Pi 環境

Raspbian をインストール直後で構築しようとしている想定で、この手順書を書いています。
そのため、まず adiary 以外の設定を確認したり、設定したりしています。

環境確認

Raspbian バージョン
今回の構築手順で検証に利用した Raspbian のバージョン情報です。
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
NAME="Raspbian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
$

raspi-config

最低限の設定変更をしておきます。
$ sudo raspi-config
1 Change User Password
2 Hostname
    ttm.jimba.ddo.jp
3 Boot Options
    B1 Desktop / CLI
4 Localisation Options
    I1 Change Locale
    I2 Change Timezone
    I4 Change Wi-fi Country
5 Interfacing Options
    P2 SSH
$
・pi ユーザパスワードを変更する。
・ホスト名を変更する。
・起動オプションで CLI に変更する。
・ロケールを日本にする*2
・SSH が有効であること確認する。

OS アップデート

前提条件にはあるけど、念のため。
$ sudo apt-get update
$ sudo apt-get upgrade

関連ソフトウェア設定

httpd (Apache2)
Apache2 をインストールしておきます。
$ sudo apt-get install apache2 apache2-doc
Apache2 インストールで Raspbian に登録される httpd ユーザを確認します。
$ grep www /etc/passwd
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
$
ここで確認できた www-data ユーザで adiary を動かす権限を管理すると、運用が楽になります。


次は adiary が動くように CGI の動作設定をします。
$ cd /etc/apache2/mods-available
$ cp -p {,/tmp/}mime.conf
$ sudo vi mime.conf
$ diff {,/tmp/}mime.conf
219c219
<       AddHandler cgi-script .cgi
---
>       #AddHandler cgi-script .cgi
$
次の Module 有効化も cgi の動作設定です。
$ sudo apache2ctl -M | grep cgi
$ sudo a2enmod cgi
$ sudo apache2ctl -M | grep cgi
 cgid_module (shared)
adiary.cgi を消したいときに使うモジュール rewrite を読み込んでおきます。
$ sudo a2enmod rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
  systemctl restart apache2
$ sudo systemctl restart apache2
apache2 のバージョン情報を表示させないように秘匿する設定です。
$ grep -i includeoptional /etc/apache2/apache2.conf
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
IncludeOptional conf-enabled/*.conf
IncludeOptional sites-enabled/*.conf
$ cd /etc/apache2/conf-available
$ sudo cp -p security.conf{,_$(date +%Y%m%d)}
$ sudo vi security.conf
(書き換え)
$ sudo diff security.conf{,_$(date +%Y%m%d)}
25c25
< #ServerTokens OS
---
> ServerTokens OS
27d26
< ServerTokens Prod
36,37c35,36
< ServerSignature Off
< #ServerSignature On
---
> #ServerSignature Off
> ServerSignature On
$
$ sudo systemctl reload apache2
他の設定は、後で行います。
dhcpcd (Static IP address)
静的 IP アドレスの設定です。
$ sudo cp -p /etc/dhcpcd.conf{,_$(date +%Y%m%d)}
$ sudo vi /etc/dhcpcd.conf
--- 以下を追記 ---
interface eth0
static ip_address=192.168.0.2/24
static routers=192.168.0.1
static domain_name_servers=192.168.0.1
static domain_name=jimba.jp
------------------
$ sudo diff /etc/dhcpcd.conf{,_$(date +%Y%m%d)}
$ sudo shutdown -r now
IPアドレス等は、構築時に読み替えます。
設定項目設定例意味
interfaceeth0eth0 の IP アドレスを指定します。
static ip_address192.168.0.2/24IPアドレスを静的に指定します。
/24 は、サブネットマスク 255.255.255.0 を示しています。
static routers192.168.0.1デフォルトゲートウェイを静的に指定します。
static domain_name_servers192.168.0.1DNS (Domain Name System) を静的に指定します。
static domain_namejimba.jpホストが属するドメイン名を静的に指定します。
Web で設定するドメイン (URL) とは別物です。
hcpcd の reload でも良さそうだけど、上記は ssh での操作なのでどちらにせよ IP アドレスが変更されて接続が切れるため、リブートしてます。
NTPd
ログの出力時刻を正しく読み取るため、NTP を ntp.nict.jp に設定します。

パッケージをインストールします。
$ sudo apt-get install ntp ntp-doc ntpdate dnsutils
設定するドメインが名前解決できるか確認します。
$ dig ntp.nict.jp +short
ntp でのやりとりができるか確認します。
$ ntpdate -q ntp.nict.jp
server 2001:df0:232:eea0::fff4, stratum 0, offset 0.000000, delay 0.00000
server 2001:df0:232:eea0::fff3, stratum 0, offset 0.000000, delay 0.00000
server 133.243.238.164, stratum 1, offset 0.000458, delay 0.03119
server 133.243.238.163, stratum 1, offset 0.000286, delay 0.03084
server 133.243.238.244, stratum 1, offset 0.000657, delay 0.03125
server 133.243.238.243, stratum 1, offset -0.000104, delay 0.03133
 8 Feb 16:40:43 ntpdate[18685]: adjust time server 133.243.238.163 offset 0.000286 sec
$
出力内容から stratum が 0 でなければ OK です。
0 がエラーです。
1 以上は、NTP サーバの階層を示します。

NTP 設定を行います。
$ sudo cp -p /etc/ntp.conf{,$(date +%Y%m%d)}
$ sudo diff /etc/ntp.conf{,$(date +%Y%m%d)}
$ sudo vi /etc/ntp.conf
---------------------------------------------------------
(pool をコメントアウトして、serverに ntp.nict.jp を指定する)
---------------------------------------------------------
$ sudo diff /etc/ntp.conf /etc/ntp.conf.$(date +%Y%m%d)
20,24c20,24
< #pool 0.debian.pool.ntp.org iburst
< #pool 1.debian.pool.ntp.org iburst
< #pool 2.debian.pool.ntp.org iburst
< #pool 3.debian.pool.ntp.org iburst
< server ntp.nict.jp iburst
---
> pool 0.debian.pool.ntp.org iburst
> pool 1.debian.pool.ntp.org iburst
> pool 2.debian.pool.ntp.org iburst
> pool 3.debian.pool.ntp.org iburst
>
$ sudo systemctl stop ntp
$ sudo ntpdate ntp.nict.jp
$ sudo systemctl start ntp
$ ntpq -p

関連コマンド

git
git でのファイルダウンロードは公式でのやり方なので、それに倣います。
$ type git > /dev/null 2>&1 || sudo apt install git
Image::Magick (PerlMagic)
adiary にあると便利な Image::Magick を先にインストールしておきます。
$ sudo apt-get install perlmagick
Net::SSLeay
adiary にあると便利な Net::SSLeay を先にインストールしておきます。
$ sudo apt-get install libnet-https-any-perl

ユーザ設定

運用ユーザの作成
運用で使うユーザを登録しておきます。
$ sudo useradd -d /home/example -m -g 1000 -s /bin/bash example
$ sudo passwd example
$ sudo vigr
-> pi と同じ場所に example を追記
$
$ sudo su -
# cd /etc/sudoers.d
# cp -p 010_{pi,example}-nopasswd
# vi 010_example-nopasswd
:%s/pi/example/
:x
# exit
$
ユーザ example は、環境に応じて読み替えてください。
運用ユーザでログインおよび sudo 可能なことを確認しておきます。
pi ユーザの不活性化
ユーザ pi を使えなくして、運用ユーザで作業するようにします。
$ sudo usermod -s /sbin/nologin pi

*2 : 特に Wi-Fi Country は、日本で認められていない周波数の電波(違法電波)を出さないようにする設定が楽。

adiary 環境構築

基本的には、公式サイトにある 自前サーバへのインストール を参照すれば足ります。
このページは adiary をインストールする Raspberry Pi の環境を整備する部分に価値があると思っています。

adiary インストール

adiary を git で /var/www/ にダウンロードします。
$ cd /var/www
$ sudo git clone https://github.com/nabe-abk/adiary
$
$ cd adiary
$ cp adiary.conf.cgi{.sample,}
$ cd ../
$
$ sudo chown -R 33:33 adiary
$ sudo chmod -R 750 adiary
$ sudo find adiary -name "*.png" -or -name "*.gif" -or -name "*.txt" -exec chmod 640 {} \;
$
adiary ディレクトリ全体が apache2 のユーザ権限 www-data (ユーザID 33) で動作するので、750 で良い。
画像やテキストファイルは実行権限不要なので 640 に一括変換しておく。

Apache2 設定

adiary のインストール後でなければ行えない Web 公開設定を行います。
設定ファイル作成のための事前調査
adiary が制限を入れたいディレクトリは .htaccess ファイルが置かれています。
自分の設定では .htaccess ファイルを無効にし、すべて apache の設定ファイルに記述するようにしているため、ファイルを探しておきます。
$ sudo find /var/www/adiary -name .htaccess
/var/www/adiary/skel/.htaccess
/var/www/adiary/data/.htaccess
/var/www/adiary/__tool/.htaccess
/var/www/adiary/plugin/.htaccess
/var/www/adiary/__cache/.htaccess
/var/www/adiary/info/.htaccess
/var/www/adiary/lib/.htaccess
/var/www/adiary/skel.local/.htaccess
設定ファイルの作成
上記の制限内容を踏まえて、設定ファイルを作成します。
$ cd /etc/apache2/sites-available
$ sudo vi 201-adiary.conf
(Config writing...)
$ sudo cat 201-adiary.conf
<VirtualHost *:80>
    ServerName  ttm.jimba.ddo.jp
    ServerAdmin xxx@jimba.ddo.jp
    DocumentRoot /var/www/adiary

    <Directory /var/www/adiary>
        Options ExecCGI
        AllowOverride None
    </Directory>

    <Directory /var/www/adiary/__cache>
        order allow,deny
        deny from all
    </Directory>

    <Directory /var/www/adiary/data>
        order allow,deny
        deny from all
    </Directory>

    <Directory /var/www/adiary/skel>
        order allow,deny
        deny from all
    </Directory>

    <Directory /var/www/adiary/__tool>
        order allow,deny
        deny from all
    </Directory>

    <Directory /var/www/adiary/plugin>
        order allow,deny
        deny from all
    </Directory>

    <Directory /var/www/adiary/info>
        order allow,deny
        deny from all
    </Directory>

    <Directory /var/www/adiary/lib>
        order allow,deny
        deny from all
    </Directory>

    <Directory /var/www/adiary/skel.local>
        order allow,deny
        deny from all
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/ttm.error.log
    CustomLog ${APACHE_LOG_DIR}/ttm.access.log combined
</VirtualHost>
【参考情報】/var/www/adiary/.htaccess に書きたい内容は、上記主設定ファイル (201-adiary.conf) の <Directory /var/www/adiary> ~ </Directory> の中に書きます。

根拠は、apache2 公式サイトより引用した以下の通りです。
普通は可能であれば .htaccess ファイルの使用は 避けてください。.htaccess ファイルに書こうと考えるようなすべての設定は、サーバの主設定ファイルの セクションで同じように行なうことができます。
Apache HTTP Server Tutorial: .htaccess files - Apache HTTP Server Version 2.4
設定ファイル有効化
設定ファイルを有効化します。
$ sudo a2ensite 201-adiary
Enabling site 201-adiary.
To activate the new configuration, you need to run:
  systemctl reload apache2
$
$ sudo systemctl reload apache2
不要ファイル削除
また、不要になった設定ファイルは、混乱のもとなので消しておきます。
$ sudo rm /var/www/adiary/skel/.htaccess
$ sudo rm /var/www/adiary/data/.htaccess
$ sudo rm /var/www/adiary/__tool/.htaccess
$ sudo rm /var/www/adiary/plugin/.htaccess
$ sudo rm /var/www/adiary/__cache/.htaccess
$ sudo rm /var/www/adiary/info/.htaccess
$ sudo rm /var/www/adiary/lib/.htaccess
$ sudo rm /var/www/adiary/skel.local/.htaccess
ひとつずつ消すのが面倒に思う人は、次のようなコマンドでも良いかもしれません。
$ sudo find /var/www/adiary -name ".htaccess" -exec rm {} \;

Web 上での設定

DNS へ登録した URL (本サイトならば http://ttm.jimba.ddo.jp/) へアクセスして、root アカウント登録や、個別アカウントの登録などを行います。
root アカウント登録
最初のログインに戸惑いますが、ユーザ名 a パスワード a 等、適当に入力してログインすると root でログインしたことになります。
個別アカウント登録
ブログを更新するユーザ等、個別にアカウントを作成します。

Web での設定後

初期画面からのリダイレクト設定
初期画面から、作成したブログ画面へ移動するための index.html 書き換えです。
$ cd /var/www/adiary
$ cp -p index.html{,_backup_$(date +'%Y%m%d')}
$ cat /dev/null > index.html
$ vi index.html
(書き換え)
$ cat index.html
<html>
  <head>
    <meta http-equiv="Refresh" content="0;URL=adiary.cgi">
  </head>
</html>
$ 
robots.txt
ボットに公開/非公開したい情報を教える設定です。

以下は Google bot 以外のクロウラを拒絶する例です

/var/www/adiary/robots.txt
User-agent: Googlebot
Disallow:

User-agent: *
Disallow: /

adiary アップデート

基本的には、公式サイトのコマンドでいけるはず。
$ sudo su -s /bin/bash www-data
$ cd ~/adiary
$ git fetch

その他

その他の設定に興味あるかたは、ツイッター等で質問いただくと反映することがあります。