年越しに際し――

2年ぐらい前に作った南ことりの前身というべきモデルです。




樹脂の形成だけで顔の表情を作る技術は凄まじく。








デカール貼りに手間取りましたけれど、組み上げていくたびに「見慣れた姿」が浮かび上がってきます。




そして完成。このモデルが真価を発揮するのは光を当てたとき。
これにより、光沢感のある素材がより際立ちます。




当初の期待以上に撮影の被写体になりそうなモデルでした。
AW Lightsailのインスタンスをまるごとコピーすることでバックアップと復元を行います。
https://lightsail.aws.amazon.com/ls/webapp/home/instances


スナップショットをクリックします。

手動スナップショットの「+スナップショットの作成」をクリックします。

任意の名前をつけて「作成」をクリックします。

作成が完了するまで待ちます。(なお、10 USD/月のインスタンスのスペックだと最初に10~15分ほどかかりました

日付、時間、スナップショットの名前が表示されれば作成完了です。
https://lightsail.aws.amazon.com/ls/webapp/home/instances

作成済みのスナップショットの左の矢印をたどっていき、右メニューから「新規インスタンスの作成」をクリックします。

通常ならここで大丈夫だと思うのですが
CreateInstancesFromSnapshot[ap-northeast-1] Sorry, you've reached your maximum limit of Lightsail Instances : 2.
と出ました。
https://lightsail.aws.amazon.com/ls/webapp/home/instances

スナップショットをクリックします。
作成済みのスナップショットの左の矢印をたどっていき、右メニューから「別リージョンへのコピー」をクリックします。

全て設定したら「スナップショットのコピー」をクリックします。

インスタンスが別リージョン(東京→ロンドン)にコピーされたことを確認します。

Lightsail管理画面 → スナップショット → バックアップしたスナップショット→新規インスタンスの作成をクリックします。
同一リージョンからのリカバリならネットワークの割当先を変えるだけですみますが、別リージョンは当然IPアドレスのレンジが異なるので、DNSの差し替えも必要になります。
https://lightsail.aws.amazon.com/ls/webapp/home/instances

ネットワーキングをクリックします。

「静的IPをアタッチする」をクリックします。

任意の名前をつけて「作成およびアタッチ」をクリックします。
DNSを変更します。
前提
ここでは、LightSailのDNSを用いてのDNSでの手順です。他のDNSサービスを利用している場合はそれに準じてください。
https://lightsail.aws.amazon.com/ls/webapp/home/instances
※ 検証環境として立ち上げる場合は、DNSレコードの追加を行ってください。
ドメインとDNSをクリックします。

割り当てをクリックします。

ドメイン名を選択し、バックアップしていたドメインを入れます。
入力後、「割り当てる」をクリックします。
割り当て後、「バックアップ時のIPとリカバリ後のIPアドレス」2つがDNSに割り当てられてしまいます。これを解消します。
管理画面 → ドメインとDNS → 対象ドメイン → DNSレコードに進みます。

複数あるうち、「バックアップ時のDNSレコード(前のDNSレコード)」を削除します。
→ 新しいIPのみがある状態にします
nslookup 設定したドメイン
SSHターミナルクライアントからログインします。
(ネットワーク情報が変わるので鍵の差し替えなどが発生しますのでそれに従います)
正常にログインできることを確認します。
気がつけば大晦日。今年の個人的な出来事を軽く振り返ってみます。
これにつきます。元々は正月休みに軽く読んでみた『Redmineで始める異世界人心掌握術』を楽しく読むことができ、仕事でなんとなく使っていたredmineに可能性を見たことでした。
ここから
と、「redmineと戯れた」一年でした。このツール、個人利用だけでもとても使い出があります。後述した療養生活でも体調を記録するために役立ちました。
こちらもまた特筆すべきことです。検査→陽性確定→療養は気が気でありませんでした。これが徒となって
憂き目に遭います。軽症で済んだことと、家族や職場のサポートに感謝しました。
願わくば、2023年がよき年であるように。
AWSはメジャーなサービスのため、ここで使われているIPアドレスは攻撃のリスクがとても高くなります。
ここでSSH権限を乗っ取ろうとする攻撃に備え、Fail2Banを導入しました。
様々なログファイルを読み込み、何度もアクセスを繰り返すようなアクセス元を遮断するプログラムです。
参考:
https://www.kkaneko.jp/tools/server/fail2ban.html
aptitude update
aptitude install fail2ban
wget https://raw.githubusercontent.com/mitchellkrogza/Fail2Ban-Blacklist-JAIL-for-Repeat-Offenders-with-Perma-Extended-Banning/master/filter.d/blacklist.conf -O /etc/fail2ban/filter.d/blacklist.conf
wget https://raw.githubusercontent.com/mitchellkrogza/Fail2Ban-Blacklist-JAIL-for-Repeat-Offenders-with-Perma-Extended-Banning/master/action.d/blacklist.conf -O /etc/fail2ban/action.d/blacklist.conf
systemctl restart fail2ban
systemctl status fail2ban
# active (running) を確認します
mv /etc/logrotate.d/fail2ban /backup/directory/path/fail2ban.bak
vi /etc/logrotate.d/fail2ban
/var/log/fail2ban.log {
monthly
rotate 13
compress
delaycompress
missingok
notifempty
postrotate
fail2ban-client flushlogs 1>/dev/null
endscript
create 640 root adm
}
fail2ban-client reload
# OKを確認します
fail2ban-client status sshd
#以下のように表示されました
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
systemctl enable fail2ban
# 自動起動を行います
vi /etc/fail2ban/jail.local
[DEFAULT]
port = 0:65535
filter = %(__name__)s
[blacklist]
enabled = true
logpath = /var/log/fail2ban.*
filter = blacklist
banaction = blacklist
action = %(action_)s
bantime = 31536000 ; 1 year
findtime = 31536000 ; 1 year
maxretry = 10
touch /etc/fail2ban/ip.blacklist
chmod 775 /etc/fail2ban/ip.blacklist
systemctl restart fail2ban
fail2ban-client reload
systemctl restart sshd
systemctl enable fail2ban
cat /var/log/fail2ban.log
cat /etc/fail2ban/ip.blacklist
AWSで運用しているだけあって、かなりのログが引っかかっています。
定額でAWSのインスタンスを利用できるLightsail。
Ubuntu系OSを利用できるものの、2022年12月時点ではUbuntu22.04に対応していません。
20.04は選べますので、
方法を紹介します。
結論を言うと、Ubuntu 22.04にアップグレードするとLigtsailの管理画面から直接SSHすることはできません。
(SSH-1アルゴリズムによるRSA認証が無効化されます)
つまり、 何も設定せずWeb画面のSSH接続で最初にアップグレードをすると、再起動した瞬間にログインできず詰みます。
これに気づかず、アップグレード後に全くログインできずインスタンスを作り直す羽目になりました。以下はメモとして残しておきます。
以下、ある程度の知識がある方ならこの手順を行えば問題ないと思います。
https://lightsail.aws.amazon.com/ls/webapp/home/instances
「インスタンスの作成」をクリックします。
自分は以下のように選択しました。
→設定後、「インスタンスの作成」をクリックします。
→ 作成後、「ネットワーキング」から静的IPを付与します。
→ 必要に応じてDNSを設定し、名前解決できるようにします。
Web画面からログインし、rootに昇格します。
sudo su -
# この時、パスワードは設定されていないのでそのまま昇格できます。
ここから、ローカルのターミナルクライアントから接続できるようにユーザーを作成し、設定します。
ここではhogeとしていますので、任意のユーザーを指定して下さい。
adduser hoge
# パスワードなどを設定します
usermod -G sudo hoge
# ユーザーhogeを管理者グループに入れます
su - hoge
# ユーザーhogeに変われることを確認します
sudo su -
# パスワード入力後にrootに昇格できることを確認します
exit
# ユーザーhogeに戻ります
whoami
# ユーザーhogeであることを確認します
ssh-keygen -t ed25519
# 鍵の格納場所は初期値でいいので空Enter。(/home/hoge/.ssh/
# パスワードを設定します。
cd .ssh
ls -l
# 以下のファイルを確認します
# └id_ed25519
# └id_ed25519.pub
# ※これらのファイルはscp等で自分のクライアントにコピーします
rm id_ed25519
# sshサーバ上でそのまま鍵を作成したので秘密鍵は*クライアントにコピー後*削除します
mv id_ed25519.pub authorized_keys
chmod 600 authorized_keys
# 公開鍵をauthorized_keysに変更し、パーミッションを厳密にします
この後、ローカルにコピーしたid_ed25519をSSHターミナルクライアントに保存して設定し、接続確認を行います。
接続ができたらいよいよUbuntu 20.04→Ubuntu22.04へのアップグレードです。
whoami
#上記、作成したユーザーであることを確認します
sudo su -
# rootに昇格できることを確認します
apt update && apt upgrade && apt autoremove
# パッケージを最新版にして不要パッケージを削除します。途中で不要パッケージを消すかを求められるので[y]で消去します
reboot
# 一度再起動をします
# 再起動後、ログインします
whoami
#上記、作成したユーザーであることを確認します
sudo su -
# rootに昇格できることを確認します
do-release-upgrade
# *ここからの作業は中断せず、一気通貫で行います*
以下、主要な質問事項です。コメント(#の後)に概要を書いています。
Reading cache
Checking package manager
Continue running under SSH?
This session appears to be running under ssh. It is not recommended
to perform a upgrade over ssh currently because in case of failure it
is harder to recover.
If you continue, an additional ssh daemon will be started at port
'1022'.
Do you want to continue?
# SSHのポートを追加するか
# → y
Starting additional sshd
To make recovery in case of failure easier, an additional sshd will
be started on port '1022'. If anything goes wrong with the running
ssh you can still connect to the additional one.
If you run a firewall, you may need to temporarily open this port. As
this is potentially dangerous it's not done automatically. You can
open the port with e.g.:
'iptables -I INPUT -p tcp --dport 1022 -j ACCEPT'
To continue please press [ENTER]
# 設定を変更するか
# → Enter
Do you want to start the upgrade?
4 packages are going to be removed. 85 new packages are going to be
installed. 555 packages are going to be upgraded.
You have to download a total of 247 M. This download will take about
49 seconds with a 40Mbit connection and about 6 minutes with a 5Mbit
connection.
Fetching and installing the upgrade can take several hours. Once the
download has finished, the process cannot be canceled.
Continue [yN] Details [d]
# アップグレード前の最終確認
# → y
There are services installed on your system which need to be restarted when certain libraries, such as libpam, libc, and libssl, are upgraded. Since these restarts may cause interruptions of service for the system, you will x
x normally be prompted on each upgrade for the list of services you wish to restart. You can choose this option to avoid being prompted; instead, all necessary restarts will be done for you automatically so you can avoid being x
x asked questions on each library upgrade. x
x x
x Restart services during package upgrades without asking?
# アップグレード時、各種サービスを再起動前にプロンプトでy/nを確認するか
# → 質問されるのがめんどいので yes
# この間、SSH等の設定変更を行うか訊いてきます。プロンプトの選択を変えずに先に進みました
# keep the local version currently installed
Remove obsolete packages?
# 不要パッケージの削除
# → Yes
System upgrade is complete.
Restart required
To finish the upgrade, a restart is required.
If you select 'y' the system will be restarted.
Continue [yN]
# アップグレード完了後にリブートするか
# → y
こうして、再起動後、無事にアップグレードが完了です。
cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.1 LTS"
以下、速やかに行います。
管理者に昇格できることを確認します。
sudo su -
rootのパスワードを設定します。
passwd root
初期ユーザー(ubuntu)が物理的にログインできないようにします。
cd /home/ubuntu/.ssh
rm authorized_keys
先だって、AWS Lightsail上で2つめのredmineを構築する手順について触れました。
こちらをLet's Encryptで常時SSL化します。
また、管理者権限で実施します。
sudo certbot certonly --manual \
--preferred-challenges dns-01 \
--server https://acme-v02.api.letsencrypt.org/directory \
-m メールアドレス \
-d *.sample.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.
Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y
# IPは記録される旨を訊かれるので了承のためY
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.sample.com with the following value:
「文字列」
# 上記文字列をDNSのテキストレコードに登録します
# 登録後、
# nslookup -type=TXT _acme-challenge.sample.comを入力し、「文字列」が返ってくるまで少し待ちます
Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
# TXTレコードが返ってくるのを確認したらEnter
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/sample.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/sample.com/privkey.pem
Your cert will expire on 2023-03-24. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
cd /SSL一時格納ディレクトリ
cp -pi /etc/letsencrypt/live/sample.com/fullchain.pem ./sample.com.crt.$(date +%Y%m)
cp -pi /etc/letsencrypt/live/sample.com/privkey.pem ./sample.com.key.$(date +%Y%m)
# 一時格納ディレクトリにコピーします
openssl x509 -noout -dates -subject -in ./sample.com.crt.$(date +%Y%m)
# 証明書の発行期限を確認します
openssl x509 -in sample.com.crt.$(date +%Y%m) -noout -modulus | md5sum
openssl rsa -in sample.com.key.$(date +%Y%m) -noout -modulus | md5sum
# 証明書と秘密鍵のハッシュがそれぞれ一致していることを確認します
openssl x509 -issuer_hash -noout -in sample.com.crt.$(date +%Y%m)
sed -n -e'1d' -e'/BEGIN/,$p' sample.com.crt.$(date +%Y%m) | openssl x509 -subject_hash -noout
# 証明書と中間証明書のハッシュがそれぞれ一致していることを確認します
mkdir /etc/certs
cp -pi sample.com.crt.$(date +%Y%m) /etc/certs
# 証明書ディレクトリ
cd /etc/certs
ln -sf sample.com.crt.$(date +%Y%m) sample.com.crt
# Let's Encryptは有効期限が3ヶ月と短いため、メンテナンスしやすいようにリンクを貼り替えるだけで更新できるようにします
ll
# シンボリックリンクが張られていることを確認します
mkdir /etc/private
cp -pi sample.com.key.$(date +%Y%m) /etc/private
# 秘密鍵ディレクトリ
cd /etc/private
ln -sf sample.com.key.$(date +%Y%m) sample.com.key
# Let's Encryptは有効期限が3ヶ月と短いため、メンテナンスしやすいようにリンクを貼り替えるだけで更新できるようにします
ll
# シンボリックリンクが張られていることを確認します
cd /etc/sites-available/redmine2.conf
<VirtualHost *:80>
servername redmine2.sample.com
# 常時SSL化の設定
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName redmine2.sample.com
ErrorLog /var/log/apache2/atlier/redmine2.sample.com_error.log
CustomLog /var/log/apache2/atlier/redmine2.sample.com_access.log combined
Alias /redmine2 /var/lib/redmine2/public
<Location /redmine2>
PassengerBaseURI /redmine2
PassengerAppRoot /var/lib/redmine2
Require all granted
</Location>
#SSL対応
SSLEngine on
Protocols h2 http/1.1
Header always set Strict-Transport-Security "max-age=63072000"
# 先に指定したLet's Encryptの格納先
SSLCertificateFile /etc/certs/sample.com.crt
SSLCertificateKeyFile /etc/private/sample.com.key
# redmine2.sample.comでアクセスしてきた場合、強制的に/redmine2サブディレクトリに遷移します
RewriteEngine On
RewriteCond %{HTTP_HOST} ^redmine2\.sample\.com
RewriteRule ^/$ https://redmine2.sample.com/redmine2/ [R]
</VirtualHost>
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE6-GCM-SHA384
SSLHonorCipherOrder off
SSLSessionTickets off
SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
http://redmine2.sample.com (自分が設定したドメイン名)にアクセスして
を確認します。また、こちらの設定は可能な限りSSLの強度を高めています。
https://www.ssllabs.com/ssltest/analyze.html
こちらの暗号化強度チェックで

A+となっています。(2022年12月現在
redmineはプロジェクトごとに機能の増減やアクセス権を増やせるものの、諸般の事情で「全く別のドメインで新たにredmineを構築する」必要がありました。
以下の手順でうまくいったので、メモとして残します。
rubyのバージョンの関係で4.2系をインストールすることにします。また、既に動いている環境なのでapacheやmysqlの初期設定は行っていません。
次の内容を実施します。
で稼働させます。
現行稼働している時に新しいものを立ち上げる場合は、現行環境のバックアップを取るなどの施策を行ってください。
以下、管理者権限で行います。
mysql -uroot -p
CREATE DATABASE redmine2 character set utf8mb4;
CREATE USER 'redmine2'@'localhost' IDENTIFIED BY 'パスワード';
GRANT ALL ON redmine2.* TO 'redmine2'@'localhost';
flush privileges;
exit
mkdir /var/lib/redmine2
chown -R www-data:www-data /var/lib/redmine2
sudo -u www-data svn co https://svn.redmine.org/redmine/branches/4.2-stable /var/lib/redmine2
cp -pi /var/lib/redmine2/config/database.yml.example /var/lib/redmine2/config/database.yml
vi /var/lib/redmine2/config/database.yml
productionの部分を以下のように変更します。
production:
adapter: mysql2
database: redmine2
host: localhost
username: redmine2
password: "パスワード"
encoding: utf8mb4
cd /var/lib/redmine2
sudo -u www-data bundle install --without development test --path vendor/bundle
sudo -u www-data bundle exec rake generate_secret_token
sudo -u www-data RAILS_ENV=production bundle exec rake db:migrate
sudo -u www-data RAILS_ENV=production REDMINE_LANG=ja bundle exec rake redmine:load_default_data
vi /etc/apache2/sites-available/redmine2.conf
<VirtualHost *:80>
ServerName redmine2.sample.com
Alias /redmine2 /var/lib/redmine2/public
<Location /redmine2>
PassengerBaseURI /redmine2
PassengerAppRoot /var/lib/redmine2
Require all granted
</Location>
ErrorLog /var/log/apache2/redmine2.sample.com_error.log
CustomLog /var/log/apache2/redmine2.sample.com_access.log combined
</VirtualHost>
リダイレクトなどで軽くハマり、この設定に落ち着きました。この後、SSL化の手順を実施します。
a2ensite redmine2.conf
apache2ctl configtest
# Syntax OKを確認します。
systemctl reload apache2.service
http://redmine2.sample.com/redmine2
でログインします。
2022年12月現在、「Mod_Securityが検知したIPアドレスネガティブリストに放り込む」は達成しました。
を把握するため、シェルスクリプトを書きました。(今回で一端終了です)
また、
も想定しています。
cron用に一部手を加えます。
ip_check.sh
#!/bin/bash
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# ログの格納場所に移動
cd /var/lib/redmine/log
# error.logからIPアドレスだけを抜き出します
cat ./error.log | awk 'match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) { print substr($0, RSTART, RLENGTH) }' | sort > ip.`date +%Y%m%d`.csv
listfile="./ip.`date +%Y%m%d`.csv"
# ip.YYYYMMDD.csvファイルがない場合にエラーを返します
if [ ! -f $listfile ]; then
echo "ファイル $listfile が存在しないので終了します。"
exit 1
fi
country_list="./country_list.csv"
# 国コード,国の名前が書かれたcountry_list.csvがない場合にエラーを返します
# このCSVファイルはログの格納場所に配置します
if [ ! -f $country_list ]; then
echo "ファイル $country_list が存在しないので終了します。"
exit 1
fi
# IPアドレスに国名を付与したファイルを定義します。(ip_list.YYYYMMDD.csv)
result_file="./ip_list.`date +%Y%m%d`.csv"
cat /dev/null > $result_file
cat ${listfile} | while read line
do
# IPアドレスを逆順に並び替えます。(例: 1.2.3.4 → 4.3.2.1
ip_revers=`echo ${line}|awk -F'.' '{print $4,".",$3,".",$2,".",$1}'|sed -e 's/ //g'`
# 並び替えたIPアドレスをcc.wariate.jpに並び替えて、国コードを抜き出します。(JP,CH,ESなど
country_code=`nslookup -type=TXT ${ip_revers}.cc.wariate.jp | grep '"'|awk -F'"' '{print $2}' `
# 国コードをcountry_list.csvから参照して国名を抜き出します。
country_name=`cat ${country_list} | grep ${country_code} | cut -d"," -f 2`
# 次の行は標準出力に返す処理を行います。cron処理する場合は#をつけて作動しないようにします。
# echo "${line},${country_name}"
# IPアドレス,国名の形式にして同ディレクトリのip_list.YYYYMMDD.csvに保存します
echo "${line},${country_name}" >> $result_file
sleep 1
done
chown www-data:www-data ip.`date +%Y%m%d`.csv
chown www-data:www-data ip_list.`date +%Y%m%d`.csv
exit
ip_count.sh
#!/bin/bash
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
cd /var/lib/redmine/log
# ip_list.csv.YYYYMMDDを読み込んで、IPアドレスをキー、国を値とする連想配列を作成します
declare -A countries
while read -r line; do
# CSVの1列目をIPアドレス、2列目を国とします
ip=$(echo $line | cut -d',' -f1)
country=$(echo $line | cut -d',' -f2)
# 連想配列に格納します
countries[$ip]=$country
done < ip_list.`date +%Y%m%d`.csv
# 結果を格納するための変数を定義します
result=""
# 連想配列を反復処理します
for ip in "${!countries[@]}"; do
# 各IPアドレスの件数を数えます
count=$(grep -c $ip ip_list.`date +%Y%m%d`.csv)
# 件数、IPアドレス、国をカンマ区切りで結合します
line="$count,$ip,${countries[$ip]}"
# 結果に追加します
result="$result\n$line"
done
# カウントした結果をcounted_ip.YYYYMMDD.csvに出力します
echo -e $result > counted_ip.`date +%Y%m%d`.csv
### ↑ここまでchatGPTが作成したスクリプト↑ ###
# 最終結果をsorted_ip.`date +%Y%m%d`.csvに出力します
# LC_ALL=Cを設定しないと日本語で書かれた国名の並べ替えがうまくいきませんでした
cat counted_ip.`date +%Y%m%d`.csv |LC_ALL=C sort -n -r > sorted_ip.`date +%Y%m%d`.csv
# 最終結果以外のログファイルを削除します
# 必要に応じて無効化してください
rm ip.`date +%Y%m%d`.csv
rm ip_list.`date +%Y%m%d`.csv
rm counted_ip.`date +%Y%m%d`.csv
chown www-data:www-data sorted_ip.`date +%Y%m%d`.csv
exit
sudo crontab -e -u root
0 7 * * * /スクリプト配置パス/ip_check.sh && /スクリプト配置パス/ip_count.sh
これで、指定した時刻に
を行うようにしてくれます。
2022年12月現在、「Mod_Securityが検知したIPアドレスネガティブリストに放り込む」は達成しました。
を把握するため、シェルスクリプトを書きました。(前回はこちらです)
以下の環境です。
前回の「エラーログからIPアドレスのみを抽出し、アクセス元の国を付与する」スクリプトが導入されていることが条件です。
chatGPTの力を借りました。何度か質問を変え、動作確認しつつコマンドを足しています。
vi ip_count.sh
#!/bin/bash
# ip_list.csv.YYYYMMDDを読み込んで、IPアドレスをキー、国を値とする連想配列を作成します
declare -A countries
while read -r line; do
# CSVの1列目をIPアドレス、2列目を国とします
ip=$(echo $line | cut -d',' -f1)
country=$(echo $line | cut -d',' -f2)
# 連想配列に格納します
countries[$ip]=$country
done < ip_list.`date +%Y%m%d`.csv
# 結果を格納するための変数を定義します
result=""
# 連想配列を反復処理します
for ip in "${!countries[@]}"; do
# 各IPアドレスの件数を数えます
count=$(grep -c $ip ip_list.`date +%Y%m%d`.csv)
# 件数、IPアドレス、国をカンマ区切りで結合します
line="$count,$ip,${countries[$ip]}"
# 結果に追加します
result="$result\n$line"
done
# カウントした結果をcounted_ip.YYYYMMDD.csvに出力します
echo -e $result > counted_ip.`date +%Y%m%d`.csv
### ↑ここまでchatGPTが作成したスクリプト↑ ###
# 最終結果をsorted_ip.`date +%Y%m%d`.csvに出力します
# LC_ALL=Cを設定しないと日本語で書かれた国名の並べ替えがうまくいきませんでした
cat counted_ip.`date +%Y%m%d`.csv |LC_ALL=C sort -n -r > sorted_ip.`date +%Y%m%d`.csv
# 最終結果以外のログファイルを削除します
# 必要に応じて無効化してください
rm ip.`date +%Y%m%d`.csv
rm ip_list.`date +%Y%m%d`.csv
rm counted_ip.`date +%Y%m%d`.csv
exit
chmod +x ip_count.sh
任意のディレクトリに以下のファイルがあることを確認します。
./ip_count.sh
出力先(上記例ではスクリプトを配置したディレクトリ)に以下のファイルが出力されます。
100, AAA.BBB.CCC.DDD,シンガポール
30, AAA.BBB.CCC.DDD,ベトナム
20,AAA.BBB.CCC.DDD,中国
合間に余計なファイルが含まれるので、ここはもっとスマートに書きたいです。
2022年12月現在、「Mod_Securityが検知したIPアドレスネガティブリストに放り込む」は達成しました。
を把握するため、シェルスクリプトを書きました。
以下の環境です。
which nslookup
# パスがあれば実装されています。
sudo apt-get install dnsutils
以下のスクリプトをベースにしています。
本スクリプトの作成者様と、IPアドレスと国の対応を結びつけるサービスの作成者様にこの場を借りて御礼申し上げます。
以下のようなCSVを作成します。
vi country_list.csv
AC,アセンション島
AD,アンドラ
AE,アラブ首長国連邦
AF,アフガニスタン
AG,アンティグア・バーブーダ
AI,アンギラ
AL,アルバニア
etc...
作成に当たっての参照先:
https://memorva.jp/memo/website/domain_cctld_country_code.php
vi ip_check.sh
#!/bin/sh
# error.logのディレクトリを指定する場合は指定して下さい
# error.logからIPアドレスだけを抜き出して同ディレクトリのip.YYYYMMDD.csvに保存します
cat ./error.log | awk 'match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/) { print substr($0, RSTART, RLENGTH) }' | sort > ip.`date +%Y%m%d`.csv
listfile="./ip.`date +%Y%m%d`.csv"
# ip.YYYYMMDD.csvファイルがない場合にエラーを返します
if [ ! -f $listfile ]; then
echo "ファイル $listfile が存在しないので終了します。"
exit 1
fi
country_list="./country_list.csv"
# 国コード,国の名前が書かれたcountry_list.csvがない場合にエラーを返します
if [ ! -f $country_list ]; then
echo "ファイル $country_list が存在しないので終了します。"
exit 1
fi
# IPアドレスに国名を付与したファイルを定義します。(ip_list.YYYYMMDD.csv)
result_file="./ip_list.`date +%Y%m%d`.csv"
cat /dev/null > $result_file
cat ${listfile} | while read line
do
# IPアドレスを逆順に並び替えます。(例: 1.2.3.4 → 4.3.2.1
ip_revers=`echo ${line}|awk -F'.' '{print $4,".",$3,".",$2,".",$1}'|sed -e 's/ //g'`
# 並び替えたIPアドレスをcc.wariate.jpに並び替えて、国コードを抜き出します。(JP,CH,ESなど
country_code=`nslookup -type=TXT ${ip_revers}.cc.wariate.jp | grep '"'|awk -F'"' '{print $2}' `
# 国コードをcountry_list.csvから参照して国名を抜き出します。
country_name=`cat ${country_list} | grep ${country_code} | cut -d"," -f 2`
# 次の行は標準出力に返す処理を行います。cron処理する場合は#をつけて作動しないようにします。
echo "${line},${country_name}"
# IPアドレス,国名の形式にして同ディレクトリのip_list.YYYYMMDD.csvに保存します
echo "${line},${country_name}" >> $result_file
sleep 1
done
exit
chmod +x ip_check.sh
任意のディレクトリに以下のファイルがあることを確認します。
./ip_check.sh
出力先(上記例ではスクリプトを配置したディレクトリ)に以下のファイルが出力されます。
AAA.BBB.CCC.DDD,シンガポール
AAA.BBB.CCC.DDD,ベトナム
AAA.BBB.CCC.DDD,中国
Powered by WordPress & Theme by Anders Norén