お名前ドットコムVPSへ移行への道5-ModSecruity[WAF]

※ 当サイトではアフィリエイト広告を利用しています。リンクは広告リンクも含みます。

この記事は約35分で読めます。
広告

お名前.com VPS にWAFを入れてみた。
使っているdocker imageがこれでいいのかとか
使い方とか、実験をしていく中で落ち着いたもので
ベストな方法ではないと思いますのでご了承ください。
あくまでも私は、こうやってみたということで動作やセキュリティの保証はできません。
まとまってないので完全に個人メモになってます。
環境
パソコン Windows11
VPS OS Ubuntu 20.04.3 LTS、 Dockerを使用
こちらの続きです。

広告

実験

OWASP/ModSecruityとは以下で解説されています。
Webサイトのセキュリティ対策は万全ですか? WAFの機能を有効に使うための運用のコツをご紹介! | 株式会社サイバープロテックのサイバーセキュリティアカデミー(サイアカ) (cyberprotec.jp)

Nginxの前にWAFのコンテナをつなげばいいだろうという推測でまずはやりました。
ポートフォワーディングをnginxからwafのコンテナにしてwafの出力先をnginxのコンテナにしてみる。
つまりnginxのports80:80 443:443をexposeにしてwafにports80:80 443:443にする。
参考:特定の文字列をパラメタに含むリクエストを遮断する簡易的なWAFをつくるメモ(ModSecurity) #Docker – Qiita
Setup Nginx as a Reverse Proxy and WAF with ModSecurity in Docker (jflower.co.uk)

先にNginxのportsをVPSに対しては閉じて内部のsharedネットワークにのみ開放しておきます。
exposeは多分そういう意味だと思ってます。(間違ってるかも)
sharedのdocker-compose.ymlを
    # ports:
    #   - "80:80"
    #   - "443:443"
    expose:
     - 80
     - 443
sudo docker-compose up -d
dockerの下にwafvpsのディレクトりを作って単独でymlを作ることにしました。
mkdir wafvps
cd wafvps
最終的なディレクトリ構成

docker-compose.yml

version: "3.9"

services:

  waf:
    image: owasp/modsecurity-crs:nginx
    ports:
      - "80:80"
      - "443:443"
    restart: always
    volumes:

      - ./modsecurity/jikken1.conf:/etc/nginx/conf.d/jikken1.conf
      - ./modsecurity/index.html:/var/www/html/index.html
      - ./modsecurity/custom-error.html:/var/www/html/custom-error.html

    container_name: waf-nginx
networks:
  default:
      name: shared
      external: true

最初alpine(軽量版)でやってったけどvimなどのインストールが大変なので
image: owasp/modsecurity-crs:nginx-alpine→image: owasp/modsecurity-crs:nginx
に変更した。
ただfreeでメモリ使用量を確認したら全部で690M/1Gになっていたので,
最終的にはimage: owasp/modsecurity-crs:nginx-alpineに戻した。
vimもdocker cp(後述)で代用できそうだし

owasp/modsecurity-crs:nginx-alpineは、OWASP ModSecurity Core Rule Set(CRS)をNginxと統合したセキュリティソリューションを提供するDockerイメージです。以下に各部分の解説を示します。

  • owasp/modsecurity-crs: この部分は、Docker Hub上のイメージ名です。OWASP(Open Web Application Security Project)は、オープンソースのウェブアプリケーションセキュリティプロジェクトであり、ModSecurity CRSはその一部です。このイメージはOWASPによって提供され、ModSecurity CRSをNginxと統合するために構築されています。
  • nginx-alpine: これは、Dockerイメージのタグで、Alpine LinuxベースのNginxイメージを指します。Alpine Linuxは、軽量でセキュリティに配慮されたLinuxディストリビューションであり、Nginxを実行するための非常に軽量な環境を提供します。このタグは、Alpine LinuxをベースにしたNginxイメージを使用することを示します。

このイメージを使用すると、Nginxを実行するコンテナ内でModSecurity CRSを有効にし、ウェブアプリケーションのセキュリティを強化することができます。Alpine Linuxベースのイメージを使用することで、ディスクスペースやメモリの使用量を最小限に抑えつつ、高いパフォーマンスを実現することができます。

このDockerイメージは、OWASP ModSecurity CRSとNginxの組み合わせを簡単に利用できるように設計されており、ウェブアプリケーションのセキュリティを向上させるための便利なソリューションとなっています。

恐らくimageで使ったのはhttps://hub.docker.com/r/owasp/modsecurity-crs/だと思われる。

sudo docker stats
でコンテナごとの使用量を見たら、全部足しても100いかないからdocker自体を動かすのにかなりつかってるのかな。wafのイメージをalpineに変えても効果は限定的かも。(メモリについては詳しくないです。)
CONTAINER ID   NAME                           CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O        PIDS
************  waf-nginx                      0.00%     64.33MiB / 964.8MiB   6.67%     36.7kB / 41.9kB   24.5MB / 262kB   3
************  proxy                          0.00%     5.145MiB / 964.8MiB   0.53%     1.34kB / 0B       7.48MB / 0B      3
************   django2_web_run_9ea11b0af0c7   1.02%     93.65MiB / 964.8MiB   9.71%     4.7kB / 15kB      43.2MB / 0B      5

80番だけ使えるようにしています。
すでにSSL証明書を設置してるドメインは設置してある位置の関係で処理が複雑になる。
または、できないかもしれないので手をかけていません。(後述)
server_nameに3つ書いてあるけど、動くのはSSL証明書取ってないドメイン(kikuichigevps.com)だけ。他はhhpsに切り替わってうまくいかない。(後述)

modsecurity/jikken1.conf

server {
    listen       80;
    listen  [::]:80;
    # listen       443 ssl http2;
    # listen  [::]:443 ssl http2;
    server_name  kikuichigevps.com django2.kikuichigevps.com django3.kikuichigevps.com;

    # location / {
    #     root /var/www/html;
    #     index index.html;
    # }

    location / {
        proxy_set_header Host $host;
        proxy_pass http://proxy;
    }

    error_page 403 /custom-error.html;

    location = /custom-error.html {
        root /var/www/html;
        internal;
    }
}

実験する中でよく出くわしたエラーパターン
コンテナ中に入れず~is restarting, wait until the container is runningというエラーのときは
エラーを確認する
例えば
sudo docker logs コンテナID -f 1>/dev/null
sudo docker logs コンテナID -f 2>/dev/null
で確認
出会ったエラー例として
default.configを自動で書き換える処理があり、(多分デバッグ用の設定を書いてる)
Volumes:で定義している最後に:roを付けていると、
書き込めないというエラーが出てた。

Portがすでに使われているというエラーのときは
config.dの*.confファイルで既にlistenされている場合が多い。

解決策
この辺のエラーはserverの設定をdefault.confという名前ではなく適当な名前.conf(例jikken1.conf)に書く。
conf.dディレクトリの*.confの中身を確認してポートを重複して定義してないか確認する。
具体的には
docker container exec -it コンテナ名 bash(alpineの場合はsh)
でコンテナの中に入って
cd /etc/nginx/conf.d
lsで*.confの名前を確認
cat ファイルで中身を確認する。

コンテナの中に入って修正しないとエラーが消せないときは
コンテナを一度削除してから新しく作る(コンテナidは変わる)と~is restarting, wait until the container is runningというエラーはなくなる。

一応動いているが、SSL化をするうえで構成を考え直しました。
既に作ったNginxのコンテナ(proxy)をつかうのではなく。
WAFのコンテナにNginxが入ってるようなのでなので、ここで各アプリへの振り分けとSSL化の処理をすることにします。
目次へ

WAFのコンテナでSSL化する

まずは実験用のサブドメインを追加します。(Let’s Encryptの個数制限に注意)

SSL化はこちら↓を参考にしてください。

SSL証明書を取得

 django5.kikuichigevps.comをSSL申請してみます。

version: "3.9"

services:

  waf:
    image: owasp/modsecurity-crs:nginx
    ports:
      - "80:80"
      - "443:443"
    restart: always
    volumes:

      - ./modsecurity/jikken1.conf:/etc/nginx/conf.d/jikken1.conf
      - ./modsecurity/index.html:/var/www/html/index.html
      - ./modsecurity/custom-error.html:/var/www/html/custom-error.html
      - /etc/letsencrypt:/etc/letsencrypt # 追記
      - /usr/share/nginx/html:/usr/share/nginx/html # 追記
    container_name: waf-nginx
    environment:
      TZ: Asia/Tokyo
### certbot ################################################
  certbot:
    image: certbot/certbot:latest
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt
      - /usr/share/nginx/html:/usr/share/nginx/html
    command: ["--version"]
networks:
  default:
      name: shared
      external: true
server {
    listen       80;
    listen  [::]:80;

    server_name  django5.kikuichigevps.com;

    location / {
        root /usr/share/nginx/html;
        index  index.html index.htm;
    }
    # 以下はSSL化のチャレンジという工程で必要
    location /.well-known/acme-challenge/ {
        root /usr/share/nginx/html;
    }
    error_page 403 /custom-error.html;

    location = /custom-error.html {
        root /var/www/html;
        internal;
    }
}
コンテナを更新
sudo docker-compose up -d 
ドキュメントルートに何か表示できているか確認のためサブドメインにアクセス。
django5.kikuichigevps.com
懸念:前SSL化に作ったvolumeをそのまま使っても大丈夫か?
(ドキュメントルートの中に作ったindex.html(Hellow World!)が表示されたので気になった)
取り合えず先に進んでみる。
SSL証明書を取得するコマンド実行
sudo docker-compose run --rm certbot certonly --webroot -w ドキュメントルート -d SSL化するドメイン
具体的には
sudo docker-compose run --rm certbot certonly --webroot -w /usr/share/nginx/html -d django5.kikuichigevps.com

結果Successfully received certificate.
cerbotのコンテナは2つになっていた。(多分、両方ともいらないかも、残しておくけど)
sudo docker volume lsでボリューム確認
2つできていた。1個は前のSSL化でできたが、もう1個は今できたのか?(取り合えず消さないように両方とも覚えておく)
有効期限確認
sudo docker-compose run --rm certbot certificates
結果
  Certificate Name: django5.kikuichigevps.com
    Serial Number: **********
    Key Type: ECDSA
    Domains: django5.kikuichigevps.com
    Expiry Date: 2024-06-12 20:48:04+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/django5.kikuichigevps.com/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/django5.kikuichigevps.com/privkey.pem
コンテナの中に入って証明書確認
sudo docker container exec -it コンテナID sh (alpineの場合、alpineでなければbash)
cd /etc/letsencrypt/live/django5.kikuichigevps.com/
sh: cd: can't cd to /etc/letsencrypt/live/django5.kikuichigevps.com/: Permission denied

/etc/letsencrypt $ ls -l
drwx------    5 root     root          4096 Mar 15 06:48 live
パーミッションがrootしかない
rootでコンテナに入らないとchmodが使えなかったので
sudo docker container exec -it --user root コンテナID sh(alpineの場合、alpineでなければbash)
参考:https://shuzo-kino.hateblo.jp/entry/2022/09/29/235853
以下の変更した
chmod 755 /etc/letsencrypt/live
chmod 755 /etc/letsencrypt/archive
参考:「さくらのレンタルサーバ」Aレコード変更前に無料SSLを導入したい
exit
sudo docker restart コンテナ名
しかし次項がダメ
目次へ

SSL化(ポート443設定)

conf.d/default.confに443の処理を追加。赤い部分はSSL化に申請したドメイン。

server {
    listen       443 ssl http2;
    listen  [::]:443 ssl http2;

    server_name  django5.kikuichigevps.com;
    ssl_certificate /etc/letsencrypt/live/django5.kikuichigevps.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/django5.kikuichigevps.com/privkey.pem;

    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256';
    ssl_prefer_server_ciphers off;

    add_header Strict-Transport-Security "max-age=2592000" always;

    location / {
        root /usr/share/nginx/html;
        index index.html index.htm;
    }

    error_page 403 /custom-error.html;

    location = /custom-error.html {
        root /var/www/html;
        internal;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
コンテナの中に入れない。
sudo docker logs コンテナID -f 1>/dev/null
で確認したら
nginx: [emerg] cannot load certificate key "/etc/letsencrypt/live/django5.kikuichigevps.com/privkey.pem": BIO_new_file() failed (SSL: error:8000000D:system library::Permission denied:calling fopen(/etc/letsencrypt/live/django5.kikuichigevps.com/privkey.pem, r) error:10080002:BIO routines::system lib)
これが出てるとコンテナの中に入れないのでパーミッションの変更もできない。
なのでjiken1.confのSSL443のlistenの処理をコメントアウト
sudo docker restart proxy
sudo docker container exec -it --user root コンテナID bash
bashが使えた(alpineじゃないから)
パーミッションを確認すると
liveとdjango5.kikuichigevps.comは755、privkey.pemは777だった。

サブドメインを取り直した。
10分ぐらいして
confを更新
sudo docker restart proxy
ドキュメントルートに何か表示できているか確認のためサブドメインにアクセス。
django6.kikuichigevps.com

SSL証明書を取得するコマンド実行
sudo docker-compose run --rm certbot certonly --webroot -w ドキュメントルート -d SSL化するドメイン
具体的には
sudo docker-compose run --rm certbot certonly --webroot -w /usr/share/nginx/html -d django6.kikuichigevps.com

結果Successfully received certificate.
SSL対応して
sudo docker restart proxy
ダメ
ログを確認。
[emerg] 1#1: cannot load certificate key "/etc/letsencrypt/live/django6.kikuichigevps.com/privkey.pem": BIO_new_file() failed (SSL: error:8000000D:system library::Permission denied:calling fopen(/etc/letsencrypt/live/django6.kikuichigevps.com/privkey.pem, r) error:10080002:BIO routines::system lib)
参考:https://support.iriusrisk.com/hc/en-us/articles/16953258480413-nginx-emerg-cannot-load-certificate

ls -l /etc/letsencrypt/live/django6.kikuichigevps.com/privkey.pemを調べたら以下だった
lrwxrwxrwx 1 root root 52 Mar 15 11:49 /etc/letsencrypt/live/django6.kikuichigevps.com/privkey.pem -> ../../archive/django6.kikuichigevps.com/privkey1.pem

これをGeminiに聞いたら
「/etc/letsencrypt/live/django6.kikuichigevps.com/privkey.pem はシンボリックリンクであり、実際のファイルは ../../archive/django6.kikuichigevps.com/privkey1.pem にあります。」

ということなのでarchiveを調べたら現状600
root@de40401345e7:/etc/letsencrypt/archive/django6.kikuichigevps.com# ls -l
total 16
-rw-r--r-- 1 root root 1517 Mar 15 11:49 cert1.pem
-rw-r--r-- 1 root root 1826 Mar 15 11:49 chain1.pem
-rw-r--r-- 1 root root 3343 Mar 15 11:49 fullchain1.pem
-rw------- 1 root root  241 Mar 15 11:49 privkey1.pem
↓chmod 644 privkey1.pem
-rw-r--r-- 1 root root  241 Mar 15 11:49 privkey1.pem
confを更新
sudo docker restart waf-nginx
成功した。https://django6.kikuichigevps.com/
表示先をDjangoのコンテナに変えても大丈夫だった。
エラーがなくなったけど、これで安全なのかは分かりません。
目次へ

modsecurityをON/OFFして動作確認

デフォルトではON、検出したらブロックされるようなので
クロスサイト・スクリプティング(XSS)で確認してみます。

メモ帳で以下のファイルを作りwaftest.htmlで保存(保存するとき「ファイルの種類」を「すべてのファイル」にしないとtxtファイルになってしまいます。)
赤字は自分のテスト対象のURLにしてください。
<form method="POST" action="http://django6.kikuichigevps.com/">
  <input type="text" name="data">
  <button>OK</button>
</form>
waftest.htmlをダブルクリックで実行すると
入力欄が出るので、以下(XSS攻撃)入力して「OK」
<input type="button" value="イチゲブログへ" onclick="location.href='https://kikuichige.com/'"></input>

modsecurity-blocked!!とでればWAFでブロックされました。

sudo docker logs コンテナID -f 1>/dev/null
でエラーログを確認すると検出されてました。
2024/03/16 09:47:21 [error] 92#92: *200 [client ***.***.***.***] ModSecurity: Access denied with code 403 (phase 2). Matched "Operator `Ge' with parameter `5' against variable `TX:BLOCKING_INBOUND_ANOMALY_SCORE' (Value: `15' ) [file "/etc/modsecurity.d/owasp-crs/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] 略 client: ***.***.***.***, server: django6.kikuichigevps.com, request: "POST / HTTP/2.0", host: "django6.kikuichigevps.com"
modsecurityをOFFにしてみる
rootで中に入って
sudo docker container exec -it --user root コンテナID bash
まずfile編集できるようにvimを入れる
apt-get update
apt-get install vim
modsecurityをOFFにしてみる(vimのキー操作は別途調べてください)
cd /etc/nginx/conf.d/
vim modsecurity.conf
modsecurity on;→off;
:wq
exit
confを更新
sudo docker restart waf-nginx
同じことをやると、あれ?同じ結果。
中入って見てみるとonに戻ってった。sudo docker restart waf-nginxだと戻るのかも。

コンテナの中に入ってvimで編集して
service nginx restart
は、パーミッションのエラーが出た。この方法は、ここで断念。

docker-compose.ymlのenvironment:でOFF

参考https://linuxfun.org/2024/01/20/how-to-use-owasp-modsecurity-crs-nginx/
コンテナの中に入ってmodsecurityの環境変数を確認
root@aaaaaaaaa:/# env | grep MODSEC
MODSEC_RULE_ENGINE=on

docker-compose.ymlのenvironment:で以下のように設定した。
MODSEC_RULE_ENGINE=offにすればブロックしなくなるらしい。
書き方も:ではなく=にした。下の例に合わせた。
https://docs.docker.jp/compose/environment-variables.html#set-environment-variables-in-containers

    environment:
      # TZ: Asia/Tokyo
      - TZ=Asia/Tokyo
      - MODSEC_RULE_ENGINE=off
コンテナを更新
sudo docker-compose up -d 
コンテナの中に入って確認
root@aaaaaaaaa:/# env | grep MODSEC
MODSEC_RULE_ENGINE=off
実際に対象にアクセスしてもブロックされることはなかったので成功した。
目次へ

ルール追加

IPを許可

https://www.bigbang.mydns.jp/waf-src-x.htmの独自ルールに載っているものを
Bingに聞いた
SecRule REMOTE_ADDR "@ipMatch 127.0.0.1" "phase:1,id:1,nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off" は ModSecurity(ウェブアプリケーションファイアウォール)で使用されるルールの一部です。以下にその詳細を説明します。

SecRule ディレクティブは、リクエストのフィルタリングとブロックのためのルールを定義するために ModSecurity で使用されます。
この具体的なルールでは次のようになっています:
REMOTE_ADDR はリクエストを行っているクライアントのIPアドレスを指します。
@ipMatch 127.0.0.1 はIPアドレスが 127.0.0.1(localhost)と一致する場合にこのルールがトリガーされることを意味します。
phase:1 はリクエストのフェーズでこのルールが評価されることを示します。
id:1 はルールにIDを割り当てます(ログ記録や管理目的で使用されます)。
nolog はこのルールのログ記録を無効にします。
allow はリクエストを許可します(つまり、ブロックしません)。
ctl:ruleEngine=Off はこのリクエストのためにルールエンジンを無効にします。
ctl:auditEngine=Off はこのリクエストのために監査を無効にします。
このルールの効果:

クライアントのIPアドレスが 127.0.0.1 と一致する場合、このルールがトリガーされます。
ルールがトリガーされた場合のアクション(リクエストのブロック、ログ記録など)は、ModSecurityの全体的な設定に依存します。
使用例:

このルールは特定のIPアドレスからのウェブアプリケーションへのアクセスを許可しています。
この場合、IPアドレス 127.0.0.1 からのリクエストを許可しています。

これを元にルールは、そのまま使った。***.***.***.***には自分のIP。idは適当な番号。
SecRule REMOTE_ADDR "@ipMatch ***.***.***.***" "phase:1,id:777,nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off"

phaseなどいろいろ分かりやすい
参考:https://qiita.com/t-uehara/items/03b528f1d7cc75cf01ea

リクエストURLを許可

リクエストURL(例 /vchartren2/api/app_vchart2/)が始まる場合に、
ModSecurityのルールが無効になります。id:は適当ですが、他と被らないほうがいいはず。

SecRule REQUEST_URI "@beginsWith /vchartren2/api/app_vchart2/" "phase:1,id:778,nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off"

ルールの適用

https://jflower.co.uk/setup-nginx-as-a-reverse-proxy-and-waf-with-modsecurity-in-docker/
を参考にしてNginxのjikken1.confの各locationに以下追加でOKだった。
modsecurity_rules '
            SecRule REMOTE_ADDR "@ipMatch ***.***.***.***" "phase:1,id:777,nolog,allow,ctl:ruleEngine=Off,ctl:auditEngine=Off"
        ';
いろいろやったが、これ以外の方法は、うまくいかなかった。

バージョン確認

バージョンはいろいろ組み合わせっているので、これかなと思うものを書いておきます。

ModSecurity Core Rule Set(CRS)
rootユーザーでコンテナの中に入って
cat /etc/modsecurity.d/owasp-crs/crs-setup.conf

ModSecurity Core Rule Set(CRS)のバージョンは見れる。
# OWASP CRS ver.*.*.*
実際に、このバージョンで動いているかは分からない。
ここhttps://coreruleset.org/でカレントバージョンが分かる。

Nginxのバージョンは同じくコンテナの中に入って
nginx -v
nginx version: nginx/*.*.*
Nginxのバージョン情報は、https://openstandia.jp/oss_info/nginx/version/が見やすい

ModSecurity-nginxは
多分https://github.com/owasp-modsecurity/ModSecurity-nginxこれだと思われる。
Version increment toと書いてあるところがヴァージョンぽい。
実際以下のように確認すると同じだった。
また右側にModSecurity v3 Nginx Connectorと書いてあるので、
そのバージョンのことでModSecurity自体はV3なのかな。

sudo docker restart コンテナ名
sudo docker logs コンテナID -f 1>/dev/null
で、それらしい記述はこれくらい
2024/03/27 07:12:54 [notice] 1#1: 
ModSecurity-nginx v*.*.* (rules loaded inline/local/remote: 0/***/0)
0/***/0の部分は、0個のインラインルール、***個のローカルルール、0個のリモートルールが読み込まれている(Gemini談)
前項のルールを適用したら2/***/0になったのでローカルルールとして読み込まれていた。
目次へ

500番エラーページ

ログを見ると”/usr/share/nginx/html/50x.html” failedが出てた。
50x.htmlが/usr/share/nginx/htmlになかった。
これがないと表面上、ファイルがないというエラーの404が表示されてしまうので
50x.htmlを作った。

modsecurity/jikken1.confの該当する部分
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

以下の50x.htmlをVsコードのターミナルで操作しているディレクトリにおき

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>500 Internal Server Error</title>
</head>
<body>
<h1>500 Internal Server Error</h1>
<p>サーバーでエラーが発生しました。</p>
<p>申し訳ありませんが、しばらくお待ちください。</p>
</body>
</html>
これでコンテナの中にコピーできます。
sudo docker cp 50x.html コンテナID:/usr/share/nginx/html
目次へ

favicon.ico

ログを見てるとfavicon.icoの読み込み失敗が多くて見ずらいのでfavionを
ここでhttps://favicon.io/favicon-generator/作って設置した。
いろんなサイズができるが32×32の画像をfavicon.icoと名前を付けた。
Vsコードにはファイルを開くで自分のパソコンのファイルを読み込んで、
左側のディレクトリにドラッグ&ドロップすればアップロード?された。

modsecurity/jikken1.confの該当する部分
    location /favicon.ico {
        root /usr/share/nginx/html;
        index favicon.ico favicon.ico;
    }
これでコンテナの中にコピーできます。
sudo docker cp favicon.ico コンテナID:/usr/share/nginx/html
目次へ

ログを見て、ちょっと調べたこと

sudo docker logs コンテナID -f 2>/dev/null
でログを見ると後ろの方に{"transaction":{"client_ip":"205.210.31.215","time_stamp":"Sun Mar 17 06:10:57 2024","server_id":"~がある。
これは ModSecurity が検出した情報が記録されてるようです。(Geminiに聞いた)
後半部分にバージョン関係の情報や設定値も見れるようです。
{"modsecurity":"ModSecurity v3.*.* (Linux)","connector":"ModSecurity-nginx v1.*.*","secrules_engine":"Enabled","components":["OWASP_CRS/*.*.*\""]},"messages":[{"message":"Request Missing a Host Header","details":{"match":"Matched \"Operator `Eq' with parameter `0' against variable `REQUEST_HEADERS:Host' (Value: `0' )","reference":"","ruleId":"920280",~略~,"attack-protocol","paranoia-level/*","OWASP_CRS","capec/1000/210/272","PCI/6.5.10"],"maturity":"0","accuracy":"0"}}]}}

調べようと思うのは
"response":{"body"の後にやたらと長いコードが記録されている。
これは実際にレスポンスしたものなのか?(ステータスコードは400だからしてないとは思うけど)

Geminiに聞いた答え
3. モジュールによって生成された疑似的なレスポンス

ログに記録されている "body" 部分が、実際には送信されていない場合があります。
例えば、ModSecurity などのモジュールが、セキュリティ上の理由でリクエストをブロックした場合、疑似的なレスポンスが生成されます。
この場合、実際のレスポンスは送信されず、クライアントはエラーメッセージを受け取ります。

ログに残らないようにできないのか?(目が痛い)
目次へ

ログイン状況の確認

lastコマンドでログイン状況が分かります。

last
reboot   system boot  *.*.*-*-generi Sat Mar 16 08:17   still running←VPSの再起動をクリックした
user777  pts/0        *.*.*.*        Thu Mar 14 15:57 - 19:09  (03:11)
reboot   system boot  *.*.*-*-generi Thu Mar 14 15:57 - 08:17 (1+16:20)←VPSの再起動をクリックした
user777  pts/0        *.*.*.*        Thu Mar 14 06:41 - 08:45  (02:03)
reboot   system boot  *.*.*-*-generi Wed Mar 13 17:22 - 08:17 (2+14:54)←VPSの再起動をクリックした
user777  pts/0        *.*.*.*        Tue Mar 12 08:24 - 18:52  (10:27)
user777  pts/0        *.*.*.*        Mon Mar 11 04:46 - 05:51  (01:04)
user777  pts/0        *.*.*.*        Sun Mar 10 04:40 - 08:11  (03:31)

各行の詳細:(Gemini談)

  • 最初の列:
    • reboot – システムが再起動されたことを示します。
    • user777 – ログインユーザー名です。
  • 2番目の列:
    • pts/0 – ログインに使用された仮想端末の名前です。
  • 3番目の列:
    • *.*.*.* – ログインしたIPアドレスです。
  • 4番目の列:
    • Thu Mar 14 15:57 – ログイン時刻です。
  • 5番目の列:
    • - 19:09 (03:11) – ログアウト時刻とログイン時間の長さです。
    • - はまだログアウトしていないことを示します。
  • 6番目の列 (reboot の場合のみ):
    • still running – システムがまだ稼働中であることを示します。
  • 7番目の列 (reboot の場合のみ):
    • user777 pts/0 – 再起動時にログインしていたユーザーと仮想端末です。

例:

  • reboot system boot *.*.*-*-generi Sat Mar 16 08:17 still running –
    • 2024年3月16日土曜日午前8時17分にシステムが再起動されました。
    • 再起動時にuser777ユーザーがpts/0仮想端末にログインしていました。
    • システムは現在も稼働中です。

その他の情報:

  • lastコマンドは、デフォルトで過去7日間のログイン履歴を表示します。
  • 表示期間を変更するには、-nオプションを使用します。
  • 特定のユーザーのログイン履歴のみを表示するには、-uオプションを使用します。

所感

imageは結局owasp/modsecurity-crs:nginx-alpineにした。
ただfreeで確認すると対して減ってなかった。
modsecurityに関しては、まだまだ使い方が分からない。
初めてやるところでGemini、Bing、ChatGptに聞くが、
知らないことなのでだまされたり、余計、泥沼にはまることもよくある。
目次へ

イチゲをOFUSEで応援する(御質問でもOKです)Vプリカでのお支払いがおすすめです。
MENTAやってます(ichige)

コメント