カテゴリー: ガジェット Page 43 of 107

Ubuntu20.04のOpenSSHを8.2p1から9.6.1pにアップデート。(9.8.1pでも同手順は有効)

概要

こちらの記事で、Ubuntu 20.04のOpensslを1.1.1から3.1.1にバージョンアップしました。

しかし、

OpenSSH_8.2p1 Ubuntu-4ubuntu0.9, OpenSSL 1.1.1f  31 Mar 2020

OpenSSHが参照しているSSLが前のままです。また、OpenSSHの脆弱性情報もあるのでセキュリティ上よろしくありません。

そこで、

  • OpenSSHを最新版にする
  • そのとき、参照するOpenSSLも現状に合わせる

作業を行いました。

参考にしたURL:

環境

  • Ubuntu 20.04
  • 上記自サイトに則って、OpenSSLを3.1.1にアップデート済み

さっくりとした手順

  1. コンフィグに必要なディレクトリの作成を行います。
  2. インストールに必要なパッケージをインストールします。
  3. 作業用ディレクトリに移動します。
  4. ソースをダウンロードします。
  5. OpenSSHをソースからビルドします。
  6. バージョンアップを確認します。

最初に

本件はSSHを扱います。念のため、サーバへのターミナルクライアントを別ウィンドウで開いておいてください。

  • 現行のバージョン確認
ssh -V
OpenSSH_8.2p1 Ubuntu-4ubuntu0.9, OpenSSL 1.1.1f  31 Mar 2020

必要なパッケージのインストール

sudo aptitude install build-essential zlib1g-dev libssl-dev libpam0g-dev libselinux1-dev libkrb5-dev

ディレクトリ作成と設定

sudo mkdir /var/lib/sshd && sudo chmod -R 700 /var/lib/sshd/ && sudo chown -R root:sys /var/lib/sshd/

作業用ディレクトリ移動

cd /hoge && pwd

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

ソースのダウンロードと展開

  • ソース取得
wget -c http://mirror.exonetric.net/pub/OpenBSD/OpenSSH/portable/openssh-9.6p1.tar.gz

2023/12/20現在の最新版を指定しています。

2024/07/02追記:CVE-2024-6387に対応する場合はこちらを指定します。
参考: OpenSSHの脆弱性 CVE-2024-6387についてまとめてみた

wget -c http://mirror.exonetric.net/pub/OpenBSD/OpenSSH/portable/openssh-9.8p1.tar.gz
  • ソース展開
tar -xzf openssh-9.6p1.tar.gz
# 上記脆弱性に対応したバージョンをダウンロードした場合は
tar -xzf openssh-9.8p1.tar.gz
  • ディレクトリ移動
cd openssh-9.6p1
# 上記脆弱性に対応したバージョンを解凍していた場合は
cd openssh-9.8p1

コンフィグ

  • OpenSSLの位置を確認
which openssl
  • 結果確認
/usr/local/ssl/bin/openssl

筆者の環境です。

  • コンフィグ
./configure --with-kerberos5 --with-md5-passwords --with-pam --with-selinux --with-privsep-path=/var/lib/sshd/ --sysconfdir=/etc/ssh --with-ssl-dir=/usr/local/ssl

--with-ssl-dir=/usr/local/sslは、opensslがあるディレクトリのヘッダを指定してます。

  • make
make
  • インストール
sudo make install

バージョンアップ確認

  • バージョン確認
ssh -V
OpenSSH_9.6p1, OpenSSL 3.1.1

バージョンアップされていることを確認します。

# 上記脆弱性に対応したバージョンは
OpenSSH_9.8p1, OpenSSL 3.3.1 4 Jun 2024
  • SSHサービス再起動
sudo systemctl restart ssh.service
  • サービス再起動確認
sudo systemctl status ssh.service

active(running)を確認します

この後、バージョンアップを行ったサーバにSSH接続できれば、作業は完了です。

確認日

2023/12/20

補充と撮影。

情報カードにものを書くようになってから、万年筆のインクの減りが更に加速しました。

そこで、土曜日の朝、上記を対象に補充です。

本体とインクの対応に関しては、この表のお陰ですんなりと判別できました。

  • 補充
  • 拭き取り
  • 試し書き

を一通り行い、

まずは一安心です。

その跡に撮影。先月の終わり頃に組み立てた

『ハリー・ポッター』教科書&教室の「占い学」が背景です。

スクリプト改修。(SSL証明書の有効期限確認スクリプト)

概要

このスクリプトを修正します。

修正後の内容

  • qa_ssl_checker.rb
require 'openssl'
require 'socket'
require 'date'
require 'uri'
require 'timeout'

# ユーザーからURLを対話的に受け取る
def get_user_input
  print "チェックしたいサイトのドメインを入力してください(例: example.com): "
  domain = gets.chomp

  # 入力がhttp://またはhttps://で始まらない場合は、https://を追加
  domain = "https://#{domain}" unless domain.start_with?('http://', 'https://')

  domain
end

# 変数で指定したURLに接続して証明書の有効期限を取得するメソッド
def get_certificate_expiry_date(url)
  uri = URI.parse(url)
  hostname = uri.host
  ssl_socket = nil
  tcp_client = nil

  begin
    # タイムアウトを5秒に設定してSSL接続を確立
    Timeout.timeout(5) do
      tcp_client = TCPSocket.new(hostname, 443)
      ssl_context = OpenSSL::SSL::SSLContext.new
      ssl_socket = OpenSSL::SSL::SSLSocket.new(tcp_client, ssl_context)
      ssl_socket.hostname = hostname
      ssl_socket.connect

      # 証明書の有効期限を取得
      cert = ssl_socket.peer_cert
      expiration_date = DateTime.parse(cert.not_after.to_s)
      days_remaining = (expiration_date - DateTime.now).to_i

      return expiration_date, days_remaining
    end
  rescue Timeout::Error
    return nil, "サーバーへの接続がタイムアウトしました。"
  rescue => e
    return nil, e.to_s
  ensure
    ssl_socket&.close
    tcp_client&.close
  end
end

# メイン処理
def main
  url = get_user_input
  expiration_date, days_remaining = get_certificate_expiry_date(url)

  if expiration_date
    formatted_date = expiration_date.strftime("%Y/%m/%d")
    puts "サイト #{url} の有効期限は #{formatted_date} です。残り #{days_remaining} 日です。"
  else
    puts "証明書の取得に失敗しました: #{days_remaining}"
  end
end

# メイン処理を呼び出し
main
  • 差分
-  print "チェックしたいサイトのURLを入力してください(https://example.comのような形式): "
-  gets.chomp
+  print "チェックしたいサイトのドメインを入力してください(例: example.com): "
+  domain = gets.chomp
+
+  # 入力がhttp://またはhttps://で始まらない場合は、https://を追加
+  domain = "https://#{domain}" unless domain.start_with?('http://', 'https://')
+  
+  domain

変更された挙動

前は、URLを入力するときに

https://~ を含めたドメインが必要でしたが、今回はドメインのみ(example.com)のみで処理をしてくれるようになります。

地味ですが、大きな改善点です。

BookStackのバージョンアップ手順。(BookStack v23.08.3 → BookStack v23.10.4)

概要

運用しているBookStackのバージョンアップを行います。

環境

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

手順

https://www.bookstackapp.com/docs/admin/updates/

ほぼ、こちらの公式記事の通りに行いました。

BookStackのディレクトリに移動

  • ディレクトリ移動
cd /var/lib/BookStack/ && pwd

インストールされているディレクトリを指定します

アップグレード

  • git pull
sudo -u www-data git pull origin release
  • 実行例(一部抜粋)
 tests/LanguageTest.php                                                              |   19 +-
 tests/Permissions/RolePermissionsTest.php                                           |   16 +-
 tests/PublicActionTest.php                                                          |    4 +-
 tests/PwaManifestTest.php                                                           |   72 ++
 tests/SecurityHeaderTest.php                                                        |   11 +-
 tests/Settings/TestEmailTest.php                                                    |    6 +-
 tests/TestCase.php                                                                  |   38 +-
 tests/ThemeTest.php                                                                 |   44 +-
 tests/Uploads/AvatarTest.php                                                        |   62 +-
 tests/Uploads/ImageTest.php                                                         |   28 +-
 tests/User/UserApiTokenTest.php                                                     |   86 +-
 tests/User/UserManagementTest.php                                                   |    6 +-
 tests/User/UserMyAccountTest.php                                                    |  339 ++++++++
 tests/User/UserPreferencesTest.php                                                  |  164 +---
 tests/User/UserSearchTest.php                                                       |    3 +-
 version                                                                             |    2 +-
 557 files changed, 14110 insertions(+), 5348 deletions(-)
 rename app/{Notifications/ConfirmEmail.php => Access/Notifications/ConfirmEmailNotification.php} (82%)
  • アップグレード
sudo composer install --no-dev
  • 実行例(一部抜粋)
  - Upgrading psy/psysh (v0.11.20 => v0.11.22): Extracting archive
  - Upgrading laravel/tinker (v2.8.1 => v2.8.2): Extracting archive
  - Upgrading mtdowling/jmespath.php (2.6.1 => 2.7.0): Extracting archive
  - Upgrading aws/aws-sdk-php (3.279.2 => 3.283.8): Extracting archive
  - Upgrading league/flysystem-aws-s3-v3 (3.15.0 => 3.16.0): Extracting archive
  - Upgrading phpseclib/phpseclib (3.0.21 => 3.0.23): Extracting archive
  - Upgrading predis/predis (v2.2.1 => v2.2.2): Extracting archive
  - Upgrading socialiteproviders/manager (v4.3.0 => v4.4.0): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

   INFO  Discovering packages.  

  barryvdh/laravel-dompdf ................................................................................................... DONE
  barryvdh/laravel-snappy ................................................................................................... DONE
  intervention/image ........................................................................................................ DONE
  laravel/socialite ......................................................................................................... DONE
  laravel/tinker ............................................................................................................ DONE
  nesbot/carbon ............................................................................................................. DONE
  nunomaduro/termwind ....................................................................................................... DONE
  socialiteproviders/manager ................................................................................................ DONE

62 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan cache:clear

   INFO  Application cache cleared successfully.  

> @php artisan view:clear

   INFO  Compiled views cleared successfully.  

自分の環境ですとキャッシュのクリアなどは自動的に行うため、上記URLの追加手順は不要でした。

バージョンアップ確認

  1. BookStackがインストールされているURLにアクセスします。
  2. 管理者権限でログインします。
  3. 設定のシステムバージョンが以下、作業時の最新版になっていれば成功です。

Nextcloud、ブルートフォースの誤検知対応(occ実行)

エラー内容

Nextcloudで以下のエラーが出たので対応を行います。

あなたのIPアドレスは、 "xxx.xxx.xxx.xxx" として認識されており、現在ブルートフォース対策機能により様々なリクエストのパフォーマンスが低下しています。IPアドレスがあなたのアドレスでない場合、プロキシが正しく設定されていない可能性があります。詳細はドキュメントをご覧ください

エラーとなった原因

ファイル共有機能の検証を行っており、その際に共有/非共有の設定を繰り返していたなどの不審な動きがあったからだと思います。(現に、通常に使用している限りではエラーは発生しませんでした)

エラー解消

エラーが出たNextcloudサーバにSSH接続して対応します。

ディレクトリ移動

cd /home/www-data/nextcloud && pwd

occ実行

sudo -u www-data php occ security:bruteforce:reset [IPアドレス]

上記エラーで出てきたIPアドレスを指定します。

エラー解消確認

  1. Nextcloudに管理者権限でログインします。
  2. 管理画面を開きます。
  3. 以下のように、エラーが解消されていることを確認します。

スリーブ新調、リストの移行。(MtG統率者戦)

少し離れていたMtG統率者戦のデッキをいじる機会がありました。

スリーブ入れ替え

そのきっかけとなったのはこちら。アニメ版『ライザのアトリエ』のキャラクタースリーブを手に入れたことです。

発売されていると聞いていたものの、店には売られておらず入手を諦めていたところに、公式サイト(Aniplex Plus)にて販売を確認。

即座に注文して届いたという次第です。

スリーブも入れ替えて、デッキもより愛着がわいてきました。

デッキリストの移行

スリーブ入れの合間、デッキリストをRedmineでの公開からBookStackへと移行。

https://barrel.reisalin.com/shelves/ac1dd

それっぽいイメージをBing Image Creatorにて抽出。

https://barrel.reisalin.com/books/7380a

この、BookStackならば、一つの統率者をテーマに

  • デッキリストの変遷
  • 対戦メモ

等を記すことができますし、「いつ記録したか」の履歴を追うこともできます。

Redmineより視認性が高いのもまたナイスです。

コマンドラインでの視覚化。(lstopoとhtop)

概要

Linuxの運用で、ちょっと役立ったコマンド2つを最近知りました。

確認した環境

Ubuntu 20.04で試しています。

lstop

サーバ内のCPU情報や構造を知るためのコマンドです。

導入

sudo apt-get install hwloc

実行結果

lstopo --of ascii

こちらはAWS Lightsail上で示した結果。コア数やディスクなども確認できます。

デスクトップの据え置き。メモリもディスクも潤沢です。

htop

topコマンドを可視化できるという存在。(というよりもtopの上位種です)

導入

sudo apt-get install htop

実行結果

htop

上部のゲージで

  • CPU使用
  • メモリ使用
  • スワップ

が変動しているのがわかります。また、タスク数なども目の当たりにできます。

F5でツリー表示できるのもポイント。

これは後々の運用に役立つので、ちょっと使い込んでみます。

ChatGPTによるシェルスクリプト。(Linuxユーザアカウント削除)

概要

先だってはオプションを忘れがちなものを自動化するを元にスクリプト&コマンド化。

今度は、「慎重な操作を要する作業」を一気通貫で行うようにします。

要件

こんな要件のスクリプトを出力です。

  1. 削除するユーザ名を対話式で聞く
     → ない場合はExit
  2. /etc/passwd /etc/shadow /etc/group のバックアップを、 /etc/old/ファイル名.$(date +%Y%m%d)でバックアップ
     → それぞれファイル:○○をバックアップしましたの表示を出す
  3. ユーザのディレクトリも消すかを聞く y/n
  4. 削除前に以下の確認
     ユーザ名:○○を削除
     ユーザのホームディレクトを消す:y or no
    これでよろしいですか?
    → n : Exit
  5. y: ユーザデータを削除する
    ディレクトリを消すでy → userdel -r を実行してメッセージ出力、Exit
    ディレクトリを消すでn → userdel を実行してメッセージ出力、Exit

ここから更に

  • ホームディレクトリのバックアップを取るかどうかを聞く
  • 差分を表示するようにする

などを加えてできたスクリプトがこちらです。

免責

意図通りに動くかは一応、確認しましたが、
本番運用の前に、検証環境で、テストアカウントで実施してください。

準備

以下のディレクトリを作ります。

  • 設定ファイルのバックアップ先
sudo mkdir /etc/old
  • ホームディレクトリのバックアップ先
sudo mkdir /home/deleted_users

スクリプト内容

  • account_delete.sh
#!/bin/bash

# 1. ユーザ名を対話的に聞く
read -p "削除するユーザ名を入力してください: " username

# ユーザが存在しない場合は終了
if ! id "$username" &>/dev/null; then
    echo "ユーザ '$username' は存在しません。終了します。"
    exit 1
fi

# 2. バックアップを作成
backup_dir="/etc/old"
backup_date=$(date +%Y%m%d)
backup_passwd="$backup_dir/passwd.$backup_date"
backup_shadow="$backup_dir/shadow.$backup_date"
backup_group="$backup_dir/group.$backup_date"

cp /etc/passwd "$backup_passwd"
cp /etc/shadow "$backup_shadow"
cp /etc/group "$backup_group"

echo "ファイル:$backup_passwd をバックアップしました。"
echo "ファイル:$backup_shadow をバックアップしました。"
echo "ファイル:$backup_group をバックアップしました。"

# 3. ユーザのディレクトリを消すかどうかを確認
read -p "ユーザのディレクトリも削除しますか? (y/n): " delete_home

# 4. ユーザディレクトリのバックアップを取るかどうかを確認
backup_home=""
if [ "$delete_home" == "y" ]; then
    read -p "ユーザのホームディレクトリのバックアップを取りますか? (y/n): " backup_home_choice
    if [ "$backup_home_choice" == "y" ]; then
        backup_home="/home/deleted_users/$username.$backup_date"
        cp -r /home/$username "$backup_home"
        echo "ユーザ '$username' のホームディレクトリをバックアップしました。"
    fi
fi

# 5. 削除前に確認
echo -e "\nユーザ名: $username を削除"
echo -e "ユーザのホームディレクトリを消す: $delete_home"
echo -e "ユーザのホームディレクトリのバックアップを取る: $backup_home\n"

read -p "これでよろしいですか? (y/n): " confirm

if [ "$confirm" == "n" ]; then
    echo "終了します。"
    exit 0
fi

# 6. ユーザデータを削除
if [ "$delete_home" == "y" ]; then
    userdel -r "$username"
    echo "ユーザ '$username' のデータとディレクトリを削除しました。"
else
    userdel "$username"
    echo "ユーザ '$username' のデータを削除しました。"
fi

# 7. バックアップと現在の差分を表示するかどうかを尋ねる
read -p "アカウント削除後、バックアップと現在の差分を表示しますか? (y/n): " show_diff

if [ "$show_diff" == "y" ]; then
    diff_passwd=$(diff /etc/passwd "$backup_passwd")
    diff_shadow=$(diff /etc/shadow "$backup_shadow")
    diff_group=$(diff /etc/group "$backup_group")

    echo -e "\n--- ファイル:$backup_passwd との差分 ---\n$diff_passwd"
    echo -e "\n--- ファイル:$backup_shadow との差分 ---\n$diff_shadow"
    echo -e "\n--- ファイル:$backup_group との差分 ---\n$diff_group"
fi

echo "終了します。"

実行権付与

  • 所有者変更
sudo chown root:root account_delete.sh

root権限でしか触れないコマンドなので、所有者もrootにします。

  • 権限変更
sudo chmod 700 account_delete.sh

通常アカウントは閲覧もできないようにします。

これで、操作時に確認をしつついざというときの切り戻しもできるようになります。

ChatGPTによるシェルスクリプトとコマンド化。(Zipアーカイブ)

概要

使うときはあるけど、オプションや順番を考えるのが面倒。

そんな悩みをChatGPTの力を借りて解決です。

やったこと

  1. 対話式で圧縮するファイルやディレクトリを指定
  2. 圧縮先のディレクトリを対話で指定(何も指定しない場合はカレントディレクトリ)
  3. アーカイブファイルを対話で指定(何も指定しない場合はファイル/ディレクトリ名.$(date +%Y%m%d).zip)
  4. zipコマンドで圧縮。ディレクトリかを判別し、ディレクトリなら-rオプションをつける

という処理を行います。

スクリプト

  • autozip
#!/bin/bash

# ユーザにファイル/ディレクトリの指定を求める関数
get_input() {
    read -p "$1: " input
    echo "$input"
}

# 対話式でファイル/ディレクトリの指定を取得
source_path=$(get_input "圧縮するファイルやディレクトリのパス")

# 対話式で圧縮先ディレクトリの指定を取得
destination_dir=$(get_input "圧縮先のディレクトリ(何も指定しない場合はカレントディレクトリ)")
destination_dir=${destination_dir:-"."}

# 対話式でアーカイブファイルの指定を取得
archive_name=$(get_input "アーカイブファイルの名前(何も指定しない場合はファイル/ディレクトリ名.\$(date +%Y%m%d).zip)")
archive_name=${archive_name:-"$(basename $source_path).$(date +%Y%m%d).zip"}

# ソースディレクトリに移動
cd "$(dirname "$source_path")" || exit

# zipコマンドで圧縮
if [ -d "$(basename "$source_path")" ]; then
    # ディレクトリの場合は-rオプションを付けて圧縮
    zip -r "$destination_dir/$archive_name" "$(basename "$source_path")"
else
    # ファイルの場合は-rオプションなしで圧縮
    zip "$destination_dir/$archive_name" "$(basename "$source_path")"
fi

echo "圧縮が完了しました。"

# カレントディレクトリに戻る
cd - || exit

作成後の処理

  • 実行権付与
chmod +x autozip
  • コマンド化
sudo chown root:root autozip && sudo mv autozip /usr/local/bin/autozip

実行結果

  • パスが通っていることを確認
which autozip

→ /usr/local/bin/autozip

に表示されます。

  • 実行確認

任意のディレクトリに移動し、

autozip

を実行。

これで、

  1. 対話式で圧縮するファイルやディレクトリを指定
  2. 圧縮先のディレクトリを対話で指定(何も指定しない場合はカレントディレクトリ)
  3. アーカイブファイルを対話で指定(何も指定しない場合はファイル/ディレクトリ名.$(date +%Y%m%d).zip)
  4. zipコマンドで圧縮。ディレクトリかを判別し、ディレクトリなら-rオプションをつける

が実行できました。

ChromebookでNextcloudのファイルを参照。

使う機会があったので調べてみました。

背景

出先(宿泊先)にChromebookしか持っていない状態でNextcloudのファイルを参照したい状況が発生しました。

Chrome拡張Nextcloud (unofficial)

https://chrome.google.com/webstore/detail/nextcloud-unofficial/kkbmcejbjlhkmljcafiaofajcbgkobcd/related

こちらをChromebookに入れてみます。

導入後、Chromebookのファイルの縦メニューを開くと

Nextcloud(unofficial)というリンクが出てきます。

接続

※予めNextcloudにログインします。

  • Name:任意の名前
  • Server domain:Nextcloudのドメイン名

を入れて「Login」をクリックします。そうすると、Nextcloudにログインしているブラウザが表示され、アクセス権の確認が出ます。

その後、接続。

接続後の挙動

エクスプローラーのように、ファイルが表示されます。プレビューはでないものの、ファイルをダウンロードすることなく閲覧が可能になりました。

ブラウザからファイルを保存する際、このNextcloudのディレクトリを指定することはできませんが、

  1. 一度ダウンロードディレクトリに保存
  2. その後、ファイルアプリからNextcloudの任意のディレクトリに保存

の手順でOKとなりました。

Page 43 of 107

Powered by WordPress & Theme by Anders Norén