カテゴリー: PC Page 26 of 51

Redmineの不正アクセス対策。(ufwと二段階認証)

概要

AWS Lightsailに構築しているRedmine。 不審なアクセスがあったので対応を行いました。

アクセスの内容

とてもシンプルに、チケットの新規発行画面に何回もアクセスしているというもの。

正規のリクエストなのでWAFでブロックされません。(解析システム:matomoで検知した次第です)

そもそも自分しかアカウントを用意していないため、この時点で不正アクセスの兆候だと判断。以下、対処を行います。

ufwでの処理

  • ufwによるブロック
sudo ufw deny from IPアドレス
# より確実を期すためにIPアドレスのネットワークアドレスを指定しました (xxx.xxx.xxx.0/24)
  • 設定確認
sudo ufw status numbered
# Anywhere DENY IN 上記で指定したIP/ネットワークアドレスを確認します
  • 設定反映
sudo ufw reload
# ファイアウォールを再読込しましたと出れば反映完了です

これでひとまず不審なアクセス元は遮断。

Redmineログイン強化

筆者が用いているRedmine4.2は二段階認証が標準で備わっていますので、それを有効化します。

  1. Redmineに管理者権限でログインします。
  2. 万一に備えて別のブラウザでもログインしっぱなしにします。
  3. 管理>設定>認証に移動します。
  4. 二段階認証を「必須」にして保存します。

その後、(別ブラウザでログインしたまま)Redmineにログイン。

後は二段階認証プロセス(Google認証システムを用いました)で指示に従ってQRコードを読み込み、生成されたコードを読み込むだけ。

ひとまず、これでID/PWによるログインに加えて認証システムの二段階で不正アクセスの被害を抑えます。

growi v6.0.15 → v6.1.0へのバージョンアップ後の処理。

結論から始まる概要

「リリースノートはよく読んでおくこと」

です。

Growi v6.1.0の変更点

バージョンアップ後、今まで表示されていた画像がうまく表示されない問題点がありました。

どうしたものかと更新情報を読み返したら

https://docs.growi.org/ja/admin-guide/upgrading/61x.html#%E7%AE%A1%E7%90%86%E8%80%85%E5%90%91%E3%81%91

と思いっきり書かれておりました。

では、GrowiをインストールしたLinuxサーバで対処を行います。

前提

  • Growi v6.1.0にバージョンアップした
  • 添付ファイルをローカルに保存

が作業の前提です。また、

  • Ubuntu 20.04
  • ディレクトリは'/opt/growi'

となっています。

実施した手順

Growiインストールディレクトリに移動

cd /opt/growi/packages/app/public/uploads && pwd
# 上記ディレクトリにいることを確認します。

添付ファイルディレクトリを移動

sudo mv attachment /opt/growi/apps/app/public/uploads/
sudo mv user /opt/growi/apps/app/public/uploads/

移動確認

cd /opt/growi/apps/app/public/uploads/ && pwd
# 上記ディレクトリにいることを確認します。

ls -l attachment
ls -l user
# 移動したディレクトリがあることを確認します。

作業後の確認

バージョンアップ前に投稿した添付ファイルがある記事で、ファイルが表示されていることを確認しました。

Redmineによる旅の準備とフィードバック。

Redmineコメントのテンプレート

個人的に用いているRedmine。一つのチケットにコメントを連ねていくことで、準備や事前情報などを系統立てて表示させることができます。

そこで「携行品はある程度傾向があるから、テンプレートプラグインで管理できそうだ」

と、こういう風にコメントテンプレートで管理。

しかし、ここに落とし穴がありました。

想定の漏れ

これは家族に言われて気づいたことです。

  • 東京都心と山間は気温がまるで違うこと
  • 温泉の湯冷め

などを全く考慮していませんでした。思い直してリパッキング。

この状況もチケットに書き足していきます。

そうして、旅の途上での出来事も次々に書いていき、

デブリーフィング

もチケット自体に記載。

こうして、旅自体を振り返りながら

  • 何をミスっていたか
  • 次はどうすれば良いか
  • 印象に残っていたことは

なども気軽に書けるので、そこは、Redmineを運用して良かったと思ったわけで。

growi v6.0.15 → v6.1.0へのバージョンアップでハマったこと。

概要

日々の記録に、ブログ/redmineの下書きに、思考の整理にと役立っているgrowi。

https://github.com/weseek/growi/releases/tag/v6.1.0

で、growiの新しいバージョンを確認したので実施しましたが、ハマりましたのでメモとして残します。

アップデートした環境

  • growi 6.0.15
  • Ubuntu 20.04
  • mongodb 4.4.13
  • node 14.21.3 (後述するバージョンアップによりv18.16.0)

また、以下を実施済みです。

実施手順

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

こちらに沿って実施しました。

  1. growiのサービスを停止します。
  2. gitコマンドで最新版を引っ張ります。
  3. アップグレードを行います。
  4. growiのサービスを再開します。
  5. アップグレードされたことを確認します。

ハマったこと1:nodeのバージョンが合わない

  • 実行コマンド
sudo yarn
  • エラー
[1/5] Validating package.json...
error growi@6.1.0: The engine "node" is incompatible with this module. Expected version "^16 || ^18". Got "14.21.3"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

とあったので、nodeのバージョンアップが必要でした。

ハマったこと1への対処

以下の記事で、最新安定版のnode.jsに差し替えました。

https://manualmaton.com/2023/03/15/

nodeのアップデート後、正常にyarnを行うことができました。

ハマったこと2: 起動スクリプトが動作しない。

sudo systemctl start growi.service

を実行しても起動せず。

systemctl status growi.service

で状況を確認します。

/bin/sh: 1: turbo: not found

というエラーが出ました。

ハマったこと2への対処

1への対処時、付随するnpmパッケージを削除したことが原因です。

sudo npm install -g turbo

として、再度

sudo systemctl start growi.service

を実行。

systemctl status growi.service

起動を確認しました。

実行後

このバージョンアップは是が非でも行いたいものでした。

なぜなら、念願のmermaid.jsが実装されたからです。

これで、別のアプリを起動せず、growiのみでのmermaid記法が楽になりました。

Nextcloud管理画面での警告対応。(occ実行)

概要

Nextcloudをバージョンアップ後、以下のような警告が管理画面で出てきました。

セットアップに関して警告がいくつかあります。
データベースにいくつかのインデックスがありません。 大きなテーブルにインデックスを追加すると、自動的に追加されないまでに時間がかかる可能性があるためです。 "occ db:add-missing-indices"を実行することによって、インスタンスが実行し続けている間にそれらの欠けているインデックスを手動で追加することができます。 インデックスが追加されると、それらのテーブルへのクエリは通常はるかに速くなります。
テーブル "oc_filecache"のインデックス "fs_parent"が見つかりません。

環境

  • Ubuntu 20.04
  • PHP8.1
  • Nextcloud 26.0.1
  • Apache 2.4

での対応です。

実施内容

  • コマンド
cd /var/www/html/ && pwd
# Nextcloudのあるディレクトリに移動します
          
sudo -u www-data /bin/php occ db:add-missing-indices
# Webサービスの実行者(ここではwww-data)を指定します  
  • 処理例
Check indices of the share table.
Check indices of the filecache table.
Adding additional parent index to the filecache table, this can take some time...
Filecache table updated successfully.
Check indices of the twofactor_providers table.
Check indices of the login_flow_v2 table.
Check indices of the whats_new table.
Check indices of the cards table.
Check indices of the cards_properties table.
Check indices of the calendarobjects_props table.
Check indices of the schedulingobjects table.
Check indices of the oc_properties table.
Check indices of the oc_jobs table.
Check indices of the oc_direct_edit table.
Check indices of the oc_preferences table.
Check indices of the oc_mounts table.

実施後

Nextcloudの管理画面でリロードを行いました。

全てのチェックに合格しました。

と出たのでOKです。

プログラム自身がチェックを行ってくれるのがNextcloudの強み。

ChatGPTによるRubyスクリプト。(エラーログ検索)

割とシンプルながら、障害などの特定を効率よくするためのスクリプトを書いてもらいました。

質問

以下の通りです。

以下を満たすスクリプトを書いてください。

1. プロンプトにてエラーログをフルパスで質問
1-1. エラーログが見つからなければ「ファイルがありません」を返して終了
2. プロンプトにて検索したい単語を指定
3. 検索単語にて行数を表示
4. 「○件見つかりました。該当する行を表示しますか?」でy/n確認
4-1. nの場合は処理を終了
4-2. yの場合は該当行を表示して終了

結果

ほぼ一発で想定通りの動きを見せるスクリプトを書いてもらいました。

# 1. プロンプトにてエラーログをフルパスで質問
print "エラーログのフルパスを入力してください: "
error_log_path = gets.chomp

# 1-1. エラーログが見つからなければ「ファイルがありません」を返して終了
unless File.exist?(error_log_path)
  puts "ファイルがありません"
  exit
end

# 2. プロンプトにて検索したい単語を指定
print "検索したい単語を入力してください: "
search_word = gets.chomp

# 3. 検索単語にて行数を表示
line_numbers = []
File.open(error_log_path, "r") do |file|
  file.each_line.with_index(1) do |line, line_number|
    line_numbers << line_number if line.include?(search_word)
  end
end

puts "#{line_numbers.length}件見つかりました。"

# 4. 「○件見つかりました。該当する行を表示しますか?」でy/n確認
unless line_numbers.empty?
  print "該当する行を表示しますか? (y/n): "
  display_lines = gets.chomp.downcase
  if display_lines == "y"
    File.open(error_log_path, "r") do |file|
      file.each_line.with_index(1) do |line, line_number|
        if line_numbers.include?(line_number)
          puts "行 #{line_number}: #{line.chomp}"
        end
      end
    end
  else
    exit
  end
else
  exit
end

エディタに記述、保存後に

ruby search_log.rb

を実行。

これで、

  • 怪しそうな箇所の行数
  • その詳細

などを絞ることが可能になり、ここからの加工も容易になります。

ChatGPTによるシェルスクリプト(パッケージの自動更新)の問題点と修正。

この記事の更に続きとなります。

以前作成したスクリプトに問題点があったので修正します。

問題点詳細

アップデートするパッケージによってはコンフィグを残すか否かをアップデート中に聞いてきます。

このプロンプトが表示されるとスクリプトは停止。処理を手動で中断して実行する羽目になります。

これを回避するため、以下のように修正いたしました。

修正差分

-    aptitude -y full-upgrade | tee $upgraded_packages >/dev/null
+    DEBIAN_FRONTEND=noninteractive aptitude -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" full-upgrade | tee $upgraded_packages >/dev/null

修正した処理の詳細

※chatGPTの回答なので信頼性は各自ご判断ください。

  1. DEBIAN_FRONTEND=noninteractive : DEBIAN_FRONTEND 環境変数に noninteractive を設定し、aptitude コマンドを非対話モードで実行します。これにより、パッケージの更新時に表示される確認メッセージを自動的に承認することができます。
  2. aptitude -y : aptitude コマンドに -y オプションを指定して、すべての質問に対して自動的に yes を返答するようにします。
  3. -o Dpkg::Options::="--force-confdef" : dpkg コマンドに --force-confdef オプションを指定して、パッケージがインストールされる際に必要なデフォルトの設定値を使用するように指定します。
  4. -o Dpkg::Options::="--force-confold" : dpkg コマンドに --force-confold オプションを指定して、既存のコンフィグファイルを保持するように指定します。
  5. full-upgrade : aptitude コマンドの full-upgrade オプションを指定して、すべてのパッケージを最新バージョンに更新します。
  6. | tee $upgraded_packages >/dev/null : 更新されたパッケージのリストを一時ファイルに保存します。パイプライン演算子 | を使用して、aptitude コマンドの出力を tee コマンドに送信し、同時に一時ファイルに書き込むように指定します。>/dev/null を追加することで、標準出力を無効化し、結果を表示しないようにします。

修正後のスクリプト全文

#!/bin/bash

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

# aptitude updateを行います。
aptitude update

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

    # パッケージのキャッシュをクリアした上でパッケージアップグレードを実施。
    aptitude clean
    DEBIAN_FRONTEND=noninteractive aptitude -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" full-upgrade | tee $upgraded_packages >/dev/null

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

   # 新しいパッケージ名を取得
   DIFF_FILE="package_diff_$now1.txt"
   NEW_PACKAGES=$(grep -E "^\+[^+]" $DIFF_FILE | awk '{print $1}' | cut -c 2-)

   # 変更されたパッケージの数と、新しいバージョンのパッケージ名のリストを表示
   UPDATED_PACKAGES=$(echo "$NEW_PACKAGES" | wc -l)
   echo "$UPDATED_PACKAGES 件のパッケージに変更がありました。以下のパッケージが更新されました:"
   echo "$NEW_PACKAGES"

    # 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
        # ファイル名に日付を追加
        now2=$(date +%Y%m%d)
        filename="restart_services_$now2.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

これでコンフィグを残すか否かのアップデートでも停止することなく動きましたが、肝心の

  • どのパッケージがコンフィグを残すか否か求められたか
  • その差分は何か

などが不明。なので、改善点はまだまだです。

Redmine Addtional Tagsによる一括タグ付け。

こちらを更に発展させました。

https://atelier.reisalin.com/projects/ryza3/issues

こうして、ゲーム『ライザのアトリエ3』の見聞録などの情報をチケットかできたものの、もっと付与したい情報がありました。

「タグ付け」による分類です。

既にあるプラグイン「Additonal Tags」でどうにかなりました。(というよりも使っている内に気づきました)

こんな形のタグ付けされていないチケット。

全て選択して

右クリックから「tags」を選択。

付与したいタグを入れていき、「追加」をクリック。

追加後、しっかりとチケットにタグが付与されていることを確認。

これで、諸々の整理がもっと楽になります。

『ライザのアトリエ3』三周目の記録と高難易度の挑戦。

一周目と二周目の概要

  1. 1周目は実績全解除を目指しました。(リンク先ネタバレあり)
  2. 2周目は各地に存在する見聞録を集めました。(リンク先ネタバレあり)

三周目の挑戦

そこで、3周目は「各地のランドマーク」をRedmineに重点的に記録していきます。

https://atelier.reisalin.com/issues/162

と、今後の調合の際に「どこに行けどの超素材が手に入るか」を記録しようというわけです。

難易度『LEGEND』追加

そんな中、待望のアップデート実施。

最高難易度「LEGEND」追加。折しも三週目に入ったばかり。引き継ぎ時に作成していたコアアイテムがどこまで通用するかを試す絶好の機会です。

結果は圧勝というか鎧袖一触。

コアアイテムを調整していないのでアイテムが使えるようなCCが溜まる前に殲滅するケースがほとんど。

こちらに関してはストーリー進行に合わせて挑戦しがいが出てくればと思います。

Let’s Encryptの証明書整合でハマったこと。(ECDSA方式での整合性確認)

概要

更新サイクルが3ヶ月と短いものの、無料で利用できるということで愛用しているLet's Encrypt。
デフォルトの暗号化形式がRSAからECDSA方式に変わったようで確認方法でハマりました。

なんとか解決したのでメモを残します。

従来の確認方法

RSA方式での証明書は、以下の

openssl x509 -in /etc/certs/hoge.example.com.crt -noout -modulus | md5sum
# SSL証明書ファイル

openssl rsa -in /etc/private/hoge.example.com.key -noout -modulus | md5sum
# 秘密鍵ファイル

を実行し、それぞれのハッシュ値が合致していることで証明書と秘密鍵の整合性の確認を取ることができています。

ECDSA方式に変わったことでの問題

2023年4月時点で、Let's Encryptのデフォルト暗号化形式がRSA→ECDSA方式に変わっていました。

openssl rsa -in /etc/private/hoge.example.com.key -noout -modulus | md5sum
# 秘密鍵ファイル

を実行すると

139945929635648:error:0607907F:digital envelope routines:EVP_PKEY_get0_RSA:expecting an rsa key:crypto/evp/p_lib.c:469:

といったエラーが出ます。

これでは証明書と秘密鍵の整合性が確認できません。

しばらくGoogleと格闘し、なんとか解決策を見つけました。

https://security.stackexchange.com/questions/73127/how-can-you-check-if-a-private-key-and-certificate-match-in-openssl-with-ecdsa

ECDSA方式でも証明書と秘密鍵の整合性が確認できるコマンド

まず、鍵がECDSA方式であることを確認。

  • 確認コマンド
openssl ec -in /etc/private/hoge.example.com.key -text -noout
# 秘密鍵のパスを指定します
  • 確認結果
(略)
ASN1 OID: prime256v1
NIST CURVE: P-256
# 上記が表示されればECDSA方式であると確認できます。

次に、以下のようにして公開鍵を抽出してハッシュ値を割り出します。

openssl x509 -pubkey -in /etc/certs/hoge.example.com.crt -noout | openssl md5
(stdin)= ハッシュ値
# SSL証明書ファイル

openssl pkey -pubout -in /etc/private/hoge.example.com.key | openssl md5
(stdin)= ハッシュ値
# 秘密鍵ファイル

### 2つのハッシュ値が合っていれば証明書と秘密鍵の整合性は取れています

以上、ECDSA方式でも整合性を確認することができました。

余談

この、「鍵を用いて鍵を取り出す」って、『ライザのアトリエ3』で無垢の鍵から秘密の鍵を抽出しているようだなと益体もないことが脳裏をよぎりました。

Page 26 of 51

Powered by WordPress & Theme by Anders Norén