最も好きな花の一つである紫陽花。名所を2つほど。
飛鳥山公園





王子公園、飛鳥山。
こちらは電車沿線との無機質な取り合わせが素晴らしいです。
本土寺
千葉北西部の名刹、本土寺。





今度は寺の広い境内を活かした密度が魅力。
曇り空だからこそ似合う花があるから梅雨は楽しみまで見えます。
最も好きな花の一つである紫陽花。名所を2つほど。





王子公園、飛鳥山。
こちらは電車沿線との無機質な取り合わせが素晴らしいです。
千葉北西部の名刹、本土寺。





今度は寺の広い境内を活かした密度が魅力。
曇り空だからこそ似合う花があるから梅雨は楽しみまで見えます。
xtcloudサーバのあるネットワークがプロキシー配下にあったため
状況が発生。それを修正します。
やることは単純です。
「configファイルの修正」
OSはUbuntuです。
config.php の場所を確認するNextcloudのインストール方法によって、設定ファイルの場所が異なります。一般的な場所は以下の通りです。
/var/www/nextcloud/config/config.php/home/www-data/nextcloud/config/config.php/var/snap/nextcloud/current/nextcloud/config/config.phpsudo cp -pi /home/www-data/nextcloud/config/config.php /path/to/backup/config.php.$(date +%Y%m%d)
sudo diff -u /path/to/backup/config.php.$(date +%Y%m%d) /home/www-data/nextcloud/config/config.php
エラーがないことを確認します。ここで~sudo~をつけるのは、一般権限では読み込みすらできないからです。
上記ファイルを$CONFIG = array ( の中に、以下の3行(プロキシの設定)を追記します。既存の設定項目の末尾() の手前)に追加してください。 当然ながら管理者権限が必要です。
'proxy' => '192.168.1.50:8080', // 自分の環境に合わせます。
'proxyuserpwd' => '', // もしプロキシに認証(ユーザー名:パスワード)が必要ならここに記述
'noproxy' => array('localhost', '127.0.0.1'), // プロキシを通さないローカルアドレス
【設定例】全体のイメージ
<?php
$CONFIG = array (
'instanceid' => 'ocxxxxxxxxxx',
'passwordsalt' => 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
// ・・・(中略)・・・
'trusted_domains' =>
array (
0 => 'localhost',
),
'datadirectory' => '/var/www/nextcloud/data',
'dbtype' => 'mysql',
// ここに追記します
'proxy' => '192.168.1.50:8080',
'proxyuserpwd' => '',
'noproxy' => array('localhost', '127.0.0.1'),
);
設定後、ファイルを保存します
sudo diff -u /path/to/backup/config.php.$(date +%Y%m%d) /home/www-data/nextcloud/config/config.php
+ 'proxy' => '192.168.1.50:8080',
+ 'proxyuserpwd' => '',
+ 'noproxy' => array('localhost', '127.0.0.1'),
など、追加したプロキシ設定が追加されていることを確認します。
設定を反映させるため、Webサーバーを再起動します。
sudo systemctl restart apache2
sudo systemctl restart nginx
sudo systemctl restart php8.x-fpm
sudo snap restart nextcloud
設定完了後、Nextcloudの管理者画面にブラウザからログインし、以下の項目を確認してください。
Ubuntu Server(GUIなし環境)において、PACファイル(プロキシ自動設定ファイル)が導入されている環境でネットワーク通信(主にAPTパッケージ管理)を有効化するための作業メモです。
割と頻出する状況だと思います。
Ubuntu ServerのCLI環境(apt コマンドなど)は、デフォルトではJavaScriptで記述されたPACファイルを直接解釈できません。
そのため、「PACファイルの内容を確認し、そこに記載されている実際のプロキシサーバーのIPとポートを直接設定する」方法が確実です。
まず、サーバー上で curl コマンドを使用してPACファイルの内容を読み込み、転送先となっているプロキシサーバーの「IPアドレス」と「ポート番号」を特定します。
curl -s http://192.168.1.10/proxy.pac
表示例
function FindProxyForURL(url, host) {
var clientIP = myIpAddress();
if (
isInNet(host, "10.0.0.0", "255.0.0.0") ||
isInNet(host, "192.168.0.0", "255.255.0.0")
) {
return "DIRECT"; // ローカル通信はプロキシを通さない
}
else {
// 外部インターネット通信用のプロキシサーバー情報
return "PROXY 192.168.1.50:8080";
}
}
return "PROXY ..." の部分に書かれている情報(上記例では 192.168.1.50:8080)を控えます。
特定したプロキシサーバー情報を、APTの設定ファイルに書き込みます。
教義・信仰に沿ったエディタを用いて、以下のファイルを編集/作成します。
/etc/apt/apt.conf.d/99proxy
ファイル内に以下の2行を記述します(手順1で確認したIPとポートに置き換えてください)。
Acquire::http::Proxy "http://192.168.1.50:8080/";
Acquire::https::Proxy "http://192.168.1.50:8080/";
※ gsettings や wpad+ などの不要な記述が残っている場合は、すべて削除して上記のみにします。
設定が正しく反映され、インターネット経由でパッケージ情報が取得できるかテストします。
sudo apt update
「無視(Ignored)」や「タイムアウト」のエラーが多発せず、ヒット(Hit)や取得(Get)が進み、最後に 読み込み完了(Reading package lists… Done)と表示されれば設定完了です。
もし curl や wget など、apt 以外の一般コマンドでもインターネット通信を行いたい場合は、現在のターミナルセッションに対して一時的に以下の環境変数を適用してください。
export http_proxy="http://192.168.1.50:8080"
export https_proxy="http://192.168.1.50:8080"
export no_proxy="localhost,127.0.0.1"
「吠えなかった犬の推理」
という言葉があります。シャーロック・ホームズ『白銀号事件』にある有名なやりとり、
「その他何か私の注意すべきことはないでしょうか?」
「あの晩の犬の不思議な行動に御注意なさるといいでしょう」
「犬は全然何もしなかったはずですが」
「そこが不思議な行動だと申すのです」
から来た、「一見すると不自然ではない(何も起きていない)ことが、状況を踏まえて考えれば極めて不自然であること」という、ミステリの定理とも言えるロジック。
筆者は公開しているVPSで不審なエラーログ(攻撃の検知ログ)は毎日のように見ていますが、先日、エラーではなく通常のアクセスログに、極めて不審な(というか完全にアウトな)一行を発見しました。
今回は、そのログの正体と、その裏に隠された攻撃者の意図について解説します。
見つかったのは、以下のようなログです(※IPアドレスやホストなどの情報はダミーに無害化しています)。
203.0.113.45 - - [02/Jun/2026:05:23:14 +0900] "POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1" 404 3097 "-" "libredtail-http"
Webサイトの運用経験がある方なら、この1行を見ただけでいくつか異様な点に気づくかと思います。
/.%2e/.%2e/ という怪しげな文字列の連続libredtail-http というUser-Agent/bin/sh(OSのシェル)に対して「POST」リクエストを送っているという異常さ幸い、ステータスコードは 404(Not Found) なので、攻撃はサーバー側で弾かれています。では、この攻撃者は一体何をやろうとしていたのでしょうか?
このリクエストは、過去に広く報道された Apache HTTP Serverの脆弱性(CVE-2021-41773など) を狙った自動スキャン(攻撃)ツールによるものです。
URLに含まれる .%2e をURLデコードすると、親ディレクトリを指す .. になります。
攻撃者は、公開フォルダ(cgi-bin)から強制的に外へ飛び出し、サーバーのルートにあるOSの実行ファイル(/bin/sh:シェル)に直接アクセスしようとしていたのです。古典的ですが強力なパストラバーサル(ディレクトリトラバーサル)攻撃です。
「情報を盗み見るだけなら GET なのでは?」と思いましたが、調べてみると攻撃者の意図が浮かび上がりました。
攻撃者の最終目的は、ファイルを覗き見ることではなく、サーバーを乗っ取ることです。POST リクエストの「ボディ(本文)」部分に、実行させたい悪意あるLinuxコマンド(マルウェアのダウンロード命令など)を乗せて送信するのが真の目的です。
GET メソッドの場合、実行したいコマンドをURLの後ろ(クエリパラメータ)に付ける必要があります。しかし、それだとアクセスログのURL部分に攻撃コマンドが丸見えになってしまいます。
Webサーバーの標準ログ設定は「ヘッダー」しか記録せず、「ボディ」は記録しません(パスワードやカード情報などの機密情報が含まれるため)。
攻撃者はこれを利用し、「POST で /bin/sh を叩こうとした」という最低限の事実だけをログに残し、肝心の悪意ある命令(ボディ)をログから隠蔽しているのです。
さらにこのログの User-Agent にある libredtail-http を調べると、明確な犯行の背景が浮かび上がってきました。
これは、感染したサーバーのパワーを勝手に使って暗号資産(仮想通貨)を強制採掘させるマルウェア「RedTail」の拡散ツールです。
もし、サーバーに脆弱性が存在し、この POST が実行(200 OK)されてしまっていた場合、以下のような身の毛もよだつシナリオが進行していました。
POST リクエストを無差別に送り始めます。筆者のVPSには、強力なWAFである ModSecurity を導入して不審な攻撃をシャットアウトしていますが、不思議なことに、今回この件に関するエラーログ(拒否ログ)は現れませんでした。
「攻撃が届いているのに、なぜWAFは吠えなかったのか?」
その理由は、以下の2つの可能性が考えられます。
筆者の環境では、ModSecurityで以下のようなカスタムルールを設けています。
# IPアドレス直打ちアクセス対策
SecRule REQUEST_HEADERS:Host "@rx ^[\d.]+(:\d+)?$" \
"id:10001,\
phase:1,\
deny,\
status:404,\
log,\
msg:'[CUSTOM RULE] Host header is a numeric IP address (incl port). Blocked immediately.',\
tag:'application-attack',\
tag:'PROTOCOL_VIOLATION/INVALID_HREQ'"
# Hostヘッダーが存在しない場合は即ブロック
SecRule &REQUEST_HEADERS:Host "@eq 0" \
"id:10002,\
phase:1,\
deny,\
status:404,\
log,\
msg:'[CUSTOM RULE] Missing Host Header. Blocked immediately.'"
「IPアドレス直打ち」や「Hostヘッダが無い」という、通常のWebブラウズではまず存在しないアクセスは、このルールで瞬殺(phase 1でブロック)されます。自動スキャナーの多くはこれで引っかかります。
この攻撃者は、筆者のサーバーの防御手段を見抜いていたのか、ご丁寧に正しいドメイン名をHostヘッダーに指定して、この網を通り抜けてきたと考えられます。
もう一つの有力な可能性は、Apache自体の挙動です。
ModSecurityがURLの中身を深く精査(パース)するよりも前の段階で、Apacheのコア機能がURLのパスを処理した結果、「物理的にファイルが存在しない(404 Not Found)」と判断して処理を終了したパターンです。
エラー(拒否)ではなく、純粋に「そんなファイルは無いよ」として正常に(?)404を返したため、WAFの検知ログには残らなかった、というわけです。
Apacheにおいて、URLの文字列をデコードして物理的なファイルパスにマッピングする処理(ap_directory_walk)は、ModSecurityの phase:1(ヘッダー検査)と phase:2(ボディ検査)の間、あるいはその手前で行われます。
【Apacheの処理フロー】
1. リクエスト受信
2. ModSecurity (phase:1) ← Hostヘッダーチェック(ドメインが正しいので通過!)
3. Apacheコア (パスの解決) ← 「/.%2e/」を解析しようとするが、そんなCGIは存在しない(404確定)
4. ModSecurity (phase:2) ← 実行される前に、Apacheが「404」として即レスポンスを返して終了
つまり、攻撃者はドメインチェック(貴方のカスタムルール10001)を賢くすり抜けたものの、Apache自体のパス解決の壁に激突して、WAFが本格的に牙を剥く前に死んでいたわけです。
それは「GETの文字数制限を回避するため」です。
RedTailのようなマルウェアは、侵入成功と同時に「Base64で難読化した巨大なシェルスクリプト」を送り込んできます。URLの末尾(GET)にこれを付けると、Apacheの最大URL長制限(LimitRequestLine:通常8KB)に引っかかり、コマンドが途中で切れて実行できません。 そのため、数万文字の「汚い攻撃コード」を確実に一発で流し込むために、ボディ制限が緩い POST を選択せざるを得ないのです。
今回、攻撃の予兆に気づけたのは、「運良く」アクセスログを見ていた結果です。
自分の身やデータを守るため、そして自分が踏み台(加害者)にならないためにも、以下の基本を徹底しましょう。
cgi-binなど)は無効化・削除しておく「エラーがない=安全」とは限らない。
攻撃があった兆候は、静かに普通のアクセスログにも現れる、というお話でした。

今回はプレイに比して余り得点が出なかったというのが正直なところ。
『タラデッキ』を用いて31点。
が主なところです。
とはいえ、ミスのリカバリーもできていたのでそこは評価しておきたいです。
元々大好きな作品『真打』のソロプレイ可能版が、さらに凄まじいブラッシュアップを遂げていました。

プレイヤーは若手の落語家となり、ライバルとネタを出し合います。季節に応じた8回の落語会の中で、
寄席を最も盛り上げた者が勝者となります。
一見、風流なテーマゲームに見えますが、その実態はガチガチの条件戦が絡み合うトリックテイキング(トリテ)。しかも、本来ソロプレイが成立しないはずのこのジャンルを、見事な仕掛けで「1人極上パズル」へと昇華させていました。
本作の最大の魅力は、「トリテの複雑なシステムが、落語のテーマと完璧にシンクロしている点」に尽きます。
カードの数値はすべてユニークで、それぞれに「滑稽噺」「人情噺」「怪談」といったスート(色)が存在します。落語の大ネタほど数値が高く、前座噺は低いため、「『牛ほめ』と『芝浜』だったら、どっちがトリ(勝利)を取るか」が直感的にわかります。初心者には見えにくい「勝ちどころ」が、テーマのおかげで自然と見えてきます。
さらに、以下の要素がトリテのシステムと見事に合致しています。
初心者が忌み嫌い、上級者が好むトリテの「複雑な条件戦」を、落語というテーマが見事に受け止めています。
普通のトリテ以上に、「負けること」に強い意味があるのも特徴的です。
トリを取った(トリックの勝者)プレイヤーほどカードの補充が後回しになるシステムのため、「ここぞという本番で勝つために、今はあえて美しく負ける」という場作りが重要になります。
これがソロプレイ(変則ドラフト)になると、さらにカウンティングによる「勝敗のコントロール」が肝となり、脳のメモリをフル活用させられます。
ボーナス要素である「称号」の獲得条件には、以下のようなものが含まれます。
これにより、「トリック(勝負)には負けているのに、全体の得点(評価)では勝っている」という不思議な状況がゲームをさらに面白くさせています。
トリックテイキングとは、本質的に「相手の手札と意思決定を読む」ゲームです。相手が何を持っているか、どのタイミングで勝ちに来るかという「他者との心理戦」が核にあるため、本来はソロプレイが最も成立しにくいジャンルです。
ところが本作は、その読み合いの代替物を「変態的(褒め言葉)」な2つの仕掛けで成立させています。
ソロモードは、ライバルに勝つこと以上に「自分の得点をどこまで伸ばせるか」という、自分自身との極限の戦いになります。「どの落語会でどの演目を出すか」「季節ボーナスをどう拾うか」が複雑に絡み合うため、「このシナリオでは全力で勝ちに行く」「ここは勝ち数をコントロールする」というジレンマが、1人プレイでも完璧に再現されています。
前作のPocketにはなかった新要素が、プレイヤーの計算を狂わせます。
これらにより、対人戦の「相手が何をしてくるか分からない不確実性」を、ランダム性+強制効果で見事に再現しています。
現に私がプレイした際、「よし、年末に満を持して『芝浜』を出したぞ!」と思った瞬間、『インタラクティブ死神』が発動。相手に『芝浜』を奪われて演じられ、理不尽に負けるというドラマが起きました。この、ほぼ必勝のパターンが引っくり返される異様さ(理不尽さ)こそが、最高に巧妙で、ゾクゾクしました。
コストカットやパッケージを極限まで抑えるためとはいえ、ルールを読むためにインターネット環境が必要なのは少々残念です(とはいえ、10分ほど読み込めばすっと頭に入っていく美しい導線ですが)。
カードが主体のコンポーネントゆえの宿命ですが、カードを保護するためにスリーブに入れると、元々のコンパクトなパッケージに収まらなくなってしまいます。(尤も、カードサイズが特殊すぎた初代『真打』の苦労に比べれば、贅沢な悩みではあるのですが……!)
元々あった「落語の要素」を見事に抽象化した粋なイラストや、ルールそのもののシンプルさはシリーズ共通の魅力として健在です。
その上で、
が見事に融合した、実に入り組んだ、そして見事な作品でした。
トリテに悲喜こもごもがあるかた、そして「制限の中で最適解を叩き出すパズル」が好きな方には刺さる作品です。
先ほどのエントリーの続きです。
「実際に筆者が施している」
Apache設定を元に「どういう動きをしているのか」を紹介します。
サイト名やIPアドレスなどはダミーにしています。
# ============================================================
# 【HTTP: 80番ポート】常時HTTPS(SSL/TLS)へのリダイレクト
# ============================================================
<VirtualHost *:80>
ServerName example.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
# ============================================================
# 【HTTPS: 443番ポート】要塞化されたメインサーバー設定
# ============================================================
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/html/public
# --------------------------------------------------------
# 1. アクセスログの間引き(ノイズカット)設定
# --------------------------------------------------------
# 自身の監視用IPなど、ログに記録させたくないIPを指定
SetEnvIf Remote_Addr "192.168.1.100" dontlog
SetEnvIf Remote_Addr "10.0.0.1" dontlog
# 検索エンジンのクローラー(健全なBot)もログから除外してノイズを減らす
SetEnvIfNoCase User-Agent "Googlebot" dontlog
SetEnvIfNoCase User-Agent "GoogleOther" dontlog
# 【外部ファイル連携】定期的・自動的に更新する悪質ボットのリストを読み込む
# ※ファイル内で「SetEnv bad_bot 1」などのフラグを立てる想定
Include /etc/apache2/conf-available/blacklist-bots.txt
# dontlogフラグが付いたアクセスは記録しない
CustomLog /var/log/apache2/example_access.log combined env=!dontlog
ErrorLog /var/log/apache2/example_error.log
# --------------------------------------------------------
# 2. メインディレクトリ制御(mod_rewrite × 環境変数)
# --------------------------------------------------------
<Directory /var/www/html/public>
Options -MultiViews
AllowOverride All
# 大量の拒否アクセスによるエラーログ肥大化を抑制(重大エラーのみ記録)
LogLevel authz_core:crit
<IfModule mod_rewrite.c>
RewriteEngine On
# 【攻撃検知】特定の動的ページに対する「大量のタグ連結」などのボット挙動を迎撃
# 例:特定のURLパスにアクセスがあり、かつクエリにURLエンコードされたカンマ等が大量に含まれる場合
SetEnvIf Request_URI "^/search/tags" is_target_page
SetEnvIf Query_String "tag=.*(%2c|,|%e3%80%81).*(%2c|,|%e3%80%81).*(%2c|,|%e3%80%81)" bad_tag_stacking
# 条件に合致したら、ログを残さず「404 Not Found(存在しない)」を返して虚無へ葬る
RewriteCond %{ENV:is_target_page} 1
RewriteCond %{ENV:bad_tag_stacking} 1
RewriteRule ^ - [E=dontlog:1,R=404,L]
# 【外部ファイル連携】スパムIPアドレスのブラックリストを読み込んで404を返す
Include /etc/apache2/conf-available/spam-ips.txt
</IfModule>
# 【アクセス拒否】上記の設定や外部リストで「bad_bot」と判定された通信を遮断
<RequireAll>
Require not env bad_bot
Require all granted
</RequireAll>
</Directory>
# 403 Forbidden(拒否)を返すと攻撃者に「防御されている」とバレるため、
# 403の際も「404 Not Found(最初から何も無い)」として処理する
ErrorDocument 403 /404.html
# --------------------------------------------------------
# 3. セキュリティヘッダーの強化(mod_headers)
# --------------------------------------------------------
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"
# --------------------------------------------------------
# 4. Nepenthes(ウツボカズラ)トラップ設定(mod_alias)
# --------------------------------------------------------
# 攻撃者が盲目的にスキャンしてくる「脆弱性のあるパス」を、ダミーの静的ファイルへ吸い込ませる
<IfModule mod_alias.c>
# WordPressを使っていない(または構成が違う)のに狙われるパス
Alias /wp-login.php /var/www/nepenthes/dummy_login.html
Alias /wp-admin /var/www/nepenthes/dummy_login.html
Alias /wordpress /var/www/nepenthes/dummy_login.html
# 漏洩すると致命的な .git ディレクトリへのスキャン対策
Alias /.git /var/www/nepenthes/dummy_git.html
# robots.txtで「巡回禁止」にしているにもかかわらず、
# 行儀悪くスクラップ(収集)しにくるAI自動巡回エージェント用のトラップ
Alias /assets-archive /var/www/nepenthes/dummy_login.html
# トラップ用ディレクトリへのアクセスを許可
<Directory /var/www/nepenthes>
Require all granted
</Directory>
</IfModule>
# --------------------------------------------------------
# 5. SSL/TLS暗号化プロトコル設定
# --------------------------------------------------------
SSLEngine on
Protocols h2 http/1.1
# 安全性の低い古いプロトコルを徹底排除(TLS 1.2 / 1.3 のみ許可)
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
SSLCertificateFile /etc/ssl/certs/example.com.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
# --------------------------------------------------------
# 6. WAF(ModSecurity)のチューニング
# --------------------------------------------------------
<IfModule security2_module>
SecRuleEngine On
# ファイルアップロードの容量制限を引き上げ(必要に応じて調整)
SecRequestBodyInMemoryLimit 524288000
SecRequestBodyLimit 524288000
SecRequestBodyNoFilesLimit 524288000
# --- 偽陽性(誤検知)の除外ルール ---
# ※システム(RedmineやWordPressなど)の特性に応じて、正常な通信が遮断されないよう調整
SecRuleRemoveById 920420 # 特定JavaScriptの誤検知対策
SecRuleRemoveById 200004 # マルチパート解析エラーの除外
SecRuleRemoveById 920300 # HTTPプロトコル違反の除外
SecRuleRemoveById 920260
SecRuleRemoveById 920270
SecRuleRemoveById 920240
# --- 記憶抹消刑(Damnatio Memoriae)システム ---
# あらかじめリスト化した凶悪なIP(negativelist.txt)からのアクセスは、
# 404エラーを返しつつ、Apacheのログ(auditlog等含む)に一切記録させず存在を抹消する
SecRule REMOTE_ADDR "@pmFromFile negativelist.txt" "phase:1,id:2,status:404,msg:'Damnatio Memoriae',nolog,noauditlog"
</IfModule>
</VirtualHost>
では、各設定の意図は後回しにして、「どういう動きなのか」を見てみましょう。
http(80番)で来たアクセスを強制的にhttps(443)に転送します。
悪意を持たないアクセスには正常に通信します。
スクレイピングや事前に設定していた悪質なボットにどう立ち向かうのかがこちらです。
と、このように、
「“アクセス”は通す
“攻撃”は阻止する
ミドルウェアで“両方”やるというのは
そう難しいことじゃあないな」
と言えるのが「個人VPSでApacheを使う理由」と言えます。
次は、それらを可能にする仕組みについて解説します。
Webサーバの中核ミドルウェアは
の二つですが、近年のトレンドは間違いなくNginx。
Nginxはなぜここまでもてはやされるのかを軽くひもといて見ます。
Nginx(エンジンエックス)が現在、Webサーバーのシェアでトップ争いをするほどもてはやされ、多くの開発者や企業に支持されているのには明確な理由があります。
主な意見やメリットをWeb上の情報からまとめると、理由は大きく分けて以下の4点に集約されます。
かつて主流だったWebサーバー(Apacheなど)は、アクセス(リクエスト)ごとに「プロセス」や「スレッド」を立ち上げて処理する方式でした。そのため、同時に大量のアクセスが来るとサーバーのメモリを使い果たしてしまい、サーバーがダウンしたり極端に遅くなったりする「C10K問題(クライアント1万台問題)」が発生していました。
これに対し、Nginxは「イベント駆動型(非同期シングルスレッド)」というアーキテクチャを採用しています。
HTMLファイル、画像、CSS、JavaScriptなどの「静的コンテンツ」をユーザーに返すスピードが圧倒的です。
ベンチマークによっては、従来のWebサーバーと比べて数倍〜十数倍以上のパフォーマンスを発揮すると言われており、リソースの消費を抑えながらWebサイトの表示速度を大幅に向上させることができます。
Nginxは単なるWebサーバーとしてだけでなく、
としての機能が非常に優れています。
現代のWebシステムでは、以下のような「役割分担」をする構成(構成例を以下に示します)がトレンドとなっています。
動的な処理(WordPressや各種Webアプリなどの重い処理)は後ろのアプリケーションサーバーに任せ、Nginxは「表に立って大量のアクセスを交通整理する」という役割を担うことで、システム全体の安定性と速度を極限まで高めることができます。
長年の歴史を持つApacheなどは、多機能である反面、設定ファイルが複雑化しがちでした。
一方、Nginxの設定は記述ルールがスマートで、直感的で分かりやすい構成になっています。軽量でコンテナ(Dockerなど)との相性も抜群に良いため、現代のクラウドネイティブな開発環境において非常に好まれています。
と、ここまで書いたらメリットしかないように感じられるNginxですが、
方にはApacheの方が優れているケースが多々あります。
「単一VPS(リソースが限られている)での個人利用」という条件に絞ると、実はApacheを選ぶ明確なメリット(むしろApacheの方が楽で優れている点)があります。
なぜ筆者のように単一VPSの個人利用ではApacheが有利になるのか、主な理由を3つに分けて解説します。
.htaccess (include)による手軽さと柔軟性個人利用、特に1台のVPSでブログやポートフォリオなど複数のサイトを試行錯誤しながら運用する場合、Apacheの .htaccess(分散設定ファイル)や include(内部ファイル) は圧倒的に便利です。
.htaccess や include(内部ファイル)ファイルを置くだけで即座に反映できます。nginx.conf)に記述する必要があり、変更のたびにサーバーの再起動(リロード)が必要です。記述を間違えるとサーバー全体が落ちるリスクがあります。個人VPSでよく使われるWordPress(PHP)を動かす場合、Apacheの方が構築が圧倒的にシンプルです。
mod_php による一体型処理:
歴史が長いApacheは、ネット上にあるトラブルシューティングや逆引きの設定情報が膨大です。
.htaccess を自動書き換えする」 仕様になっています。Apacheであればプラグインを入れるだけで勝手に設定が完了します。.htaccess の記述(Apache用)を、自分でNginx用の設定構文に翻訳して nginx.conf に手動で追記しなければならないケースが多々あります。「でも、Nginxの方が軽いし速いのでは?」と思われるかもしれませんが、「個人利用のアクセス規模」であれば、体感できるほどの差はまず出ません。
が余りにも強いから、に尽きます。
mod_rewrite という「最強のアーミーナイフ」mod_rewrite は、URLの書き換えやリダイレクトを自由自在に行える、Apache史上最も強力なモジュールのひとつです。個人VPSでWebサイトを運営する際、これほど頼りになるツールはありません。
.htaccess(inlude) との相乗効果:
.htaccess に書けるため、Webサーバー全体の設定を汚すことなく、Webアプリケーション側(WordPressなど)が自身をコントロールするためにフル活用できます。rewrite 指令はありますが、Apacheの mod_rewrite ほど複雑な条件分岐(複数条件の組み合わせや、ファイル・ディレクトリの存在チェックを挟んだ高度なルーティング)をスマートに書くのが難しく、設定が肥大化・複雑化しやすいという弱点があります。mod_security(WAF)との「歴史的・機能的な相性の良さ」個人VPSは常に世界中からのサイバー攻撃(ブルートフォースアタック、SQLインジェクション、クロスサイトスクリプティングなど)に晒されるため、オープンソースのWAF(Webアプリケーションファイアウォール)である mod_security の存在は非常に大きいです。
mod_security はApacheのモジュールとして開発された歴史があるため、Apacheとの親和性は抜群です。インストールも容易で、挙動も非常に安定しています。mod_security(最新はv3)を動かすには、多くの場合ソースコードからモジュールを自分でコンパイル(ビルド)して組み込む必要があり、バージョンアップのたびにメンテナンスの手間が発生するなど、個人運用のハードルがかなり高くなります。Nginxが「大量の荷物を最速で右から左へ捌くプロフェッショナル」だとすれば、
Apacheは「どんな要求にもその場で柔軟に応え、自分で自分の身を守る武装も完璧な万能戦士」です。
個人VPSという「限られた1台の環境」だからこそ、
mod_security でガッチリ身を守り、mod_rewrite で複雑なURL設計をスマートにこなし、.htaccess で手軽に設定を変えるというApacheの特性が120%活きます。「もてはやされているから」という理由だけでNginxを選ぶと、このあたりの「痒いところに手が届く便利さ」を全て手動の泥臭い設定(あるいはコンパイル作業)で補うことになり、途中で挫折してしまうケースも少なくありません。
では次回の記事から、筆者が実際にVPSで運用している「mod_rewrite による超柔軟なURL制御」と「mod_security による鉄壁の防御設定」の具体例を、コードを交えてご紹介します
自分のサーバでその場で障害状況を見るための道具を洗練させています。
#!/bin/bash
# --- カラー定義 ---
GREEN='\033[0;32m' # 緑:正常・低負荷
RED='\033[0;31m' # 赤:高負荷・警告
BLUE='\033[0;34m' # 青:ヘッダ・情報
YELLOW='\033[1;33m' # 黄:中負荷・注意
NC='\033[0m'
BOLD='\033[1m'
# --- デフォルト設定 ---
TOP_N=10
MODE="all"
# --- ヘルプ表示 ---
usage() {
echo -e "${BLUE}Usage: $0 [-c] [-m] [-n NUM] [-i]${NC}"
echo " -c : CPU使用率順で表示"
echo " -m : メモリ使用率順で表示"
echo " -n : 表示行数 (Default: ${TOP_N})"
echo " -i : 対話式モード (Interactive)"
exit 0
}
# --- 対話モード (Interactive Mode) ---
interactive_mode() {
echo -e "${BLUE}${BOLD}=== 対話設定モード ===${NC}"
# モード選択
echo -e "表示モードを選択してください:"
echo " 1) 全て表示 (デフォルト: Enter)"
echo " 2) CPUのみ"
echo " 3) メモリのみ"
read -r -p "選択 [1-3]: " mode_choice
case "$mode_choice" in
2) MODE="cpu" ;;
3) MODE="mem" ;;
*) MODE="all" ;;
esac
# 行数指定
read -r -p "表示行数を入力してください (デフォルト: 10): " input_n
if [[ "$input_n" =~ ^[0-9]+$ ]]; then
TOP_N="$input_n"
else
TOP_N=10
fi
echo ""
}
# --- CPU情報の表示 ---
show_cpu_info() {
echo -e "${BLUE}${BOLD}--- 💻 CPU Information ---${NC}"
if [ -f /proc/cpuinfo ]; then
# メーカー名 / モデル名
local model_name
model_name=$(grep -m 1 "model name" /proc/cpuinfo | cut -d: -f2 | sed 's/^[ \t]*//')
# 物理コア数 (無い場合はソケット数等からフォールバック)
local cores
cores=$(grep -c "^processor" /proc/cpuinfo)
# 周波数 (MHz から GHz に変換して見やすく)
local cpu_mhz
cpu_mhz=$(grep -m 1 "cpu MHz" /proc/cpuinfo | cut -d: -f2 | sed 's/^[ \t]*//')
echo -e " ${YELLOW}Model:${NC} ${model_name:-Unknown}"
if [ -n "$cpu_mhz" ]; then
# 簡易的にGHz変換(小数点以下2桁)
local cpu_ghz
cpu_ghz=$(awk -v mhz="$cpu_mhz" 'BEGIN {printf "%.2f", mhz/1000}')
echo -e " ${YELLOW}Speed:${NC} ${cpu_ghz} GHz (${cpu_mhz} MHz)"
fi
echo -e " ${YELLOW}Cores:${NC} ${cores} threads"
else
echo -e "${RED}/proc/cpuinfo が見つかりません。${NC}"
fi
echo ""
}
# --- Memory & zRAM ---
show_memory_status() {
echo -e "${BLUE}${BOLD}--- 🧠 Memory & zRAM Status ---${NC}"
# free -h の表示
echo -e "${YELLOW}[Physical Memory]${NC}"
free -h | awk 'NR==1{print " " $0} NR>1{print $0}'
echo ""
# zramctl の表示
if command -v zramctl > /dev/null; then
echo -e "${YELLOW}[zRAM Compression Status]${NC}"
zramctl --output-all
else
echo -e "${RED}zramctlはこの環境にはありません。${NC}"
fi
echo ""
}
# --- ディスク使用量 (Storage Status) ---
show_disk_status() {
echo -e "${BLUE}${BOLD}--- 💾 Disk Usage Status ---${NC}"
# 主要なファイルシステム(tmpfs等を除く実ディスク)を抽出して表示
df -h -x tmpfs -x devtmpfs -x squashfs 2>/dev/null || df -h
echo ""
}
# --- プロセス監視 (Process Tracking) ---
show_top() {
local sort_key="$1"
local title="$2"
echo -e "${BLUE}${BOLD}--- ${title} (Top ${TOP_N}) ---${NC}"
# Header (見出し列の幅を調整してズレを防止)
printf "${BLUE}%-6s %-6s %-8s %-12s %-20s %s${NC}\n" "%CPU" "%MEM" "PID" "USER" "UNIT" "COMMAND"
echo "------------------------------------------------------------------------------------------"
# ps コマンド。head/tailのロジックを整理し、空文字による awk の挙動エラーを防止
ps -e -o pcpu,pmem,pid,user,unit:20,args --sort="${sort_key}" | \
tail -n +2 | head -n "$TOP_N" | \
awk -v red="$RED" -v green="$GREEN" -v yellow="$YELLOW" -v nc="$NC" '
{
cpu=$1; mem=$2; pid=$3; user=$4; unit=$5;
# カラー判定
color=nc;
if (cpu > 50.0 || mem > 50.0) color=red;
else if (cpu > 10.0 || mem > 10.0) color=yellow;
else color=green;
# 6列目以降のコマンド引数を結合
cmd=""; for(i=6;i<=NF;i++) cmd=cmd" "$i;
# 先頭の余分なスペースを削除
sub(/^ /, "", cmd);
printf "%s%-6s %-6s %-8s %-12s %-20s %-50s%s\n", color, cpu, mem, pid, user, unit, substr(cmd,1,50), nc
}'
}
# --- 引数解析 ---
# オプション指定がない場合はデフォルトで対話モードを起動
if [ $# -eq 0 ]; then
interactive_mode
else
while getopts "cmn:ih" opt; do
case $opt in
c) MODE="cpu" ;;
m) MODE="mem" ;;
n) TOP_N="$OPTARG" ;;
i) interactive_mode ;;
h|*) usage ;;
esac
done
fi
# --- 実行 ---
clear
echo -e "${GREEN}監視を開始します。${NC}\n"
# システム情報の表示 (常に表示)
show_cpu_info
show_memory_status
show_disk_status
# プロセス情報の表示
case $MODE in
cpu) show_top "-pcpu" "CPU Consumers" ;;
mem) show_top "-pmem" "Memory Consumers" ;;
all)
show_top "-pcpu" "CPU Consumers"
echo ""
show_top "-pmem" "Memory Consumers"
;;
esac
echo -e "\n${GREEN}プロセスが表示されました${NC}"
-c や -m など)が指定された場合は、その設定に従います。usage(ヘルプ表示)使い方を間違えた時や、-h オプションを付けた時に、コマンドのオプション一覧を表示してスクリプトを終了します。
interactive_mode(対話設定モード)引数なしで実行された時に呼ばれます。read コマンドを使ってユーザーに入力を促し、表示したいモード(全て/CPUのみ/メモリのみ)や、ランキングを何件表示するか(デフォルト10件)を動的に決定します。
show_cpu_info(CPU情報の表示)Linuxのシステムファイル /proc/cpuinfo を読み込んで解析します。
awk を使って計算し GHz 単位に変換して見やすく表示します。show_memory_status(メモリとzRAMの状況)free -h コマンドで、人間が見やすい単位(GBやMB)で物理メモリの空き状況を表示します。zramctl コマンドがある環境(メモリ圧縮技術 zRAM が有効な環境)では、その圧縮ステータスも同時に表示します。show_disk_status(ディスク使用量)df -h コマンドでストレージの残量を表示します。-x tmpfs などを指定することで、メモリ上の仮想ファイルシステムを除外した「実際の物理ディスク(SSDやHDD)だけ」を狙って表示する工夫がされています。show_top(プロセス監視のコア処理)ps コマンドで現在動いているプロセスの一覧を、指定されたリソース(CPUまたはメモリ)の消費量が多い順に並び替えて取得します。tail と head を使って、指定された件数(デフォルト10件)だけを切り出します。awk を使ってデータを1行ずつ処理し、CPUまたはメモリの使用率が50%を超えていれば「赤」、10%を超えていれば「黄」、それ以下なら「緑」に文字色をリアルタイムに変化させて出力します。実行する際のオプションによって、動きを切り替えることができます。
| オプション | 実行例 | 動き |
|---|---|---|
| (なし) | ./script.sh | 対話モード。画面の指示に従って入力する。 |
-c | ./script.sh -c | CPU使用率の高いプロセスをトップ10で表示する。 |
-m | ./script.sh -m | メモリ使用率の高いプロセスをトップ10で表示する。 |
-n [数値] | ./script.sh -c -n 5 | CPUの高いプロセスを上位5件だけ表示する。 |
-h | ./script.sh -h | ヘルプ(使い方の説明)を表示する。 |
LinuxサーバーやPCの健康状態を、コマンド一つでパッと色鮮やかに確認できる非常に実用的かつ便利なものに仕上げた自負があります。
今回の東武ワールドスクウェアでの日帰りはいつもとちょっと異なったものをいただきました。

地元企業、岩下食品とのタイアップメニュー。あの新生姜をこんな量を入れた原価はどうなっているんだと考えたくなるラーメン。
ショウガの刺激、酸味が豚骨ベースのスープによく似合い、更に、麺もショウガを練り込んでいるという徹底ぶり。
合間に載せたキャベツがいいアクセントとなって、豚骨ベースなのに後味が軽いという不思議なラーメン。
付け合わせの餃子にしても、刻み生姜がたっぷり添えられて、餃子の油を打ち消してくれるパーツとして機能しています。

また、この時いただいたコロッセオ近くのカフェのアイスも甘みとコクがよく合いますし、何より目の前にコロッセオやパルテノン神殿、ヴァチカンまで見られるという異国情緒の盛り合わせでした。
Powered by WordPress & Theme by Anders Norén