fail2banとFreeBSDのpfで通信がただちに遮断されない?

クラッキング
© いらすとや

2020年9月末現在にfail2banに入っているpfパケットフィルタ用のアクション設定の内、Ban対象IPアドレスが発生した際に発動するactionbanは以下のようなの。条件によって多少違うかもだけど。

block drop quick proto tcp from <f2b-フィルタルール名> to any

仮にフィルタルール名をexampleとしてルールを作成して運用し、Ban対象になるログが記録されたとする。そのIPアドレスは192.168.0.11とする。

/var/log/fail2ban.log
2020-09-30 12:00:00,000 fail2ban.actions        [191]: NOTICE  [example] Ban 192.168.0.11
fail2banのフィルタルールexampleが作ったルール
# pfctl -a "f2b/example" -s rules
block drop quick proto tcp from  to any
f2b-exampleのフィルタルールでBanされているIPアドレスリスト
# pfctl -a "f2b/example" -t f2b-example -T show
   192.168.0.11
   192.168.0.47

fail2banでexampleフィルタルールを有効にしたことで発生しているルールは予定どおりで問題ないように見える。
BanされているIPアドレスリストに192.168.0.11が含まれているので予定どおりの動作になっている。
そして、暫く後に確認したところ、192.168.0.11からはもう訪れることがなくなっていることが確認できた。

ところが

もう一度fail2banのログを見る

/var/log/fail2ban.log
2020-09-30 12:00:10,500 fail2ban.filter         [191]: INFO    [localban] Found 192.168.0.11 - 2020-09-30 12:00:10
2020-09-30 12:00:11,000 fail2ban.actions        [191]: NOTICE  [localban] 192.168.0.11 already banned

しばらくこんなのが続いていた。「アクセスされたけど既にBanされてる」というメッセージ。凄い矛盾というかおかしな話。

サービスログを確認する
Sep 30 11:59:40 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 11:59:50 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:00:00 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:00:10 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:00:20 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:00:30 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:00:40 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:00:50 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:01:00 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:01:10 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:01:20 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:01:30 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:01:40 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:01:50 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:02:00 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:02:10 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:02:20 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:02:30 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:02:40 hoge example[25572]: client=[192.168.0.11], undesirable record
Sep 30 12:02:50 hoge example[25572]: client=[192.168.0.11], undesirable record

黄色の行がfail2banによってBanが確定したログ。Banされた時刻以降もたしかにアクセスが続いている。

12:00:00にBanされたら以降のアクセスは無いことを期待すると思うが、実際にはしばらく(意外と長く)アクセスが続くことがある。
fail2banがログを読んでBanと認識したのが実際には12:00:00より数分遅いのかというとそうではないらしい。そしてBan対象の192.168.0.11から全く新しい通信を行おうとした場合は12:00:00直後からでもアクセスできないっぽい。
どうも、セッションが切断されずに継続される場合はBanを発生させても通信は遮断されないよう。辞めた従業員を翌日以降も顔パスで会社に出入りさせてる警備員みたいな感じ。
この挙動はfail2banではなくpfが引き起こしてるみたい。

ググってみたらこんなやりとりがあった。

https://github.com/fail2ban/fail2ban/issues/1924

攻撃的?なぜ揉めてるのかニュアンスが理解できないのだが、単純にBanしたついでに pfctl -k IPアドレス を実行するんで良くない?ってことでこれを採用。

pf用のアクションを決めているファイルは/usr/local/etc/fail2ban/action.d/pf.conf

actionban = <pfctl> -t <tablename>-<name> -T add <ip> && <pfctl> -k <ip>

黄色の部分が元のアクションから増えた部分。
いまのところ、これで期待したとおりBan後は問答無用で遮断されるという動作になっている。

つまり、長らくpfの動きを正しく理解せずに使ってたということだけど、dropルールより状態を優先させる動きがデフォルトってヘンじゃないかしら?

タイトルにはFreeBSDって付けてるが、FreeBSD以外でもpfが使えるOSでおそらく同じ?

「使用していない JavaScript の削除」と「使用していない CSS を削除してください」

最近はGoogleさんのウェブサイトのページの評価がうるさくなってユーザーエクスペリエンスというものが重視される傾向。今年はCore Web Vitals(コアウェブバイタル)とかいうものに振り回された(振り回されている?)ウェブサイトの管理者も多い筈。 コアウェブバイタルの3つLCP, FID, CLS、それとFCPの合わせて4つの指標が重要ね。コアウェブバイタルは今年は猶予期間だからとのんびり構えないで早めに対処した方が良さげ。対処するとページの表示速度が改善され、より多くの閲覧者が訪れる、少なくとも減りはしないことが期待される。
難しそうだからと途方に暮れることはなく、GoogleのPageSpeed InsightsやChromeブラウザ内蔵デベロッパーツールのLighthouseを使えばご丁寧に改善点を教えてくれるので1つ1つ潰していくだけ。
で、今回は難しそうで簡単そうでそうでもない「使用していない JavaScript の削除(Remove unused JavaScript)」と「使用していない CSS を削除してください(Remove unused CSS)」の2つの対処。

現在の「がとらぼ」は大きく2つに分かれていて「画面が暗いブログ」と「画面の明るい中華スマホのスペック紹介」になっている。1つのWordPressでテンプレートを2つ用意してブログとスマホ紹介で見た目が全く異なるようになっている。ブログ用の方はフルスクラッチの自作テンプレートでCSSも全部自作。スマホ用の方はテンプレート自体は自作だけど見た目の部分についてはほぼSemantic UIというフレームワークに頼っている。Semantic UIは導入そのものはとても簡単にできるのだが、単に「入れました、使いました」だとGoogleさんの評価が大変悪い。指摘されるのが「使用していないJS/CSSを削除してください」。今回はそれを改善する。
Semantic UI以外でも大きめのフレームワークを使うと同じ指摘を食らう筈だが、対処方法は同じなので少しは参考になる部分がある筈。

使用していないCSSを削除してください 1
PageSpeed InsightsでSemantic UIを使っているページを診断してみた。「改善できる項目」の中に「使用していない JavaScript の削除」と「使用していない CSS を削除してください」がある。(画像の赤い四角の部分)

使用していないCSSを削除してください 2
「使用していない JavaScript の削除」と「使用していない CSS を削除してください」をクリックするとそれぞれ指摘対象のJavascript, CSSファイルのPathが表示される。

この、「使用していない JavaScript の削除」と「使用していない CSS を削除してください」は指摘されているJS/CSSファイルが要らないから削除しろということではなく、指摘されているファイル内に使っていないコードが多すぎるのでそれを省けというもの。ここで指摘の意味を取り違えると対処方法がわからなくなる。Googleさんの指摘って意味が判らないのが多いから困る。

使用していないCSSを削除してください 3
Chromeブラウザを起動して[F12]キーを押す。Macだと[Command]+[Option]+[I]かな?
Chromeブラウザ内蔵デベロッパーツールが起動する。

使用していないCSSを削除してください 4
ここで、[Ctrl]+[Shift]+[p]を押す。Macの場合は[Command]+[Shift]+[p]かな?
小窓がポップアップするのでテキストボックスにshow coverageと入力する。部分一致で候補が表示されるので実際にはcoverとかで良い。

使用していないCSSを削除してください 5
「[Drawer] Show Coverage」という候補が表示されるのでそれをクリックする。

使用していないCSSを削除してください 6
下部にドロワーが表示されるというかウィンドウが分割されたようになって、Coverageタブが選択された状態になる。
その中央の[]をクリックする。

使用していないCSSを削除してください 7
そのページで読み込まれているJava scriptやCSSのファイルがリストされ、そのファイルで使用されているコードの割合が表示される。上の画像では赤枠で囲ったsemantic.min.cssがSemantic UIのCSSファイルだが、約630KBのファイルを読み込んで、そのファイルのCSSコードの内ページ表示で使用されているのが僅か2.2%であることを示している。つまり630KBも読み込んで97.8%は無駄になっている。これは指摘されても仕方ない。(本当はもう少し多くのコードが使われる)
このリストの中から目的のファイルの行をクリックする。(上の画像だと赤枠で囲ったsemantic.min.cssをクリック)

使用していないCSSを削除してください 8
ファイルを(ダブル)クリックすると上側のConsoleタブが選択されていたところがSourcesタブに切り替わる。(基本的には自動の筈だが切り替わらない場合は手動で[Sources]をクリック)
クリックしたファイルのコードが表示される。改行,余分な空白/タブが削除されたコンパクト化されているcss,jsファイルもフォーマット化されてわかりやすく表示される。
使用中のコードと未使用のコードが色分けされるので青緑の帯が付いた(使用されている)コードをコピーしてエディタなどに貼る。繰り返して使用中のコードを全て抜き出す。

別ページでも同様に繰り返して使用中のコードを抜き出す。普通のWordPressのブログならトップベージ、固定ページ、投稿ページ、記事のリストのページのようにページの種類ごとに各1ページずつから抜き出せば良いかと。ただし、テーブルだとかアイコンだとか特定のページでしか使用していないコードは別途抜き出しの必要も。
ある程度名の知れたフレームワークならCSSコードが系統で分けてあるはずなので整理しながら重複しないように抜き出せる筈。

これで、一応ページの表示そのものに使用されているコードだけは抜き出せたが、それだけではちょっと足りない筈。
元ファイルと比較する方が良い。CSSにに慣れてる人なら先の使用されていないCSSコードの中に必要なコードが混じっていることに気付くかもなので、使用されていないCSSコードに分類されていてもコピーしておけば良い。
元ファイルと比較した場合は元ファイルの分類別コメントをコピーしておく方が後の編集がラクになる。
@media hogeとかイベント・アニメーション関連などはモレ注意。大抵は使用中コードの青緑でマークされている前後に隣接して存在するのであるていどは判るようになっている。

使用中のコードを抜き出して編集したファイルをsemantic-subset.cssなどのファイル名で保存する。
semantic-subset.cssからコメント,改行,タブ,余計な空白を除去してsemantic-subset.min.cssを出力する。
必要に応じてsemantic-subset.min.cssをBrotli圧縮またはGzip圧縮する。(ウェブサーバが静的Brotli/Gzip圧縮対応の場合)
HTMLファイルのHTMLヘッダのCSSファイルのpath+ファイル名を変更する。WordPressならテーマのディレクトリにあるheader.phpと必要に応じてfunctions.phpでファイルの指定を変更する。

JavascriptもCSSの場合と一応同じ方法が使える。ただし、ページ表示しただけでは表示で使用したコードだけしかマークされない。Semantic UIのサイドバーであればトグルボタンを少なくとも2回押してスライドオープン、クローズを実行しなくては必用なコードと不要なコードが判らない。動作に必要なコードを削ってしまうとJavascriptの実行エラーで他の必要なJavascriptまで動かなくなると困った事態になるかもしれない。Semantic UIのJavascriptは1つの巨大なファイルに複数の機能別に関数が分かれて入っているので使用する機能の関数だけまるごと抜き出す方が無難。Javascriptの巨大なコードがスラスラ理解できる人はさらに不要なコードを取り除いてファイルをダイエットさせれば良いかなと思う。

Semantic UI 2.4.2のdist/semantic.jsは以下の様になっている。
site: 11-498行
form: 499-2205行
accordion: 2206-2818行
checkbox: 2819-3651行
dimmer: 3652-4385行
dropdown: 4386-9047行
modal: 9048-10083行
nag: 10084-10591行
popup: 10592-12124行
progress: 12125-13056行
rating: 13056-13565行
search: 13566-15071行
shape: 15071-15993行
sidebar: 15994-17027行
sticky: 17028-17987行
tab: 17988-18940行
transition: 18940-20036行
api: 20037-21204行
visibility: 21205-22515行

たとえば、「がとらぼ」のスマホ用ページならSemantic UIのJavaScriptはサイドバーしか使っていないのでサイドバー関連の15994〜17027行だけ抜き出してsemantic-subset.jsのようなファイル名で保存する。
semantic-subset.jsからコメント,改行,タブ,余計な空白を除去してsemantic-subset.min.jsを出力する。
必要に応じてsemantic-subset.min.jsをBrotli圧縮またはGzip圧縮する。(ウェブサーバが静的Brotli/Gzip圧縮対応の場合) HTMLファイルのHTMLヘッダのJavascriptファイルのpath+ファイル名を変更する。WordPressならテーマのディレクトリにあるheader.phpと必要に応じてfunctions.phpでファイルの指定を変更する。

これで、ファイルサイズ自体が大幅に小さくなる。 変更前のsemantic.jsは737KB。余計な空白・コメント・改行の無いsemantic.min.jsが275KB。
semantic.jsからSemantic UIのサイドバー機能のコードだけをまるごと抜き出したファイルサイズは約34KB。余計な空白・コメント・改行の無くしたsemantic-subset.min.jsが13KB。ファイルサイズでは約5%になった。
この小さくなったファイルの内、ページ表示時に使うコードは8.5%で91.5%が無駄なコードとして指摘される。サイドバーのオープン・クローズを実行した場合、使用コードが80.1%になり未使用コードが19.9%になる。結構使われるのよね。
でも、正直なところ、サイドバーのスライドによるオープン・クローズ程度なら1KBも要らないので自分で作っちゃった方が圧倒的にコンパクトな筈。

使用していないCSSを削除してください 9
CSSとJavascriptのダイエットが完了したのでもう一度PageSpeed Insightsで計測してみた。ダイエット前のスコアが52で、ダイエット後が64なのでスコアが12上昇したことになる。また、「使用していない CSS を削除してください」の指摘は無くなり、「使用していない JavaScript の削除」の指摘対象からは今回スリムになったsemantic-subset.min.jsは消えている。しかし、残り3つの指摘されているファイルがあるので、これもなんらかの対応が必用。

ちなみに、他に指摘されている改善可能な項目は「適切なサイズの画像」「次世代フォーマットでの画像の配信」「効率的な画像フォーマット」。
「適切なサイズの画像」はモバイル端末には画面サイズに合わせて小さい画像を出せというやつ。pictureタグを使えば指摘されない。WordPressのブログ等ではメディアの扱いをWordPressまかせにしていれば指摘されない部分。
ただし、素のWordPressでは次世代フォーマットの画像を扱えないので「次世代フォーマットでの画像の配信」で指摘を食らう。
「がとらぼ」では画像をWordPressまかせでなく独自管理にしていてimgタグを使っている。画像を複数サイズ用意するのが面倒なのでpictureタグは使っていない。その代わり基本出力が次世代フォーマット画像のWebP。WebP非対応ブラウザにはJpegかPNGを送る。これはNginxまかせ。
基本がWebPなら「次世代フォーマットでの画像の配信」の指摘は喰らわない筈なのに指摘されてるのはAliExpressの商品画像のせい。これは手出しできない他所のウェブサイトなのでどうしようもない。「効率的な画像フォーマット」もAliExpressの同じ画像が指摘を受けている。迷惑な話。

針金4箇所曲げるだけの高利得な謎アンテナを建ててみた

針金4箇所曲げるだけの高利得な謎アンテナを作る」の続き。
待ちに待ったSMA端子が届いたのでアンテナを一気に作り上げた。(先週のことね)

謎アンテナを建ててみた 1
今度は騙されて買ったカラー針金じゃなくて本当の銅線をSMA端子につないで、この銅線をアンテナのU字の部分に接触させることにした。ところが、これは意外とダメだった。前回と同じく特性が全く落ち着かない。しっかりした力で1周巻き付けたので接触が悪いとかではなさそう。ハンダも使ってみたが変わらず。思いついたいろんな方法で固定しようと試みたがダメだった。

その後、アンテナの特性が落ち着かないのは前回使った連結パーツのせいっぽいことが判明。(写真の白いやつ)

謎アンテナを建ててみた 2
結局、こうなった。
連結パーツはアンテナ本体には使わずにアンテナの支柱2本を接続する用にした。この支柱は園芸用のもので、グラスファイバーに青い樹脂をコーティングしたもの。アンテナとの接触部はこの青い樹脂を剥がしてグラスファイバーに直接触れるようにした。グラスファイバーは一応絶縁なのでこれで特性が安定するようになった。固定に使ったのは細いタイバンド4本。SMA端子からアンテナ本体の接続(給電部)は家庭用の電源ケーブルを使った。並行フィーダを使うより更に悪いとは思うけど、なぜかこの方が安定したので採用。給電部、アンテナの上側(写真では右側)の方が150mmエレメントから少し遠く、アンテナ下側(写真では左側)の方が150mmエレメントに少しだけ近め。この下側の接続部は写真の位置よりも150mmエレメントから離そうとすると一気に全く別の特性を示すようになる。理由は不明。なので、調整はこの下側の接続部を先に固定して、上側の接続部をズラす方法で行った。

謎アンテナを建ててみた 3
防水は、SMA端子周辺を熱収縮チューブと自己融着テープ+ビニールテープ、給電部は自己融着テープ+ビニールテープにし、アンテナ本体のアルミ棒自体はむき出しとした。

謎アンテナを建ててみた 4
屋根の上に上げてみた。アルミ棒のアンテナ本体は一番上。(写真では黒い線みたいに見えてる)
そのアンテナ本体を支えているのは塩ビパイプ。塩ビパイプの上の方にある太い筒はLNAとバンドパスフィルタとUSBのRTL-SDRのチューナー本体が入っている。
太い筒の下側から出たケーブルが太い筒の上側にひっかかった状態だが、アンテナを建てたときに肉眼では気付かず、帰ってから写真を見てひっかかりに気付いた。(眼が悪いので2階の屋根の高さは見えないのよね)
ところで、そもそもアンテナのマストが塩ビパイプというのが大失敗。大して強くない風でもビョンビョン揺れる。すぐには無理だが金属製のパイプに交換して揺れを抑えるつもり。ケーブルのひっかかりもそのときに直せば良いかなと。

アンテナを上げる直前、測定はアンテナとバンドパスフィルタ+LNA直前の間のコネクタ。アンテナ製作時に付けたSMA端子から測定ポイントまでは約51cmのRG59ケーブルで、このケーブルを測定したところ直近でインピーダンスが下がるのは1075MHz付近。1090MHzからは僅かにズレているけど、まぁいいかな。(以下2枚)

謎アンテナを建ててみた 5
590〜1590MHzという広い範囲で見た特性。右のグラフの青い線がSWR、赤い線がインピーダンスの抵抗成分(だよね?)。NanoVNA V2を使って1000MHzの広い範囲を100箇所の測定なので1090MHzジャストの周波数は見れなくて、画像では少しズレた1095MHzにマーカーがある。
その1095MHzではインピーダンス50Ω、SWR1.13。

謎アンテナを建ててみた 6
範囲を狭めて940〜1140MHz。1090MHzは中央ではなく右に近い方(マーカーの場所)
1090MHzのインピーダンスは50.9Ω、SWRは1.03。以前のような測定無しで作った「なんちゃってアンテナ」だとこうはいかない。ただ、使いたい周波数でSWRが低いから本当に良いアンテナなのかは?わからないよね。

謎アンテナを建ててみた LNA + BPF
そして、今回はLNAとバンドパスフィルタも新しいものなので楽しみなような心配のタネであるような。
写真の左がLNA、右がバンドパスフィルタ、奥側がLNAに150mAに絞って提供するための定電流ダイオードとACアダプタを挿すためのソケット(前回の写真を流用)
使ってみたところ、動作自体は正常。LNAの写真には増益40dBと書かれているのが写っているが1090MHz付近だと30dB程度。これが大きすぎるのか、ADS-Bでは300〜100kmほどの遠くの航空機を良く捉える反面、50km以内の近いのが消える傾向。近くの強い信号が壊れる?アンテナが良好ならLNAは無しか増益10dB程度の方が良いのかな?

謎アンテナを建ててみた 7
アンテナ設置後から18時間ほどで新しく取得し直したカバレッジ。地図の同心円の中心は白塗りにしている。
しばらく使っていた「なんちゃって同軸コリニアアンテナ」ときのカバレッジとあまり変わらない。なぜなら、アンテナがある実家周辺の地形から「期待される見晴らし」的にこれが限界だから。ただし、前回のアンテナのときに3日ほど待ってようやく得られたカバレッジの形を新しいアンテナとLNA+BPFでは数時間で得ている。ここでも遠くを捉えるのが得意という性質が反映されたと思われる。 しかし、近くの航空機の信号が壊れる?からなのか北北東、南東、西の3方向が全然埋まらない。この方向は地形的に遠くの航空機を捉えるのが無理なので近くを航空機が飛んでくれないとカバレッジのエリアとしては埋まらないのだが、近くを飛んでも信号が(壊れて)受け取れないといつまでも埋まらない。