こちらのバリエーションが2つほど。
1.カレー風味

なんとなく買ったものの、使い道がなかった(追加の材料が面倒だった)ため持て余していたドライカレーの素。

これを合わせたものがこちら。カレー粉という万能調味料が見事に合わさりました。
2.バターとハム

いつもはツナ缶を入れるところを、「ロースハムブロックが余っていた」として、こちらに差し替え。ツナ缶の油はバターで補いました。

トーストに合わせても最高にマッチです。
こちらのバリエーションが2つほど。

なんとなく買ったものの、使い道がなかった(追加の材料が面倒だった)ため持て余していたドライカレーの素。

これを合わせたものがこちら。カレー粉という万能調味料が見事に合わさりました。

いつもはツナ缶を入れるところを、「ロースハムブロックが余っていた」として、こちらに差し替え。ツナ缶の油はバターで補いました。

トーストに合わせても最高にマッチです。
オープンソースのWeb解析、
WordPressとMatomoを別々のサーバーで運用し、wp-matomo(現在の名称は「Connect Matomo」)を使用して連携させる手順を整理しました。
この設定により、WordPress側で収集したデータを別サーバーのMatomoへ送信し、WordPressの管理画面内でアクセス統計を確認できるようになります。
まず、データの受け皿となるMatomo側で「接続許可証(トークン)」と「サイトID」を確認します。
注意
※注意
トークンは一度しか表示されません。必ずこのタイミングでコピーしてください。
次に、WordPressにインストールしたプラグインにMatomoの情報を入力します。
https://analytics.example.com/)。末尾に / を含めてください。接続しただけでは計測が始まらない場合があるため、以下の設定を確認します。
別サーバー構成でうまく動かない場合は、以下をチェックしてください。
-URLの正確さ: Matomo URLが http か https か、またサブディレクトリ(/matomo/ など)にインストールしていないか再確認してください。
接続に失敗し、その接続ログが出てこない事態も発生しました。
その答えは、筆者が設定したapacheの.confファイルに入りました。
SSL設定を、筆者の標準の
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
から、以下の形で修正。
SSLProtocol -ALL +TLSv1.2 +TLSv1.3
これにより通信ができるようになりました。これには以下の理由があります。
当初の設定: SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2 (意訳:TLS 1.3 のみを許可し、それ以外をすべて禁止する)
修正後の設定: SSLProtocol -ALL +TLSv1.2 +TLSv1.3 (意訳:TLS 1.2 と 1.3 の両方を許可する)
WordPressサーバーがMatomo APIにアクセスする際、内部ではPHPの cURL や openssl ライブラリが使用されます。もしWordPress側のOSやライブラリのバージョンが少し古い場合、あるいは最新であってもクライアント側の設定が TLS 1.2 までしか対応していない場合、Matomoサーバーが「TLS 1.3以外は受け付けない」という設定になっていると、共通の通信言語が見つからず、接続が即座に遮断されます。
WordPress(PHP)が外部サーバーと通信する際、バックグラウンドではシステム標準のOpenSSLライブラリが動いています。
TLS 1.3 を利用するには、OpenSSL 1.1.1以上が必要です。
もしWordPress側のサーバーOSが少し前の世代(例:Ubuntu 18.04やCentOS 7など)であったり、PHPのコンパイル環境が古い場合、TLS 1.3でのハンドシェイクを完遂できず、TLS 1.2での接続を試みようとします。
このとき、Matomo側が -TLSv1.2(1.2禁止)としていると、WordPress側は「接続できるプロトコルがない」と判断し、エラーを出します。
Apacheのアクセスログ(access.log)には、HTTPリクエストが成功または失敗した記録が残ります。しかし、SSL/TLSのハンドシェイク(暗号化の交渉)は、HTTPリクエストが送られる前段階で行われます。
TLS 1.2が禁止されている場合: 通信路を確立する前の「挨拶(ハンドシェイク)」の時点でサーバー側が「そのプロトコルは使えません」と接続を切断します。
こういうとき、以下のコマンドが有効です。
openssl s_client -connect analytics.example.com:443 -tls1_2
もし、このコマンドを実行して CONNECTED(00000003) と表示され、その後に証明書の情報がズラッと出てくれば、「インフラ(OS/ネットワーク/Apache)の土台は完璧である」という証明になります。
逆にここでエラーが出るなら、WordPressの設定(プラグイン)をいくらいじっても解決しないということが一瞬で分かります。
そのため、Apacheは「Webサイトへのアクセス」として認識する前に通信が終了してしまい、通常のアクセスログには一行も記録されないという事態が起こった話。
厳格な設定が裏目に出たという話でした。
こちらの記事の続き。WebアクセスシステムMatomoをWordpressと連携させ、wp-matomoと連携するときに、Mod_Securityが邪魔をしたので処置を行いました。
Matomoがデータ送信の準備として送った Expect ヘッダーが、WAFのポリシーによって「制限されたヘッダー」と判定されたログです。(IP/ホストなどはダミーに置き換え)
[Wed Jan 21 20:55:18.015915 2026] [security2:error] [pid 34746:tid 133273950865088] [client 192.0.2.100:56166] [client 192.0.2.100] ModSecurity: Warning. String match within "/content-encoding/ /proxy/ /lock-token/ /content-range/ /if/ /x-http-method-override/ /x-http-method/ /x-method-override/ /x-middleware-subrequest/ /expect/" at TX:header_name_920450_expect. [file "/usr/share/modsecurity-crs/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf"] [line "1187"] [id "920450"] [msg "HTTP header is restricted by policy (/expect/)"] [data "Restricted header detected: /expect/"] [severity "CRITICAL"] [hostname "matomo.example.com"] [uri "/"] [unique_id "aXC-pq-hNmFZwWUY4ipYBAAAAEg"]
上記の Expect ヘッダー検知により、異常スコアがしきい値(5点)に達したため、通信が遮断(403 Forbidden)されたログです。
[Wed Jan 21 20:55:18.044159 2026] [security2:error] [pid 34746:tid 133273950865088] [client 192.0.2.100:56166] [client 192.0.2.100] ModSecurity: Warning. Operator GE matched 5 at TX:blocking_inbound_anomaly_score. [file "/usr/share/modsecurity-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "233"] [id "949110"] [msg "Inbound Anomaly Score Exceeded (Total Score: 5)"] [hostname "matomo.example.com"] [uri "/"] [unique_id "aXC-pq-hNmFZwWUY4ipYBAAAAEg"]
最終的にどのカテゴリの攻撃として判定されたかをまとめた報告ログです。
[Wed Jan 21 20:55:18.307310 2026] [security2:error] [pid 34746:tid 133273950865088] [client 192.0.2.100:56166] [client 192.0.2.100] ModSecurity: Warning. Unconditional match in SecAction. [file "/usr/share/modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "98"] [id "980170"] [msg "Anomaly Scores: (Inbound Scores: blocking=5, detection=5, per_pl=5-0-0-0, threshold=5) - (Outbound Scores: blocking=0, detection=0, per_pl=0-0-0-0, threshold=4) - (SQLI=0, XSS=0, RFI=0, LFI=0, RCE=0, PHPI=0, HTTP=0, SESS=0, COMBINED_SCORE=5)"] [hostname "matomo.example.com"] [uri "/index.php"] [unique_id "aXC-pq-hNmFZwWUY4ipYBAAAAEg"]
サーバー全体のセキュリティを下げるのではなく、特定のホスト(Matomoドメイン)に限定して、干渉しているルールのみを無効化します。
/etc/modsecurity/rules/request-900-exclusion-rules-before-crs.conf 等に、以下の内容を追記、または作成します。
# ===================================================================
# アプリケーション別除外ルール: Matomo (matomo.example.com)
# ===================================================================
# 1. ターゲットとなるホスト名を指定し、それ以外は処理をスキップ
# ※ホスト名はご自身の環境に合わせて適宜読み替えてください
SecRule HTTP_HOST "@streq matomo.example.com" \
"id:5001,phase:1,nolog,pass,chain,skipAfter:END_MATOMO_RULES_PRE"
# 2. 特定されたホストに対し、干渉しているIDのみを無効化(外科手術)
SecAction "ctl:ruleRemoveById=920450,ctl:ruleRemoveById=932370,ctl:ruleRemoveById=930130"
# スキップ先マーカー
SecMarker END_MATOMO_RULES_PRE
上記、設定を行ったら
sudo apache2ctl configtest
apache 再起動
sudo systemctl restart apache2.service
apache 再起動確認
systemctl status apache2.service
active(running)を確認します。
その後、wordpressのConnect Matomoのページに難度アクセス。
tail -f /var/log/matomo/matomo_error.log
等として(エラーログの場所は自分の環境に合わせます)
上記のログが出なければOKです。
「最初にDetectionOnlyにしていたから助かった」に尽きます。
apacheの設定で
# Mod_security
<IfModule security2_module>
## 最初は検知モード
SecRuleEngine DetectionOnly
#SecRuleEngine On
と、コメントでオフオンを切り替えられる運用を組み込んでいたため、失敗を回避しました。
どハマりしたのがその、wp-connectとmatomoの連携だったのはまた改めて記します。
オープンソースの解析システムであるMatomoをインストールしたときのメモです。
ということで運用しました。
以前のメモがPHP8.3(mod-php)のインストールだったので、php-fpm版を改めて書き起こしています。
リアルタイムでアクセスする性質上、PVが非常に多いWebサイトではサーバ自体の冗長化構成が必要です。(上記URL参照)
筆者のサイトは10万ページ/月に満たないので、そこそこのスペックで運用できています。
既に以下のシステムがWAN環境に揃っていること。
www-dataです。sudo mysql -u root -p
CREATE DATABASE IF NOT EXISTS matomo CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
DB名は自分の環境に合わせます。
CREATE USER 'matomo'@'localhost' IDENTIFIED BY 'YOUR_STRONG_PASSWORD';
DBユーザーは自身の環境に合わせます。パスワードはポリシーに沿って強固なものを設定してください。
GRANT ALL PRIVILEGES ON matomo.* TO 'matomo'@'localhost';
exit;
mysql -u matomo -p
DB名・ユーザー名は適宜自分が設定したものに読み替えてください。
SHOW DATABASES;
作成したDBがあることを確認します。
EXIT
MySQLコンソールから抜けます。
cd /hoge &&pwd
自分の環境に合わせます。
wget https://builds.matomo.org/matomo-latest.zip
unzip matomo-latest.zip
sudo chown -R www-data:www-data matomo
ディレクトリ一式をApache実行ユーザー(www-data)に修正します。
sudo mv matomo /home/www-data/
自分の環境に合わせます。(筆者環境は/home/www-data/matomo で動かします)
ls -ld /home/www-data/matomo
該当ディレクトリにファイル一式があることを確認します。
【】内を自分の環境に合わせます。
コマンド一式をコピー → 別のエディタにペースト
その後、【】内を自分の環境に修正してコピー
コマンド一式をSSHクライアントに貼り付ける
cat <<- __EOF__ | sudo tee /etc/apache2/sites-available/matomo.conf > /dev/null
<VirtualHost _default_:80>
ServerName 【設定したドメイン名】
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName 【設定したドメイン名】
CustomLog 【/var/log/matomo/matomo_access.log combined】
ErrorLog 【/var/log/matomo/matomo_error.log】
# アクセスログとエラーログは自分の環境に合わせて設定します。
DocumentRoot 【/home/www-data/matomo】
# PHPファイルの処理をFPMに渡す設定
<FilesMatch "\.php$">
SetHandler "proxy:unix:/var/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
# -----------------------
<Directory 【/home/www-data/matomo】>
# DcoumentRootとDirectoryは自分の環境に合わせて設定します
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
#SSL設定
SSLEngine on
Protocols h2 http/1.1
# SSLを有効化します
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
#TLS1.3に対応していないクライアントがアクセスする場合は以下を用います
#SSLProtocol -ALL +TLSv1.2 +TLSv1.3
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
SSLUseStapling On
SSLStaplingCache "shmcb:/var/run/apache2/ssl_stapling(32768)"
# 2025年5月よりLet's EncryptはSSL Staplingに伴うOCSPを廃止しました。そのため、証明書をLet's Encryptにしている場合は上記2行をコメントアウトし、代わりにこちらを用いてください。
# SSLUseStapling Off
SSLCertificateFile 【/etc/certs/example.com.crt】
# SSL証明書を指定します
SSLCertificateKeyFile 【/etc/private/example.com.key】
# 秘密鍵を指定します
# SSLCACertificateFile 【/etc/certs/example.com.CA.crt】
# 中間証明書が発行元から別ファイルで提供されている場合は、この直上をコメントアウトして中間証明書を指定します
# index.php への転送設定
DirectoryIndex index.php
#セキュリティヘッダー付与
Header always set Strict-Transport-Security "max-age=63072000"
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-XSS-Protection "1; mode=block"
# Matomo: 機密情報が含まれるディレクトリへの直接アクセスを禁止
<DirectoryMatch "/(config|core|lang|tmp|vendor)">
Require all denied
</DirectoryMatch>
# Matomo: .ini や .json といった設定ファイルへの直接アクセスを禁止
<FilesMatch "\.(ini|json)$">
Require all denied
</FilesMatch>
</VirtualHost>
__EOF__
ls -l /etc/apache2/sites-available/matomo.conf
ファイルがあることを確認します。
sudo a2ensite matomo.conf
sudo apache2ctl configtest
Syntax OKを確認します
sudo systemctl restart apache2.service
sudo systemctl status apache2.service
ブラウザで
にアクセスし、初期画面が出ることを確認します。
をそれぞれ入力し、「次へ」をクリックします。正常に入力されれば「テーブルを作成されました」と出るので「次へ」をクリックします。
をそれぞれ入力して「次へ」をクリックします。
を設定して「次へ」をクリックします。
これらを設定後、トラッキングタグが表示されます。これらを控えて「次へ」をクリックします。
「おめでとうございます!」と表示されればインストールの一連の作業は完了します。
2026年1月20日、筆者が管理するサーバにて、典型的な Open Proxy スキャニング(公開プロキシ探索攻撃) を検知しました。
WAF(ModSecurity)が、いかにして「身勝手な中継依頼」を門前払いしたか、実際のログからそのメカニズムを記録します。
以下は、攻撃者が CONNECT メソッドを使用して外部ドメイン(www.baidu.com)へ接続しようとした際のログです。
[Tue Jan 20 05:43:59 2026] [security2:error] [client xx.xx.xx.xx]
ModSecurity: Warning. Match of "within %{tx.allowed_methods}" against "REQUEST_METHOD" required.
[id "911100"] [msg "Method is not allowed by policy"] [data "CONNECT"] [severity "CRITICAL"]
[hostname "www.baidu.com"] [uri "/"]
このログから、攻撃者の明確な意図が読み取れます。
通常、Web閲覧(GET/POST)には使われない CONNECT メソッドが使用されています。これは本来、プロキシサーバに対して「外部サーバへのトンネルを作れ」と命じるためのコマンドです。
[hostname "www.baidu.com"]
攻撃者は、筆者のサーバに接続していながら、リクエストの宛先に www.baidu.com を指定しています。これは、筆者のサーバを「踏み台(Open Proxy)」にして、中国の検索エンジンにアクセスしようとする試みです。
これは、ほぼ、金盾の影響下にある者が当局の規制を逃れるため、私のvpsを利用しようとしたという背景でしょう。
ID 911100 の発動: ModSecurity CRS は、許可リストにないメソッド(CONNECT)を検知した瞬間、問答無用で CRITICAL 判定を下しました。
また、筆者のapacheのバーチャルサイトの設定もいい動きをしました。
ErrorDocument 403 404.html
としていたため、ModSecurity がアクセスを拒絶した後、Apache は設定された ErrorDocument に従い、403 forbiddenではなく、内部的に 404 not found を返しています。
攻撃者側から見れば、外部へのトンネルが開通するどころか、「そんなページ(機能)は存在しない」 という素っ気ない返答を掴まされて終わったことになります。
今回の事例は、WAFのポリシーを「必要なものだけを許可し、不要なものは拒否する」状態に保ったことが防御につながった例です。
オレだけが外に出る事を
許可しろォォォ─────ッだが!
ウイルスは
許可しないィィィ────ッ感染した部分は
出る事は
許可しないィィィィィ───ッ!!
というイルーヅォの言葉は割とセキュリティで重要という言葉を以て、本記事を締めくくります。
サーバーの構築メモやドキュメント作成時に、「現在のディスク使用状況をサクッとMarkdownの表にしたい」と思ったのがこちらのワンライナーのきっかけ。
通常、df -h などのコマンドを使いますが、結果をブログやGitHubのIssueに貼り付けるには整形の手間がかかります。
今回は、lsblk と jq を組み合わせて、実行するだけで綺麗なMarkdownテーブルを出力する魔法のワンライナーをご紹介します。
以下のワンライナーを使用しました。
{ echo -e "| デバイスパス | 全サイズ | 使用率 | 空き容量 | マウントポイント |"; echo -e "| --- | --- | --- | --- | --- |"; lsblk -lnpo NAME,SIZE,FSUSE%,FSAVAIL,MOUNTPOINT --json | jq -r '.blockdevices[] | select(.mountpoint != null and (.name | contains("loop") | not)) | "| \(.name) | \(.size) | \(.["fsuse%"] // "0%") | \(.fsavail // "-") | \(.mountpoint) |"'; }
実行すると、以下のようなMarkdown形式のテキストが得られます。
| デバイスパス | 全サイズ | 使用率 | 空き容量 | マウントポイント |
|---|---|---|---|---|
| /dev/vda1 | 149G | 24% | 109.9G | / |
| /dev/vda15 | 106M | 6% | 98.2M | /boot/efi |
| /dev/vda16 | 913M | 13% | 702.4M | /boot |
このコマンドは大きく分けて3つのパートで構成されています。
echo -e を使って、Markdownの表の1行目(項目名)と2行目(区切り線)を出力しています。
lsblk コマンドに複数のオプションを渡しています。
-l: リスト形式で表示-n: ヘッダーを非表示にする-p: フルデバイスパスを表示(/dev/vda1など)-o ...: 必要な項目(名前、サイズ、使用率、空き容量、マウントポイント)を指定--json: データを扱いやすいJSON形式で出力します。JSONデータを jq で加工し、Markdownの行 | ... | ... | の形に変換しています。
select(.mountpoint != null): マウントされていないデバイスを除外します。contains("loop") | not: Snapパッケージなどで増えがちな loop デバイス(仮想デバイス)を除外してスッキリさせています。\(.name) | ...: JSONの値をMarkdownのパイプ記号で囲んで出力します。このワンライナーを使えば、サーバー調査の結果をそのままドキュメントに記録できるため、作業効率が大幅にアップします。特にファイルサーバやWebサーバの定点観測に役立つでしょう。
GROWI(Wikiシステム)をセルフホストする場合、本体の他にMongoDB、Elasticsearch、そしてリバースプロキシとしてのApacheなど、複数のサービスを管理する必要があります。これらを個別に手動で起動・停止するのは手間がかかり、手順ミスも起きやすくなります。
そこで、サービス間の依存関係を考慮し、安全かつ簡潔に管理するためのBashスクリプトを作成しました。
a2ensite / a2dissite を活用し、サービス停止時にはApache自体は止めず、GROWIへのアクセスパスのみをクリーンに遮断します。manage-growi.shsystemctlをいじるので、root権限で作っておきます。
#!/bin/bash
# ==============================================================================
# GROWIスタック管理スクリプト
# 対応サービス: MongoDB, Elasticsearch, Apache2, GROWI
# ==============================================================================
# --- [ 設定セクション ] ---
APACHE_CONF_NAME="growi.conf"
SITE_NAME="${APACHE_CONF_NAME%.conf}"
SERVICES=("mongod.service" "elasticsearch.service" "apache2.service" "growi.service")
# カラー出力設定
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# --- [ ユーティリティ関数 ] ---
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_err() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
log_ok() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
# 実行権限チェック
if [[ $EUID -ne 0 ]]; then
log_err "このスクリプトの実行にはroot権限(sudo)が必要です。"
fi
# サービスの状態確認
is_active() {
systemctl is-active --quiet "$1"
return $?
}
# --- [ メイン機能 ] ---
start_services() {
log_info "GROWIスタックの起動を開始します。"
# 1. MongoDB
log_info "データベース (MongoDB) を起動中..."
systemctl start mongod.service
is_active mongod.service || log_err "MongoDBの起動に失敗しました。"
# 2. Elasticsearch
log_info "検索エンジン (Elasticsearch) を起動中..."
systemctl start elasticsearch.service
# 応答待ち(最大75秒)
for i in {1..15}; do
if is_active elasticsearch.service; then break; fi
[[ $i -eq 15 ]] && log_err "Elasticsearchの起動がタイムアウトしました。"
sleep 5
done
# 3. Apache (設定の有効化)
log_info "Apacheのリバースプロキシ設定を有効化しています..."
if [ ! -L "/etc/apache2/sites-enabled/${APACHE_CONF_NAME}" ]; then
a2ensite "${SITE_NAME}" > /dev/null
fi
systemctl reload apache2.service || systemctl start apache2.service
# 4. GROWI 本体
log_info "GROWI本体を起動中..."
systemctl start growi.service
sleep 3
if is_active growi.service; then
log_ok "すべてのサービスが正常に起動しました。"
else
log_err "GROWIの起動に失敗しました。ログを確認してください。"
fi
}
stop_services() {
log_info "GROWIスタックを停止します。"
# サービス影響を最小限にするため、リバースプロキシから先に遮断
log_info "GROWI本体を停止中..."
systemctl stop growi.service
log_info "Apacheの設定を無効化しています..."
if [ -L "/etc/apache2/sites-enabled/${APACHE_CONF_NAME}" ]; then
a2dissite "${SITE_NAME}" > /dev/null
systemctl reload apache2.service
fi
log_info "バックエンドサービスを停止中..."
systemctl stop elasticsearch.service
systemctl stop mongod.service
log_ok "すべての関連サービスが正常に停止しました。"
}
show_status() {
echo -e "\n${YELLOW}--- サービス稼働状況 ---${NC}"
printf "%-25s %s\n" "サービス名" "ステータス"
printf "%-25s %s\n" "------------------------" "-------"
for s in "${SERVICES[@]}"; do
if is_active "$s"; then
printf "%-25s ${GREEN}RUNNING${NC}\n" "$s"
else
printf "%-25s ${RED}STOPPED${NC}\n" "$s"
fi
done
if [ -L "/etc/apache2/sites-enabled/${APACHE_CONF_NAME}" ]; then
echo -e "Apache設定 (${APACHE_CONF_NAME}): ${GREEN}ENABLED${NC}"
else
echo -e "Apache設定 (${APACHE_CONF_NAME}): ${RED}DISABLED${NC}"
fi
echo ""
}
# --- [ エントリポイント ] ---
ACTION=${1:-"menu"}
case "$ACTION" in
start) start_services ;;
stop) stop_services ;;
status) show_status ;;
restart) stop_services; start_services ;;
menu)
echo -e "${YELLOW}実行する操作を選択してください:${NC}"
select opt in "Start" "Status" "Stop" "Restart" "Exit"; do
case $opt in
Start) start_services; break ;;
Status) show_status; break ;;
Stop) stop_services; break ;;
Restart) stop_services; start_services; break ;;
Exit) exit 0 ;;
*) echo "無効な選択です。" ;;
esac
done
;;
*)
echo "Usage: $0 {start|stop|status|restart}"
exit 1
;;
esac
スクリプトを使用するには、実行権限の付与と、システム上のファイル名の確認が必要です。
ファイルを manage-growi.sh として保存した場合、以下のコマンドを実行します。
sudo chmod +x manage-growi.sh
スクリプト内の APACHE_CONF_NAME="growi.conf" が、実際に /etc/apache2/sites-available/ に存在するファイル名と一致しているか確認してください。
このスクリプトは root権限(sudo) が必要です。
引数なしで実行すると、メニューが表示されます。
sudo ./growi-stack.sh
特定の操作を即座に実行したい場合に使用します。
sudo ./growi-stack.sh startsudo ./growi-stack.sh stopsudo ./growi-stack.sh statussudo ./growi-stack.sh restartstatus)現在の各サービスの稼働状況が一覧で表示されます。
--- サービス稼働状況 ---
サービス名 ステータス
------------------------ -------
mongod.service RUNNING
elasticsearch.service RUNNING
apache2.service RUNNING
growi.service RUNNING
Apache設定 (growi.conf): ENABLED
start)依存関係を考慮し、DBから順に起動していきます。
[INFO] GROWIスタックの起動を開始します。
[INFO] データベース (MongoDB) を起動中...
[INFO] 検索エンジン (Elasticsearch) を起動中...
[INFO] Apacheのリバースプロキシ設定を有効化しています...
[INFO] GROWI本体を起動中...
[SUCCESS] すべてのサービスが正常に起動しました。
このスクリプトは、単なる一括起動ではなく、GROWIの依存関係を考慮した設計になっています。
| 順序 | 起動時 (Start) | 停止時 (Stop) | 理由 |
|---|---|---|---|
| 1 | MongoDB | GROWI本体 | DBがないとアプリが落ちるため / 停止は入り口から。 |
| 2 | Elasticsearch | Apache設定無効 | 検索エンジンを準備。 |
| 3 | Apache設定有効 | Elasticsearch | インフラが整ってから外部公開。 |
| 4 | GROWI本体 | MongoDB | 最後にアプリを立ち上げる。 |
[ERROR] が出た場合は、個別のログを確認してください。journalctl -u growi.service -fjournalctl -u elasticsearch.service -fsystemctl enable [サービス名] を各サービスに設定するのが一般的です。このスクリプトは、メンテナンス時の手動メンテナンス用として最適です。
安定した強さを誇り、カットされなければ覇道を進むことができるダー・シュワーム。

しかも、マジョリティが
と、ダー・シュワームのためにあるようなものだったので、むしろ三番手でなぜ誰も取らなかったのかと思いながらスタート。


研究も3ゴールと上位タイル1つ(鉱山×2点)

得点は188点と、相当の点数をたたき出せました。
と、ミスった部分がほぼない珍しい状況でした。
今月届いたノートパソコン、ThinkPad。

こちらのサプライを少し揃えました。

ダイソーで
イヤホンは元々持っていますけど、別に分けておけばペアリングの手間を省けます。

存外小さめのケースも好感触。

これに加えて
一式をお気に入りのポーチにまとめることができました。
クリスマスに喰らった広域IPからのDDoSを排除した話。そこでの「友軍相撃(Friendly Fire)」をやらかしたという失敗談です。
このときのメモはこちらにまとめています。
df -h コマンドが数分間フリーズ(Dステート一歩手前の待機状態)。調査の結果、ネットワーク層およびカーネル層での遮断を確認しました。
curl -v を実行した際、特定のIP帯域(103.151.x.x 等)へのTCPハンドシェイクが Trying... のまま進まず、タイムアウトすることを確認。
この時点で、「ああ、超・広範囲のブロックが徒になったか」と実感です。
ipset list コマンドにより、自作の防御システム『ONE OUTS』で使用している ufw-blocklist に、以下の広域ブロックが登録されていることを突き止めました。
103.0.0.0/8 (Wasabi東京リージョンを含むアジア圏の広大な帯域)85.0.0.0/8 (Nextcloud公式サーバーを含む欧州圏の広大な帯域)結論: 昨年末のDDoS攻撃を鎮圧するために設定した「第1オクテット(/8)単位のブロック」が、正常な業務通信を巻き添えにする(Friendly Fire)結果を引きおこしたのです。
干渉していた巨大なブロックエントリを ipset から削除し、通信路を復旧させました。
sudo ipset del ufw-blocklist 103.0.0.0/8
sudo ipset del ufw-blocklist 85.0.0.0/8
sudo ipset save ufw-blocklist -f /etc/ufw/ipsets.save
この状態では、まだs3fsプロセスが固まっていますので、これも対処。
sudo killall -9 s3fs
sudo fusermount -u -z /mnt/wasabi2
sudo mount -a
各サービスが正常なステータスに戻ったことを確認しました。
curl -I https://s3.ap-northeast-1.wasabisys.com で 303 See Other が即座に返ることを確認。
df -h が遅延なく応答し、Wasabiバケットの容量が表示されることを確認。
管理画面の「インターネット接続なし」の警告が消え、外部連携機能が復旧したことを確認。
「このマウントはバックアップのため、普段めったに触れなかった」に尽きます。
今回、バックアップをいじるようになってからようやく気づいた次第です。これに関しては反省。
「使ってなければそれは見えていないのと同じ」というバイアスでした。
これは、対象のIPアドレスをシャットアウトする「慈悲なき王」です。
を身を以て体感しました。なので、これを振るう時は更に注意する必要がありました。
それにしても、「自分だけが使うサーバのため、被害が自分だけで済んで良かった」と改めて思った次第です。こちらの記事にて
「『いい鉄砲は打ち手を選ぶ』ってことわざ知ってるか?
威力のある鉄砲は その分扱いも難しく危険
だから未熟者が使うと打ち手の方がケガをするってことさ」が自分へ向かうことのないよう、日々、管理/監視を怠らないようにする必要があると知った出来事でした。
が、まさに自分に向かっていったというお話しで、本件を締めます。
Powered by WordPress & Theme by Anders Norén