カテゴリー: Linux Page 3 of 50

Redmineのマルチドメインのメモ。

公開用Redmine等で取得しているreisalin.com。今回、新たに「ryza.jp」を取得しました。

そこで、「1つのRedmineサイトに対して、別のドメインからアクセス可能にする」方法を取ったのでメモに残します。

やったこと

の両方からアクセスできるようにする。

環境

  • Ubuntu 24.04
  • Apache 2.4
  • Redmine 5.1
  • (DB等は割愛)

以下のように設定しています。

https://atelier.reisalin.com/projects/zettel/knowledgebase/articles/19

準備

  1. DNS設定で、両方のドメインから同一のIPが引けるように設定を行いました。
  2. ワイルドカード証明書を取得しました。

実施手順

ディレクトリ移動

cd /etc/apache2/sites-available && pwd

ファイルコピー

sudo cp -pi atelier.conf atelier_ryza.jp.conf

ファイル編集

  • 主な編集
-servername atelier.reisalin.com
+servername atelier.ryza.jp
  RewriteEngine On
         RewriteCond %{HTTPS} off
         RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

-    CustomLog /var/log/atelier/atelier_access.log combined env=!dontlog
+    CustomLog /var/log/atelier_ryza/atelier_access.log combined env=!dontlog

-SSLCertificateFile /etc/certs/reisalin.com.crt
-SSLCertificateKeyFile /etc/private/reisalin.com.key
+SSLCertificateFile /etc/certs/ryza.jp.crt
+SSLCertificateKeyFile /etc/private/ryza.jp.key

かなり単純な編集です。すなわち、コピーした後で

  • servernameを変える
  • ログの出力先を必要に応じて追加する
  • 証明書と秘密鍵をドメインに応じたものに変える

.conf有効化と反映

  • .conf有効化
sudo a2ensite atelier_ryza.jp.conf
  • 整合性確認
sudo apache2ctl configtest

Syntax OKを確認します。

Webサービス再起動

  • サービス再起動前確認
systemctl status apache2.service

active(running)を確認します。

  • サービス再起動
sudo systemctl restart apache2.service && $?

0を確認します。

  • サービス再起動後確認
systemctl status apache2.service

active(running)を確認します。

確認

以下、両方のサイトにアクセスします。

それぞれで同じコンテンツが見えればOKです。

備考

なぜ、このマルチドメインがうまくいったか?

Redmineのプログラムが、内部処理としてURLを参照しないというある種のおおらかさに救われました。また、リンクの参照なども(明示しない限りは)相対パスで記述されるため、混乱も少なかったと思います。

これが、他の(特にLalavelフレームワークのようなPHP環境)だとAPP_URLが関係するため、両立は今回のように上手くいきません。別途、リバースプロキシーを立てるなどの配慮が必要です。

Let’s Encryptによるワイルドカード証明書の設定。(証明書発行のみ)

こちらの記事を2025年版に対応すると共に、改めて、「証明書の発行」に絞った形です。

期せずして新たなドメインが取得できたので、こちらのワイルドカード証明書をLet's Encryptで作っていきます。

環境

  • Ubuntu 24.04

前提条件

  • 取得したドメインへのDNSが設定できること。
  • Let's Encryptが取得できていること
  • 備考として、別サーバでも配布しやすいように、オリジナルの/etc/letsencrypt/live/ではなく、任意の作業ディレクトリに証明書一式を保存する運用を行っています。

実施手順

サーバにターミナル接続して実施します。

root昇格

sudo su -

作業ディレクトリ作成

  • ディレクトリ作成
mkdir /hoge/bbb.jp_ssl$(date +%Y%m)
  • ディレクトリ移動
cd /hoge/bbb.jp_ssl$(date +%Y%m)

証明書発行

certbot certonly --manual \
    --preferred-challenges dns \
    --server https://acme-v02.api.letsencrypt.org/directory \
    -m あなたの有効なメールアドレス@example.com \
    -d "*.bbb.jp" \
    -d "bbb.jp"
  1. コマンド発行後、TXTレコードの登録指示がある。
  2. 管理しているDNSサーバにて、指示があったTXTレコードを登録
  3. 以下のコマンドで結果が返ってくるまでしばらく待つ
nslookup -type=TXT _acme-challenge.bbb.jp

→ 結果が返ってきたらEnter。証明書が更新される。

証明書一式を作業ディレクトリにコピー

  • 証明書を作業ディレクトリにコピー
cp -pi /etc/letsencrypt/live/bbb.jp/fullchain.pem ./bbb.jp.crt.$(date +%Y%m)
  • 秘密鍵を作業ディレクトリにコピー
cp -pi /etc/letsencrypt/live/bbb.jp/privkey.pem ./bbb.jp.key.$(date +%Y%m)

(通例、証明書は制限されています。読み取り時は注意してください)

証明書の整合性を確認

  • 期限が延びていることを確認
openssl x509 -noout -dates -subject -in bbb.jp.crt.$(date +%Y%m)
  • 証明書から公開鍵を取得
openssl x509 -pubkey -in bbb.jp.crt.$(date +%Y%m) -noout | openssl md5
  • 秘密鍵から公開鍵を取得
openssl pkey -pubout -in bbb.jp.key.$(date +%Y%m) | openssl md5

→ 両者が同じことを確認

  • 証明書のチェーンを確認
openssl crl2pkcs7 -nocrl -certfile bbb.jp.crt.$(date +%Y%m) | openssl pkcs7 -print_certs -outform PEM | awk 'BEGIN {c=0;} /BEGIN CERTIFICATE/ {c++} { print > "cert" c ".pem"}' && openssl verify -CAfile cert2.pem cert1.pem

openssl verify -CAfile cert2.pem cert1.pem
cert1.pem: OK

となることを確認

後は、これらの証明書を適切な位置に配置すれば完了です。

注意事項

  • 秘密鍵の保管は慎重に行ってください。
  • Let's Encryptのワイルドカード証明書の有効期限は90日と短いものです。更新忘れは特に注意してください。

nvmによるnpmアップデートとGrowiの起動スクリプト修正。

Growiサーバのメンテナンス中、「新しいnpmのバージョンが出ている」ということで、

以下のコマンドを実施。

sudo npm install -g npm@11.4.0

しかし、以下のエラーが出てきました。

npm error code EBADENGINE
npm error engine Unsupported engine
npm error engine Not compatible with your version of node/npm: npm@11.4.0
npm error notsup Not compatible with your version of node/npm: npm@11.4.0
npm error notsup Required: {"node":"^20.17.0 || >=22.9.0"}
npm error notsup Actual:   {"npm":"10.9.0","node":"v20.15.1"}
npm error A complete log of this run can be found in: /root/.npm/_logs/2025-05-20T01_02_55_477Z-debug-0.log 

これを解決するため、結構なハマり案件があったのでメモを残します。(実施日:2025/05/20)

動作前環境

  • Ubuntu 22.04
  • Growi v7.2.4
  • node.js 20.15.1
  • npm 10.9.0
  • pnpm 9.12.3
  • MongoDB/Apacheによるリバースプロキシーは割愛します。

以下を参考にインストールしています。

https://barrel.reisalin.com/books/growi/page/ubuntu2404growi-v7v710-ImY

(盛大にハマったものの)最終的に解決した手順

  1. nvm (Node Version Manager)のインストールと環境設定
  2. Growiサービス(systemd 経由)起動時でのバージョン不一致の特定
  3. 起動スクリプトの修正

nvmインストール

  • root昇格

※growiをroot権限で実行するため

sudo su -
  • growiサービス停止
systemctl stop growi.service
  • growiサービス停止確認
systemctl status growi.service

inactive(dead)を確認

  • nvmインストールスクリプトの実行
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
  • nvm環境の有効化と確認
export NVM_DIR="$HOME/.nvm" 
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" 

一度セッションを切り、再度sudoを行いました。

nvm --version

0.39.7と表示されることを確認。

(まだrootです)

  • nvm経由でNode.jsをインストール

npm@11.4.0と互換性があるNode.jsをインストールします。

nvm install v20.19.2
  • Node.jsバージョンの使用とデフォルト設定
nvm use v20.19.2
nvm alias default v20.19.2
  • Node.jsバージョン確認
node -v

v20.19.2を確認

npm -v

10.7.0を確認

  • npmのインストール
npm install -g npm@11.4.0
  • npmバージョン確認
npm -v

11.4.0を確認

  • 事前にインストールされているpnpmの削除
rm -rf /root/.local/share/pnpm
  • コマンドパスのキャッシュクリア
hash -r
  • pnpmインストール
npm install -g pnpm
  • pnpmバージョン確認
pnpm -v

10.11.0を確認

  • rootから抜ける
exit

Growiとのバージョン不一致と原因確認

  • growi起動
sudo systemctl start growi.service
  • growi起動確認
systemctl status growi.service

とし、Growiの管理画面にアクセスしましたが、バージョンは変わらず。

システム上は確かにバージョンアップされているにもかかわらず、です。

そこで、

pgrep growi

で原因を探し、

ls -l /proc/<PID>/exe

を確認したところ、systemdから起動されたGrowiのNode.jsプロセスが、バージョンアップ前の

/usr/local/bin/nodeを利用していることを確認。

これは、上述したリンク先のsystemdサービスの実行環境が、nvmの環境変数(PATH)を正しく引き継いでいなかったからです。

起動スクリプトの修正

  • growiサービス停止
sudo systemctl stop growi.service
  • growiサービス停止確認
systemctl status growi.service

inactive(dead)を確認

  • Growi起動ディレクトリに移動
cd /path/to/growi/root/directory && pwd

筆者環境/home/www-data/growi

  • 起動スクリプトのバックアップ
sudo cp -pi growi-start.sh /path/to/backup/diretory/growi-start.sh.$(date +%Y%m%d)

任意のバックアップディレクトリを指定します。

  • diffによるバックアップ確認
diff -u /path/to/backup/diretory/growi-start.sh.$(date +%Y%m%d) growi-start.sh

差分が無いことを確認します。

  • スクリプト修正

growi-start.shを、任意の手段で修正します。

#!/bin/bashの直下、起動スクリプトの直上に以下のように記載します。

# NVM environmentをロード (NVM_DIRを直接指定)
export NVM_DIR="/root/.nvm" # $HOMEの代わりに直接パスを指定
if [ -s "$NVM_DIR/nvm.sh" ]; then
  \. "$NVM_DIR/nvm.sh"  # nvmをロード
  # 次の行でスクリプト実行時のnodeとnpmのバージョンをログに出力
  echo "NVM for GROWI startup script loaded. Using Node version: $(node -v), npm version: $(npm -v)" > /tmp/growi_nvm_load.log
else
  # NVMが見つからない場合もログに出力
  echo "NVM_DIR ($NVM_DIR) not found or nvm.sh not found for GROWI startup script." > /tmp/growi_nvm_load.log
fi

# GROWIの起動コマンド
  • 修正確認
diff -u /path/to/backup/diretory/growi-start.sh.$(date +%Y%m%d) growi-start.sh
+
+# NVM environmentをロード (NVM_DIRを直接指定)
+export NVM_DIR="/root/.nvm" # $HOMEの代わりに直接パスを指定
+if [ -s "$NVM_DIR/nvm.sh" ]; then
+  \. "$NVM_DIR/nvm.sh"  # nvmをロード
+  # 次の行でスクリプト実行時のnodeとnpmのバージョンをログに出力
+  echo "NVM for GROWI startup script loaded. Using Node version: $(node -v), npm version: $(npm -v)" > /tmp/growi_nvm_load.log
+else
+  # NVMが見つからない場合もログに出力
+  echo "NVM_DIR ($NVM_DIR) not found or nvm.sh not found for GROWI startup script." > /tmp/growi_nvm_load.log
+fi
+
+# GROWIの起動コマンド

修正確認

  • growi起動
sudo systemctl start growi.service
  • growi起動確認
systemctl status growi.service

この後、Growiに管理者権限でアクセスし、管理画面に移動します。

項目
GROWI7.2.4
node.js20.19.2
npm11.4.0
pnpm10.11.0

となっていたため、正しく参照できています。

Google Geminiによるシェルスクリプト。(SSLの整合性確認)

Google Geminiに

「発行/別サーバからインポートしたSSL証明書の整合性確認を行うシェルスクリプト」

を書いてほしいと尋ねました。

条件は

  • コマンド [SSL証明書の入ったディレクトリ]形式
  • 証明書は
    • ドメイン名.crt.yyyymm
    • Let's Encryptのように証明書と中間証明書が結合された形式
  • 秘密鍵は
    • ドメイン名.key.yyyymm

の2つが入ったディレクトリを想定。

できあがったスクリプト

#!/bin/bash

# SSL証明書と秘密鍵の情報を表示するスクリプト
# サーバー証明書の有効期限、ドメイン名、発行局を表示します。
# また、対応する秘密鍵の存在と一致確認も行います。

# 使用法を表示する関数
usage() {
  echo "使用法: $0 <証明書と鍵が格納されているディレクトリ>"
  echo "ディレクトリには '[ドメイン名].crt.yyyymm' のような名前の証明書ファイルを配置してください。"
  echo "また、対応する秘密鍵ファイルは '[ドメイン名].key.yyyymm' の形式です。"
  echo "証明書ファイルは、サーバー証明書と中間証明書が結合された形式を想定しています。"
  exit 1
}

# 引数が指定されているか確認
if [ -z "$1" ]; then
  usage
fi

TARGET_DIR="$1"

# ディレクトリが存在するか確認
if [ ! -d "$TARGET_DIR" ]; then
  echo "エラー: ディレクトリ '$TARGET_DIR' が見つかりません。"
  exit 1
fi

# openssl コマンドが利用可能か確認
if ! command -v openssl &> /dev/null; then
    echo "エラー: openssl コマンドが見つかりません。OpenSSLをインストールしてください。"
    exit 1
fi

echo "ディレクトリ '$TARGET_DIR' 内のSSL証明書情報:"
echo "=================================================="

CERT_FILES_FOUND=0 # 処理した証明書ファイルのカウンタを初期化

# プロセス置換を使用して、CERT_FILES_FOUND が現在のシェルで更新されるようにする
while IFS= read -r -d $'\0' CERT_FILE; do
  CERT_FILES_FOUND=$((CERT_FILES_FOUND + 1)) # カウンタを増やす
  FILENAME=$(basename "$CERT_FILE")
  echo "処理中の証明書: $FILENAME"

  # --- 有効期限 ---
  EXPIRY_DATE_FULL=$(openssl x509 -noout -enddate -in "$CERT_FILE" 2>/dev/null)
  if [ $? -ne 0 ] || [ -z "$EXPIRY_DATE_FULL" ]; then
      EXPIRY_DATE_DISPLAY="有効期限の抽出エラー"
  else
      EXPIRY_DATE_DISPLAY=$(echo "$EXPIRY_DATE_FULL" | sed 's/notAfter=//')
  fi
  echo "  有効期限: $EXPIRY_DATE_DISPLAY"

  # --- ドメイン名 (サブジェクトのコモンネーム(CN) および サブジェクト代替名(SANs)) ---
  DOMAIN_NAME_DISPLAY="N/A"
  SUBJECT_CN_RAW=$(openssl x509 -noout -subject -nameopt multiline -in "$CERT_FILE" 2>/dev/null | grep 'commonName')
  SUBJECT_CN=""
  if [ $? -eq 0 ] && [ -n "$SUBJECT_CN_RAW" ]; then # grep で commonName が見つかった場合
    SUBJECT_CN=$(echo "$SUBJECT_CN_RAW" | sed -e 's/^\s*commonName\s*=\s*//' -e 's/\s*(Default)\s*$//' | head -n 1)
  fi
  
  # SANs を取得 (もしあれば最初の SAN 行のみ)
  SANS_TEXT=$(openssl x509 -noout -text -in "$CERT_FILE" 2>/dev/null | awk '/X509v3 Subject Alternative Name:/ {found=1; getline; print; exit} END{if(!found)print ""}')
  SANS_TEXT_CLEANED=$(echo "$SANS_TEXT" | sed 's/^\s*//') # 先頭の空白を削除
  SANS_LIST=""
  PRIMARY_SAN_DOMAIN=""

  if [[ "$SANS_TEXT_CLEANED" == "DNS:"* ]]; then
      # SANsリストを整形: DNS:プレフィックスを除去、空白除去、カンマ区切り、重複除去
      SANS_LIST=$(echo "$SANS_TEXT_CLEANED" | sed 's/DNS://g' | tr -d ' ' | tr ',' '\n' | awk '!seen[$0]++' | tr '\n' ',' | sed 's/,$//')
      if [ -n "$SANS_LIST" ]; then
        PRIMARY_SAN_DOMAIN=$(echo "$SANS_LIST" | cut -d',' -f1) # 最初のSANを主要ドメインとする
      fi
  fi

  if [ -n "$PRIMARY_SAN_DOMAIN" ]; then # 主要SANがある場合
      DOMAIN_NAME_DISPLAY="$PRIMARY_SAN_DOMAIN"
      # 主要SAN以外のSANがあれば表示
      OTHER_SANS=$(echo "$SANS_LIST," | sed "s/$PRIMARY_SAN_DOMAIN,//" | sed 's/,$//') 
      if [ -n "$OTHER_SANS" ]; then
          DOMAIN_NAME_DISPLAY="$PRIMARY_SAN_DOMAIN (他のSAN: $OTHER_SANS)"
      fi
      # CNが存在し、かつ主要SANと異なる場合にCNも表示
      if [ -n "$SUBJECT_CN" ] && [ "$SUBJECT_CN" != "$PRIMARY_SAN_DOMAIN" ]; then
          DOMAIN_NAME_DISPLAY="$DOMAIN_NAME_DISPLAY [CNも存在: $SUBJECT_CN]"
      fi
  elif [ -n "$SUBJECT_CN" ]; then # 主要SANが無く、CNがある場合
      DOMAIN_NAME_DISPLAY="$SUBJECT_CN"
      if [ -n "$SANS_LIST" ]; then # SANリスト自体は存在する (CNが主要となるケース)
          IS_CN_IN_SANS=0
          # SANS_LISTを配列に変換して確認しやすくする
          IFS=',' read -r -a SAN_ARRAY <<< "$SANS_LIST"
          for san_entry in "${SAN_ARRAY[@]}"; do
            if [ "$san_entry" = "$SUBJECT_CN" ]; then IS_CN_IN_SANS=1; break; fi
          done
          
          if [ $IS_CN_IN_SANS -eq 0 ]; then # CNがSANリストに含まれていない場合
             # SANリストがCNと異なる場合にのみSANリストを表示 (CNが唯一のSANである場合を除く)
             if [ "$SANS_LIST" != "$SUBJECT_CN" ]; then
                DOMAIN_NAME_DISPLAY="$SUBJECT_CN (SAN: $SANS_LIST)" # SAN -> SANs に統一すべきか検討
             fi
          else # CNがSANリストに含まれている場合、CN以外のSANがあれば表示
             OTHER_SANS_THAN_CN=""
             TEMP_SANS_LIST=""
             for san_entry in "${SAN_ARRAY[@]}"; do
                if [ "$san_entry" != "$SUBJECT_CN" ]; then
                    TEMP_SANS_LIST="${TEMP_SANS_LIST}${san_entry},"
                fi
             done
             OTHER_SANS_THAN_CN=$(echo "$TEMP_SANS_LIST" | sed 's/,$//')

             if [ -n "$OTHER_SANS_THAN_CN" ]; then
                DOMAIN_NAME_DISPLAY="$SUBJECT_CN (他のSAN: $OTHER_SANS_THAN_CN)"
             fi
          fi
      fi
  else # CNもSANも取得できなかった場合
      DOMAIN_NAME_DISPLAY="エラー: コモンネームまたはサブジェクト代替名を抽出できませんでした。"
  fi
  echo "  ドメイン名: $DOMAIN_NAME_DISPLAY"

  # --- 発行局 (サーバー証明書を発行した中間認証局) ---
  # 証明書ファイル内の最初の証明書のIssuerを取得
  ISSUER_CN_RAW=$(openssl x509 -noout -issuer -nameopt multiline -in "$CERT_FILE" 2>/dev/null | grep 'commonName')
  ISSUER_CN="N/A"
  if [ $? -eq 0 ] && [ -n "$ISSUER_CN_RAW" ]; then # grepでcommonNameが見つかったか確認
      ISSUER_CN=$(echo "$ISSUER_CN_RAW" | sed -e 's/^\s*commonName\s*=\s*//' -e 's/\s*(Default)\s*$//' | head -n 1)
  fi
  
  ISSUER_FULL_RAW=$(openssl x509 -noout -issuer -nameopt oneline,-space_eq,-show_type -in "$CERT_FILE" 2>/dev/null)
  ISSUER_FULL="N/A"
  if [ $? -eq 0 ] && [ -n "$ISSUER_FULL_RAW" ]; then
      ISSUER_FULL=$(echo "$ISSUER_FULL_RAW" | sed 's/issuer=//')
  fi

  if [ "$ISSUER_CN" != "N/A" ]; then
    echo "  発行局 (CN): $ISSUER_CN"
    echo "  発行局 (詳細): $ISSUER_FULL"
  else
    echo "  発行局 (詳細): $ISSUER_FULL (CNが見つからないか、CNの抽出エラーです)"
  fi

  # --- 秘密鍵の確認 ---
  # 証明書ファイル名から対応する秘密鍵ファイル名を推測 (例: domain.crt.yyyymm -> domain.key.yyyymm)
  KEY_FILE_CANDIDATE_NAME=$(basename "$CERT_FILE" | sed -E 's/\.crt\.([0-9]{6})$/.key.\1/')
  POTENTIAL_KEY_FILE="$TARGET_DIR/$KEY_FILE_CANDIDATE_NAME"

  if [ -f "$POTENTIAL_KEY_FILE" ]; then
    echo "  秘密鍵ファイル: $(basename "$POTENTIAL_KEY_FILE")"
    KEY_MATCH_STATUS="未確定 (エラーまたは非対応の鍵タイプ)"
    KEY_TYPE="不明"

    CERT_PUBKEY=$(openssl x509 -noout -pubkey -in "$CERT_FILE" 2>/dev/null) # 証明書から公開鍵を抽出
    KEY_IS_ENCRYPTED_OR_BAD_FORMAT=0
    PRIV_KEY_PUBKEY="" # 初期化

    # 鍵の種類を特定し、その公開鍵コンポーネントを取得 ('openssl pkey' は汎用的な鍵読み取り試行)
    if openssl pkey -in "$POTENTIAL_KEY_FILE" -noout >/dev/null 2>&1; then # まず鍵として読めるか
        if openssl rsa -in "$POTENTIAL_KEY_FILE" -noout -check >/dev/null 2>&1; then # RSA鍵か
            KEY_TYPE="RSA"
            PRIV_KEY_PUBKEY=$(openssl rsa -in "$POTENTIAL_KEY_FILE" -pubout 2>/dev/null) # RSA秘密鍵から公開鍵を抽出
        elif openssl ec -in "$POTENTIAL_KEY_FILE" -noout -check >/dev/null 2>&1; then # EC鍵か
            KEY_TYPE="EC"
            PRIV_KEY_PUBKEY=$(openssl ec -in "$POTENTIAL_KEY_FILE" -pubout 2>/dev/null) # EC秘密鍵から公開鍵を抽出
        else # その他の鍵タイプ (DSAなど) か、上記チェックをパスしないがpkeyでは読める鍵
            KEY_TYPE="その他 ('openssl pkey'で解析可能)"
            PRIV_KEY_PUBKEY=$(openssl pkey -in "$POTENTIAL_KEY_FILE" -pubout 2>/dev/null) # 汎用的に公開鍵抽出を試行
        fi
        if [ $? -ne 0 ] || [ -z "$PRIV_KEY_PUBKEY" ]; then # 公開鍵の抽出に失敗した場合
             KEY_IS_ENCRYPTED_OR_BAD_FORMAT=1 # 暗号化されているか、形式に問題がある可能性
        fi
    else # 'openssl pkey' で解析不可の場合
        KEY_IS_ENCRYPTED_OR_BAD_FORMAT=1 # 破損または暗号化の可能性が高い
        KEY_TYPE="読み取り不可または暗号化"
    fi

    if [ "$KEY_IS_ENCRYPTED_OR_BAD_FORMAT" -eq 1 ]; then
        KEY_MATCH_STATUS="鍵の読み取りエラー (暗号化、パスワード保護、または不正な形式の可能性あり)。検出された鍵タイプ: $KEY_TYPE"
    elif [ -n "$CERT_PUBKEY" ] && [ -n "$PRIV_KEY_PUBKEY" ]; then # 証明書の公開鍵と秘密鍵由来の公開鍵が両方取得できた場合
      if [ "$CERT_PUBKEY" = "$PRIV_KEY_PUBKEY" ]; then # 公開鍵同士を比較
        KEY_MATCH_STATUS="証明書と一致 ($KEY_TYPE)"
      else
        KEY_MATCH_STATUS="証明書と不一致 ($KEY_TYPE)"
      fi
    elif [ -z "$CERT_PUBKEY" ]; then # 証明書から公開鍵が取得できなかった場合
      KEY_MATCH_STATUS="証明書からの公開鍵生成エラー"
    else # 秘密鍵ファイルから公開鍵が取得できなかった場合 (鍵は読めたが公開鍵抽出に失敗)
      KEY_MATCH_STATUS="秘密鍵ファイルからの公開鍵生成エラー ($KEY_TYPE)"
    fi
    echo "    鍵の状態: $KEY_MATCH_STATUS"
  else
    echo "  秘密鍵ファイル: $(basename "$KEY_FILE_CANDIDATE_NAME") 見つかりません"
  fi
  echo "--------------------------------------------------"
done < <(find "$TARGET_DIR" -type f -name "*.crt.*[0-9][0-9][0-9][0-9][0-9][0-9]" -print0) # プロセス置換の終了

# このチェックで、ファイルが処理されたかどうかが正しく反映される
if [ "$CERT_FILES_FOUND" -eq 0 ]; then
    echo "ディレクトリ '$TARGET_DIR' 内に *.crt.*[数字6桁] のパターンに一致する証明書ファイルは見つかりませんでした。"
    echo "(例: domain.com.crt.202312)"
fi

これを `ssl-check.sh` として保存し、実行権限を付けます。

使用例

./ssl-check.sh /ディレクトリのフルパス

で実行した結果、

ディレクトリ '/hoge/' 内のSSL証明書情報:
==================================================
処理中の証明書: hoge.example.com.crt.202505
  有効期限: Aug 28 23:17:58 2025 GMT
  ドメイン名: *.hoge.example.com
  発行局 (CN): E5
  発行局 (詳細): C=US, O=Let's Encrypt, CN=E5
  秘密鍵ファイル: hoge.example.com.202505
    鍵の状態: 証明書と一致 (EC)
--------------------------------------------------

と、

  • 有効期限
  • ドメイン名
  • 自己証明でないか(発行局から発行されているか)

が明示的に分かるようになりました。

Ubuntu 24.04 aptitude updateエラー対応メモ(aptコマンドのLabel変更にによるパッケージリストの変更)

ちょっとハマったのでメモです。

環境

  • OS: Ubuntu 24.04

発生した問題

sudo aptitude update を実行した際に、特定のPPA (PHPリポジトリ) でエラーが発生し、パッケージリストの更新に失敗しました。
(※筆者の好みでaptitudeを用いています)

エラーメッセージの抜粋:

E: Repository 'https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble InRelease' changed its 'Label' value from '***** The main PPA for supported PHP versions with many PECL extensions *****' to 'PPA for PHP'
E: Failed to download some files
W: https://ppa.launchpadcontent.net/ondrej/php/ubuntu/dists/noble/InRelease を取得できませんでした:
E: 一部のインデックスファイルのダウンロードに失敗しました。無視されたか古いものを代わりに利用しています。

Ubuntu24.04をインストールしたばかりの頃に追加したリポジトリが古くなり、アップグレードができないという状態でした。

対処方法

以下の通りに実施しました。

リポジトリの Label 変更を許可

sudo apt update --allow-releaseinfo-change

変更許可後のupdate

sudo aptitude update

これにより、上記のエラーが解消され、正常にパッケージのアップグレードが成功しました。

Ubuntu 20.04環境でGrowi アップデート (v7.0.11 → v7.2.2) 失敗と MongoDB 切り戻しのメモ。

概要

以下の環境でGrowi v7.0.11 から v7.2.2 へのアップデートを試みたものの、サーバーのCPUハードウェア制約により断念し、データベース (MongoDB) を元の安定バージョンへ切り戻しました。

その時のメモです。

作業前の環境

  • OS: Ubuntu 20.04 LTS (Focal Fossa)
  • Growi: v7.0.11
  • Node.js: v18.20.8
  • MongoDB: v4.4.9

目指したこと

  • まずはMongoDB を Growi v7.2.2 が要求する v6.0 以上へアップデートする。

詰まったところ

Growi v7.2.2 の要求事項確認

  • Node.js: v18 以上のためOK。
  • MongoDB: v6.0 以上が必要だったため、現在の v4.4.9 アップデートが必要。

MongoDB段階的アップデート計画

MongoDB v4.4 から v6.0 へは、段階的なアップグレード (4.4 → 5.0 → 6.0 の順) が推奨されるため、まず MongoDB v5.0 へのアップデートに着手しました。

MongoDB 5.0 のGPGキー追加:

wget -qO - https://www.mongodb.org/static/pgp/server-5.0.asc | sudo apt-key add -

MongoDB 5.0 のリポジトリリストファイル作成:

echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/5.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-5.0.list

パッケージリストの更新:

sudo aptitude update
sudo aptitude upgrade

CPUのAVX命令セット非対応問題の発覚

バージョンアップを確認するため

mongod --version

を実施しましたが、Illegal instruction (コアダンプ) というエラーが発生しました。

調査の結果、MongoDB v5.0 以降ではCPUがAVX (Advanced Vector Extensions) 命令セットをサポートしていることが必須要件となっていることが判明。

grep -q avx /proc/cpuinfo && echo "AVX supported" || echo "AVX not supported"

AVX not supportedと表示されたため、現在のサーバーでは MongoDB v5.0 及びそれ以降のバージョン (v6.0を含む) を動作させることが不可能であると結論。

そのため、目指したMongoDBのアップデートもGrowiのバージョンアップも断念。

MongoDB の切り戻し作業 (v4.4.x へ)

なので、切り戻しを行います。単にバージョンを指定してのインストールはうまくいきませんでした。

というのも依存関係の解決時に libc6 >= 2.34libssl3 (Ubuntu 22.04 Jammy のライブラリ) を要求するエラーが発生したからです。

これは、

/etc/apt/sources.list.d/

ディレクトリに最初のMongoDBのアップデート時のリポジトリが残っていたためです。

不要なMongoDBリポジトリ設定の削除

sudo rm /etc/apt/sources.list.d/mongodb-org-5.0.list
sudo rm /etc/apt/sources.list.d/mongodb-org-6.0.list

インストール済みパッケージのクリーンアップ

sudo aptitude purge mongodb-org mongodb-org-database mongodb-org-database-tools-extra mongodb-org-mongos mongodb-org-server mongodb-org-shell mongodb-org-tools mongodb-database-tools mongodb-mongosh

MongoDB v4.4 用GPGキーの再設定

wget https://www.mongodb.org/static/pgp/server-4.4.asc &&  sudo apt-key add server-4.4.asc
sudo aptitude update

MongoDB v4.4.x のインストール

apt-cache policy mongodb-org-server

インストール候補がMongoDB v4.4系であることを確認。

sudo aptitude install mongodb-org-server=4.4.29 mongodb-org-shell=4.4.29 mongodb-org-tools=4.4.29` 

動作確認

mongod --version

以下を確認。

db version v4.4.29
Build Info: {
    "version": "4.4.29",
    "gitVersion": "f4dda329a99811c707eb06d05ad023599f9be263",
    "openSSLVersion": "OpenSSL 1.1.1f  31 Mar 2020",
    "modules": [],
    "allocator": "tcmalloc",
    "environment": {
        "distmod": "ubuntu2004",
        "distarch": "x86_64",
        "target_arch": "x86_64"
    }
}
systemctl status mongod

active(running)を確認。

この切り戻しにより、Growi が正常に動作することを確認しました。

MongoDB パッケージの固定 (Hold)

sudo aptitude hold mongodb-org-server mongodb-org-shell mongodb-org-tools

として、不要なアップデートを防ぐ措置を執りました。

結論

そもそもの問題として、いくらローカル環境とは言え、既にEOLを迎えているUbuntu20.04の延命措置を執ろうとしたことが誤りです。

また、OSのバージョンアップをしたとしてもCPUが対応していないと言うことが判明したことは、ハードウェアのリプレースも必要だという現実も突きつけられました。

いい機会なので、自宅のローカル環境の見直しを図ります。

Nextcloudのアプリ、Memoriesの警告に対処。(ffmpegインストール)

Nextcloudのアルバムアプリ、Memoriesのエラーに対処します。

環境

  • Nextcloud 31.0.4
    • Memories 7.5.2
  • Ubuntu 22.04
  • Apache 2.4
  • php 8.2
  • MySQL 8

事象

Nextcloudの管理画面、Memoriesの項目で、

ffmpeg preview binary not found. Thumbnail generation may not work for videos.

と出たので、この警告メッセージに対処します。

意味としては

  • Nextcloudがサムネイルを作成する際にffmpegを利用するが見つからなかった。
  • 特に、動画のサムネイルがうまく表示されない。

対処

Nextcloudがインストールされているサーバのターミナル(SSH接続)で実施します。

  • ffmpegインストール

※筆者の好みでaptitudeを用いています。

sudo aptitude update
sudo aptitude install ffmpeg
  • インストール確認
which ffmpeg

→ 上記方法であれば、/usr/bin/ffmpegと表示されます。

対処後の確認

再度、Nextcloudの管理画面からMemoriesへと進み、上記の警告が消えていることを確認します。

そこで、その下にあるトグルを変更していきます。以下、オンにした方がいい項目です。

  • Images (JPEG, PNG, GIF, BMP):一般的なイメージ画像
  • HEIC (Imagick): Appleデバイスで利用するイメージ画像
  • Videos (ffmpeg): 動画(サーバ上にこれが無いために警告が出ていたため)

これらを設定後、Memoriesアプリでサムネイルが作成されているかを確認します。

手動でのサムネイル生成

※ファイル数によっては時間がかかり、サーバのリソースをそれなりに消費するため、負荷が少ない時間帯で行った方が望ましいです。

  • Nextcloudのルートディレクトリに移動
cd /path/to/nextcloud/root/directory && pwd

※筆者環境 /home/www-data/nextcloud

  • occによるサムネイル生成
sudo -u www-data php occ preview:generate-all

sudo -u www-dataの実行権限については自分の環境に合わせます。(RockyLinux等のRHEL系ディストリビューションはapachehttpdなどです)

NextcloudのWebからのアップデート失敗時の対処。(コマンドラインによるNextcloudのアップデート)

NextcloudはWebからアップデートが行えますが、

  • バックアップ
  • ダウンロード
  • 整合性チェック

等で失敗し、リトライをしてもまた同じところで詰まるというケースが非常に多いです。

(例ではDownloading)で失敗しています。

そこで、その回避策(というかより安定している手段)として、コマンドラインによるアップデートを実施します。

作業確認環境

筆者環境です。マイナーバージョンなどは実施環境に合わせます。

  • Ubuntu 22.04
  • Nextcloud 31.03 → 31.04へのアップグレード
  • Apache (ユーザwww-dataで実行)
  • MySQL
  • php 8.2.28

さっくりとした手順

  1. メンテナンスモードを有効化します。
  2. Nextcloud一式のバックアップを行います。
  3. Nextcloudで用いているDBのバックアップを取ります。
  4. コマンドラインでアップデートがあるかのチェックを行います。
  5. コマンドラインでNextcloudのアップグレードを行います。
  6. バージョンアップを確認します。

メンテナンスモードを有効化

  • Nextcloudのルートディレクトリ移動
cd /path/to/nextcloud/root/directory && pwd

自分の環境に合わせます。(筆者環境/home/www-data/nextcloud)

  • メンテナンスモード有効化
sudo -u www-data php occ maintenance:mode --on
  • メンテナンスモード確認

運用中のNextcloudのURLにアクセスし、メンテナンスモードであることを確認します。

Nextcloudのバックアップ

  • Nextcloudの一式バックアップ
sudo -u www-data cp -pir /home/www-data/nextcloud /path/to/backup/directory/nextcloud.$(date +%Y%m%d)
  • 退避前、退避先、バックアップ先のアクセス権限などはそれぞれ自分の環境に合わせます。
  • このバックアップ方法はあくまでも例です。
  • ※プログラムによっては非常に膨大なファイル数が予想されます。適切なバックアップ手段を考慮してください。
  • vpsなどで動かしている場合は、スナップショットを撮っておいて、後から復元した方が確実です。

  • バックアップ確認
ls -l /path/to/backup/directory/nextcloud.$(date +%Y%m%d)

退避先にディレクトリファイル一式があることを確認します。

mysqldumpでバックアップを取得する

  • 作業ディレクトリに移動
cd /hoge && pwd

任意のディレクトリを指定します。

  • DBバックアップ作成
mysqldump -h localhost -u nextcloud -p --no-tablespaces --single-transaction nextcloud > nextcloud_backup.$(date +%Y%m%d).sql

DB名やユーザーは自分の環境に合わせます。

  • DBバックアップ作成確認
ls -la nextcloud_backup.$(date +%Y%m%d).sql

ファイルがあることを確認します。

Nextcloudのアップグレードチェック

  • Nextcloudのルートディレクトリ移動
cd /path/to/nextcloud/root/directory && pwd

自分の環境に合わせます。(筆者環境/home/www-data/nextcloud)

  • occコマンドによるアップグレード確認
sudo -u www-data php occ update:check

表示例

Nextcloud 31.0.4 is available. Get more information on how to update at https://docs.nextcloud.com/server/31/admin_manual/maintenance/upgrade.html.
Update for side_menu to version 5.1.0 is available.
Update for spreed to version 21.0.4 is available.

と出たので、アップグレードはコマンドラインでも有効です。

コマンドラインによるアップグレード

sudo -u www-data php occ upgrade
  • 新しいバージョンのダウンロード
  • コードの展開
  • データベーススキーマの更新
  • アプリの更新

を一括で行ってくれるコマンドです。

Keep maintenance mode active? [y/N] 

nでメンテナンス画面から抜けます。

Webでのアップグレード確認

管理者権限でNextcloudにブラウザでアクセスし、

  1. 管理画面からアップグレードされていること
  2. 他の機能が使えること

を確認できれば成功です。


切り戻し

失敗したときの手順です。再度、バックアップ一式があることを確認してください。なお、失敗したことを前提にしているため、再度の切り戻しは一切考慮しません。

  • アップグレードに失敗したファイル一式の削除
sudo rm -rf /home/www-data/nextcloud 
  • バックアップからの切り戻し
sudo mv /path/to/backup/directory/nextcloud.$(date +%Y%m%d) /home/www-data/nextcloud
  • 管理者権限でMySQLにログインする
mysql -u root -p
  • 対象のDBを確認する
SHOW DATABASES;

nextcloudが動いているDBであることを再確認してください。

  • 本当に削除すべきDBかを確認する
SELECT COUNT(*) FROM nextcloud.oc_users;
  • 不具合が発生したDBを削除する

二回ほど深呼吸して、落ち着いて作業しましょう。

DROP DATABASE nextcloud;
  • DBを再作成する
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
  • MySQLから抜ける
EXIT
  • DB復元
mysql -h localhost -u nextcloud -p nextcloud < /hoge/nextcloud_backup.$(date +%Y%m%d).sql

この後、メンテナンスモードを解除して、以前と同じ状態か確認します。

sudo -u www-data php occ maintenance:mode --off

作業後:バックアップDBの削除

平文でSQLがサーバ上にあるのは危険な状態なので、以下の措置を執ります。

  • 作業ディレクトリに移動
cd /hoge && pwd

バックアップを行ったディレクトリを指定します。

  • DBバックアップ確認
ls -la nextcloud_backup.$(date +%Y%m%d).sql

ファイルがあることを確認します。

  • バックアップしたDBの削除
shred -u nextcloud_backup.$(date +%Y%m%d).sql
  • DBバックアップ削除確認
ls -la nextcloud_backup.$(date +%Y%m%d).sql

ファイルが無いことを確認します。

DBのデータ容量を確認するSQL文

概要

MySQLの運用時、「このDBはどのぐらいのディスク容量を消費しているのか?」は日々のメンテナンスのみならずバックアップや移行などにも気になるところ。

そんな確認方法についてのTIPSです。

環境

以下のサーバで動作を確認しました。

  • Ubuntu 22.04 / Ubuntu 24.04
  • MySQL 8.0.x

前提

  • MySQLターミナルで操作します。
  • そのDBへのSELECT権限を持っていなければ操作できません。

操作

  • MySQLログイン
mysql -u user -p

自分の環境に合わせます。

  • DB確認
SHOW DATABASES;

ここで、参照したいDB名を確認します。

  • SQL実行
SELECT
    table_schema AS 'データベース名',
    SUM(data_length + index_length) AS '合計サイズ(バイト)',
    SUM(data_length) AS 'データサイズ(バイト)',
    SUM(index_length) AS 'インデックスサイズ(バイト)',
    -- 人が読みやすいようにメガバイト(MB)やギガバイト(GB)でも表示
    ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS '合計サイズ(MB)',
    ROUND(SUM(data_length) / 1024 / 1024 / 1024, 2) AS '合計サイズ(GB)'
FROM
    information_schema.TABLES
WHERE
    table_schema = '調べたいデータベース名' -- ここにサイズを知りたいデータベース名を入力してください
GROUP BY
    table_schema;
  • 表示例
+-----------------------+----------------------------+-------------------------------+----------------------------------------+---------------------+---------------------+
| データベース名        | 合計サイズ(バイト)         | データサイズ(バイト)          | インデックスサイズ(バイト)             | 合計サイズ(MB)      | 合計サイズ(GB)      |
+-----------------------+----------------------------+-------------------------------+----------------------------------------+---------------------+---------------------+
| nextcloud             |                  432685056 |                     163741696 |                              268943360 |              412.64 |                0.15 |
+-----------------------+----------------------------+-------------------------------+----------------------------------------+---------------------+---------------------+
1 row in set (0.01 sec)

この例では、DB「nextcloud」に対して412MBのデータを消費していることが明らかになりました。

Ubuntu 24.04にNextcloudをインストール

Ubuntu 20.04もEOLを迎えたため、こちらのバージョンでのインストールを確認です。

前提

以下が稼働済みです。

  • OS: Ubuntu 24.04 LTS
  • データベース: MySQL 8.0 (Ubuntu 24.04 の標準リポジトリで利用可能)
  • Webサーバー: Apache 2.4 (Ubuntu 24.04 の標準リポジトリで利用可能)
  • ドメインと証明書: Nextcloud を設定するドメイン名と、それに対応する有効なSSL/TLSサーバー証明書(例: Let's Encrypt などで取得したもの)が準備されていること。

さっくりとした手順

※SSHログインし、ターミナルでの操作を行います。

  1. 必要なPHPパッケージ(PHP 8.3 と関連モジュール)をインストールします。
  2. PHPの設定(メモリ制限、OPcache、APCu)を行います。
  3. Nextcloud用のデータベースとユーザーを作成します。
  4. Nextcloudの最新版プログラムをダウンロードし、適切な場所に配置します。
  5. Nextcloudを動かすためのApache設定ファイルを設定します。
  6. Webブラウザで設定を行います。

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

  • PHP・モジュールインストール
sudo aptitude install php8.3 php8.3-fpm php8.3-opcache php8.3-pdo php8.3-bcmath php8.3-calendar php8.3-ctype php8.3-fileinfo php8.3-ftp php8.3-gd php8.3-intl php8.3-json php8.3-mbstring php8.3-mysql php8.3-posix php8.3-readline php8.3-sockets php8.3-bz2 php8.3-tokenizer php8.3-zip php8.3-curl php8.3-iconv php8.3-xml php8.3-imagick php8.3-gmp php8.3-apcu libapache2-mod-php8.3
補足
  • php8.3-fpm: Apache で mod_php の代わりに PHP-FPM を使用する場合にインストールします。(今回は libapache2-mod-php8.3 を使っていますが、FPMの方がパフォーマンスや分離の点で推奨される場合もあります)。もしFPMを使う場合はApacheの設定も変わります。この手順ではlibapache2-mod-php8.3(mod_php)を前提とします。
  • php8.3-ldap: LDAP/AD連携を使用する場合にインストールしてください。
  • php8.3-dev: 通常の運用には不要ですが、PECLなどで拡張機能をコンパイルする場合に必要です。
  • Apache再起動
sudo systemctl restart apache2.service
  • PHPインストール確認
php -v

表示例:PHP 8.3.n

PHPの設定を行います。

Nextcloud のパフォーマンスと安定性のために、PHPの設定を調整します。

  • memcacheとAPCuの有効化
cd /etc/php/8.3/cli/conf.d

以下のファイルのように修正します。ない場合は、以下のように追記します。

cat <<- __EOF__ | sudo tee -a /etc/php/8.3/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.3/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__
  • php.iniバックアップ
sudo cp -pi /etc/php/8.3/apache2/php.ini /path/to/backup/php.ini.$(date +%Y%m%d)

任意のバックアップディレクトリを指定します。

  • バックアップ確認
diff -u /path/to/backup/php.ini.$(date +%Y%m%d) /etc/php/8.3/apache2/php.ini 

差分が存在しないことにより、バックアップが取れていることを確認します。

  • sedによるファイル書き換え
sudo sed -i 's/memory_limit = .*/memory_limit = 512M/g' /etc/php/8.3/apache2/php.ini

memory_limitを推奨値の512Mに置き換えます。

  • 書き換え後の差分確認
diff -u  /path/to/backup/php.ini.$(date +%Y%m%d) /etc/php/8.3/apache2/php.ini
  • 差分
-memory_limit = 128M
+memory_limit = 512M
  • apache 再起動
sudo systemctl restart apache2.service

NextcloudのDBを作成します。

  • MySQLにroot権限でログイン
mysql -u root -p
  • MySQLユーザ追加
CREATE DATABASE IF NOT EXISTS nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nextcloud'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YOUR_STRONG_PASSWORD';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost';
FLUSH PRIVILEGES;
EXIT;

★重要: YOUR_STRONG_PASSWORD は必ず推測されにくい強固なパスワードに変更してください。

IDENTIFIED WITH mysql_native_password BY は MySQL 8.0 で推奨される認証方式の一つです。

  • 追加したNextcloud用ユーザでログイン
mysql -u nextcloud -p

設定したパスワードでログインできることを確認します

  • DB作成確認
SHOW DATABASES;

作成したデータベースnextcloudがあることを確認します

EXIT;

Nextcoludのプログラムを配置します。

  • 作業用ディレクトリ移動
cd /hoge && pwd

任意の作業用ディレクトリを指定します。

  • ファイル取得
wget https://download.nextcloud.com/server/releases/latest.zip
unzip latest
  • Web公開用ディレクトリにファイル一式を移動
sudo mv nextcloud /home/www-data/

自分の環境に合わせます。(筆者はファイルサーバとして運用するので、/home領域に設置しました)

  • 所有者変更
sudo chown -R www-data:www-data /home/www-data/nextcloud

Apacheの設定ファイルを作成します。

  • ログディレクトリの作成
sudo mkdir /var/log/nextcloud

環境に合わせます。

  • ディレクトリの所有者変更
sudo chown www-data:www-data /var/log/nextcloud
  • nextcloud用の設定ファイル作成
  • 【】部分は自分の環境に合わせます。
cat <<- __EOF__ | sudo tee -a /etc/apache2/sites-available/nextcloud.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/nextcloud/nextcloud_access.log combined
    ErrorLog /var/log/nextcloud/nextcloud_error.log
    DocumentRoot 【/home/www-data/nextcloud】
    # 上記手順で指定したディレクトリです
    <Directory 【/home/www-data/nextcloud】>
    # 上記手順で指定したディレクトリです
        Options -MultiViews
        AllowOverride All
        Require all granted
    </Directory>

#SSL設定
  SSLEngine on
    Protocols h2 http/1.1
  # SSLを有効化します

SSLCertificateFile 【/etc/certs/hoge.example.com.crt】
# SSL証明書を指定します
SSLCertificateKeyFile 【/etc/private/hoge.example.com.key】
# 秘密鍵を指定します

# SSLCACertificateFile 【/etc/certs/hoge.example.com.CA.crt】
# 中間証明書が発行元から別ファイルで提供されている場合は、この直上をコメントアウトして中間証明書を指定します

    # 推奨されるSSL/TLS設定 (Mozilla Intermediate Compatibility)
    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     on
    SSLCompression          off
    SSLSessionTickets       off # PFSを強化する場合

    # OCSP Stapling (パフォーマンス向上)
    SSLUseStapling On
    SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"

    # セキュリティヘッダー
    Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
    Header always set Referrer-Policy "no-referrer"
    Header always set X-Content-Type-Options "nosniff"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set X-Permitted-Cross-Domain-Policies "none"

</VirtualHost>
__EOF__
  • Apache設定ファイル反映
sudo a2ensite nextcloud.conf
  • 設定ファイルのコンフィグ確認
sudo apache2ctl configtest

Syntax OKを確認します

  • Apache再起動
sudo systemctl restart apache2.service

ブラウザ上でNextcloudのセットアップを行います。

  • ブラウザでアクセス

ブラウザで、

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

にアクセスし、以下を確認してください。

  • 以下のセットアップ画面が出ること。
  • httpがhttpsとなっていること。

以下を入力して「インストール」をクリックします。

  • ユーザ名:
  • 管理者のユーザ名
  • パスワード:
  • 管理者パスワード
  • データベースのユーザー名
  • 作成したユーザー名(nextcloud)
  • データベースのパスワード
  • 設定したデータベースのパスワード
  • データベース名
  • 作成したデータベース(nextcloud)
  • データベースのホスト名
  • localhost:3306
    • (MySQLのポート番号)

推奨アプリのインストールに関しては、好みでスキップかインストールを行ってください。

インストールが完了したら、以下のような画面が出ます。

Page 3 of 50

Powered by WordPress & Theme by Anders Norén