タグ: Ubuntu Page 17 of 22

ChatGPTによるシェルスクリプト。(Ubuntuサーバのパッケージ全体の更新とサービス再起動の有無)

脆弱性などに対応するため、Linuxサーバのパッケージを最新に保つことは重要です。

ですが、どこかでトラブルが発生した際に「どのパッケージを更新してから異常が発生したか」の履歴を追うことも必要。

そこで、以下のシェルスクリプトをChatGPTに尋ねながら作ってみました。

動作確認環境

  • Ubuntu 20.04で動作を確認しました。
  • 筆者の好みの関係上、パッケージ管理はaptitudeを用いています。
  • また、サービス再起動の有無を確認するため、checkrestartをインストールします。(debian-goodiesをインストール)

要件

ChatGPTに要求した要件は以下の通りです。

  • パッケージ一覧のリストを作成する。
  • パッケージ全体のupdateを行う。
  • そのupdateで差異があった場合はファイルに出力して更新を行う。
  • サービス再起動があったらそれを標準出力とファイルに出力する。

かなりの試行を重ねて以下のスクリプトができあがりました。

スクリプト内容

  • update-packages.sh
#!/bin/bash

# インストールされているパッケージの一覧を取得して別ファイルに出力します。
now=$(date +%Y%m%d)
dpkg-query -W > installed_packages_$now.txt

# aptitude updateを行います。
aptitude update

# updateの結果:
if aptitude search '~U' | grep -q '^i'; then
    # 対象パッケージ,変更前バージョン,変更後のバージョン を記入した日付付きのファイルを作成。
    now=$(date +%Y%m%d)
    upgraded_packages=$(mktemp)

    # パッケージのキャッシュをクリアした上でパッケージアップグレードを実施。
    aptitude clean
    aptitude -y full-upgrade | tee $upgraded_packages >/dev/null

    # パッケージ一覧からの差分を別ファイルで作成。(実行日の日付を付与)
    new_packages=$(mktemp)
    dpkg-query -W > $new_packages
    diff -u installed_packages_$now.txt $new_packages > package_diff_$now.txt

    # checkrestartを実行して結果を取得
    now=$(date +%Y%m%d)
    checkrestart_output=$(checkrestart)

    # サービスを再起動する必要のあるプロセスを抽出してファイルに出力
    restart_services=$(echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | awk '{print $NF}' | sort -u)

    if [[ -n "$restart_services" ]]; then
        # ファイル名に日付を追加
        now=$(date +%Y%m%d)
        filename="restart_services_$now.txt"

        echo "以下のサービスを再起動してください:" >> "$filename"
        echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | grep -v "restart$" >> "$filename"
        echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | grep "restart$" >> "$filename"

        echo "以下のサービスを再起動してください:"
        echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | grep -v "restart$"
        echo "$checkrestart_output" | awk '/^(These are the systemd services|These are the initd scripts)/{flag=1;next}/^$/{flag=0}flag' | grep "restart$"


    else
        echo "再起動するサービスはありません"
    fi
fi

記入後、以下を実施します。

sudo chown root:root update-packages.sh
# root権限で実施するため

sudo chmod 744 update-packages.sh

確認結果

sudo bash update-packages.sh

を実行後、

  • 現在インストールされているパッケージのバージョンを別ファイルに出力
  • パッケージのアップデート
  • その際に差分があればアップグレード
  • サービス再起動の有無を判断し、あればそのサービスを表示

という結果が出ました。

今後の展望

  • 可読性を高くする
  • 自動実行を行う
  • ログ化してローテーションを行う

等は実施したいです。

Redmine脆弱性対応。(4.2.x→4.2.10へのバージョンアップ)

これを行うきっかけ

こちらの記事:

https://blog.redmine.jp/articles/redmine-security-scanner/

で運用中のRedmineに既知の脆弱性がないかをチェックできるWebサービスの存在を知ったからでした。

で、現在のRedmineのURLを調べてみたら

E。

何度見てもEです。多少自信はあったので、この結果はその鼻っ柱を打ち砕くものでした。

そこで、現在運用中のRedmineのバージョンアップを図り脆弱性に対応します。

環境

  • Ubuntu 20.04 (AWS Lightsailで稼働中)
  • 動かしていたRedmine:4.2.9
  • Apache 2.4 / mod-passangerでRubyアプリを使用(Ruby 2.7系)
  • MySQL 8.0.3

作業に備えての前提

  • 本手順では「使用するDBの削除」を伴います。作業の際には慎重に行って下さい。
  • Webサービスを止める/何も入っていないRedmineが途中でできるため、ユーザアクセスができない状況が発生します。
  • また、筆者環境はfiles配下をクラウドストレージにマウントしています。手順は自身の環境に合わせてください。

さっくりとした手順

  1. スナップショットのバックアップ
  2. DBのバックアップ
  3. redmineのディレクトリを一度mvでリネームしてバックアップ。
  4. apache停止
  5. redmineのDBを消す。
  6. redmineのDBを新たに作る。(ユーザは全て権限があるので問題なし)
  7. apache再開
  8. ディレクトリを再作成し、新しい空のRedmineを作る。
  9. themesとpluginを再配置。filesのシンボリックリンクを貼り替える。
  10. themesとpluginを再配置した状態でDBマイグレーション。
  11. DBリストア。

データバックアップ

万一に備え、AWSからインスタンスのスナップショットを取得します。

mysqlによるDBバックアップ

mysqldump -h localhost -u redmine -p --no-tablespaces --single-transaction redmine > redmine_backup.$(date +%Y%m%d).sql
# DB名やDBユーザは自信の環境に合わせます

データ退避

cd /var/lib
# Redmineが格納されているディレクトリの親ディレクトリに移動します

ls -ld redmine
# 退避対象のディレクトリがあることを確認します

sudo mv redmine redmine_$(date +%Y%m%d)

ls -ld redmine_$(date +%Y%m%d)

apache停止

ここでWebサービスを停止するのは、DBを削除するためです。

systemctl status apache2.service

sudo systemctl stop apache2.service

systemctl status apache2.service

DB削除

慎重に行って下さい。

sudo mysql -u root -p
show databases;
/* redmineのDBがあることを確認 */

drop database redmine;

show databases;
/* redmineのDBがないことを確認 */

CREATE DATABASE redmine character set utf8mb4;

show databases;
/* redmineのDBがあることを確認 */

exit

Redmine再インストール

ソースダウンロード

sudo mkdir /var/lib/redmine

sudo chown -R www-data:www-data /var/lib/redmine

sudo -u www-data svn co https://svn.redmine.org/redmine/branches/4.2-stable /var/lib/redmine
# 4.2系の最新安定版をダウンロードします

退避させたディレクトリからconfigファイルコピー

sudo cp -pi /var/lib/redmine_$(date +%Y%m%d)/config/database.yml /var/lib/redmine/config/database.yml

cat /var/lib/redmine/config/database.yml
#中身確認

sudo cp -pi /var/lib/redmine_$(date +%Y%m%d)/config/configuration.yml /var/lib/redmine/config/configuration.yml

cat /var/lib/redmine/config/configuration.yml
#中身確認

Redmineインストール

cd /var/lib/redmine

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

apache再開

systemctl status apache2.service

sudo systemctl start apache2.service

systemctl status apache2.service

再開後の仮パスワード作成

対象のRedmineにアクセスします。

IDとパスワードがadmin / admin に戻っている状態のため、仮パスワードを発行します。

退避したディレクトリからデータを再配置

cd /var/lib/redmine_$(date +%Y%m%d)/plugins

sudo cp -pir ./* /var/lib/redmine/plugins/
# プラグイン一式をコピーします

cd /var/lib/redmine_$(date +%Y%m%d)/public/themes

sudo cp -pir ./* /var/lib/redmine/public/themes/
# テーマ一式をコピーします

シンボリックリンク貼り替え

これは筆者の環境が

  • logディレクトリとfilesディレクトリを別の場所にリンクを張っているための措置です。
  • それ以外の場合は上述した /var/lib/redmine_$(date +%Y%m%d)からfilesやlogをコピーして下さい。
cd /var/lib/redmine

sudo rm -rf files

sudo rm -rf log

sudo ln -sf /mnt/wasabi/redmine/files files
# wasabiクラウドストレージを利用しています。

sudo chown -h www-data:www-data files

sudo ln -sf /var/log/redmine log
# ログは/var/log配下で一括管理しています。

sudo chown -h www-data:www-data log

データ再マイグレーション

プラグイン再マイグレーション

cd /var/lib/redmine

sudo -u www-data bundle install

sudo -u www-data bundle exec rake redmine:plugins:migrate RAILS_ENV=production

apacheリスタート

systemctl status apache2.service

sudo systemctl restart apache2.service

systemctl status apache2.service

DBリストア

cd /hoge
# mysqldumpを行ったディレクトリ

mysql -h localhost -u redmine -p redmine < redmine_backup.$(date +%Y%m%d).sql
# パスワードはredmineインストール時に設定したDBユーザのものです

apacheリスタート

systemctl status apache2.service

sudo systemctl restart apache2.service

systemctl status apache2.service

動作確認

この状態でRedmineに管理者権限でログインします。手順通りなら

  • テーマ
  • 添付ファイル
  • プラグイン

などが正常に動いていると思います。

バージョンアップ後の診断

2023/03/18現在のRedmine4.2系の最新安定版:4.2.10がインストールされ、A+ と診断されました。

AWS LightsailからNextcloudをアンインストール。

AWS Lightsailで検証したNextcloudをアンインストールします。

導入していた環境

以下の環境で動かしていたNextcloudをアンインストールします。

  • Ubuntu 20.04
  • Apache 2.4
  • PHP 8.1
  • MySQL 8.0.3

そもそも:なぜアンインストールを行ったか?

スペック不足。

外部公開を目指しAWSのLightsailインスタンスで立ち上げましたが、

  • 表示速度
  • 処理能力

その他が納得いくものではありませんでした。

機能が被っている

  1. タスク管理/文書管理としてRedmine
  2. フォトアルバムとしてPiwigo

をインストールしているため、これらと機能が被るものを同一サーバにインストールするには望ましくありません。

ローカル環境との混同

これが一番の問題でした。ローカル(自宅環境)で既に運用しているNextcloudにはかなりのセンシティブ情報が含まれています。これが外部環境に誤ってアップロードされてしまうのはセキュリティポリシー上問題があると判断。

実施した手順

さっくりとした手順

  1. 本当にアンインストールしていいかいったん深呼吸します。
  2. クライアントからアカウントを削除します。(PCを利用している場合)
  3. バーチャルファイルを無効にします。
  4. DBを削除します。
  5. バーチャルファイルを削除します。
  6. ファイルを削除します。

アンインストールでも残すもの

  • PHPは既に他のサービスで動かしているので残します。
  • MySQL/Apacheについても同様です。

削除対象の確認

  1. 深呼吸する
  2. お茶を入れて飲みながらじっくり考え

削除を決意。

重要なファイルがあるかを確認

もう一度確認します。

PCクライアントから設定削除

WindowsなどでNextcloudのアカウントを設定していたので、こちらを削除します。

バーチャルファイル無効化

  • バーチャルファイル無効化
cd /etc/apache2/sites-available && pwd

sudo a2dissite nextcloud.conf
# 自分が設定した環境に合わせます。
  • 無効化反映
sudo systemctl restart apache2.service

この時点でアクセスできないことを確認です。

DB削除

mysql -u root -p
# mysqlのrootパスワードでログイン
SHOW DATABASES;
/* 削除対象を確認します */

DROP DATABASE nextcloud;
/* DB名を再度確認します */
/* 容赦なく削除されるので慎重に行ってください */

SHOW DATABASES;
/* DBがないことを確認します */

EXIT

プログラム一式を削除

  • nextcloud配置ディレクトリ削除
cd /var/www/html && pwd
# nextcloudが格納しているディレクトリ

ls -ld nextcloud
# ディレクトリがあることを確認します

sudo rm -rf nextcloud

ls -ld nextcloud
# ディレクトリがないことを確認します
  • nextcloudバーチャルファイル削除
cd /etc/apache2/sites-available && pwd
# 対象ディレクトリにいることを確認します

sudo rm nextcloud.conf 

後始末

  • 独自ドメインで運用していたのであれば、Nextcloudのために設定していたDNS情報を削除します。
  • 削除されたことを確認します。

最後に

スペックや機能の面でほぼほぼ「こうなるだろうな」という予感はありました。
ですが、一応、やってみるだけの価値はありました。(ローカル環境と比べ著しく遅いと体感でき、後の未練を断つことができました)

ChatGPTによるシェルスクリプト。(日時を指定してのシャットダウン)

概要

「要件は定義できるけどそれを実行する術を知らない」とき、ChatGPTは非常に有用です。

そこで、以下のスクリプトを書いてもらいました。

ChatGPTへの要件

  • 指定時刻にはLinuxサーバのシャットダウンを行いたい。
  • 検証機なので、副系への切り替えなどは考慮しない。
  • 後々を考えて、スクリプトとして残し、思い立ったときには実行できるようにしたい。

ということで、以下の質問をしました。

計画停電に備え、指定時刻にLinuxサーバのシャットダウンをしたいと思います。
そこで、以下のシェルスクリプトを書いてください。

  1. 対話式で日付(YYYYMMDD)と時刻(HHMM)の入力プロンプトを出す
  2. 形式が違う場合はエラーを出し、再度の入力を求める
  3. 入力後、指定日時を表示しy/nで確認
  4. 受付後、バックグラウンドで常駐
  5. 指定時刻になったらシャットダウンを行う

ChatGPTからの回答

以下が、示したスクリプトです。

  • スクリプト名:shutdown.sh
#!/bin/bash

# 1. 日付と時刻の入力プロンプトを出す
read -p "シャットダウンする日時を指定してください(YYYYMMDD HHMM): " shutdown_time

# 2. 形式が違う場合はエラーを出し、再度の入力を求める
until [[ $shutdown_time =~ ^[0-9]{8}\ [0-9]{4}$ ]]; do
    echo "日付と時刻の形式が正しくありません。再度入力してください。"
    read -p "シャットダウンする日時を指定してください(YYYYMMDD HHMM): " shutdown_time
done

# 3. 入力後、指定日時を表示しy/nで確認
echo "指定された日時は ${shutdown_time:0:4}/${shutdown_time:4:2}/${shutdown_time:6:2} ${shutdown_time:9:2}:${shutdown_time:11:2} です。"
read -p "この日時でシャットダウンを行いますか? (y/n): " confirm

# 4. 受付後、バックグラウンドで常駐
if [[ $confirm =~ ^[Yy]$ ]]; then
    shutdown_sec=$(date -d "${shutdown_time:0:8} ${shutdown_time:9:4}" +%s)
    current_sec=$(date +%s)
    if [[ $shutdown_sec -lt $current_sec ]]; then
        echo "指定された日時は過去のため、シャットダウンは行われません。"
    else
        wait_sec=$(( shutdown_sec - current_sec ))
        echo "シャットダウンまでの待機時間は $wait_sec 秒です。"
        sudo sleep $wait_sec && sudo shutdown -h now &
        echo "シャットダウンを開始しました。"
    fi
else
    echo "シャットダウンを中止しました。"
fi

動作確認

上記スクリプトを対象サーバに保存後、以下の処理を行いました。

sudo chown root:root shutdown.sh
# shutdownコマンドは管理者ユーザのみ実行権限があるので所有者もrootにします

sudo chmod 744 shutdown.sh
# rootのみに実行権限を与えます
sudo bash shutdown.sh

と入力後、想定通りYYYYMMDD形式とHHMM形式で日付と時間を入力するよう求められました。なので、30分後などの日時を指定して実行します。

バックグラウンドで実行されているか、以下を確認しました。

ps aux |grep shutdown

# 下記の表示を確認。
# root      107296  0.0  0.0  10536   280 pts/0    S    14:27   0:00 bash shutdown.sh

その後、実行時間になってシャットダウンを確認。

動作確認日

2023/03/14

Ubuntu 20.04に最新安定版のnodejsのインストール。

ふと思い立ったので、AWS Lightsailで稼働するUbuntuに最新安定版のnodejsを入れてみました。

動作確認環境

  • Ubuntu 20.04

実施した手順

さっくりとした手順

  1. aptitude(apt)を用いてnodejsとnpmをインストールします。
  2. n packageシステムをインストールします。
  3. n packageで最新安定版のnodejsをインストールします。
  4. 最初に入れたnodejsとnpmをアンインストールします。
  5. nodeとnodejsが同じコマンドを参照するようにシンボリックリンクを張ります。

aptitudeによるnodejsとnpmのインストール

パッケージインストール

こちらではaptitudeを用いています。好みなどに合わせてaptに読み替えてください。

sudo aptitude update

sudo aptitude install nodejs

sudo aptitude install npm
# 300近いパッケージが一気にインストールされます

インストール後の確認

nodejs -v
# v10.19.0が表示されることを確認

npm -v
# 6.14.140が表示されることを確認

n packageのインストール

sudo npm install -g n

n packageによる最新版安定版のインストール

sudo n stable

表示確認

node -v
# 18.15.0が表示されることを確認
nodejs -v
# 10.19.0が表示されることを確認

と、両者のバージョンが異なります。aptitude(apt)でインストールしたパッケージが残っているために発生しているようです。

そこで、最初にインストールしたパッケージをアンインストールします。

最初に入れたnodejsとnpmをアンインストール

sudo apt purge nodejs npm

その後、一度シェルから抜けます。

シンボリックリンク実行

再ログイン後、nodejsのパスが通っていませんでした。

which node
# /usr/local/bin/nodeと表示


which nodejs
# 何も表示されず

コマンドが見つからないので、これも修正します。

sudo ln -s /usr/local/bin/node /usr/local/bin/nodejs
node -v
# 18.15.0が表示されることを確認

nodejs -v
# 18.15.0が表示されることを確認

両方で同じバージョンが表示されるようになりました。

動作確認日

2023/03/13

フォトアルバムPiwigoの写真格納ディレクトリをWasabiクラウドストレージに設定。

概要

AWSサーバに設置したフォトアルバムPiwigo。

こちらをWasabiクラウドストレージと連携させます。

動作確認環境

  • Ubuntu 20.04
  • Piwigo 13.6.0
  • Apache 2.4
  • PHP 8.1
  • MySQL 8.0.32

前提

  • Piwigoがインストール済みであること
  • いくつかの写真をアップロード済みであること
  • Wasabiクラウドストレージがs3fsでマウントされていること
  • また、Piwigoのルートディレクトリは /var/www/html/piwigo です。

確認した手順

さっくりとした手順

  1. 写真格納ディレクトリを確認します。
  2. Wasabiのクラウドストレージ(バケット)にアップロード用のディレクトリを作成します。
  3. 既存の写真格納ディレクトリをバケットに移動します。
  4. シンボリックリンクを作成します。
  5. 動作を確認します。

格納ディレクトリの確認

  • findによる確認
find /var/www/html/piwigo/ -type f -name "*.jpg" -print

以下のディレクトリに写真が格納されていました。

  • /var/www/html/piwigo/_data/
  • /var/www/html/piwigo/upload/

クラウドストレージ設定

  • ディレクトリ移動
cd /mnt/wasabi
# s3fsでマウント済みのディレクトリに移動します
  • ディレクトリ作成、所有者変更
sudo mkdir piwigo

sudo chown www-data:www-data piwigo

ls -ld piwigo
# ディレクトリが作られていることと所有者がwww-dataであることを確認します

写真格納ディレクトリをデータごと移動

  • ディレクトリ移動
cd /var/www/html/piwigo && pwd
# piwigoのドキュメントルートに移動します

sudo mv _data /mnt/wasabi/piwigo/

sudo mv upload /mnt/wasabi/piwigo/

sudo chown -R www-data:www-data /mnt/wasabi/piwigo

シンボリックリンク作成

sudo ln -s /mnt/wasabi/piwigo/_data _data

sudo chown -h www-data:www-data _data

sudo ln -s /mnt/wasabi/piwigo/upload upload

sudo chown -h www-data:www-data upload
  • リンク作成確認
ls -ld  /var/www/html/piwigo/_data
ls -ld  /var/www/html/piwigo/upload
# それぞれのリンクがクラウドストレージのバケットであること、リンクの所有者がwww-dataであることを確認します

設定反映、動作確認

  • apacheサービス再起動
sudo systemctl restart apache2.service

systemctl status apache2.service
  • 動作確認

設定したpiwigoのサイトにアクセスします。

  1. ファイルが閲覧できることを確認します。(NW越しにマウントするので時間はそれなりにかかります)
  2. アルバムにファイルをアップロードできることを確認します。
  3. アルバムにアップロードしたファイルが表示されることを確認します。

上記が確認できれば設定完了です。

こうしてできあがったサイトが以下の

https://hideout.reisalin.com/

です。今までに撮りためていた写真をご紹介する機会斗羽がやっとできたという形です。

動作確認日

2023/03/08

UbuntuサーバにフォトアルバムPiwigoインストール。

概要

メインで使っていたフォトアルバムLycheeの代わりにインストールしてみました。

動作確認環境

  • Ubuntu 20.04
  • MySQL 8
  • Apache 2.4
  • PHP 8.1

で動作を確認しています。

前提

上記が運用されていること

  • ドメインで名前解決できること
  • そのドメインに対する適切なSSL証明書が導入されていること

が条件です。

手順

さっくりとした手順

  1. プログラムを配置します。
  2. DBを設定します。
  3. Apache設定ファイルを追記して反映します。
  4. Web画面でインストールを行います。

Piwigo入手

  • 作業用ディレクトリに移動
cd hoge && pwd
  • Piwigoダウンロード
wget https://piwigo.org/download/dlcounter.php?code=latest -O piwigo-latest.zip
# 最新版のダウンロード
  • zip展開
unzip piwigo-latest.zip
  • アクセス権変更
sudo chown -R www-data:www-data piwigo
  • ディレクトリ配置
sudo mv piwigo /var/www/html/
# 運用に合わせて配置ディレクトリを指定してください
ls- ld /var/www/html/piwigo
# ファイルがあること、所有者がwww-dataを確認します

DB設定

mysql -u root -p
CREATE DATABASE piwigo CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'piwigo_user'@'localhost' IDENTIFIED BY 'パスワード';
/* パスワードは任意のものを設定します */
GRANT ALL ON piwigo.* TO 'piwigo_user'@'localhost';
GRANT RELOAD ON *.* TO 'piwigo_user'@'localhost';
/* 後の運用を考えて、dumpが取得できるようにします */
FLUSH PRIVILEGES;
EXIT;

apache設定

バーチャルファイル作成

  • ServerName
  • ドメイン
  • 格納場所(ログ含む)
  • SSL証明書及び秘密鍵格納位置

は自分の環境に合わせてください。

cat <<- __EOF__ | sudo tee -a /etc/apache2/sites-available/piwigo.conf
<VirtualHost _default_:80>
ServerName album.example.com
# 公開するサーバのドメイン名を指定
 RewriteEngine On
        RewriteCond %{HTTPS} off
        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    ServerName album.example.com
    CustomLog /var/log/apache2/piwigo_access.log combined
    ErrorLog /var/log/apache2/piwigo_error.log
# ログの格納先を指定を指定

    DocumentRoot /var/www/html/piwigo
    <Directory /var/www/html/piwigo>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted
    </Directory>
# DocumentRootは実際に配置したディレクトリを指定

  SSLEngine on

    Protocols h2 http/1.1
    Header always set Strict-Transport-Security "max-age=63072000"

SSLCertificateFile /etc/certs/example.com.crt
SSLCertificateKeyFile /etc/private/example.com.key
# 証明書と秘密鍵のパスを指定

</VirtualHost>

SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder     off
SSLSessionTickets       off

SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
__EOF__

バーチャルファイル有効化

sudo a2ensite piwigo.conf

設定反映

sudo apache2ctl configtest
# Syntax OKを確認します
sudo systemctl restart apache2.service
systemctl status apache2.service
# active (running)を確認します

表示確認

http://設定したドメイン

にアクセス後、以下が表示されます。

データベース設定

  • ユーザー: DBユーザ名
  • パスワード: 設定したDBのパスワード
  • データベース名:DB名

を入力します。

管理設定

  • ユーザ名:管理者名を入れます。
  • パスワード:管理者のパスワードを入れます。
  • メールアドレス:メールアドレスを入力します。

設定後、以下が表示されると設定完了です。

Redmineサーバのウイルススキャン。(ClamAVとinotifyによる添付ファイルの自動スキャン)

概要

Redmineの稼働サーバにウィルス対策ソフトClam-AVをインストールし、不審なファイルのアップロードを防ぎます。

動作要件

  • スキャン対象はRedmineの添付ファイル格納ディレクトリです。
    • それ以外にも転用できるようにスクリプトを変数で定義しています。
  • inotifyサービスを利用して、スキャン対象を絞ります。
  • スキャンするタイミングは上記格納ディレクトリにファイルがアップロードされたときです。これによってCPU消費を節約します。
  • ClamAVによって不審なファイルと判断された場合、そのファイルを削除します。その後、詳細はログに出力されます。

動作確認環境

  • Ubuntu 20.04
  • ClamAV 0.103.8

手順

  • サーバのターミナルからコマンドラインで設定を行います。
  • パッケージ管理はaptitudeを利用しています。好みに合わせてaptに置き換えてください。

さっくりとした手順

  1. ClamAVをインストールします。
  2. 最新のウィルス定義ファイルがダウンロードできることを確認します。
  3. ClamAVの動作を確認します。
  4. inotifyサービスをインストールします。
  5. チェックスクリプトを作成します。
  6. スクリプトをサービス化します。
  7. サービスの動作を確認します。

ClamAVの設定と確認

ClamAVのインストール

sudo aptitude update

sudo aptitude install clamav clamav-daemon

ウィルス定義ファイルの更新

sudo freshclam

で定義ファイルを更新しようとしたところ、以下のエラーが出ました。

sudo freshclam

ERROR: /var/log/clamav/freshclam.log is locked by another process
ERROR: Problem with internal logger (UpdateLogFile = /var/log/clamav/freshclam.log).
ERROR: initialize: libfreshclam init failed.
ERROR: Initialization error!

対処を行います。

sudo lsof /var/log/clamav/freshclam.log

COMMAND    PID   USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
freshclam 7001 clamav    3wW  REG  202,1     2161 2319263 /var/log/clamav/freshclam.log
# この時に出てきたPIDを控えておきます。

このプロセスを停止します。

sudo kill -9 7001
# 出てきたPIDを指定します

ログファイルのパーミッション変更

sudo chmod -R 777 /var/log/clamav/

上記を実施後、

sudo freshclam

定義ファイルが更新されることを確認しました。

ウイルス定義ファイル自動更新

sudo systemctl start clamav-freshclam.service

sudo systemctl enable clamav-freshclam.service

systemctl status clamav-freshclam.service
# active (running)を確認します

ClamAVの動作確認

  • バージョン確認
clamscan --version
ClamAV 0.103.8/26829/Thu Mar  2 20:16:49 2023
# 2023/03/03、aptでインストールした際のバージョン
  • eicarテストファイルによる確認
cd ~

wget http://www.eicar.org/download/eicar.com

clamscan eicar.com
  • テスト結果
Win.Test.EICAR_HDB-1 FOUND

----------- SCAN SUMMARY -----------
Known viruses: 8654357
Engine version: 0.103.8
Scanned directories: 0
Scanned files: 1
Infected files: 1
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)

が表示されたので、機能していることを確認です。

rm eicar.com

でテストファイルを削除します。(スキャンしただけなのでファイルの自動削除は行われません)

スクリプト作成

inotifyのインストール

sudo aptitude install inotify-tools

スクリプト生成

  • 以下のスクリプトを教義・信仰に沿ったエディタで作成します。
  • スクリプト名:clamav-inotify.sh
#!/bin/bash

## 変数ここから
# 監視対象のディレクトリを指定してください。
WATCH_DIR="/var/lib/redmine/files"

# スキャン対象の最大サイズを指定してください。
# Redmineのようにアップロード上限をWeb画面から設定できる場合、そのサイズに合わせます。
MAX_FILE_SIZE="10240M"

# スキャンログのパスを定義します。
SCAN_LOG="/var/log/redmine/redmine-scan.log"
## 変数ここまで


# 監視対象のディレクトリ (およびサブディレクトリ) に新しいファイルが作成されたときに、そのファイルをスキャンする処理を行います
inotifywait -m -r -e create --format '%f' "$WATCH_DIR" |
while read FILE
do
    # 新しいファイルがディレクトリでなく、かつ隠しファイルでないことを確認します。
    if [ ! -d "$FILE" ] && [ "$(echo "$FILE" | cut -c1)" != "." ]; then
        # ClamAVを使用して新しいファイルをスキャンします。
        RESULT=$(clamscan --recursive --max-filesize="$MAX_FILE_SIZE" "$WATCH_DIR/$FILE")
        if echo "$RESULT" | grep -q " FOUND"; then
            echo "ウイルスが検出されました: $FILE" >> "$SCAN_LOG"
            rm "$WATCH_DIR/$FILE"
        else
            echo "スキャンが完了しました: $FILE" >> "$SCAN_LOG"
        fi
    fi
done
  • 実行権付与
sudo chmod +x clamav-inotify.sh

スクリプトのサービス化

  • 以下のスクリプトを教義・信仰に沿ったエディタで作成します。
  • 配置ディレクトリ:/etc/systemd/system/
  • サービス名:clamav-inotify.service
  • ファイル内容
[Unit]
Description=ClamAV Inotify Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/bash /home/hoge/clamav-inotify.sh
# 上記のスクリプトをフルパスで指定します
Restart=always
User=root

[Install]
WantedBy=multi-user.target
  • サービスの有効化
sudo systemctl enable clamav-inotify.service

sudo systemctl start clamav-inotify.service

systemctl status clamav-inotify.service
# active (runnning)を確認します

動作確認

テストウィルスを配置→削除確認

cd /var/lib/redmine/files
# スクリプトで指定したスキャン対象ディレクトリに移動します。

sudo wget http://www.eicar.org/download/eicar.com
# eicarテストウィルスをダウンロードします。

ls -l eicar.com
# ファイルがある状態から削除されていることを確認します。

ログ確認

cat /var/log/redmine/redmine-scan.log
# スクリプトで指定したログ

以下のようにログに出れば成功です。

/mnt/wasabi/redmine/files/eicar.com: Win.Test.EICAR_HDB-1 FOUND

----------- SCAN SUMMARY -----------
Known viruses: 8654357
Engine version: 0.103.8
Scanned directories: 0
Scanned files: 1
Infected files: 1
Data scanned: 0.00 MB
Data read: 0.00 MB (ratio 0.00:1)
Time: 34.852 sec (0 m 34 s)
Start Date: 2023:19:03 11:50:39
End Date:   2023:19:03 11:51:14
ウイルスが検出されました: eicar.com

動作確認日

2023/03/03

fail2banの再設定。

概要

不正アクセスからサーバを保護するfail2ban。様々なルールが存在するため、チューニングの失敗によっては機能不全に陥ります。

そんなこんなで、ちょっとハマった出来事を記します。

確認実施環境

Ubuntu 20.04

fail2banはアンインストールできない場合があります。

apt-get --purge autoremove fail2ban

をやってもアンインストールできませんでした。

対処: dpkgのinfoファイル削除

sudo su -
# この作業は全て管理者権限で行った方がいいです

cd /var/lib/dpkg/info/

ls -l fail*
rm fail*
# fail2banのみのパッケージがあることを確認して消去します

apt-get --purge autoremove fail2ban
# この段階でようやくアンインストールできました

cd /etc/

rm -rf fail2ban
# fail2banの設定を変更します

と、dpkgのinfoファイルを削除して

ufwとうまく連携できません。

「なぜチューニングに失敗したのか」の理由です。ネットにあるfail2banの記事は大概がiptablesとの連携を前提としているため、Ubuntu系での標準ファイアウォールであるufwとうまく連携できませんでした。

なので、

  • 記事を鵜呑みにして設定するとエラーが発生してfail2banの起動に失敗する。
  • 再設定のためにアンインストールしようとすると上記問題が発生する

という経緯があります。

対処:ufwに即した設定変更

参考記事:
https://blog.fernvenue.com/archives/ufw-with-fail2ban/

前提:

まっさらな状態で(上記手段でアンインストールした上で)

sudo aptitude install fail2ban

を実行した状態とします。

jail.localを編集します。

協議・信仰に沿ったエディタで以下のファイルを編集(作成)します。

  • ファイル名 /etc/fail2ban/jail.local

○内容

[ufw]
enabled=true
filter=ufw.aggressive
action=iptables-allports
logpath=/var/log/ufw.log
maxretry=1
bantime=-1
ignoreip = 127.0.0.0/8 ::1
# ignoreipは任意の(自分のアクセス元)を指定ください

[sshd]
enabled=true
filter=sshd
mode=normal
port=22
protocol=tcp
logpath=/var/log/auth.log
maxretry=3
bantime=-1
ignoreip = 127.0.0.0/8 ::1
# ignoreipは任意の(自分のアクセス元)を指定ください
  • ファイル名 /etc/fail2ban/filter.d/ufw.aggressive.conf

○内容

[Definition]
failregex = [UFW BLOCK].+SRC=<HOST> DST
ignoreregex =

設定反映

systemctl enable fail2ban
systemctl start fail2ban
systemctl statsu fail2ban

これで、不審なアクセスは次回以降は有無を言わせずブロックする設定となります。

検証:AWS LightsailのUbuntuにWasabiクラウドストレージをマウント。

概要

(ほぼ)固定費でそれなりのスペックのサーバを運用できるAWS Lightsail。ストレージを増やすには

  • スペックの増強を図る
  • AWS S3などのクラウドストレージを増強する

といった策が必要です。ですが、もっと低価格で利用できるサービスはないものかと探していたところにみつけました。

クラウドストレージ:Wasabi

https://wasabi.com/ja

なかなか挑戦的な言葉が書かれています。

  1. 1TBでも6$程度
  2. データ転送料無料

は魅力的。(逆に言えば、たとえ1バイトのファイルしか保存しなくても最低1TB分は請求されます)

そして、S3と同じプロトコルが使えるとのこと。

無料トライアルもあるので、Linuxサーバにマウントできるかを検証してみます。

試した手順

環境

AWS上で動かしているUbuntu 20.04で利用しています。

さっくりとした流れ

  1. Wasabiのアカウントを作成します
  2. バケットを作成します
  3. アクセスキーを作成します
  4. Linuxサーバで必要なパッケージをインストールします
  5. アクセスキーを保存します
  6. マウントを確認します
  7. fstabを修正します

詳細の手順

Wasabiアカウント作成

上記URLから自身のアカウントを作成。確認メールからパスワードを設定します。

バケット作成

ログイン後、「バケット」をクリック。

任意のバケット名を入力し、地域を選択します。(ここでは大阪を選択)

バージョン管理などは全て無効の状態で「次」をクリック。

確認画面後に「バケットを作成」で作成できました。

アクセスキーの生成

アクセスキーをクリックし「新しいアクセスキーを作成する」からアカウントキーと秘密鍵を控えます。(この情報は全てのストレージへのアクセスに必要となるため、取り扱いは厳重にしてください)

Linuxサーバ上での動作

スナップショット取得

念のため、作業直前にAWSコンソールからスナップショットを作成します。

必要パッケージインストールします

sudo aptitude update
sudo aptitude install s3fs

パスワードファイルの作成

信仰・協議に従ってエディタを起動します。次のファイルを作成します。

.passwd-s3fs
# アクセスキー:秘密鍵 の順番で貼り付け

chmod 600 .passwd-s3fs

ls - ${HOME}/.passwd-s3fs
# ファイルがあることを確認します

マウントポイントの指定

sudo mkdir /mnt/wasabi
# /mntファイルに任意の名前を作成ください

udo s3fs 【wasabiで作成したバケット名】 /mnt/wasabi -o passwd_file/【上記作成したパスワードファイルのパス】/.passwd-s3fs -o url=https://【バケットのリージョン名】.wasabisys.com -o use_path_request_style -o endpoint=【バケットのリージョン名】 -o allow_other

これでマウントしたことを確認しました。

WasabiのWebインタフェースから任意のファイルをアップロード。

cd /mnt/wasabi 
# 作成したマウントポイントに移動します

ここから、アップロードしたファイルが確認できれば設定完了です。

fstabの設定

システムを再起動してもマウントできるようにfstabの設定を追記します。

sudo cp -pi /etc/fstab /path/to/directory/fstab.date +%Y%m%d
diff -u /etc/fstab /path/to/directory/fstab.date +%Y%m%d
# 差分がないことでバックアップを確認します

バックアップ後、協議・信仰に従ったエディタで末尾に追記します。

s3fs#【wasabiバケット名】 /mnt/wasabi fuse _netdev,allow_other,passwd_file=/【パスワードファイルのパス】/.passwd-s3fs,url=https://s3.バケットのリージョン名wasabisys.com,use_path_request_style,endpoint=バケットのリージョン名 0 0

マウント確認

sudo mount -a
# エラーが出ないことを確認します

df -h
# マウントしたバケットが見えているかを確認します

今後の検証

トライアルの間、

  • マウントしたディレクトリに保存されたファイルをWebに公開できるか
  • 遜色なく利用できるか
  • 転送速度などに問題ないか

を確認後、本格的に使っていこうと思います。

Page 17 of 22

Powered by WordPress & Theme by Anders Norén