アナログツールとして非常に気に入ってしまった情報カード。それをもっと効率的に使おうということで手に入れたのがこちらです。
B6用クリップボード

取り寄せたのはB6のクリップボード。

情報カードは元々B6サイズに規格化されているため、サイズは完璧です。
収納

既にある布のケースにもしっかりフィットしました。

壁に掛けるリングにキーリングを着けることで、さらに取り出しやすくしています。
「既存のもので改良する余地がある」のは、規格化された文具の利点で美点です。
アナログツールとして非常に気に入ってしまった情報カード。それをもっと効率的に使おうということで手に入れたのがこちらです。

取り寄せたのはB6のクリップボード。

情報カードは元々B6サイズに規格化されているため、サイズは完璧です。

既にある布のケースにもしっかりフィットしました。

壁に掛けるリングにキーリングを着けることで、さらに取り出しやすくしています。
「既存のもので改良する余地がある」のは、規格化された文具の利点で美点です。
この合わせ技によって、効率的な記入ができるようになります。
など、書くフォーマットが決まっている文書はかなりあります。そのテンプレートの使い方が以下の通り。


一度保存してしまえば、どのブックのどのページでも参照できます。
非常に便利な機能ですが、一般公開しているURLに設定していると、このテンプレートが閲覧されます。
そこで使うのが「権限設定」です。

権限を設定します。(以下、設定例)
設定後、保存をします。

ブラウザのゲスト機能などを用いて、ログインしていない状態で、先ほど権限を設定したURLにアクセスします。

閲覧できないことを確認します。
これで、管理者だけがテンプレートを参照できる環境ができます。
BookStackをより安全に運用するため、別パーティションに格納します。
以前やったこの手法がそのまま使えました。
sudo mkdir -p /path/to/directory/bookstack/images
# 適切なパーティション内のディレクトリを指定します。
# 筆者環境: /mnt/wasabi/bookstack/images
sudo chown -R www-data:www-data /path/to/directory/bookstack/images
cd /home/www-data/bookstack/public/uploads/images && pwd
# 格納ディレクトリに移動します。(自分の環境に合わせます。
sudo cp -pir ./* /path/to/directory/bookstack/images
# 筆者環境:
# sudo cp -pir ./* /mnt/wasabi/bookstack/images/
ls -la /path/to/directory/bookstack/images
cd /home/www-data/bookstack/public/uploads
ls -lad images
# imagesディレクトリがあることを確認
sudo mv images images_org
ls -lad images
# imagesディレクトリがないこと(エラー)を確認
sudo -u www-data ln -s /path/to/directory/bookstack/images images
# 筆者環境
# sudo -u www-data ln -s /mnt/wasabi/bookstack/images images
ls -la images
# 別パーティションに作成したフォルダに向き先があることを確認します
sudo systemctl restart apache2.service
# 念のためWebサービスを再起動します。
幸いなことに、既に構築しているサービスと連携させることができました。
それを更に発展させます。
BookStackにあるヘッダーを用いて以下を行います。
BookStackに管理者権限でログインします。
設定>カスタマイズ>カスタムheadタグに進みます。

以下のコードを入れます。
<style>
body {
--font-body: 'TakaoPGothic', Regular;
--font-heading: 'TakaoPGothic', sans-serif;
--font-code: 'TakaoPGothic', monospace;
}
</style>
※この操作は、別にMatomoトラッキングシステムを運用していることが前提です。※
上記の</stile>に続けて、以下のようなコードを入れます。
<!-- Matomo -->
<script>
<!-- Matomoシステムで提示されたトラッキングコードを貼り付け -->
</script>
<!-- End Matomo Code -->
以下を確認します。
日本語フォントは表示されましたが、PDFがうまくエクスポートできません。(htmlやMarkdown形式のエクスポートは可能)
これを修正しつつ、コンテンツを増やしていきます。
BookStackの構築がうまくいき、「これは使えそうだ」と思ったので、AWS Ligtsail上に構築しました。
上述した通りです。
https://barrel.reisalin.com/books/bookstack/page/bookstack
/etc/logrotate.d/bookstackに
/var/log/bookstack/*.log {
daily
missingok
ifempty
copytruncate
rotate 10
compress
create 0640 www-data www-data
}
を作成しました。
既に動いているので使わない手はありません。
https://barrel.reisalin.com/books/bookstack/page/bookstackmod-security
で連携させました。
既に「BarrelGazer」というサイト名をつけたので、それっぽいロゴやバナーをAIに描写してもらいました。



Scrapboxのように階層で区別できる上に「本棚」というイメージがお気に入りです。
しかも、描写が速いのが特徴。あとはMarkdownの自動補完があれば言うことなしですが、そこはローカルで動かしているGrowi環境との連携です。
Redmineのプラグイン、knowledgebaseのようなWiki編集/公開システム「BookStack」を検証機に入れてみます。
こちらが既に動いています。
また、このサイト用のドメインを有しており、ドメインに即した証明書も発行済みです。
cd /hoge
# 任意の作業ディレクトリに移動します
sudo php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
sudo php composer-setup.php
sudo php -r "unlink('composer-setup.php');"
sudo php composer.phar install --no-dev --optimize-autoloader
composer --version
# バージョンが表示されることを確認します。
mysql -u root -p
CREATE DATABASE bookstack;
CREATE USER 'bookstackuser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON bookstack.* TO 'bookstackuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
DB名/パスワードはポリシーに応じて適切なものを指定します。
cd /home/www-data
# パーティションの都合上、/home/www-dataに置いています。
# 環境に合わせて適切なWebサービス公開ディレクトリを指定してください。
sudo git clone https://github.com/BookStackApp/BookStack.git --branch release --single-branch
sudo chown -R www-data:www-data BookStack
cd BookStack
sudo cp -pi .env.example .env
教義・信仰に沿ったエディタで以下を編集します。
APP_URL=https://hoge.example.com
# 公開用URLを指定します
# Database details
DB_HOST=localhost
DB_DATABASE=bookstack
DB_USERNAME=bookstackuser
DB_PASSWORD=password
# DB名、パスワードなどは先ほど作成したものです。
sudo php artisan key:generate
sudo php artisan migrate --force
sudo php artisan db:seed --force
/etc/apache2/sites-available/bookstack.conf
<VirtualHost *:80>
servername hoge.example.com
# ドメイン名を指定します
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# HTTPアクセスを強制的にHTTPSにリダイレクトします
</VirtualHost>
<VirtualHost *:443>
ServerName hoge.example.com
# ドメイン名を指定します
CustomLog /var/log/bookstack/bs_access.log combined
ErrorLog /var/log/bookstack/bs_error.log
DocumentRoot /home/www-data/BookStack/public
# 自身の環境に合わせます
<Directory /home/www-data/BookStack/public>
# 自身の環境に合わせます
AllowOverride All
Require all granted
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</Directory>
#SSL設定
SSLEngine on
Protocols h2 http/1.1
# SSLを有効化します
SSLCertificateFile /etc/certs/example.com.crt
# SSL証明書を指定します
SSLCertificateKeyFile /etc/private/example.com.key
# 秘密鍵を指定します
# SSLCACertificateFile /etc/certs/example.com.CA.crt
# 中間証明書が発行元から別ファイルで提供されている場合は、この直上をコメントアウトして中間証明書を指定します
#セキュリティヘッダー付与
Header always set Strict-Transport-Security "max-age=63072000"
Header set X-Content-Type-Options "nosniff"
Header always append X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
</VirtualHost>
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:EC6-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
sudo a2ensite bookstack.conf
sudo apache2ctl configtest
# Syntax OKを確認します
sudo systemctl restart apache2.service
https://設定したドメイン
でアクセスします。
以下のログイン画面が出れば成功です。

が初期パスワードです。ログイン後、直ちにアカウント情報を設定してください。
等を行っていきます。
先だってChatGPTが書いた
このスクリプト、Bingが書くとどうなるかを試してみました。
#!/bin/bash
# ループフラグを設定
loop=true
# ループ開始
while $loop; do
# IPアドレスを尋ねる
echo "ブロックしたいIPアドレスを入力してください。"
read ip
# IPアドレスの形式をチェック
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
# IPアドレスそのままか、/24ごとブロックするか、/16ごとブロックするかを0~2で質問
# 空エンターは0
echo "IPアドレスをそのままブロックする場合は0、/24ごとブロックする場合は1、/16ごとブロックする場合は2を入力してください。"
echo "何も入力しない場合は0とみなします。"
read option
# オプションに応じてIPアドレスを変換
case $option in
1)
# /24ごとブロックする場合
ip=${ip%.*}.0/24
;;
2)
# /16ごとブロックする場合
ip=${ip%.*.*}.0.0/16
;;
*)
# その他の場合はIPアドレスそのまま
;;
esac
# 実行前に内容を確認する。yなら続行、nなら中止
echo "ufw deny from $ip to any を実行します。よろしいですか? (y/n)"
read confirm
if [[ $confirm == [yY] ]]; then
# yならufw deny処理を行う
sudo ufw deny from $ip to any
echo "ルールを付け加えました。"
else
# nなら中止メッセージを出す
echo "処理を中止しました。"
fi
# 「ルールを付け加えました。他のIPブロックしますか?」の分岐を出す。yなら1に戻る。nなら次の処理
echo "他のIPをブロックしますか? (y/n)"
read loop
if [[ $loop == [yY] ]]; then
# yならループフラグをtrueにして1に戻る
loop=true
else
# nならループフラグをfalseにしてループを抜ける
loop=false
fi
else
# IPアドレスの形式が不正な場合はエラーメッセージを出す
echo "正しいIPアドレスを入力してください。"
fi
done
# ufw reloadを行う
echo "ufw reload を実行します。"
sudo ufw reload
# 現在のブロック状況を出しますか? yならufw status numberedを表示。nなら終了メッセージを出す
echo "現在のブロック状況を表示しますか? (y/n)"
read status
if [[ $status == [yY] ]]; then
# yならufw status numberedを表示する
sudo ufw status numbered
else
# nなら終了メッセージを出す
echo "スクリプトが終了しました。"
fi
Bingはネットワークアドレスの切り出しが素直です。
# オプションに応じてIPアドレスを変換
case $option in
1)
# /24ごとブロックする場合
ip=${ip%.*}.0/24
;;
2)
# /16ごとブロックする場合
ip=${ip%.*.*}.0.0/16
;;
*)
# その他の場合はIPアドレスそのまま
;;
esac
# ネットワークアドレスに変換
if [[ -n "$block_cidr" ]]; then
if [[ $block_option == "1" ]]; then
# /24で区切る場合
network_address=$(echo $ip_address | cut -d'.' -f1-3)
# CIDR表記の生成 (/24)
cidr_notation="$network_address.0$block_cidr"
elif [[ $block_option == "2" ]]; then
# /16で区切る場合
network_address=$(echo $ip_address | cut -d'.' -f1-2)
# CIDR表記の生成 (/16)
cidr_notation="$network_address.0.0$block_cidr"
fi
else
cidr_notation="$ip_address"
fi
と、シンプルになっています。
蛇足ですが、ChatGPTはこの処理にたどり着くまで5回ぐらいの錯誤を繰り返しました。
なので、このケースで言えばBingはよりユーザーの意図をくみ取ったと考えられます。
こちらの選択肢もあると分かったという収穫。
不正アクセス対策として役立つUFW。これによる不審なIPアドレスの遮断をもっと効率的に行うようにしてみました。
攻撃者は複数のIPアドレスから同時に不正アクセスをしてくるパターンが多々あり、
ufw deny from xxx.yyy.1.1
ufw deny from aaa.bbb.0.2
とやるより、
ufw deny from xxx.yyy.1.0/24
ufw deny from aaa.bbb.0.0/16
と、ネットワークアドレスごと遮断した方が効率的だからです。
#!/bin/bash
# ユーザーからIPアドレスとブロック範囲を入力してもらい、
# UFWを使用して指定した範囲のIPアドレスをブロックするスクリプトです。
while true; do
# IPアドレスを尋ねる
read -p "ブロックしたいIPアドレスを入力してください: " ip_address
# ブロック範囲を尋ねる
read -p "IPアドレスをそのままブロックする場合は0、/24ごとにブロックする場合は1、/16ごとにブロックする場合は2を入力してください(空エンターは0): " block_option
# 入力が空の場合はデフォルトで0(IPアドレスそのまま)とする
block_option=${block_option:-0}
# ブロック範囲を計算
case $block_option in
1) block_cidr="/24" ;;
2) block_cidr="/16" ;;
*) block_cidr="" ;;
esac
# ネットワークアドレスに変換
if [[ -n "$block_cidr" ]]; then
if [[ $block_option == "1" ]]; then
# /24で区切る場合
network_address=$(echo $ip_address | cut -d'.' -f1-3)
cidr_notation="$network_address.0$block_cidr"
elif [[ $block_option == "2" ]]; then
# /16で区切る場合
network_address=$(echo $ip_address | cut -d'.' -f1-2)
cidr_notation="$network_address.0.0$block_cidr"
fi
else
cidr_notation="$ip_address"
fi
# 設定内容を確認する
echo "以下の内容でブロックを行います:"
echo "IPアドレス: $cidr_notation"
read -p "よろしいですか?(y/n): " confirm
# ユーザーが処理を続行しない場合、スクリプトを終了する
if [[ $confirm != "y" && $confirm != "Y" ]]; then
echo "処理を中止しました。"
exit 0
fi
# ブロックルールをufwに追加
sudo ufw deny from "$cidr_notation"
# エラーがあった場合はエラーメッセージを表示して終了
if [[ $? -ne 0 ]]; then
echo "ERROR: 不正なソースアドレス"
exit 1
fi
echo "ルールを付け加えました。"
# 他のIPをブロックするか尋ねる
read -p "他のIPをブロックしますか?(y/n): " continue_blocking
if [[ $continue_blocking != "y" && $continue_blocking != "Y" ]]; then
break
fi
done
# ufwを再読み込みする
sudo ufw reload
# ブロック状況を確認するか尋ねる
read -p "現在のブロック状況を確認しますか?(y/n): " check_status
if [[ $check_status == "y" || $check_status == "Y" ]]; then
sudo ufw status numbered
fi
# 終了メッセージを出す
echo "IPブロックを終了しました。"
このスクリプトを
chmod +x ufw_deny.sh
とすれば作成は完了です。
./ufw_deny.sh
ブロックしたいIPアドレスを入力してください:
# IPアドレスを入力します
IPアドレスをそのままブロックする場合は0、/24ごとにブロックする場合は1、/16ごとにブロックする場合は2を入力してください(空エンター
は0):
# IPアドレスのレンジを
# IPアドレスそのまま:0
# /24(255.255.255.0)で区切る:1
# /16(255.255.0.0)で区切る:2
IPアドレス:
よろしいですか? (y/n):
# 先ほどのIPを表示します。ネットワークアドレスの場合は、/24 /16で区切って表示します。
# 内容を確認します。
# y を入力後、ufwの処理が走ります。一般ユーザーの場合はsudoパスワードが訊かれます。
ルールを追加しました
ルールを付け加えました。
# ufw deny from (入力したIP/NWアドレス)を実行します。
他のIPをブロックしますか?(y/n):
# 続行するかを訊きます。yの場合はIPアドレスから始まります。
ファイアウォールを再読込しました
現在のブロック状況を確認しますか?(y/n):
# yの場合は sudo ufw status numberedを実行します。
と、
まで一元管理してくれます。
机の上での参照がしやすくなりました。

「何かに使えそうだ」と過去に購入していたアイアンメモスタンドが、本来の使われ方をすることになりました。

単にマグネットで止めるだけです。
このマグネットはマーカーも兼ねていますので、ToDoの記録なんかにももってこい。
また、質量がそれなりにあるので散らばったり机から落ちるということもありません。
この記事の続きです。
シェルスクリプトによって、スペースで区切られただけのIPアドレスをリスト化することに成功したので、
192.168.1.2
192.168.1.3
172.28.1.3
172.28.1.5
...
といったIPアドレスのリストを
2, 192.168.1.0/24
2, 172.28.1.0/24
というように、/24で区切ったアドレス帯と件数を表示するスクリプトをchatGPTに作成いただきました。
#!/bin/bash
# ファイルのパスを引数として受け取る
file_path=$1
# ファイルが存在するかを確認する
if [ ! -f "$file_path" ]; then
echo "指定されたファイルが見つかりません。"
exit 1
fi
# ネットワークアドレスごとにIP数をカウントして表示
awk -F. '{print $1"."$2"."$3".0"}' $file_path | sort | uniq -c | while read count address; do
echo "$count, $address/24"
done
あとは実行権を付与します。
./network-address-count.sh /path/to/log/file
# 上述のリンク先でのログファイルを指定します。
2, 71.6.146.0/24
1, 71.6.158.0/24
1, 71.6.199.0/24
11, 71.6.232.0/24
のように、攻撃をしてきたIPアドレスをネットワークアドレスごとにカウントすることができました。
これは、今後の防御手段をしる手段として有効です。
Powered by WordPress & Theme by Anders Norén