Apache
Webサーバ、Apacheについて
- Apache設定
- Apacheのインストールと初期設定
- Apacheのホームディレクトリを変更。
- Apacheで特定のアクセス元からの通常アクセスをログに残さない設定。
- apacheで特定のユーザーエージェントからのアクセスを拒否。
- Apacheモジュール
- Ubuntu20.04サーバにApacheのDoS対策モジュール(mod_evasive)を導入。
- UbuntuサーバにMod_Securityを導入。
- Mod_Securityで特定のルールを無視する設定(Nextcloudでの偽陽性を排除)
- Ubuntu 24.04サーバにmod_dosdetectorを導入。
- Apache運用
Apache設定
Apacheのインストールと初期設定
概要
Ubuntu24.04にWebサーバーApacheをインストールします。最近のトレンドではNginxではあるものの、
- 豊富なモジュールとカスタマイズ
- 動的コンテンツの設定をしやすい
- 小規模サイトを立ち上げる上での手間の少なさ
を考慮してのApache設定です。
さっくりとした手順
- Apacheのインストールを行います。
- Apacheの設定を行います。
- 設定の反映を確認します。
インストールを行います。
- レポジトリ追加
sudo add-apt-repository ppa:ondrej/apache2
- パッケージ全体のアップデート
sudo aptitude update
- apacheのインストール
sudo aptitude install apache2
- バージョン確認
apache2ctl -v
Server version: Apache/2.4.62 (Ubuntu)
Server built: 2024-07-22T12:37:10
- サービス稼働確認
systemctl status apache2.service
enabled
とactive (running)
を確認します。
設定を行います。
- 設定ファイルのバックアップ
sudo cp -pi /etc/apache2/apache2.conf /path/to/backup/directory/apache2.conf.$(date +%Y%m%d)
任意のバックアップディレクトリを指定します。
- 設定ファイルのバックアップ確認
diff -u /path/to/backup/directory/apache2.conf.$(date +%Y%m%d) /etc/apache2/apache2.conf
差分が無いことでバックアップを確認します。
- 設定ファイル追記
sudo tee /etc/apache2/apache2.conf > /dev/null << 'EOF'
ServerSignature Off
ServerTokens Prod
ServerName 自分のサーバー名
EOF
自分のサーバー名を英数字で置き換えてください。
- サーバーの署名をオフにして
- 最小限の情報のみを公開し
- Webサーバの名前を指定する
内容です。
- 追記確認
diff -u /path/to/backup/directory/apache2.conf.$(date +%Y%m%d) /etc/apache2/apache2.conf
- 差分内容
+ ServerSignature Off
+ ServerTokens Prod
+ ServerName 自分のサーバー名
設定反映を確認します。
- 構文確認
sudo apache2ctl configtest
Syntax OKを確認します。
- サービス再起動
sudo systemctl restart apache2.service
- サービス再起動確認
systemctl status apache2.service
active (running)
を確認します。
- 設定反映確認
curl -I http://localhost
以下のように、ServerヘッダーにApacheのみが表示されていることを確認します。
Server: Apache
Apacheのホームディレクトリを変更。
Ubuntu系LinuxにapacheやnginxといったWebサーバをパッケージ管理システムでインストールすると、通常は
/var/www
がホームディレクトリとなります。
コンテンツ系を/var
に余り入れたくないという好みの問題があるため、ここを変えていきます。
通常、www-dataは/usr/sbin/nologin
となっているためシェルでログインはできませんが、rubyでbundle install
を行う際にホームディレクトリを参照するケースがあるため、この措置を執ります。
さっくりとした手順
- 新たなホームディレクトリを作成して設定します。
- /etc/passwdファイルを書き換えます。
ディレクトリの作成と設定
- ディレクトリ作成
sudo mkdir -p /home/www-data
運用に合わせます。
- ディレクトリの所有者変更
sudo chown -R www-data:www-data /home/www-data
- 設定確認
ls -ld /home/www-data
所有者がwww-dataになっていることを確認します。
passwdファイルの書き換え
※システム全体のアカウントを制御する重要なファイルです。取り扱いは慎重に行ってください。※
- バックアップ作成
sudo cp -pi /etc/passwd /path/to/backup/directory/passwd.$(date +%Y%m%d)
任意のバックアップディレクトリを指定します。
- バックアップ作成確認
diff -u /path/to/backup/directory/passwd.$(date +%Y%m%d) /etc/passwd
エラーがなければバックアップは成功です。
- ファイル書き換え
sudo sed -i 's|/var/www|/home/www-data|' /etc/passwd
- 書き換え確認
diff -u /path/to/backup/directory/passwd.$(date +%Y%m%d) /etc/passwd
以下の差分を確認します。
-www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
+www-data:x:33:33:www-data:/home/www-data:/usr/sbin/nologin
差分がこの2つだけであることを確認できたら設定完了です。
Apacheで特定のアクセス元からの通常アクセスをログに残さない設定。
概要
Webサービスの運用時、「誰がいつどこにアクセスしたか」を判別するアクセスログはとても重要なものです。 ではありますが、Webアクセス解析時に自分のアクセスログが邪魔になるケースがありました。
そこで、Apacheの設定ファイルで特定のアクセス元からのログを残さないようにしました。
確認環境
- OS : Ubuntu 20.04 LTS
- Apache 2.4系
前提
- 大本のコンフィグ(httpd.conf)ではなくバーチャルサイトで設定していること。
- Apache設定ファイルに管理者権限で設定ができること。
- 除外するIP/NWに対し、合意が取れていること。
注意事項
- この方法でエラーログの除外設定はできません。
実施した手順
ほぼ全てSSHクライアントターミナルからの操作です。
さっくりとした手順
- コンフィグのバックアップを取ります。
- ログを残さない除外IP/NWを加えます。
- コンフィグの整合性を確認し、設定を反映します。
- 除外したIP/NWからのアクセスログが出ないことを確認します。
コンフィグ設定
コンフィグのバックアップを取ります。
- バックアップ
sudo cp -pi /etc/apache2/sites-available/sites.conf /path/to/backup/directory/sites.conf.$(date +%Y%m%d)
自分が設定しているバーチャルサイトのコンフィグ / バックアップディレクトリに合わせます。
- diffによるバックアップ確認
diff -u /etc/apache2/sites-available/sites.conf /path/to/backup/directory/sites.conf.$(date +%Y%m%d)
差分がなければバックアップできています。
コンフィグファイルを編集します。
/etc/apache2/sites-available/sites.conf
設定ファイルを管理者権限で編集します。
編集例
ここでは、以下の設定とします。
- 除外IP: 192.168.1.11
- 除外NW: 192.168.2.0/24
- アクセスログの格納場所: /var/log/redmine/access.log
# 以下のIP/NWはアクセスログに記録させません
SetEnvIf Remote_Addr "192.168.1.11" dontlog
SetEnvIf Remote_Addr "^192\.168\.2\." dontlog
CustomLog /var/log/redmine/access.log combined env=!dontlog
保存後、以下のような差分を確認します。
diff -u /path/to/backup/directory/sites.conf.$(date +%Y%m%d) /etc/apache2/sites-available/sites.conf
- ●差分
+ # 以下のIP/NWはアクセスログに記録させません
+ SetEnvIf Remote_Addr "192.168.1.11" dontlog
+ SetEnvIf Remote_Addr "^192\.168\.2\." dontlog
- CustomLog /var/log/redmine/access.log combined
+ CustomLog /var/log/redmine/access.log combined env=!dontlog
コンフィグの整合性を確認後に設定を反映します。
- コンフィグ確認
sudo apache2ctl configtest
Syntax OKを確認します。
- 反映前のサービス確認
systemctl status apache2.service
active (running)を確認します。
- Apache再起動
sudo systemctl restart apache2.service
- 反映後のサービス確認
systemctl status apache2.service
active (running)を確認します。
動作確認
設定後の動作を確認します。
- アクセスログ確認コマンド発行
tail -f /var/log/redmine/access.log
自分の環境(設定したアクセスログ)に合わせます。
- エラーログ確認コマンド発行
※別ターミナルで開きます。
tail -f /var/log/redmine/error.log
自分の環境(設定したエラーログ)に合わせます。
- ブラウザで以下を実施
- 設定したIP / NWから設定対象のWebサイトにアクセスする。
- 設定したIP / NWからのアクセスログが出ないこと。
- 設定していないIP / NWから設定対象のWebサイトにアクセスする。
- 設定していないIP / NWからのアクセスログが出ること。
- 設定したIP / NWから設定対象のWebサイトにアクセスするがエラーを起こす。(404/403エラーなど)
- 設定したIP / NWからのエラーログが出ること。
- 設定していないIP / NWから設定対象のWebサイトにアクセスするがエラーを起こす。(404/403エラーなど)
- 設定していないIP / NWからのエラーログが出ること。
apacheで特定のユーザーエージェントからのアクセスを拒否。
概要
自分のサーバのアクセスログを見たら
"GET /picture.php?/6797/category/73 HTTP/1.1" 200 14394 "-" "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)"
と、クローラーが大量にアクセスしてきました。robots.txtも意に介さない悪名高いbotのようなので、このアクセスを、サーバで拒否します。
環境
- Ubuntu 20.04
- Apache 2.4 (aptでインストールしたため、ディレクトリは
/etc/apache2
配下にあります。
また、バーチャルサイトによる複数のサイトを運用しているので、そのうちの1つだけを弾きます。
さっくりとした手順
- Apacheのバーチャルサイトの設定ファイルのバックアップを取ります。
- 設定ファイルを追記します。
- 設定を反映します。
- 拒否されていることを確認します。
設定ファイルのバックアップ
- ディレクトリ移動
cd /etc/apache2/sites-available && pwd
- ファイルバックアップ
sudo cp -pi hoge.conf /path/to/backup/directory/hoge.conf.$(date +%Y%m%d)
設定を行いたい自分の設定ファイルを、任意のバックアップディレクトリにバックアップします。
- バックアップ確認
diff -u /path/to/backup/directory/hoge.conf.$(date +%Y%m%d) hoge.conf
差分が無ければ(エラーがなければ)バックアップは成功です。
設定ファイル追記
上述した設定ファイルを教義・進行に則ったエディタで編集します。(要管理者権限)
- 追記例
DocumentRoot /var/www/html/hoge
<Directory /var/www/html/hoge>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
##スパムクローラーを拒否
SetEnvIfNoCase User-Agent "facebookexternalhit/1.1" spam_crawler
SetEnvIfNoCase User-Agent "SemrushBot/7~bl" spam_crawler
SetEnvIfNoCase User-Agent "AhrefsBot" spam_crawler
SetEnvIfNoCase User-Agent "MJ12bot" spam_crawler
SetEnvIfNoCase User-Agent "DotBot" spam_crawler
SetEnvIfNoCase User-Agent "Baiduspider" spam_crawler
SetEnvIfNoCase User-Agent "YandexBot" spam_crawler
SetEnvIfNoCase User-Agent "Sogou web spider" spam_crawler
SetEnvIfNoCase User-Agent "Exabot" spam_crawler
SetEnvIfNoCase User-Agent "MegaIndex.ru" spam_crawler
SetEnvIfNoCase User-Agent "SeznamBot" spam_crawler
SetEnvIfNoCase User-Agent "BLEXBot" spam_crawler
SetEnvIfNoCase User-Agent "Bytespider" spam_crawler
<RequireAll>
Require all granted
## スパムクローラーを拒否
Require not env spam_crawler
</RequireAll>
/var/www/html/hoge
は自分の環境に合わせます。
- 差分確認
diff -u /path/to/backup/directory/hoge.conf.$(date +%Y%m%d) hoge.conf
- 差分例
- Require all granted
+ ##2 スパムクローラーを拒否
+ SetEnvIfNoCase User-Agent "facebookexternalhit/1.1" spam_crawler
+ SetEnvIfNoCase User-Agent "SemrushBot/7~bl" spam_crawler
+ SetEnvIfNoCase User-Agent "AhrefsBot" spam_crawler
+ SetEnvIfNoCase User-Agent "MJ12bot" spam_crawler
+ SetEnvIfNoCase User-Agent "DotBot" spam_crawler
+ SetEnvIfNoCase User-Agent "Baiduspider" spam_crawler
+ SetEnvIfNoCase User-Agent "YandexBot" spam_crawler
+ SetEnvIfNoCase User-Agent "Sogou web spider" spam_crawler
+ SetEnvIfNoCase User-Agent "Exabot" spam_crawler
+ SetEnvIfNoCase User-Agent "MegaIndex.ru" spam_crawler
+ SetEnvIfNoCase User-Agent "SeznamBot" spam_crawler
+ SetEnvIfNoCase User-Agent "BLEXBot" spam_crawler
+ SetEnvIfNoCase User-Agent "Bytespider" spam_crawler
+ <RequireAll>
+ Require all granted
+ ##スパムクローラーを拒否
+ Require not env spam_crawler
+ </RequireAll>
設定反映
- 構文確認
sudo apache2ctl configtest
Syntax OK
を確認します。
- Apache再起動
sudo systemctl restart apache2.service
- Apache再起動確認
systemctl status apache2.service
active(running)
を確認します。
設定反映確認
設定を行ったアクセスログを開きます。
403 3772 "-" "facebookexternalhit/1.1
のように、ステータスコードが「403」になっていれば、アクセス拒否されています。
Apacheモジュール
Ubuntu20.04サーバにApacheのDoS対策モジュール(mod_evasive)を導入。
概要
DoS/DDoS対策ができるモジュールをApacheに導入したときのメモです。
環境
- Ubuntu 20.04
- Apache 2.4系
- FWにufwを利用
さっくりとした手順
- mod_evasiveモジュールをインストールします。
- apache2実行ユーザー(www-data)がufwを利用できるように設定します。
- mod_evasiveモジュールの設定をします。
- 設定の反映を行います。
まずはサーバにターミナルログインするところから始めます。
mod_evasiveのインストール
sudo aptitude install libapache2-mod-evasive
このとき、postfixが依存関係でインストールされる場合があります。メール機能が使えない(AWS等で送信が制限されているなど)は、途中の設定で「何もしない」を選択します。
apache2実行ユーザーの権限変更
これは、www-dataがufwを実行する場合の処理です。権限昇格の危険性を承知した上で、慎重に作業を行ってください。
- sudoersファイルのバックアップ
sudo cp -pi /etc/sudoers /path/to/backup/directory/sudoers.$(date +%Y%m%d)
任意のバックアップディレクトリを指定します。
- diffによるバックアップ確認
sudo diff -u /path/to/backup/directory/sudoers.$(date +%Y%m%d) /etc/sudoers
差分がないことを確認します。
- ファイル追記
echo 'www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw' | sudo tee -a /etc/sudoers
- ファイル追記確認
sudo diff -u /path/to/backup/directory/sudoers.$(date +%Y%m%d) /etc/sudoers
以下の差分を確認します。
+www-data ALL=(ALL) NOPASSWD: /usr/sbin/ufw
evasiveの設定変更
- ファイルバックアップ
sudo cp -pi /etc/apache2/mods-available/evasive.conf /path/to/backup/directory/evasive.conf.$(date +%Y%m%d)
- diffによるバックアップ確認
sudo diff -u /path/to/backup/directory/evasive.conf.$(date +%Y%m%d) /etc/apache2/mods-available/evasive.conf
差分がないことを確認します。
-
以下のファイルを教義・信仰に沿ったエディタで編集していきます。
-
/etc/apache2/mods-available/evasive.conf
-
-
編集例
DOSHashTableSize 3097
DOSPageCount 100
DOSSiteCount 100
#かなり緩く設定して、後で狭めていった方が偽陽性を防げます。
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 10
#DOSEmailNotify you@yourdomain.com
#メール通知を行わないため、ここを省いています
DOSSystemCommand "sudo ufw deny proto tcp from %s to any port 80,443"
# 検証時に自分のサイトがブロックされるのを防ぐため、ポートは80/443に絞っています
DOSLogDir "/var/log/mod_evasive"
DOSWhitelist 127.0.0.1
DOSWhitelist xx.xx.xx.xx
# 対象外としたいIPアドレス(自分の環境など)
参考:Apache の DoS攻撃対策モジュール mod_evasive
- 設定編集確認
sudo diff -u /path/to/backup/directory/evasive.conf.$(date +%Y%m%d) /etc/apache2/mods-available/evasive.conf
- 差分例
- #DOSHashTableSize 3097
- #DOSPageCount 2
- #DOSSiteCount 50
- #DOSPageInterval 1
- #DOSSiteInterval 1
- #DOSBlockingPeriod 10
+ DOSHashTableSize 3097
+ DOSPageCount 100
+ DOSSiteCount 100
+ DOSPageInterval 1
+ DOSSiteInterval 1
+ DOSBlockingPeriod 10
#DOSEmailNotify you@yourdomain.com
- #DOSSystemCommand "su - someuser -c '/sbin/... %s ...'"
- #DOSLogDir "/var/log/mod_evasive"
+ DOSSystemCommand "sudo ufw deny proto tcp from %s to any port 80,443"
+ DOSLogDir "/var/log/mod_evasive"
+ DOSWhitelist 127.0.0.1
+ DOSWhitelist xx.xx.xx.xx
</IfModule>
設定反映
- 構文確認
sudo apache2ctl configtest
Syntax OK
を確認します。
- apache再起動
sudo systemctl restart apache2.service
これで、不審なアクセスが大量にあったときにufwで弾く体制が整いました。
UbuntuサーバにMod_Securityを導入。
ApacheのWAFモジュールであるmod_securityを導入します。
- AWS Lightsailで早々とインストールしていた
- 各種不審なIPアドレスを弾くための盾
として機能しているにもかかわらず文書化していなかったので、Web Arenaでの検証を機に文章に残します。
環境
- Ubuntu 24.04 (20.04でも一応動くとは思います)
- Apache 2.4
※ パッケージ管理にaptitudeを用いています。必要に応じてaptに読み替えてください。
さっくりとした手順
- mod_securityのインストールを行います。
- mod_securityの設定を行います。
- Apacheのバーチャルサイトにmod_securityを組み込みます。
- 設定を反映して動作を確認します。
mod_securityのインストールを行います。
- パッケージ全体のアップデート
sudo aptitude update
- mod_securityインストール
sudo aptitude install libapache2-mod-security2
- インストール確認
sudo apache2ctl -M |grep security
security2_module (shared)
と表示されていることを確認します。
ModSecurityの設定
- 設定ファイル書き換え
sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
推奨ファイルをそのまま設定ファイルとして書き換えます。
OWASP Core Rule Set (CRS)のインストールと設定
- ディレクトリ移動
cd /usr/share/modsecurity-crs && pwd
- ルールセットのダウンロード
sudo git clone https://github.com/coreruleset/coreruleset.git
- ルールセットの設定書き換え
sudo mv /usr/share/modsecurity-crs/coreruleset/crs-setup.conf.example /usr/share/modsecurity-crs/coreruleset/crs-setup.conf
mod_securityモジュールにCRSを読み込む設定を追記
- ディレクトリ移動
cd /etc/apache2/mods-available/ && pwd
- ファイルのバックアップ
sudo cp -pi security2.conf /path/to/backup/directory/security2.conf.$(date +%Y%m%d)
任意のバックアップディレクトリを指定します。
- バックアップ確認
diff -u /path/to/backup/directory/security2.conf.$(date +%Y%m%d) security2.conf
エラーがなければバックアップは成功です。
- ファイル追記
/etc/apache2/mods-available/security2.conf
を、以下の差分になるように教義・信仰に沿ったエディタで編集します。(要root権限)
- </IfModule>
+ # Include OWASP ModSecurity CRS rules if installed
+ IncludeOptional /usr/share/modsecurity-crs/*.load
+</IfModule>
- 設定追記の整合性を確認
sudo apache2ctl configtest
Syntax OK
を確認します。
- Apache再起動
sudo systemctl restart apache2.service
- Apache再起動確認
systemctl status apache2.service
active (running)
を確認します。
Apacheのバーチャルサイト編集
稼働済みのApacheバーチャルサイトの設定ファイルをいじります。バックアップ確認は入念に行ってください。
- ディレクトリ移動
cd /etc/apache2/sites-available && pwd
- バーチャルサイトの設定ファイルバックアップ
sudo cp -pi your_site.conf /path/to/backup/directory/your_site.conf.$(date +%Y%m%d)
.confファイルやバックアップディレクトリは自分の環境を指定します。
- バックアップ確認
diff -u /path/to/backup/directory/your_site.conf.$(date +%Y%m%d) your_site.conf
エラーがなければバックアップは成功です。
- ファイル追記
/etc/apache2/sites-available/your_site.conf
を、以下の差分になるように教義・信仰に沿ったエディタで編集します。(要root権限)
# Mod Security
## ModSecurity有効化
SecRuleEngine On
## ModSecurity検知モード
### 検知モードで動かす場合はSecRuleEngine Onをコメントアウトしてこちらを有効化します
#SecRuleEngine DetectionOnly
## ファイルのアップロードをできるようにします。
SecRequestBodyInMemoryLimit 524288000
SecRequestBodyLimit 524288000
## テスト用の検知パラメータを付け加えます。
SecRule ARGS:modsecparam "@contains test" "id:4321,deny,status:403,msg:'ModSecurity test rule has triggered'"
- ファイル差分
diff -u /path/to/backup/directory/your_site.conf.$(date +%Y%m%d) your_site.conf
+# Mod Security
+
+## ModSecurity有効化
+SecRuleEngine On
+## ModSecurity検知モード
+### 検知モードで動かす場合はSecRuleEngine Onをコメントアウトしてこちらを有効化します
+#SecRuleEngine DetectionOnly
+
+## ファイルのアップロードをできるようにします。
+SecRequestBodyInMemoryLimit 524288000
+SecRequestBodyLimit 524288000
+
+## テスト用の検知パラメータを付け加えます。
+ SecRule ARGS:modsecparam "@contains test" "id:4321,deny,status:403,msg:'ModSecurity test rule has triggered'"
+
- 設定追記の整合性を確認
sudo apache2ctl configtest
Syntax OK
を確認します。
- Apache再起動
sudo systemctl restart apache2.service
- Apache再起動確認
systemctl status apache2.service
active (running)
を確認します。
mod_security動作確認
- ブラウザで、上記の設定を行ったWebサイトにアクセスし、閲覧できることを確認します。
- アドレスバーの末尾に
?modsecparam=test
を追加してアクセスします。
のように、アクセスできないことを確認します。
また、サーバでも
sudo cat /path/to/sites_log/directory/sites_error.log
※ログの格納場所やログの名前は自分の環境に合わせます。
を開き、
ModSecurity: Access denied with code 403 (phase 2). String match "test" at ARGS:modsecparam. [file "/etc/apache2/sites-enabled/your_site.conf"] [line "53"] [id "4321"] [msg "ModSecurity test rule has triggered"] [hostname "host_address"] [uri "/"] [unique_id "xxxxxxx"]
のように、エラーが発生していることを確認します。
備考
Wordpress、Redmine等のWebアプリは自身の操作によって「不審なアクセス」として遮断することが極めてよくあります。(偽陽性)
そのため、テストを行った後は
## ModSecurity有効化
#SecRuleEngine On
## ModSecurity検知モード
### 検知モードで動かす場合はSecRuleEngine Onをコメントアウトしてこちらを有効化します
SecRuleEngine DetectionOnly
として検知モードとして動かした方が良いでしょう。
Mod_Securityで特定のルールを無視する設定(Nextcloudでの偽陽性を排除)
Nextcloudにmod_securityを導入するに当たり、気をつけなければならないのがファイルの閲覧や登録、入力処理中にMod_securityが不審な処理として判断してしまうこと(偽陽性)です。
そこで、
- 偽陽性と思われるログの調査
- 調査時の補助線引き
- 偽陽性になるルールを無視する設定
を行います。
ログ確認
/var/log/nextcloud_error.log
から、以下のようなログを見ました。
[Wed Sep 11 16:35:02.048442 2024] [security2:error] [pid 32762:tid 32762] [client aaa.bbb.ccc.ddd:56994] [client aaa.bbb.ccc.ddd] ModSecurity: Warning. Operator GE matched 5 at TX:inbound_anomaly_score. [file "/usr/share/modsecurity-crs/rules/RESPONSE-980-CORRELATION.conf"] [line "92"] [id "980130"] [msg "Inbound Anomaly Score Exceeded (Total Inbound Score: 5 - SQLI=0,XSS=0,RFI=0,LFI=0,RCE=0,PHPI=0,HTTP=0,SESS=0): individual paranoia level scores: 5, 0, 0, 0"] [ver "OWASP_CRS/3.3.5"] [tag "event-correlation"] [hostname "nextcloud.hoge.com"] [uri "/ocs/v2.php/apps/user_status/api/v1/heartbeat"] [unique_id "ZuFIJU_udFaqxqrJvRLaPQAAAAA"]
ここで見たいのは
- クライアントのIPアドレス
- どのようなルールIDを
- どのぐらい検知したか
です。
ログ確認のワンライナー
これらを確認するため、copilotの助けを借りてawkスクリプトを生成します。
awk '/ModSecurity/ {
ip = gensub(/.*\[client ([0-9.]+):.*/, "\\1", "g", $0);
rule_id = gensub(/.*\[id "([0-9]+)"\].*/, "\\1", "g", $0);
print rule_id, ip;
}' /var/log/nextcloud/nextcloud_error.log | sort | uniq -c
これを実行したところ、Mod_Securityがエラーとして検知したログの中から
36 911100 127.0.0.1
267 911100 aaa.bbb.ccc.ddd
65 920420 aaa.bbb.ccc.ddd
36 949110 127.0.0.1
267 949110 aaa.bbb.ccc.ddd
36 980130 127.0.0.1
267 980130 aaa.bbb.ccc.ddd
という結果を確認しました。127.0.0.1はローカルアドレス、aaa.bbb.ccc.dddも自分がアクセスしてきたIPアドレス。この間、自分がしていたのはNextcloudの設定変更やファイルの閲覧のみです。
Mod_securityが検知したルールIDを「偽陽性」と判断し、処置していきます。
Mod_Securityで特定のルールを検知させない処理
Apacheのバーチャルサイトで設定しているという形です。
設定ファイルの修正
- ファイルのバックアップ
sudo cp -ci /etc/apache2/sites-available/nextcloud.conf /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d)
設定ファイルやバックアップディレクトリは自分の環境に合わせます。
- バックアップ確認
diff -u /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d) /etc/apache2/sites-available/nextcloud.conf
エラー無く、差分も表示されていなければバックアップは成功です。
- ファイル修正
/etc/apache2/sites-available/nextcloud.conf
を以下のように修正していきます。(要root権限)
# Mod_security
## 最初は検知モード
SecRuleEngine DetectionOnly
## 偽陽性と判断したID
SecRuleRemoveById 911100
SecRuleRemoveById 920420
SecRuleRemoveById 949110
SecRuleRemoveById 980130
- ファイル修正確認
diff -u /path/to/backup/directory/nextcloud.conf.$(date +%Y%m%d) /etc/apache2/sites-available/nextcloud.conf
SecRuleRemoveById ID
で、これにマッチするパターンは無視します。
- 差分例
## 最初は検知モード
SecRuleEngine DetectionOnly
+
+## 偽陽性と判断したID
+SecRuleRemoveById 911100
+SecRuleRemoveById 920420
+SecRuleRemoveById 949110
+SecRuleRemoveById 980130
+
</VirtualHost>
設定ファイルの設定反映
- 構文確認
sudo apache2ctl configtest
Syntax OK
を確認します。
- 設定反映
sudo systemctl restart apache2.service
- Apache稼働確認
systemctl status apache2.service
active(running)
を確認します。
動作確認
ターミナルで
tail -f /var/log/nextcloud/nextcloud_error.log
としてエラーログを流します。(エラーログは自分の環境に合わせます)
- 上記処理を行ったNextcloudにアクセスして操作をしていきます。
- 処理を行ったIDが検知されないことを確認します。
Ubuntu 24.04サーバにmod_dosdetectorを導入。
概要
過剰なWebクローラーによりサーバのパフォーマンスが落ちることがあるため、mod_dosdetectorを入れてみます。
mod_dosdetector は、Apache HTTP Server 用のモジュールで、DoS(Denial of Service)攻撃を検出し、対策を講じるためのものです。このモジュールは、特定のIPアドレスからの過剰なリクエストを監視し、しきい値を超えた場合にそのIPアドレスを一時的にブロックすることで、サーバーのリソースを保護します。
mod_evasiveとの違いは
- 細かい設定が可能で
- 特定の条件下での対応が可能
ということでこちらを採用します。
環境
- Ubuntu 24.04
- Apache 2.4
- Apache2-devがインストールされていることが前提です。
さっくりとした手順
- gitでソースをダウンロードします。
- Makefileを書き換えた上でインストールします。
- 設定ファイルを作成します。
- 設定を有効化し、Apacheを再起動します。
mod_dosdetectorのダウンロード
- ソース格納ディレクトリに移動
cd /usr/local/src && pwd
自分の環境に合わせます。
- git clone
sudo git clone https://github.com/stanaka/mod_dosdetector.git
- 展開したディレクトリに移動
cd mod_dosdetector && pwd
Makefileの書き換えとインストール
- Makefile修正
デフォルトのMakefileは/usr/sbin/apxs
となっているため書き換えます。
sudo sed -i 's|^APXS=.*|APXS=/usr/bin/apxs|' Makefile
- インストール
sudo make install
- インストール確認
cat /etc/apache2/mods-available/dosdetector.load
LoadModule dosdetector_module /usr/lib/apache2/modules/mod_dosdetector.so
と表示されます。
設定ファイル追加
参考: mod_dosdetectorを使ってみましょうよ。~挫折を乗り越え~
sudo tee /etc/apache2/mods-available/dosdetector.conf > /dev/null <<EOF
<IfModule dosdetector_module>
DoSDetection on
DoSPeriod 60
DoSThreshold 5
DoSHardThreshold 10
DoSBanPeriod 60
DoSTableSize 100
DoSIgnoreContentType ^(image/|application/|text/javascript|text/css)
</IfModule>
EOF
- DoSDetection on
- 説明: DoS (Denial of Service) 検出を有効にします。
- DoSPeriod 60
- 説明: DoS攻撃を検出するための監視期間を秒単位で指定します。
- DoSThreshold 5
- 説明: DoS攻撃と見なすリクエストの閾値を指定します。
- DoSHardThreshold 10
- 説明: より厳しい閾値を指定します。
- 60秒間に同一IPアドレスから10回以上のリクエストがあった場合、即座にそのIPアドレスをブロックします。
- DoSBanPeriod 60
- 説明: DoS攻撃と見なされたIPアドレスをブロックする期間を秒単位で指定します。
- DoSTableSize 100
- 説明: DoS検出のために保持するIPアドレスの最大数を指定します。
- DoSIgnoreContentType ^(image/|application/|text/javascript|text/css)
- 説明: DoS検出から除外するコンテンツタイプを正規表現で指定します。
設定有効化とApache再起動
- mod有効化
sudo a2enmod dosdetector
- Webサービス再起動
sudo systemctl restart apache2.service
まずはこれで様子を見てみます。
Apache運用
Ubuntuサーバのサイト無効化とLet's Encryptの自動更新停止。
ドメイン変更を伴うサーバのサイト移転を行いました。そこで、旧サーバのサイトのみの停止措置を行います。
環境
- Ubuntu 20.04
- Apache 2.4のバーチャルサイトを利用
- Let's Encryptの自動更新を止める
再確認
データの移行が完全に済んでいることを確認します。
手順
設定ファイルを無効化します。
- ディレクトリ移動
cd /etc/apache2/sites-enabled && pwd
- 有効化されているサイトの確認
ls -la
sites-le-ssl.conf
のように、Let's Encryptの自動更新を利用しているサイトにシンボリックリンクが張られていることを確認します。
コマンドによるサイト停止
sites-le-ssl.conf
- リンクがないことを確認
ls -la
シンボリックリンクがないことを確認します。
旧サイトの設定ファイルを退避します。
- ディレクトリ移動
cd /etc/apache2/sites-available/ && pwd
- ファイル退避
sudo mv sites-le-ssl.conf /path/to/backup/directory/sites-le-ssl.conf.$(date +%Y%m%d)
- ファイル退避確認
ls -la sites-le-ssl.conf
ファイルがないことを確認します。
ls -la /path/to/backup/directory/sites-le-ssl.conf.$(date +%Y%m%d)
ファイルがあることを確認します。
Apacheを再起動します。
- 構文確認
sudo apache2ctl configtest
Syntax OK
を確認します。
- サービス再起動
sudo systemctl restart apache2.service
- サービス稼働確認
systemctl status apache2.service
active (running)
を確認します。
旧サイトにアクセスできないことを確認します。
Let's Encryptの一部の自動更新を無効化します。
sudo certbot delete --cert-name 無効化するドメイン
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Deleted all files relating to certificate ドメイン
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
のように、メッセージが出ればOKです。