タグ: Ubuntu Page 9 of 14

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に公開できるか
  • 遜色なく利用できるか
  • 転送速度などに問題ないか

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

Redmineのファイル一式の日次バックアップ。(復旧方法込みのシェルスクリプト作成)

概要

Redmineのメンテナンスの中で重要となるDBのバックアップは記載しました。

ここでは、それ以外のファイル一式をバックアップするスクリプトを作成することで不測の事態に備えます。

バックアップ対象となるファイル群

基本的に、以下のファイル群が残っていれば復旧は(理論上)可能です。

  • /Redmine格納ディレクトリ/plugins配下一式
  • /Redmine格納ディレクトリ/files配下一式
  • /Redmine格納ディレクトリ/public/themes配下一式
  • /Redmine格納ディレクトリ/config/database.yml
  • /Redmine格納ディレクトリ/config/configuration.yml (メール設定などで設定している場合)
  • /Redmine格納ディレクトリ/config/additional_environment.rb (プラグインなどで追記している場合)

本記事で扱うこと

  1. 先に述べたバックアップ対象となるファイル群の定期バックアップを行うシェルスクリプトを作成します。
  2. バックアップ時、パスワードが書かれているコンフィグに関してはその箇所をマスクします。(これもスクリプトに組み込みます)
  3. 動作を確認し、cronに設定して日次でバックアップを行います。

動作を確認した環境

  • Ubuntu 20.04 LTS
  • Redmine 4.2

実施前提

  • 利用しているRedmine環境の容量を確認し、バックアップ先に十分な空き容量があることを確認してください。
  • 本スクリプトは「全てのデータを一時的なバックアップディレクトリにコピーした上で圧縮し、そのディレクトリは削除する」処理を取っています。その容量も加味してください。
  • バックアップ元(Redmine格納ディレクトリ)の所有者が全てRedmine実行ユーザ(通例はwww-data)となっていることを確認してください。
  • また、本記事において、Redmineの格納ディレクトリは/home/www-data/redmineと一般的な構成と異なっております。

確認した手順

  • Redmineが稼働しているUbuntuサーバのターミナル上での操作です。

さっくりとした手順

  1. バックアップディレクトリを作成します。
  2. バックアップスクリプトを作成します。(環境に合わせて修正します)
  3. crontabに登録します。

バックアップディレクトリ作成

sudo mkdir -p /home/backup/redmine
# 運用に合わせて指定ください

sudo chown -R www-data:www-data /home/backup/redmine
# Redmineディレクトリの所有者に設定します

cd /home/backup/redmine && pwd
# 指定したディレクトリに移動します

リストア方法のテキストファイル作成

バックアップから切り戻すとき、作業者はかなり焦るものです。そこで、簡単な手順をバックアップファイル一式に配置しておけばスムーズな復旧を行うことができます。

以下の内容を教義・信仰に沿ったエディタで作成します。(ここでは筆者が用いているテキスト内容です。必要に応じて修正してください)

  • テキスト内容
    • テキスト名:how_to_restore.md
    • テキストの所有者はスクリプトの実行者と同じ(またはroot)である必要があります。
    • 上記、設定したディレクトリと同じ場所に作成します。
# Redmine復旧方法

## 前提環境

- Ubuntu 20.04系サーバ
- MySQL 8.3以上
- Apache 2.4系
- Redmineの実行ユーザはデフォルトのwww-data

## 【リストア/移行方法】

### 移行先にRedmineを作成

1. 新たにRedmineサイトを立ち上げます。(移行元と移行先のバージョンは合わせます)
2. リストア先/移行先のdb名/dbユーザはバックアップ元と同じにします。
3. バックアップされたdatabase.ymlを /redmine/config/配下に上書きます。dbパスワードを設定してください。
4. この状態で、Redmineのデータマイグレーションまで行います。

### バックアップされたファイル一式の再配置

- files/ディレクトリ一式は /redmine/配下に上書きしてください。
- plugins/ディレクトリ一式は /redmine/配下に上書きしてください。
- themesディレクトリ一式は /redmine/public/配下に格納してください。
- configuration.yml : (あるなら)/redmine/config/配下に上書き。メールパスワードを設定してください。
- additional_environment.rb : (あるなら)/redmine/config/配下に上書きします。

※ それぞれのディレクトリ/ファイルの所有者を「www-data」にします。

sudo chown -R www-data:www-data /redmine格納ディレクトリ/
> 例 sudo chown -R www-data:www-data /var/lib/redmine

### プラグインのDBマイグレーション

1. redmineを配置したディレクトリに移動します。(例; cd /var/lib/redmine/
2. 以下のコマンドを発行して、プラグインのマイグレーションを行います。

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

### プラグインマイグレーション後のApache再起動

1. 以下を実施してWebサービスを再起動します。
sudo systemctl restart apache2.service

### DBのリストア

1. 別途、バックアップしたRedmineのsqlファイルを移行先サーバの任意のディレクトリに転送します。
2. 以下のコマンドを発行して、DBをリストアします。

mysql -u redmineのdbユーザ -p redmineのdb名 < バックアップしたsql
> 例  mysql -u redmine -p redmine < redmine_backup

### DBリストア後のApache再起動

1. 以下を実施してWebサービスを再起動します。

sudo systemctl restart apache2.service

### 動作確認

移行先(または復旧した)Redmineのホストにブラウザでアクセスし、バックアップした時の状態になっているかを確認します。

スクリプト作成

以下の内容を教義・信仰に沿ったエディタで作成します。

  • スクリプト内容
    • スクリプト名:redmine_daily_backup.sh
    • 実行ユーザ:Redmineの所有者 (通例はwww-dataです)、またはroot
#!/bin/bash

### ▼ここからはスクリプトの変数を定義します。""の記述は自身の環境に合わせて修正ください。▼ ###
# バックアップ先のディレクトリを指定します。
backup_dir="/home/backup/redmine"
# バックアップ元のRedmineが格納されているディレクトリを指定します。
redmine_dir="/home/www-data/redmine"
# ファイルに付与する日付/作業ディレクトリ名/バックアップファイル名を指定します。
current_date=$(date +%Y%m%d)
backup_name="redmine_backup_${current_date}"
zip_file="redmine_backup.${current_date}.zip"
# 保存する日数を指定します。(ここでは3日にします。)
retention_period=3
### ▲変数はここまでです▲ ###

# 一時的なバックアップディレクトリを作成します。
mkdir "${backup_dir}/${backup_name}"

# # Redmineのユーザデータ/プラグイン/テーマをバックアップディレクトリにコピーします。

cp -R "${redmine_dir}/plugins" "${backup_dir}/${backup_name}"
cp -R "${redmine_dir}/files" "${backup_dir}/${backup_name}"
cp -R "${redmine_dir}/public/themes" "${backup_dir}/${backup_name}"

# マイグレーション時に必要となるdatabase.ymlをコピーします。この時、パスワードが書かれている行をマスクします。
cp $redmine_dir/config/database.yml $backup_name
sed -i 's/password:.*/password: "type your db password"/' $backup_name/database.yml

# メール設定などでconfiguration.ymlを設定している場合、これもコピーします。(存在しない場合はコピーしません)
# 同様にパスワードが書かれていたらその行はマスクします。
if [ -f $redmine_dir/config/configuration.yml ]; then
  cp $redmine_dir/config/configuration.yml $backup_name
  sed -i 's/password:.*/password: "type your password"/' $backup_name/configuration.yml
fi

# プラグイン設定などでadditional_environment.rbを設定している場合、これもコピーします。(存在しない場合はコピーしません)
if [ -f $redmine_dir/config/additional_environment.rb ]; then
  cp $redmine_dir/config/additional_environment.rb $backup_name
fi

# スクリプトと同じディレクトリにあるhow_to_restore.txtをバックアップディレクトリに流し込みます。(存在しない場合はコピーしません)
if [ -f $backup_dir/how_to_restore.txt ]; then
  cp $backup_dir/how_to_restore.txt $backup_name/how_to_restore.md
fi

# バックアップディレクトリをzip形式で圧縮します。
cd "${backup_dir}"
zip -r "${zip_file}" "${backup_name}"

# 一時的なバックアップディレクトリを削除します。
rm -rf "${backup_dir}/${backup_name}"

# 上記retention_periodで指定した日数前のバックアップしたzipファイルを削除します。
find "${backup_dir}" -type f -name "redmine_backup.*.zip" -mtime +"${retention_period}" -delete
  • 実行権限の付与
chmod +x redmine_daily_backup.sh

動作確認

sudo -u www-data bash redmine_daily_backup.sh
# 管理者権限で実行する場合は sudo bash redmine_daily_backup.sh

以下を確認します。

  • エラーなく実行できること
  • redmine_backup.実行日付.zip形式でファイルが作成されること
  • sudo -u www-data unzip redmine_backup.実行日付.zipでファイルが解凍されディレクトリに移動できること
  • ymlファイルのパスワードが「type your (db) password」と本来のパスワードが上書きされていること
  • 設定したhow_to_restore.mdが回答したディレクトリの中にあり、参照できること

Crontab設定

Cron登録

sudo crontab -e -u www-data
# 管理者が実行する場合は sudo crontab -e -u root

登録内容例

5 0 * * * /home/backup/redmine/redmine_daily_backup.sh
# 実行時刻、頻度などは自分の運用形態に合わせます。

Cron登録確認

sudo tail -20 /var/log/cron.log

操作時刻に

  • BEGIN EDIT
  • REPLACE
  • END EDIT

が表示されれば設定は完了です。

動作確認日

2023/02/08

MySQLの定期バックアップ、現状の運用に修正。

こちらの記事を2023年2月時点での運用に併せ、以下、修正しました。

概要

Redmineのメンテナンスの中で、「データベースのバックアップ」は非常に重要なものです。

そこで、改めて、シェルスクリプトとCronによるバックアップ手順を整理しました。

動作を確認した環境

  • Ubuntu 20.04 LTS
  • Redmine 4.2
  • MySQL 8.0.32

実施前提

  • MySQLに管理者権限でログインできること。
  • Redmine用のDBとDBユーザ、DBパスワードを把握していること。
  • また、DBサーバはローカルホストです。

確認した手順

  • Redmineが稼働しているUbuntuサーバのターミナル上での操作です。
  • MySQL以外は全て一般権限で実行します。

さっくりとした手順

  1. Redmineのデータベースユーザに権限を付与します。
  2. バックアップディレクトリを作成します。
  3. アカウントファイルを作成します。
  4. バックアップスクリプトを作成します。
  5. crontabに登録します。

データベース設定

管理者権限でMySQLにログインします。

mysql -u root -p

データベースのユーザ権限を変更します。

これを行わないとDump処理ができませんでした。

GRANT RELOAD ON *.* TO '【RedmineのDBユーザ】'@'localhost';
FLUSH PRIVILEGES;
EXIT

ディレクトリとスクリプト作成

バックアップディレクトリ作成

sudo mkdir -p /home/backup/mysql
# 運用に合わせて指定ください。ファイルサーバや別パーティションにマウントしている方がサーバ事態の障害発生でも冗長化を持たせられます。

sudo chown -R hoge:hoge /home/backup/mysql
# ディレクトリの所有者をログインユーザに修正します

cd /home/backup/mysql && pwd
# 指定したディレクトリに移動します

アカウントファイル作成

※このファイルを作成しないと、「安全ではない」とエラーが出ます。

以下の内容を教義・信仰に沿ったエディタで作成します。(【】内は取り除き、自分の設定に合わせます)

  • アカウントファイル内容
  • ファイル名:account.txt
[client]
user = 【RedmineのDBユーザ】
password = "【RedmineのDBユーザ用パスワード】"

アカウントファイルでアクセスできることを確認

mysql --defaults-extra-file=account.txt

MySQLのプロンプトが出れば成功です。exitで抜けます。

スクリプト作成

以下の内容を教義・信仰に沿ったエディタで作成します。

  • スクリプト内容
  • スクリプト名:mysql_daily_backup.sh
#!/bin/bash

# スクリプトの日付形式を定義します
date=$(date +"%Y%m%d")

# バックアップディレクトリを定義します
# 上記手順で示したディレクトリを指定してください
backup_dir="/home/backup/mysql"

# アカウントファイルを指定します
credentials_file="$backup_dir/account.txt"

# バックアップ時に指定するオプションを定義します
options="--defaults-extra-file=$credentials_file --no-tablespaces --single-transaction"

# バックアップファイル名を定義します
backup_file="$backup_dir/redmine.sql.$date.gz"

# バックアップを実行し、.gz形式でバックアップをします
mysqldump $options -h localhost redmine | gzip > $backup_file

# 10世代前の圧縮ファイルを削除します(運用に合わせて指定ください)
find $backup_dir -type f -name "redmine.sql.*.gz" -mtime +10 -delete
  • 実行権限の付与
chmod +x mysql_daily_backup.sh

動作確認

sh mysql_daily_backup.sh

以下を確認します。

  • エラーなく実行できること
  • redmine.sql.実行日付.gz形式でファイルが作成されること
  • gunzip redmine.sql.実行日付.gzでファイルが解凍できること

Crontab設定

Cron登録

crontab -e

登録内容例

0 0 * * * /home/backup/mysql/mysql_daily_backup.sh
# 実行時刻、頻度などは自分の運用形態に合わせます。

Cron登録確認

sudo tail -20 /var/log/cron.log

操作時刻に

  • BEGIN EDIT
  • REPLACE
  • END EDIT

が表示されれば設定は完了です。

動作確認日

2023/02/08

AWS LightsailにSwap領域を確保。(Ubuntuでの設定)

概要

筆者が用いているAWS Lightsail。自動起動サービスやWebサービスの追加のためメモリが心許なくなりました。

インスタンスの底上げを図る前にいったんSwap領域を確保して、メモリの枯渇に備えます。

環境

  • Ubuntu 20.04
  • 2GBメモリ/60GBディスクのインスタンスを利用

実施した手順

さっくりとした手順

  1. 現在のメモリとディスク容量を確認します。
  2. Swap領域を確保します。
  3. 確保したSwap領域を有効化します。
  4. Swap領域が増えたことを確認します。
  5. fstabを修正します。
  6. fstab修正後にシステムを再起動し、Swap領域有効化を確認します。

作業の前に

ディスク起動時のオプションなど、特に重要なシステム領域の設定ファイルを修正する作業です。
失敗時に復旧できるようシステム全体のバックアップを取ることを強く推奨します。

現在のメモリ情報を確認

free -h
# -hオプションは(human readableの略だそうです)
  • ○実行結果
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       1.6Gi       114Mi        58Mi       209Mi       109Mi
Swap:            0B          0B          0B

Swapが全く作成されていません。

現在のディスク容量の確認

df -h
  • ○実行結果
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        59G  7.6G   51G  13% /
(後略)

まだ容量的に問題なさそうなので、2GBのディスク領域をSwapとして割り当てます。

Swap領域の確保

sudo fallocate -l 2G /swap

ls -ldh /swap
# 指定ディレクトリに2GBのファイルがあることを確認します

Swapの有効化

  • ★/swapのパーミッション変更
sudo chmod 600 /swap

ls -ldh /swap
# rootのみが読み書き可能なことを確認します
  • ★/swapの設定
sudo mkswap /swap
  • ○実行結果
スワップ空間バージョン 1 を設定します。サイズ = 2 GiB (2147479552 バイト)
ラベルはありません, UUID=f6d01f7d-6a48-45e9-a483-5757ec47cd8e
  • ★/swapの有効化
sudo swapon /swap

Swap有効化確認

free -h
  • ○実行結果
              total        used        free      shared  buff/cache   available
Mem:          1.9Gi       1.2Gi       430Mi        58Mi       283Mi       499Mi
Swap:         2.0Gi          0B       2.0Gi

2GBのSwap領域が確保されました。まずは一安心です。

fstab設定

  • ★/etc/fstabのバックアップ
sudo cp -pi /etc/fstab /path/to/backup/directory/fstab.$(date +%Y%m%d)

diff -u /etc/fstab /path/to/backup/directory/fstab.$(date +%Y%m%d)
# 差分が無いことでバックアップが取れていることを確認します。
  • ★/etc/fstab追記
cat <<- __EOF__ | sudo tee -a /etc/fstab
/swap none swap sw 0 0
__EOF__
  • ○差分確認
diff -u /path/to/backup/directory/fstab.$(date +%Y%m%d) /etc/fstab
  • ●差分
+/swap none swap sw 0 0

再起動後の修正確認

  • ★システム再起動
sudo reboot
  • ★再起動後の確認

以下が確認できれば作業完了です。

  1. サーバにログインできること
  2. Webサービスなど既存システムが設定前と同様に稼働すること
  3. free -h を実行し、Swap領域が確保されていること

NextcloudサーバのPHPアップグレードとエラー解消、そして再設定。(PHP7.4→PHP8.1)

Nextcloudを動かしている自宅サーバでPHPをアップグレード。

ちょっとだけハマったのでメモを残します。

環境

以下の環境でNextcloudを動かしています。

  • Ubuntu 20.04
  • Apache
  • MySQL
  • PHP 7.4

さっくりとした手順

  1. PHP7.4をアンインストールします。
  2. PHP8.1をインストールします。
  3. 追加モジュールを有効化します。
  4. NextCloudの追加設定を行います。

手順

  • 今回は全て通常ユーザで作業をします。
  • また、viを使わずコマンドを用いて設定を置き換えています。
  • 設定をするのはPHPのみです。他は設定の変更をしていません。
  • パッケージ/モジュールのインストールにaptitudeを用いています。好みに合わせてaptをご利用ください。

PHPの削除を行います。

sudo apt-get --purge autoremove php*

PHP8.1をインストールします。

sudo aptitude install php8.1

sudo aptitude install php8.1-{opcache,pdo,bcmath,calendar,ctype,fileinfo,ftp,gd,intl,json,ldap,mbstring,mysql,posix,readline,sockets,bz2,tokenizer,zip,curl,iconv,phar,xml}

sudo aptitude install php8.1-apcu

sudo aptitude install php8.1-memcached

php -v
# PHP 8.1.14 (cli)を確認しました。(2023/01/19)

apache再起動を行います。

sudo systemctl restart apache2.service

アップグレード後にエラー。

PHPアップグレード後、Nextcloudにアクセスするとこうなりました。

前の設定が全て消えたので、エラーが発生しました。

こちらを解消していきます。

エラーチェック

cd /var/www/html/nextcloud/
# Nextcloudの格納ディレクトリに移動します。自分の環境に置き換えてください。

sudo -u www-data php ./occ
# NextcloudのCLIインタフェースです
エラー内容
An unhandled exception has been thrown:
OCP\HintException: [0]: Memcache \OC\Memcache\APCu not available for local cache (Is the matching PHP module installed and enabled?)

memcacheとAPCuが読み込まれていないと怒られましたので、有効化していきます。

memcacheとAPCuの有効化

cd /etc/php/8.1/cli/conf.d
cat <<- __EOF__ | sudo tee -a /etc/php/8.1/cli/conf.d/10-opcache.ini
opcache.enable=1
opcache.enable_cli=1
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=10000
opcache.memory_consumption=128
opcache.save_comments=1
opcache.revalidate_freq=1
__EOF__
cat <<- __EOF__ | sudo tee -a /etc/php/8.1/cli/conf.d/20-apcu.ini
[apcu]
apc.enabled=1
apc.shm_size=32M
apc.ttl=7200
apc.enable_cli=1
apc.serializer=php
__EOF__
sudo systemctl restart apache2.service

再設定後の確認

cd /var/www/html/nextcloud/
# nextcloudの格納ディレクトリに移動します

sudo -u www-data php ./occ
# エラーが出ず、occのオプションが表示されることを確認しました。

この後、Nextcloudにアクセスし、画面が表示されることを確認しました。

管理者画面確認

Nextcloudに管理者アカウントでログインし、管理者設定を確認すると

  • PHPのメモリ制限が推奨値の512MB以下です。
  • テーマ別アプリは有効ですが、PHPモジュール「imagick」が有効ではありません。ファビコン生成を正しく行うには、このモジュールをインストールし、有効化する必要があります。
  • PHP モジュール "gmp" および "bcmath" が有効になっていない。WebAuthnパスワードレス認証を利用する場合は、これらのモジュールが必要です。

が出てきました。これを修正していきます。

php.ini修正

sudo cp -pi /etc/php/8.1/apache2/php.ini /etc/old/php.ini.$(date +%Y%m%d)
# /etc/oldがなければディレクトリを作成するか、任意のバックアップパスを指定してください

diff -u /etc/php/8.1/apache2/php.ini /etc/old/php.ini.$(date +%Y%m%d)
# 差分が存在しないことにより、バックアップが取れていることを確認します。

sudo sed -i 's/memory_limit = 128M/memory_limit = 512M/g' /etc/php/8.1/apache2/php.ini
# memory_limitを推奨値の512Mに置き換えます。
差分確認
diff -u  /etc/old/php.ini.$(date +%Y%m%d) /etc/php/8.1/apache2/php.ini
# 取得したバックアップと置き換えたファイルの差分を確認します
  • 差分
-memory_limit = 128M
+memory_limit = 512M

不足モジュールのインストール

sudo aptitude install php8.1-{imagick,gmp}

設定反映と確認

sudo systemctl restart apache2.service

Nextcloudに管理者アカウントでログインし、管理者設定を確認。

「すべてのチェックに合格しました」

と出たので設定完了です。

redmineのテーブルをタブ区切りで書くプラグイン導入。(redmine_tsv_macro)

これで、Redmineでの記事やチケットの作成作業が更に捗ります。

プラグイン概要

こういうエクセルファイルのテーブルをredmineのMarkdownに書き写す場合、TyporaやGrowiのテーブル機能を経由して変換する必要がありました。

これをほぼコピペだけで完結させるプラグインです。

参照URL

  • https://taikii.net/posts/2019/12/redmine-plugins-2019/
  • https://github.com/taikii/redmine_tsv_macro

手順

全て管理者権限で実施しています。

redmineディレクトリに移動します。

cd /var/lib/redmine/plugins
# 自分の環境に読み替えます

プラグインをインストールします。

sudo -u www-data git clone https://github.com/taikii/redmine_tsv_macro.git
# Webサービスを実行するユーザに合わせます(apache,nginxなど)

システムに反映させます。

systemctl restart apache2.service
# 自身の環境に合わせます

使い方

テーブルを作りたいところに{{tsv_h }}と入力し、その間にエクセルのブックをコピーしてペーストするだけです。

入力例

{{tsv_h
日付    曜日  天気  朝   朝:場所    昼   昼:場所    夜   夜:場所    備考
2023/1/1    日   晴れ  おせち 自宅  おせち 自宅  カレー 自宅  
2023/1/2    月   晴れ  明太釜玉うどん 自宅  クリームパスタ 自宅  餃子雑煮    自宅  
2023/1/3    火   晴れ  鳥オムレツ   自宅  ソーセージ定食 自宅  カツ丼 自宅  
2023/1/4    水   晴れ  ハンバーグ定食 自宅  春巻き弁当   自宅  雑煮  自宅  
2023/1/5    木   晴れ  ソーセージ定食 自宅  チャーシュー麺セット  ぎょうざの満洲 プラウンマサラ 自宅  
}}

出力結果

Excelのみならず、Googleスプレッドシート経由でも他のアプリを利用することなく、ブラウザ間のみでシートの貼り付けが可能になります。

また、{{tsv_h }}{{tsv }}とすることで、ヘッダを用いないテーブルが作成可能です。

注意点

  • ヘッダは空白行を作らないようにしてください。そうしないと全体のテーブルがずれます。
  • また、セルに改行があったり記号などでも崩れるようです。
  • 崩れないテーブルを作りたい場合は素直に他のツールを使います。

mod_securityが検知した不審なアクセスをufwで一括遮断。

あらまし

apacheにmod_securityを導入後、以下を実施しました。

  1. Mod_Securityが検知した不審なアクセスのうち、IPアドレスのみを抜き出す
  2. その抜き出したIPアドレスをMod_securityによってブロックする
  3. これを日次で追加していく

この方法はそこそこうまくいっています。ですが、「これら不審なアクセス元はWebだけでの攻撃だけか? メールやSSHへの攻撃もしているだろう」と思い立ち、不審なアクセスを元から絶つ方法を採りました。

環境

AWS Lightsailで以下を動かしています。

  • Ubuntu 20.04
  • いわゆるLAMP環境

前提

以下が準備済みです。

  • Mod_Security導入済み
  • 前述したmod_securityから不審なアクセス元のみを抜き出したIPアドレスのリストがある
    • このリストをnegativelist.txtとして用意しています。
リスト形式
192.168.0.1
192.168.1.123

のように、一行ずつIPアドレスだけが記述されているファイルです。

さっくりとした手順

  1. ufwを有効化します。
  2. 不審なアクセス元のIPアドレスのみを抜き出したnegativelist.txtを一行ずつ読み込みアクセスを遮断するシェルスクリプトを作成します。
  3. 作成したスクリプトを実行します。

実行の前の注意事項

  • 自環境のアクセスが遮断される可能性があることに注意してください。
  • 事前にスナップショットやバックアップを取り、失敗した時に備え切り戻しができる準備を強く推奨します
  • この方法によりアクセスができなくなった等に対し、筆者は責任を負いかねます。

手順

全て管理者権限で実施しています。

ufwがインストールされていることを確認します。(導入済みの場合はスキップ)

apt list ufw
#  [インストール済み] となっていることを確認します。

ufwを有効化します。(導入済みの場合はスキップ)

ufw enable

許可するサービスを指定します。(導入済みの場合はスキップ)

ufw limit ssh
# 連続したSSHアクセスを遮断します
ufw allow http
ufw allow https
# その他の許可するサービスは必要に応じて指定してください

この段階で、以下を確認します。

  • ターミナルクライアントからSSH接続ができること
  • 既存のサービスが外部NWからアクセスできること

サービス確認

ufw status
実行例
状態: アクティブ

To                         Action      From
--                         ------      ----
22                         LIMIT       Anywhere                  
80                         ALLOW       Anywhere                  
443                        ALLOW       Anywhere                  
22 (v6)                    LIMIT       Anywhere (v6)             
80 (v6)                    ALLOW       Anywhere (v6)             
443 (v6)                   ALLOW       Anywhere (v6)             

シェルスクリプトを作成します。

vi /hoge/add_ufw.sh
スクリプト内容
#!/bin/bash

# UFWを念のため事前に有効化します
ufw enable

# ファイルに書かれたIPアドレスを一行ずつ読み込みアクセスを遮断します。
while read line; do
    ufw deny from $line
# 読み込むファイルを指定します
done < /path/to/negativelist.txt

シェルスクリプトに実行権限を与えます。

chmod +x /hoge/add_ufw.sh

シェルスクリプトを実行します。

./hoge/add_ufw.sh
# 行数によっては相当な時間がかかります

実行後の確認を行います。

ufw status
実行例(抜粋)
Anywhere                   DENY        192.168.0.1              
Anywhere                   DENY        192.168.1.111              

まとめ

これで、「Webサイトに対して不審なアクセスを行ったIPをまるごと遮断する」ことが可能になりました。相当乱暴な方法ではあることにご注意ください。

Page 9 of 14

Powered by WordPress & Theme by Anders Norén