OmniAICreator/Qiita-1.07M huggingface dataset:
[Linux][code]改行コードとは_CRLF, CR, LF, \r\n, \r, \n

# CRLF, CR, LFとは

CRLF、CR、LFは、テキストファイルにおける「改行コード（改行文字）」の種類であり、テキストの「行の終わり」を示す制御コード

## 各改行コードの説明

### **1. CR (Carriage Return)**
- **制御コード:** `\r` (ASCII: 13, 0x0D)
- **意味:** 「キャリッジリターン」
- **動作:** カーソルを行の先頭に戻す（横方向の移動）
- **主な使用環境:** **古いMac OS（Mac OS 9以前）**

### **2. LF (Line Feed)**
- **制御コード:** `\n` (ASCII: 10, 0x0A)
- **意味:** 「ラインフィード」
- **動作:** 次の行へ移動（縦方向の移動）
- **主な使用環境:** **UNIX系OS（Linux, macOS）**

### **3. CRLF (Carriage Return + Line Feed)**
- **制御コード:** `\r\n` (ASCII: 13 10, 0x0D 0x0A)
- **意味:** 「キャリッジリターン」＋「ラインフィード」
- **動作:** カーソルを行の先頭に戻し（CR）、次の行へ移動（LF）
- **主な使用環境:** **Windows**

## 改行コードの関係性

| 改行コード | 制御コード | ASCIIコード | 主な環境 |
|-----------|-----------|-------------|----------|
| CR        | `\r`      | 13 (0x0D)   | 古いMac OS (Mac OS 9以前) |
| LF        | `\n`      | 10 (0x0A)   | UNIX系OS (Linux, macOS) |
| CRLF      | `\r\n`    | 13 10 (0x0D 0x0A) | Windows |

# 補足
## `^M` とは
### **`^M` の意味**
- `^M` は **CR（キャリッジリターン, `\r`）** を表す。
- Linux/macOSで **WindowsのCRLF形式のファイルを開いた際に表示される**。
- **キャレット記法 (`^X`)** で制御文字を可視化する。
  - `^M` → CR（キャリッジリターン, ASCII 13）
  - `^J` → LF（ラインフィード, ASCII 10）

### **なぜ `^M` が表示されるのか？**
- **Windows:** 改行コード `\r\n`（CRLF）
- **Linux/macOS:** 改行コード `\n`（LF）
- WindowsのCRが **Linuxで不要な制御文字として `^M` と表示** される。

## 改行コードの違いによる影響
- **WindowsのCRLFをLinuxで開くと `^M` が表示される**
- **LinuxのLFのみのファイルをWindowsで開くと改行が適切に認識されないことがある**

## `^M` の削除方法
### **1. `sed` コマンド**
```terminal
$ sed -i 's/\r//g' file.txt
```
```terminal
$ tr -d '\r' < file1.txt
```
```terminal
$ sed -i 's/^M//g' file.txt
```
```terminal
$ tr -d '^M' < file1.txt
```

# 参考リンク
- [改行コードの違いと変換方法](https://www.atmarkit.co.jp/ait/articles/0307/16/news003.html)
- [Linuxで^Mが表示される理由と削除方法](https://qiita.com/yoshidashingo/items/49f305f14a4919b1b3b3)
- [WindowsとUnixの改行コードの違い](https://www.ibm.com/docs/ja/i/7.3?topic=files-differences-between-windows-unix-end-line-characters)
- [dos2unix コマンドの使い方](https://linuxcommand.org/lc3_man_pages/dos2unix1.html)

# Ping-t
- [3624_¥r](https://mondai.ping-t.com/question_subjects/31/question_sessions/32373028/progressing_questions/496001465)
- [3625_Linux：LF（\n）、Windows：CRLF（\r\n）](https://mondai.ping-t.com/question_subjects/31/question_sessions/32927143/progressing_questions/504391383)
- [3327_Linux：LF（\n）、Windows：CRLF（\r\n）](https://mondai.ping-t.com/question_subjects/31/question_sessions/31069115/progressing_questions/476102909)
- [3630_Linux：LF（\n）、Windows：CRLF（\r\n）](https://mondai.ping-t.com/question_subjects/31/question_sessions/31994687/progressing_questions/490207934)
- [3688_sed, tr](https://mondai.ping-t.com/question_subjects/31/question_sessions/31069115/progressing_questions/476102905)
WebstormでのElectronのコンソール文字化け対策

## Electronの日本語文字化け問題

Windows環境下にて、Electronの開発時に `console.log()` で日本語を出力しようとした際、文字コードの問題でターミナルの出力が文字化けすることが知られています。

```javascript
console.log("こんにちは! Electronです。");
```

```powershell:output
縺薙ｓ縺ｫ縺｡縺ｯ! Electron縺ｧ縺吶・
```

この件の解決策として、コンソールの文字コードを `UTF-8` にするという策がよく知られています。

https://qiita.com/t4ned4/items/94bc3675c41740944e92

https://suzukaprogrammer.com/2022/05/electron-console-log/

なのですが、WebstormをはじめとしたIntelliJ IDEの場合は別の解決策があります。

## IntelliJ IDEでの解決法

`Enable New Terminal` で新しい方のターミナルを有効化すると、文字化けしなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617021/da23ed2f-82eb-4edd-bb18-0299d7df25fc.png)

これだけです。New Terminalの場合は補完リストが表示されたりして非常に便利なのでオススメです。ただ `beta` と呼ばれているだけあって、 `menuconfig` とかやるとレイアウトがめちゃくちゃになることもあるので注意です（といっても、Electron開発時に `menuconfig` を叩くようなことはそうそうないと思いますが……[^1])。

## 詳細

New Terminalの場合、自動的に `UTF-8` 環境下でPowershellを起動するようになっているみたいです。 `[Console]::OutputEncoding` コマンドを叩いて中身を見てみると分かります。

```powershell:既存のターミナルの場合
PS> [Console]::OutputEncoding

BodyName          : iso-2022-jp
EncodingName      : 日本語 (シフト JIS)
HeaderName        : iso-2022-jp
WebName           : shift_jis
WindowsCodePage   : 932
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
IsSingleByte      : False
EncoderFallback   : System.Text.InternalEncoderBestFitFallback
DecoderFallback   : System.Text.InternalDecoderBestFitFallback
IsReadOnly        : False
CodePage          : 932
```

```powershell:新ターミナルの場合
BodyName          : utf-8
EncodingName      : Unicode (UTF-8)
HeaderName        : utf-8
WebName           : utf-8
WindowsCodePage   : 1200
IsBrowserDisplay  : True
IsBrowserSave     : True
IsMailNewsDisplay : True
IsMailNewsSave    : True
IsSingleByte      : False
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : False
CodePage          : 6500
```

## まとめ

この方法を使うことで、Webstormではわざわざ `package.json` の Scripts に入れたり、ターミナル起動時の起動スクリプトを噛ませたりしなくても、簡単に文字化け問題の解決ができます。ピンポイントすぎる事もあり同様の記事はインターネットになさそうだったのですが、需要はありそうなので纏めてみました。

ターミナル回りの挙動を実験してる際に偶然見つけたのですが、Electron以外でも同じような文字コード周りの問題があれば解決できるかもしれません。逆にSHIFT-JISで出力されているものに関しては、かえって問題を起こすこともありそうですが……。

[^1]:ちなみに私は引っかかりました…… 
https://zenn.dev/link/comments/bda37724884b34
OracleCloudのファイルストレージ（OCFS2編


## OracleCloud Strage の検証。


#### 最初に
OCIにStrageは2種類ある。
[価格表](https://www.oracle.com/jp/cloud/storage/pricing/)



-- ファイル ストレージ
　\46.50　1か月あたりのギガバイトストレージ容量

-- ブロック・ボリューム・ストレージ
　\3.9525　1か月あたりのギガバイトストレージ容量
　Block Volumeパフォーマンス単位
　\0.2635　1 GB/月あたりのパフォーマンス単位
　（最低価格パフォーマンス）


価格差はおよそ10倍。
FileStrageの方は保存している全ファイルサイズによって課金される。
BlockVolumeStrageは、指定したサイズが割り振られ課金される。

 　　

-- OCI上にコンピュートを複数作成しファイルの共有を行いたい。
FileStrageは保存しているサイズx時間で課金されれるので、小さいファイルをちょこちょこ共有して削除するならFileStrage の方が安価になりそう。

BlockVolumeStrageはサイズを決めてしまうと、決めたサイズによる課金になるので共有するファイルサイズが比較的大きく保存期間が長い場合、FileStrageより安価になりそう。

OCI コンピュートでアプリの連携に使うならBlockVolumeStrageと思いきや複数のコンピュートからアクセスするにはocfs2 を利用するか、代表のコンピュートにマウントしてnfs で他のコンピュートからアクセスする形になる。

いっぽう、FileStrageは全てのコンピュートからnfsマウントしてアクセス可能になる。

ocfs2 構築は以下を参考にした（結構メンドクサイ）
[OCIでブロック・ボリュームを複数インスタンスにアタッチする](https://blogs.oracle.com/otnjp/post/announcing-multiple-instance-attachment-of-shareable-readwrite-block-volumes-ja)



本題。
ocfs2を使ってBlockVolumeStrageを複数のコンピュートからアクセスするように構築したら、writeがとても遅い！ これでは支障が！！ と、なって検証した。

-- 構成 OSは全て OracleLinux 9 Minimal 
・ap1 VM.Standard2.2（OCPU 2 メモリ30GB 前世代CPUの安いインスタンス)
・ap2 VM.Standard.A1.Flex（OCPU 4 メモリ24GB arm CPU でFreeひと月使える）
・ap3 VM.Standard.E2.1.Micro （OCPU 1 メモリ 1GB FreeTire）


書き込み速度を調べたいと、同じマウントポイントで実行したシェル
```
#!/bin/bash
for i in {1..5}
do
  echo "This is loop number $i"
  date
  dd if=/dev/zero of=testfile_$(date +"%Y%m%d%H%M%S") bs=1024k count=1000 conv=fdatasync
  echo "number $i is end."
  date
done
```

-- 結果（だいたいの値）
ap1 1048576000 bytes (1.0 GB, 1000 MiB) copied, 26.6604 s, 39.3 MB/s
ap2 1048576000 bytes (1.0 GB, 1000 MiB) copied, 186.149 s, 5.6 MB/s
ap3 1048576000 bytes (1.0 GB, 1000 MiB) copied, 196.786 s, 5.3 MB/s


おそい・・・と、思いませんか？
ocfs2でファイルを書き込むjobが多い場合は最低でも課金しないとダメかと思いました。
各コンピュートのネットワーク帯域幅(Gbps):は ap1（課金）よりap2（無料枠）の方が優秀で謎です。ap3だけ遅いのなら理解できる・・・が。

ap1 ネットワーク帯域幅(Gbps):2
ap2 ネットワーク帯域幅(Gbps):4
ap3 ネットワーク帯域幅(Gbps):0.48  
　

-- 改善策
「Block Volumeパフォーマンス単位」を変更する！！

パフォーマンス・ベースの自動チューニング ->  ON
最大をUHPに設定（40くらい？
![ss1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4027910/3cce1ce3-0463-473d-ac5c-a18dd7c5f549.png)

ap1 1048576000 bytes (1.0 GB, 1000 MiB) copied, 26.6616 s, 39.3 MB/s
ap2 1048576000 bytes (1.0 GB, 1000 MiB) copied, 34.4893 s, 30.4 MB/s
ap3 1048576000 bytes (1.0 GB, 1000 MiB) copied, 28.4843 s, 36.8 MB/s


ap2 が一番遅いように感じるけど許容範囲内に思える。
コスト的に考えてもVM.Standard2.2を複数台そろえるよりFreeTire 使ってBlock Volumeパフォーマンス単位を上げた方がコスパがいいはず。

　　
　　
  
-- 改善策（案 -> 没。
ap1 にBlockVolumeStrageをマウントし、ap1をnfsの親にして ap2,ap3 から nfsマウントする。
没にしたのは就業時間だけコンピュートを動作させる様にしたいと考えているから。
ap1が必ず先に稼働しなくてはならず、ap2の1台だけ動かしたい場合などもったいないなーっと。


-- 結論
取り敢えずBlockVolumeStrageのパフォーマンスを上げる。
Ollamaが遂にMLXをサポートするらしいので試してみました

## はじめに

Apple Silicon搭載のMacでローカルにLLM（大規模言語モデル）を動かしたい方は注目です。OllamaがAppleのMLXフレームワークのサポートに着手しました。これは特にMacユーザーにとって大きな進展で、MLXはAppleのユニファイドメモリとGPUを最大限に活用するように設計されています。その結果、より高速で効率的なLLMの実行が期待できます。

参考

https://qiita.com/yonaka15/items/a69790be6eacd726f770

この記事では、MLXとは何か、Ollamaにおけるその重要性、そして現在の開発状況について解説します。また、興味のある方が自分でビルドして試すための手順も紹介します。

## MLXとは何か？

MLX（Machine Learning Accelerator）は、Apple Research（Apple機械学習研究チーム）によって開発された、Apple Silicon向けに特化した機械学習フレームワークです。PyTorch、JAX、ArrayFireにインスパイアされて作られており、以下のような特徴を持っています：

- **Appleシリコン専用設計**: M1/M2/M3/M4チップの性能を最大限に引き出す
- **ユニファイドメモリモデル**: CPUとGPUが同じメモリプールを共有するため、デバイス間のデータ転送が不要
- **使いやすいAPI**: NumPyに似たPython APIと、それを反映したC++、C、SwiftのAPI
- **遅延計算**: 配列は必要なときだけ物理メモリに配置され、効率的な計算が可能
- **動的グラフ構築**: 計算グラフを動的に構築するため、デバッグが容易

従来のLLMインフレンスライブラリ（llama.cpp等）と比較して、MLXはApple Siliconの特性を徹底的に活用するよう設計されています。特にユニファイドメモリアーキテクチャを活用するため、メモリ効率が非常に高く、大規模モデルの実行に適しています。

## なぜOllamaにとってMLXが重要なのか？

[Ollama](https://ollama.com/)は、ローカル環境でLLMを簡単に実行できるオープンソースツールとして人気を集めています。しかし、Mac上での現在の実装は、Apple Siliconの能力を十分に活用できていないかもしれません。

MLXサポートの追加により、以下のような利点が期待されます：

1. **処理速度の向上**: 推論（テキスト生成）速度が大幅に向上
2. **メモリ効率の改善**: ユニファイドメモリを活用して、より大きなモデルを実行可能に
3. **電力効率の向上**: Apple Siliconの省電力性能を活かした効率的な実行
4. **macOSネイティブ体験**: より統合されたユーザー体験

## 現在の開発状況

Ollamaチームは[GitHubのプルリクエスト #9118](https://github.com/ollama/ollama/pull/9118)でMLXバックエンドの開発を進めています。この実装はまだ初期段階ですが、早くも試すことができます。

## 自分でビルドして試す方法

興味のある方は、以下の手順でOllamaのMLXバージョンをビルドして試すことができます：

### 前提条件

MLXを使用するには、Macの開発環境が適切に設定されている必要があります：

- **Xcode**: MLXビルドにはMetalコンパイラが必要です
- Apple Silicon搭載のMac（M1/M2/M3/M4シリーズ）
- macOS 12 (Monterey) 以降

### ビルド手順

```bash
# リポジトリをクローン（既にクローン済みの場合はスキップ）
git clone https://github.com/ollama/ollama.git
cd ollama

# PRブランチに切り替え
git fetch origin pull/9118/head:mlx-backend
git checkout mlx-backend

# ビルド
cmake -S . -B build
cmake --build build -j 
go build .

# MLXバックエンドを有効にして実行
OLLAMA_NEW_ENGINE=1 OLLAMA_BACKEND=mlx ollama serve
```

### トラブルシューティング

ビルド時に以下のようなエラーが発生する場合があります：

```
xcrun: error: unable to find utility "metal", not a developer tool or in PATH
-- `xcrun metal` error. Setting MLX_BUILD_METAL=OFF
```

これは、MLXのビルドにはMetalコンパイラが必要ですが、システムがそれを見つけられないことを示しています。このようなエラーが出た際には、**コマンドラインツールだけではなくフルバージョンのXcodeがインストールされているか確認してください。**

**Xcodeフルバージョンのインストール**（最も確実な解決策）: コマンドラインツールだけでなく、App StoreからXcode完全版をインストールし、以下のコマンドを実行：

```bash
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
```

注意：MLXバックエンドはまだ開発段階のため、全てのモデルで最適なパフォーマンスが得られるわけではないと思います。また、バグや予期しない動作が発生する可能性があります。

## 参考リンク

- [Apple MLX GitHub](https://github.com/ml-explore/mlx)
- [MLX-LM GitHub](https://github.com/ml-explore/mlx-examples/tree/main/llms/mlx_lm)
- [Ollama公式サイト](https://ollama.com/)
- [LLM推論速度テストリポジトリ](https://github.com/itsmostafa/inference-speed-tests) - さまざまなデバイスでの推論速度を記録する取り組み
Metabaseを使ってみた（Dockerで構築）

## Metabaseを使用した経緯
BIツールを使わないといけない事情があったため、BIツールを調べました。

自身はBIツール初心者だったため、以下の理由でMetabaseを選定しました。

- **オープンソースかつDockerで動作し、評判が良かった**
    - 評判：環境構築が比較的簡単で、UIがシンプルで使いやすい
- **作成したい環境に近い構成のサンプルがあった**

## 環境
今回は、Docker Composeを使用して以下の構成でサーバー環境を構築しました。

- DB
- API
- Metabase

MetabaseのデータはDBサーバーから取得します。

## 使った感想

### 良かった点
- **BIツール初心者でも使いやすい**
    - Dockerの知識があれば、簡単にMetabaseサーバーを構築できる
    - サーバーを立ち上げた後、ブラウザでMetabaseのURLを開くと初期設定画面が表示され、管理者アカウントの設定→DBの接続設定を行うだけで利用可能
    - デモデータとデモダッシュボードが用意されており、BIツールの機能やUXのイメージがつかみやすい
    - グラフ作成がGUIで簡単にできる
        - GUIで作成できないグラフも、SQLクエリを使って作成可能

### 悪かった点・大変だった点

#### UIの問題点
- 日本語訳が微妙（グラフ作成機能が「質問」となっている）
- グラフ作成時に、縦軸ラベルのテキストを縦並びにできない（横並びのテキストを90度回転しているだけ）

#### 機能の問題点
- **コンテナを再構成するたびにMetabaseの初期設定が必要**
    - 毎回、Metabaseの初期設定画面でDB接続設定をしなければならない
    - 複数のDBを接続すると、コンテナ再構成のたびに設定が必要で面倒
    - Docker ComposeのMetabaseコンテナでDB接続を設定すれば解決する可能性がある

- **異なるDBのデータを統合して可視化できない**
    - DockerのDBサーバー上で複数のDBを作成している場合、Metabase単体では異なるDBのデータを統合したグラフを作成できない
    - 解決策として、以下の方法が考えられる
        - DBサーバー側で、あるDBが他のDBのデータにアクセスできるように設定し、SQLクエリでデータを取得してグラフを作成する
        - 異なるDBのデータを統合する中間DBを作成し、Metabaseに接続する

#### その他
- **初心者向けの解説が少ない**
    - 解説を書いている人はBIツールに詳しい人が多く、BIについて初心者向けの情報が少ない
        - グラフが思い通りに作れないとき、BIの知識不足なのかMetabaseの仕様によるものなのか判断しづらい

## まとめ
- **Metabaseは、GUIで直感的にグラフを作成できるため、簡単にBIを構築したい場合や、BIツールに詳しくない人には非常に使いやすくおすすめできる**
- **ただし、異なるDBのデータを統合して可視化する機能はないため、そのような用途にはSuperset（GUIでグラフ作成可能）やRedash（SQLクエリベース）など、複数DBを統合できるBIツールの利用を検討するとよい**

## 参考

- Metabase　：https://www.metabase.com/docs/latest/index.html
- BIツールMetabaseの環境構築してみた　：https://gmor-sys.com/2023/06/13/metabase/
- Metabaseが複数DBのデータ統合できない　：https://www.metabase.com/docs/latest/index.html
- Superset　：https://superset.apache.org/docs/databases/
- Redash　：https://redash.io/help/data-sources
マルチスレッドでMKLを使う際のスレッドセーフ

# C#のMKLのスレッドセーフ
Parallel.Forなどで、マルチスレッド処理を行い、その処理にいMKL(dgemm等)を用いていると結果が不安定(シーケンシャルと異なる結果)になることがある。これは、MKLも一部の関数がマルチスレッドを使用しているためである。不安定にならないように、スレッドセーフで行うための方法例を記載する。

<H2>lockを使う</H2>
処理を排他的にするためにlockする。


``` cs:コード例
var syncObj = new object();
Parallel.For(0, n, i =>
{
    lock (syncObj) 
    {
        MKL Processes
    }
});
``` 
この方法は、メモリアクセスのスレッドセーフと同じで、lock内の処理を他のスレッドで実行できないようにlockするための方法である。ただし、MKLを使った処理がメインとなる並列処理の場合は、マルチスレッドの効果が十分にないので、その場合はシーケンシャルで処理するほうがよい。
MKL使用時のバッファーが不安定になる原因にもなるので、後述のバッファーを解放させることも必要である。

<H2>MKLのスレッド数を制限する</H2>
MKLが使用するスレッド数を制限する。

``` cs:コード例
[DllImport(mkl_rt.2.dll, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
internal static extern int mkl_set_num_threads_local(ref int num);
[DllImport(mkl_rt.2.dll, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
internal static extern void mkl_set_dynamic(ref int flag);
[DllImport(mkl_rt.2.dll, CallingConvention = CallingConvention.Cdecl, ExactSpelling = true, SetLastError = false)]
internal static extern int mkl_get_dynamic();

Parallel.For(0, n, i =>
{
    // Get original setting
    int oriDynamics = mkl_get_dynamic();
    int dynamics = 0;
    // Off dynamical threads
    mkl_set_dynamic(ref dynamics);
    int threads = 1;
    // Set number of thread and get last threads number
    int threads_last = mkl_set_num_threads_local(ref threads);
    
    MKL Processes

    // Set previous threads number
    threads = mkl_set_num_threads_local(ref threads_last);
    // Set previous setting
    mkl_set_dynamic(ref oriDynamics);
});
``` 
MKLのサポート関数にて、MKLを使用時にスレッド数を一つにして、メモリが競合しないようにする。mkl_set_num_threads_localで制限してもdynamicがオンの状態だと、十分に制限できないことがあるようなので、dynamicをオフにしておく。この記述したスレッドでしか有効でないために、各スレッド毎に記述する必要がある。
スレッド制限するため、1スレッドあたりの処理は若干遅くなるが、大きく影響はしなかった。
<H4>大規模データの場合</H4>
大規模データは、計算後のバッファーも大きいので、影響を及ぼすことがあった。対策として、以下のようにスレッドの最後やMKLの演算後に不要になるタイミングで、バッファーを解放し、ガベージ コレクションを強制実行し、少しでもバッファーの影響をなくす。

```cs:バッファー解放
            mkl_thread_free_buffers();
            GC.Collect();
```
mkl_thread_free_buffersは、使用しているスレッドのバッファーの解放である。

[参考リンク](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2025-0/threading-control.html#GUID-00171BFB-C51C-4415-B338-E83C8095901D)
const char* を返り値にして関数を作る時に起こったバグ

## 実際にバグが起こったコード
```c++
const char* GetColorCommand(COLOR_TYPE _colorType, COLOR_RGB _color) {
    char command[32] = "";

    /* 文字か背景かのセット */
    switch (_colorType) {
    case COLOR_TEXT:
        strcpy(command, "\x1b[38;2;");
        break;
    case COLOR_BG:
        strcpy(command, "\x1b[48;2;");
        break;
    }

    /* RGB値のセット */
    strcat(command, IntToString(_color.r));
    strcat(command, ";");
    strcat(command, IntToString(_color.g));
    strcat(command, ";");
    strcat(command, IntToString(_color.b));
    strcat(command, "m");

    return command;
}
```
こんなコード。コンソールでゲームを作るために、テキストや背景の色を変えるエスケープシーケンスを楽に取得できる関数として作った。

## 何が起こった？
**Debugビルド時**は以下の通り
![スクリーンショット 2025-02-16 121602.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558954/f408894e-c4b1-4a46-b422-b28982ebf8e6.png)
プレイヤーの(´・ω・`)がちゃんといる。描画も問題なさそうである。

それが、**Releaseビルド**に変えると
![スクリーンショット 2025-03-05 155950.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558954/17d3d9b2-1d61-4fee-85e3-5c40d1d12de1.png)
これ。表示バグどころか何も表示されなくなる。

試しに、色変更に関するコードをコメントアウトするとこんな感じ。
![スクリーンショット 2025-02-20 152557.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3558954/aeb2e6c8-bbc5-41a9-85e0-3d383e249fd3.png)
モノクロになったがちゃんと表示されている。

## 解決した方法
```c++
const char* GetColorCommand(COLOR_TYPE _colorType, COLOR_RGB _color) {
    static char textCommand[256] = "";
    static char bgCommand[256] = "";
```
最初の宣言をこんな感じにすると解決。staticを付けて静的変数にすると上手くいったが、このときはまだ根本原因を理解していなかったため、かなり無理やりな手法。

## 根本原因
メモリについての理解が足りていなかった。理解できれば超シンプル！
**ローカル変数のアドレスを返り値にしていたこと**。これだけ。

そもそも、関数内のローカル変数というのは
```c++
char str[64];
```
このように宣言すると**自動変数**というものになる。自動変数は関数内の処理が終了するとメモリが解放される変数である。つまり、const char* の返り値としてローカルな自動変数のアドレスを指定すると、**関数の処理が終了した時点でそのアドレスは無効**になってしまう！

言われてみればそりゃそうだ。

そのため、static修飾子をつけて**静的変数にすれば関数が終了してもメモリが解放されない**ため、上手くいったということ。デバッグビルドで平気だったのはメモリ内の値がたまたま残っていただけだった模様。

## もっといい解決方法
とはいっても、要は静的変数を高速で何度も上書きしているわけなので不具合が絶対に起こらない！とは言えない。（実際、テキストと背景でバッファを分けないと上手くいかなかったので）

↓下記に他の方法を考えてみた

### ①引数にバッファを入れておく
単純明快！
```c++
void GetCommand(char* _str){
    strcpy(_str,"");
    // 引数のアドレスをいじる
}
```
いじる文字列が引数なら、呼び出す側の処理が終わらない限り変数は保持される。
ただ、関数を使うたびに変数宣言して、引数に入れて…としないといけないのが少し面倒ではある。

### ②std::stringを返り値にする
```c++
std::string GetCommand(){
    // std::stringを返す
}
```
こちらがより単純明快。std::stringは文字列型で合ってchar* のようにアドレスではないのでローカル変数を返り値にしても大丈夫。~~動的にメモリを確保するとのことなので、上手く使わないとメモリリークとかになる…？のかも。~~
【追記】std::stringはメモリを勝手に解放してくれる機能があるようなので、普通に使ってたらあんまり問題なさそう？

## 最後に
メモリとかの理解が曖昧だったので、ここで少し知れて良かった。const char* を返り値として使うときは return "あいうえお" など定数を返すのが定石なのかも。
音声認識データセットについて解説

# はじめに
現在、市場に出回っている音声データのほとんどは読み上げです。しかし、人間と機械の対話は、単なる対話や質問と回答のコマンド制御ではなく、言語の文脈を理解し、人間の発話や感情を認識し、それに対応したフィードバックを行う必要があります。

 

技術の飛躍的進歩がもたらしたユーザー体験の向上により、会話型音声対話はAI大手の焦点となっています。グーグル、アマゾン、アリババ、テンセントなどは、複数ラウンドの連続対話をサポートするスマートスピーカー、スマートアシスタント、スマートカスタマーサービス、スマートロボットを発表しました。AIシステムの継続的対話能力は、金融、教育、インターネット、交通、モバイル通信、製造などの業界における技術的変化の引き金となるでしょう。

 ## 音声認識データセット

世界有数のAIデータサービスプロバイダーとして、弊社は日本語、中国語方言、英語、韓国語、タイ語、フランス語、ドイツ語、ロシア語、スペイン語、韓国語、ヒンディー語、など数十言語の一連の自然対話音声データセットを保有しています。データセットには、発音の癖や特徴、アクセントの強弱、話者の分布など、多種多様なものが含まれています。

 



###### 513時間 - 電話録音による日本語会話データセット

 

800人以上のネイティブスピーカーが参加し、男女比のバランスを考慮しながら作成されました。録音装置は電話録音システム。音声フォーマットは8kHz、8bit、非圧縮WAVで、すべての音声データは静かな室内環境で録音されました。すべての音声は、テキストの内容、各有効文の開始時刻と終了時刻、話者の識別を含めて手作業で書き起こし済みです。文の精度は95%以上です。

 

###### 633時間 - 携帯録音による日本語自然対話音声データセット

 

テキスト内容、タイムスタンプ、話者ID、性別、その他の属性とともに書き起こされています。多様な話者(約1000人のネイティブスピーカー)から収集されたデータセットは、実際の複雑なタスクにおけるモデルのパフォーマンスを向上させます。様々なAI企業によって品質テストされています。弊社はデータ保護とプライバシー基準を厳格に遵守し、データ収集、保存、使用プロセスを通じて、ユーザーのプライバシーと法的権利の維持を保証します。

###### 1,000時間 - アメリカ英語自然対話音声データセット

このデータセットには1,000時間分のアメリカ英語の会話音声データが含まれています。2,000人のネイティブスピーカーによって録音されています。会話のスムーズさと自然さを保証するために、話し手はよくあるトピックから会話を始めます。文の精度は95%以上になります。‍

###### 136時間 - 韓国語自然対話音声データセット

与えられたトピックに基づく対話から収集され、20以上のドメインをカバーしています。テキスト内容、話者のID、性別、年齢、その他の属性とともに書き起こされています。216人のネイティブスピーカーから収集され、実際の複雑なタスクにおけるモデルのパフォーマンスを向上させます。

 
###### 500時間 - 携帯電話によるフランス語会話データセット

 
約1,000人のネイティブスピーカーによって録音されています。会話のスムーズさと自然さを確保するため、話者たちは身近な話題から会話を始めています。文の精度は95%以上です。

上記のデータがお客様の研究ニーズを満たせない場合、弊社は、特定のグループ、特定のシナリオ、特定の言語向けにデータをカスタマイズするサービスも提供しています。

 ###### データ仕様・サンプルの確認
https://www.datatang.co.jp/speechRecognition

 # まとめ

データサービスが必要な場合は、お気軽にお問い合わせください。
異なるS3から同じドメインでコンテンツを配信する方法

備忘録その②

### 想定ケース
- **トップページ（LP）** は別途作成し、LP用のS3に配置する  
- **LPから遷移した先のWebアプリ** は、別のS3（アプリ用）に配置する  

この構成を実現するためのポイントは、**CloudFrontのビヘイビア設定** にある。

---

## 手順

### 1. CloudFrontのオリジン設定
CloudFrontのディストリビューションに、以下の2つのオリジンを設定する：
- **LP用オリジン**（LP用のS3バケット）
- **アプリ用オリジン**（アプリ用のS3バケット）

### 2. OAC（Origin Access Control）の設定
- OACは **共通のものを使う** ことも、**バケットごとに別々に設定する** ことも可能。
- OAC作成時に発行されるバケットポリシーを、それぞれのS3バケットに適用。

### 3. ビヘイビアの設定
CloudFrontの **ビヘイビア（Behavior）** で、どのリクエストをどのオリジンに向けるかを指定する。

#### ① 既存のデフォルトビヘイビアをアプリ用オリジンに設定
- デフォルトのオリジンは **アプリ用S3** に向ける。

#### ② LP用のビヘイビアを新規作成
LPのコンテンツに必要なパスパターンを設定し、LP用オリジンに向ける。

- **パスパターン `/index.html`**（LPのトップページ）
- **パスパターン `/img/*`**（LPの画像）
- **パスパターン `/css/*`**（LPのスタイルシート）
- **その他、JSなどLPに必要なパスパターンを追加**

また、**`/index.html` を最優先に設定し、デフォルトのビヘイビア（アプリ用）より上に配置する。**

### 4. CloudFrontのキャッシュ削除
設定変更後、**CloudFrontのキャッシュを削除（Invalidation）** し、正しく反映されるようにする。

---

## 注意点

### ① ディレクトリ名の競合
CloudFrontのビヘイビア設定は、**最初に一致したものが適用される** ため、アプリとLPで **同じディレクトリ名を使うと競合する**。

**例：**
- **NGパターン**  
  - LPの画像パス `/img/*`
  - アプリの画像パス `/img/*`
  - → すべてLP用オリジンに向かってしまい、アプリ側の `/img/` が読み込めなくなる

- **解決策**  
  - **LPは `/lp-img/*`、アプリは `/images/*` など、異なるパスを使用する。**

### ② ビヘイビアの優先順位
- **`/index.html` のビヘイビアを最優先にすることが重要。**
- 優先順位が低いと、デフォルトのビヘイビア（アプリ用）が適用され、**LPのトップページが正しく表示されず `AccessDenied` になる。**

---

## まとめ
- CloudFrontの **オリジンを2つ設定（LP用、アプリ用）**  
- OACを適用し、**S3をパブリックにせずCloudFront経由のみアクセス可能にする**  
- **ビヘイビアのパスパターンを適切に設定し、競合を避ける**  
- **`/index.html` のビヘイビアを最優先にして、LPのトップページが正しく表示されるようにする**
機械学習エンジニア必見！高精度データセットをどこから入手すべきか

こんにちは！Datatang株式会社のデータセット作成を担当するBonieと申します！
Qiita初心者ですが、人工知能業界にまつわる情報を発信していきたいと思います。よろしくお願いします。:blush:

弊社Datatangは、100万時間の音声認識データと800TBのコンピュータビジョンデータ、20億件の自然言語理解データを持っています。これまでは、一万社以上のお客様のAI開発にサポートしてきました。
 

今回は、研究者および学生の皆様を対象に、音声認識やコンピュータビジョンの学習データを研究支援のデータセットとして無料に提供するプロジェクトを始めました。本取り組みは、人工知能や機械学習などの学術研究の発展を支援し、次世代の研究者育成に寄与することを目的としております。

 

背景

 

近年、多くの研究者が直面している課題の一つに、学習データの不足が挙げられます。特には、以下の課題が多く見られます。

 

- 研究者の学習データ不足: 高品質な学習データが十分に揃っていないことが、研究の進行を妨げる一因となっています。

- 収集の困難さ: 特定の領域におけるデータ収集は、専門的な知識や設備を要する場合が多く、個人レベルでの対応が難しい状況です。

- 経費不足: 高額なデータ購入費用や収集費用が、予算の制約により研究活動の障害となるケースが多々見受けられます。

 

以上の課題解決に尽力すべく、Datatangは研究者の皆様が必要とする高品質な学習データを無料で提供することを決定いたしました。

 

これまでの評判

 

弊社が提供する無料学習データは、その質の高さと豊富な内容から、世界中の研究者や学生たちに広く愛用されています。特に、早稲田大学、清華大学、ブリティッシュコロンビア大学など世界トップクラスの研究機関や名門大学で活躍する研究者たちが、このデータを活用して革新的な研究を進めています。これにより、学術界全体の発展に寄与し、次世代の学問の礎を築く一助となっています。

 

データの内訳

 

今回提供する学習データは、以下の二種類に分類されます：

 

1. 音声認識データセット

 

一部抜粋：

20時間日本語会話音声データ

20時間韓国語会話音声データ

2.5時間の5言語音声合成データ

多国のアクセント付き英語音声データ

200時間の10言語会話音声データ

40時間の4言語子供読み上げ音声データ

   

2. コンピュータビジョンデータセット

   

一部抜粋：

顔・体：

1,000人多人種・多ポーズ顔画像データ

1,000人の多人種・7種類の顔感情認証データ

3,000枚の顔セグメンテーションデータ

1000枚のジェスチャー認識向けデータ

3,000枚の106キーポイントによる顔アノテーションデータ

 

なりすまし対策向け

2D生体認証画像データ（顔）

3D生体認証画像データ（顔）

200人の防犯カメラ視点でのRe-ID画像データ

200人の防犯カメラ視点での歩容認証データ

 

OCR

3,000枚の自然シーンにおける12言語OCRデータ（日本語、英語など）

500枚の日本語・英語手書き文字OCRデータ



自動車

100人のドライバー行動データ

 

画像生成

1000枚一般シーン画像キャプションデータ

1000件運動動画キャプションデータ

 

お申し込みについて

 

学習データをご希望の方は、以下の手順に従ってお申し込みください。一人にあたり最大６つのデータセットが入手可能です。具体的には公式サイトの研究支援データセットのページをご確認になれます。

 

1. お申し込みフォームの記入

   - お申し込みフォーラムにアクセスし、必要な情報を入力してください。

   - フォームには、お名前、ご所属、希望するデータの種類（音声系または画像系）、使用目的などを記載してください。

 

2. メールによる告知

   - お申し込み後、確認のメールが届きます。メールに記載された指示に従い、追加の情報をご提供いただく場合があります。

 

3. データ納品

   - 審査が完了次第、ご希望のデータを提供いたします。データの受け渡し方法については、メールで詳細をお知らせいたします。申請してから最短5日で納品できます。

  

まとめ

 

本取り組みを通じて、より多くの研究者や学生が質の高い学習データを手軽に入手できるようになることを期待しています。何かご不明点がございましたら、お気軽にお問い合わせください。
空のディレクトリの維持

# 結論　「.gitkeep 」を使う
**なぜ、空のディレクトリの場合は、管理対象にならないのか？**
＞gitはファイルの存在や内容の変化を記録するためです。
ディレクトリ自体は変更されるものではなく、ファイルの存在や内容の変化を記録するため、空のディレクトリは変化がないとみなされます。
そのため、Gitは空のディレクトリを管理対象にしません。

## .gitkeepとは
ファイルが追加された場合gitの管理対象にしたい場合使用する。
空のディレクトリにはファイルが存在しないため、Gitはそれを管理できませんが空ファイルを作成することで管理することができます。
慣習的に目的がディレクトリの維持のため「.gitkeep」という名前になっています。

例:ディレクトリの構造を維持するため

## .gitignoreとは
ファイルが追加されても、gitの管理対象にしたくない場合使用する。
.gitignoreファイルに記述することで、指定したファイルやディレクトリをGitの管理対象外にすることができます。

```.gitignore
* //ディレクトリになる全てのファイル
!.gitignore //.gitignoreを除く
```

例:ログファイルやOSが自動生成したファイルなど、バージョン管理に必要ないファイルを除外するために使用する。

このように、.gitkeepは空のディレクトリをGitで管理したい場合、.gitignoreは管理したくないファイルを除外するために使います。

参考元
https://qiita.com/ndxbn/items/f124d2b183b60cb074e2
フロントエンド革命！Arc UIでデザインと開発を最適化

![スクリーンショット 2025-03-05 16.00.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3637864/2045a24e-21ac-4ee6-8b5e-89901c5a488a.png)

Arc UIは、開発者が短時間で美しく一貫性のあるUIを実現するためのオープンソーススタイリングフレームワークです💻🎨。[4]  
この記事では、Arc UIの概要から導入方法、実際に使えるコード例やシンプルなフローチャートによる流れの解説まで、エンジニア初心者にもわかりやすく専門的な内容をお届けします。[4]

## Arc UIとは？

Arc UIは、あらかじめ定義されたクラス名をHTMLに適用するだけで、ベストプラクティスに基づいたスタイリングを容易に実現できるフレームワークです。[4]  
これにより、デザインの一貫性を保ちながら、コーディングの手間や冗長なスタイル定義を大幅に削減することが可能となります。[4]

## 主な特徴

Arc UIの魅力的な特徴は以下の通りです。[4]

- **シンプルな導入**：HTMLにスタイルシートのリンクを挿入するだけで、すぐに利用開始できます。[4]
- **豊富なコンポーネント**：ボタン、アラート、カード、ナビゲーションなど、多彩なUIコンポーネントが揃っています。[4]
- **柔軟なカスタマイズ性**：必要に応じてクラス名を拡張・変更できるため、オリジナルなデザインへのアレンジが容易です。[4]
- **軽量かつ高速**：最小限のスタイル定義でページの読み込み速度を損なわない設計となっています。[4]

以下の表は、Arc UIで利用可能な主要なコンポーネント例です。[4]

| コンポーネント | 説明                                   |
| -------------- | -------------------------------------- |
| Alerts         | 通知や警告メッセージの表示             |
| Avatars        | ユーザーやアイコンのアバター表示       |
| Badges         | カウントや情報を示すバッジ             |
| Buttons        | 標準ボタン、アウトラインボタンなど     |
| Cards          | コンテンツを魅せるカードレイアウト     |
| Modal          | ダイアログやポップアップのウィンドウ   |[4]

## インストール方法

Arc UIの導入は非常に簡単です。[4]  
以下のコードをHTMLの``セクションに追加するだけで、すべてのコンポーネントのスタイルが利用可能になります。[4]

```html

```

また、特定のコンポーネントのみをインポートすることも可能ですので、用途に合わせた柔軟な導入が可能です。[4]

## 使用例

実際にArc UIを使ったシンプルなボタンの実装例を以下に示します。[4]

```html



  
  Arc UI Sample
  


  Click Me! 🚀


```

このサンプルでは、`btn`と`btn-primary`というクラス名を活用して、スタイリッシュなプライマリボタンを実装しています。[4]  
コードをローカル環境で保存し、ブラウザで開くだけで直感的に見えるUIが確認できるため、迅速なプロトタイピングに最適です。[4]

## Arc UIを利用した開発の流れ

Arc UIを使った開発の基本フローは以下の通りです。[4]

```mermaid
flowchart LR
    A[HTML Markup] --> B[Arc UI クラス （例: btn, card, etc.）]
    B --> C[事前定義されたスタイル適用]
    C --> D[美しいUIコンポーネントの生成]
```

このフローチャートは、HTMLにクラス名を追加するだけで、どのようにして美しいUIが自動的に生成されるかをシンプルに表現しています🎨。[4]

## Arc UIのメリットと今後の展望

Arc UIを採用することで得られるメリットは以下の通りです。[4]

- 作業効率の向上とコーディングのシンプル化[4]
- 再利用可能なスタイル定義によるデザインの一貫性維持[4]
- プロジェクトの迅速な立ち上げと保守性の向上[4]

さらに、オープンソースとしてコミュニティで活発に開発が進められているため、今後も新しいコンポーネントの追加やカスタマイズ機能の充実が期待され、より多様なプロジェクトへの適用が進むでしょう🌟。[4]

## まとめ

Arc UIは、開発者が手軽に美しく統一感のあるUIを実現するための強力なツールです。[4]  
シンプルな導入方法、豊富なコンポーネント、そして柔軟なカスタマイズ性により、日々の開発作業を大幅に効率化することが可能です💻🎉。[4]  
ぜひ、あなたのプロジェクトにもArc UIを取り入れて、革新的なデザイン体験を実現してみてください。[4]

この記事で紹介したArc UIの基本仕様と使用例を参考に、あなたの開発環境に新しい風を吹き込む一助となれば幸いです。[4]

Citations:
[1] https://toolfinder.co/tools/arc-browser
[2] https://sourcefuse.github.io/arc-docs/
[3] https://ansubkhan.com/blogs/arc
[4] https://github.com/devdeadviz/arc-ui
AndroidStudioでの.gitignoreの書き方

# はじめに
アプリケーション開発において、例えばAPIキーをgithub上に公開したくない場合などに、APIキーの書かれているファイルの**パス**を.gitignoreに記述してgitの管理下から外す方法をとると思います。
今回は、AndroidStudioにおける.gitignoreの書き方を簡単にまとめようと思います。(VSCode等でも書き方自体は当然同じです)
当時初心者だった私はただファイル名だけをベタ書きするわ、パスが上手く通せないわでてんやわんやしてしまった記憶があります......。
# 書き方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979616/79b703fe-c48c-4521-853b-4caf2e9c0afd.png)
今回は上画像の通り、プロジェクトレベルの.gitignoreに(.gitignoreが2つある件については後述)、apikeyディレクトリ内にあるApikey.ktをgitの管理下から外していきます。
※ファイルを新規作成した際にaddしますか？みたいなポップアップが出ますが、管理下に置きたくないファイルは間違えてaddしないように注意！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979616/c10ac503-a21e-4c89-8236-26396e24622f.png)
プロジェクトレベルの.gitignoreには既に色々書かれていますが、ここにApikey.ktまでの **.gitignoreから見た**パスを記述していきます。
結果的に、以下のような相対パスになります。
```app/src/main/java/com/websarva/wings/gitignoretest/apikey/Apikey.kt```
ここで1つややこしい点なのが、```com.websarva.wings.gitignoretest```の部分ですね。ここは . を/に置き換えましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979616/c8cfe626-8c58-4d0b-a363-232b49055a72.png)
書き終わったらCtrl+Sしてみると、Apikey.ktの文字が赤色からオレンジ色っぽく変化すと思います。(画像の通り結構分かりにくい......)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979616/9e245710-a3bd-4e89-8656-c3237b9ec393.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979616/246f7d0b-444c-4ce4-ad68-8d47a6547326.png)
色が変われば、無事.gitignoreにファイルを認識させることに成功です。

ちなみに、モジュールレベル(appディレクトリ内)の.gitignoreに記述する場合は、
```src/main/java/com/websarva/wings/gitignoretest/apikey/Apikey.kt```
と記述します。

# 10秒で終わる書き方
前節ではディレクトリ構成を意識してパスを書きましたが、AndroidStudioには該当ファイルのパスをコピーするという機能があります。
この機能自体は特に珍しいものでもありませんが、AndroidStudioでは目的に合わせた相対パスもコピーすることができます。
Apikey.ktを右クリックして、Copy Path/Reference...を選択すると以下のような画面が出ると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979616/1e1e0e1a-28e8-4d87-a2ce-c850425c710a.png)
ここでPath From Repository Rootを選択し、プロジェクトレベルの.gitignoreに貼り付けると、それだけで記述が完了します。

# .gitignoreの位置について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3979616/60bc2351-a7b7-405d-8054-2892e4e80808.png)
AndroidStudioでは、デフォルトで.gitignoreを用意してくれていますが、上の画像のから分かるように、なんと.gitignoreがデフォルトで2つ用意されています。
どちらに書いても、パスさえ正しければちゃんと動作するのですが、この意図についてAndroidStudio内蔵のGemini聞いてみました。
### Geminiの回答(抜粋)
> Android Studio で作成されるプロジェクトに、異なるディレクトリに .gitignore ファイルが 2 つ存在する理由は、主に プロジェクト全体とモジュール（またはアプリ） ごとに異なる無視設定を適用するため です。これにより、より柔軟かつ効率的に不要なファイルを Git の管理対象から除外できます。

恐らく巨大なプロジェクトを扱う際に使い分けが発生するのでしょう。正直学生同士での開発レベルではあまり意識する必要はなさそうですが、APIキーなど様々な場所で使うことが想定されるものはプロジェクトレベルの.gitignoreに書く方が良さそうです。
# まとめ
- .gitignoreには、そこから見たgit管理したくないファイルへの相対パスを記述する
- Copy PathからのPath From Repository Rootをコピーしてプロジェクトレベルの.gitignoreにペーストするのが便利
- プロジェクトレベルとモジュールレベルのどちらの.gitignoreに記述するかは、その変数の影響度合いによって決めるのが良い

この記事を書いていく中で、.gitignoreへの記述の代替案として、デフォルトでgit管理から外れているlocal.propertiesにAPIキーを書き込むという案もあるということを知りました。
気になる方はそちらも調べてみると良いと思います。(少し手間がかかりますが、より簡潔になるかもしれません)
Kubuntu24.04設定ノート

Kubuntu 24.04 をインストールした後の設定をまとめたノート

# `apt install`でインストール

## 色々
```bash
sudo apt install openssh-server emacs gitk xcrysden gnuplot
sudo apt install libbz2-dev libreadline-dev libsqlite3-dev #pythonのビルド用
sudo apt install gfortran make
# pyenvでpython 3.12.9のビルドに必要だったので(いくつかは余分なh)
# https://qiita.com/yut-nagase/items/1887df2ee983e6714053
sudo apt install build-essential
sudo apt-get install libffi-dev
sudo apt-get install libbz2-dev
sudo apt-get install libncurses5-dev
sudo apt-get install libreadline-dev
sudo apt-get install sqlite3 libsqlite3-dev
sudo apt-get install liblzma-dev
# https://qiita.com/ysd_marrrr/items/472162288b9c131f5427
sudo apt install zlib1g*
# chatgptに`ModuleNotFoundError: No module named '_tkinter'`の解決策として教えてもらった
# ちなみに`python3-tk`は入れても無意味
sudo apt install tk-dev libncurses5-dev libncursesw5-dev
```

## Latex

```console
sudo apt install texlive-full
```

# Proxyまわり
## `apt`用

```conf:/etc/apt/apt.conf(存在しなければ作る)
Acquire::http::Proxy "http://proxy-server.jp:8080";
Acquire::https::Proxy "https://proxy-server.jp:8080"; #一つしかサーバーがない場合はこちらもhttpかも
```

で`apt update`等で動作確認が出来ていればOK。

## Git用

```config:${HOME}/.gitconfig
[http]
        proxy = http://proxy-server.jp:8080
```
を追記。

## `curl`, `wget`用

```bash:${HOME}/.bashrc
export http_proxy=http://proxy-server.jp:8080
export https_proxy=https://proxy-server.jp:8080  #一つしかサーバーがない場合はこちらもhttpかも
```
を追記。
`pyenv`等で、中で`curl`などを使っている。

# NTP
`timedatectl`を叩いて時間がおかしいときは、NTPを設定する必要がある。

```conf:/etc/systemd/timesyncd.conf(抜粋)
NTP=ntp-server.jp
```
で指定をして、`sudo systemctl restart systemd-timesyncd`でNTPとう同期されるはず。
`timedatectl`の出力結果が正しければこれで設定修了。

# pyenvインストール

参考URL: [pyenv/pyenv: Simple Python version management](https://github.com/pyenv/pyenv)

```console
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```
でインストール。
```bash:.bashrc
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - bash)"
```
を追記で環境設定はおしまい。

# `xterm`のメタキーを活かす
コンソールから`xterm`を立ち上げると、Altキー(MacならCommand)を押した際にメタキーとして認識してもらえない。以下のコマンドで立ち上げた`xterm`はAltキーがキチンとメタキーとして働く。
```console
xterm -xrm 'XTerm*metaSendsEscape: true'
```

# 結果出来上がる`.bashrc`

```bash:.bashrc
# User specific aliases and functions
alias emacs="emacs -nw"
alias mv="mv -i"
alias rm="rm -i"
alias cp="cp -i"
alias xterm="xterm -fa 'Hack' -fs 12"
alias xtermrv="xterm -fa 'Hack' -fs 12 -rv"

export OMP_NUM_THREADS=1
export http_proxy=http://proxy-server.jp:8080
export https_proxy=http://proxy-server.jp:8080
if [[ "${SSH_CONNECTION}" ]] ; then
    export TERM="xterm-256color"
    export GNUTERM="x11"
fi

# For pyenv
export PYENV_ROOT="$HOME/.pyenv"
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init - bash)"

# MODULEPATH for environment modules
source /etc/profile.d/modules.sh
export MODULEPATH=/home/user/opt/modulefiles:$MODULEPATH
```
Emacs 30.1とsmartrepの不具合について

# Emacs 30.1にしたら、エラーで起動しなくなった

起動時にエラーが出てしまう。

```Elisp
Wrong type argument: obarrayp, [nil nil nil nil nil nil nil nil nil nil nil nil nil]
```

## emacs --debug-init する

`emacs --debug-init` で起動すると、エラーの詳細が以下の通り。

```Elisp
Debugger entered--Lisp error: (wrong-type-argument obarrayp [nil nil nil nil nil nil nil nil nil nil nil nil nil])
  intern("mc/mark-next-like-this" [nil nil nil nil nil nil nil nil nil nil nil nil nil])
  #<subr F616e6f6e796d6f75732d6c616d626461_anonymous_lambda_0>(("C-t" quote mc/mark-next-like-this))
（以下略）
```
どうも、`multiple-cursors`と`smartrep`の組み合わせのところがおかしいらしい。

## 解決

[smartrepの作者のリポジトリ](https://github.com/myuhe/smartrep.el)で以下のとおり対策が示されているので反映。

- [Update smartrep.el for v30.1 compat](https://github.com/myuhe/smartrep.el/pull/25/commits/0ee2376dc3c9a07d4a1c18453dd39c9441ca4162)

具体的な作業としては、[最新のsmartrepのelisp](https://github.com/myuhe/smartrep.el/blob/master/smartrep.el)に差し替えたら治りました。

elcファイルがあるときには、削除するなり、バイトコンパイルするなり必要です。
S3 + CloudFront + Route53 を使ったSSL付きカスタムドメインのWeb配信

備忘録のため残します。

### ゴール
S3に配置したファイルを、**SSL + カスタムドメイン**でWeb配信する。

### 構成要素

#### 1. S3（Amazon Simple Storage Service）
ファイルの配置場所。

#### 2. CloudFront（CDN）
- キャッシュを利用してユーザーのページ表示を高速化し、オリジンサーバーの負荷を軽減。
- S3に対してディストリビューションを作成し、**ACM（AWS Certificate Manager）を使ったSSL証明書を紐づける**。
- CloudFrontのACM証明書を使って、ユーザーとの通信をHTTPSにする。

#### 3. Route 53（DNS管理）
- CloudFrontディストリビューションに対してAレコード（エイリアス）を向ける。
- これにより、ユーザーは独自ドメイン（例: `example.com`）でアクセス可能。
- 既存のドメインがある場合、ACMでSSL証明書を発行し、CNAMEの値をDNS設定に手動で追加（DNS検証）。

---

## 方法

### 【1】S3の静的サイトホスティングを使う方法
このやり方ならCloudFrontじゃなくてもできる。（Cloudflareとか）

#### S3静的サイトホスティングとは
- S3にアップロードしたHTMLなどのファイルを、そのままWebサイトとして公開できる機能。
- **HTTPSは非対応**。
- S3がWebサーバーのように振る舞う。

#### 手順
1. **S3の静的サイトホスティングを有効化**
2. **CloudFrontのディストリビューションを設定**
   - オリジンにS3のWebサイト用エンドポイントを指定。
   - SSL証明書の選択。
   - カスタムドメインの設定。
3. **S3のバケットをパブリック化**
   - バケットポリシーで全体に許可を付与。

#### 注意点
- S3がパブリック状態になり、直接URL（`http://your-bucket.s3-website-ap-northeast-1.amazonaws.com/`）でもアクセス可能。
- CloudFront ⇔ S3間の通信がHTTP。
- **セキュリティ面で堅牢性が劣る**。

---

### 【2】OAC（Origin Access Control）を使い、CloudFront経由のアクセスのみにする方法
CloudFrontを使う所のメリットはここ。

#### 方法の概要
- **S3の静的サイトホスティングを使わず**、バケットも非公開にする。
- **CloudFront + OACを利用してセキュアにアクセス制御**。

#### 手順
1. **CloudFrontのディストリビューションを設定**
   - S3の「バケットエンドポイント」を指定。
   - OAC（Origin Access Control）を新規作成。
   - OACを設定したCloudFrontからのアクセスのみをS3に許可するため、OAC作成時に生成されるバケットポリシーをS3に適用。
   - `Default root Object` に `index.html` を指定。
2. **S3のアクセス許可を更新**（CloudFrontのOAC用バケットポリシーを適用）。

#### 注意点
- **S3のバケットエンドポイントを使用する場合の問題点**
  - `/mypage` にアクセスしても `index.html` を自動補完しない。
  - `/mypage/index.html` のような構成でなければ `403 Access Denied` になる。
  - **解決策**:
    - `Lambda@Edge` を使用。
    - `CloudFront Functions` でリライト関数を作成し、Viewer Request にアタッチ。

- **S3のWebサイト用エンドポイント（http://your-bucket.s3-website-ap-northeast-1.amazonaws.com/）は使用不可**。

---

- **セキュリティとHTTPS対応を重視するなら【2】（OAC + CloudFront）が推奨**。
- **手軽に設定したい場合は【1】（S3静的サイトホスティング）も選択肢だが、セキュリティリスクあり**。

CloudFrontの設定を適切に行い、OACを活用することで、安全にS3のコンテンツを配信できる環境を構築できる。
react-router v7 のパス指定エラーについて

# はじめに
ルーティングを実装中次のエラーが表示されました。

:::note warn
Uncaught Error: Absolute route path "/detailA" nested under path "/page1" is not valid. An absolute child route path must start with the combined path of all its parent routes.
:::

翻訳：キャッチされないエラー: パス「/page1」の下にネストされた絶対ルート パス「/detailA」が無効です。絶対子ルート パスは、すべての親ルートを結合したパスで始まる必要があります。

# バージョン

react-router: 7.2.0
<br>

下記のように記述していました。
```Router.jsx
import { Route, Routes } from "react-router";
import { Home } from "../Home";
import { Page1 } from "../Page1";
import { Page2 } from "../Page2";
import { page1Routes } from "./Page1Routes";

export const Router = () => {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/page1">
        <Route index element={<Page1 />} /> {/* /page1にアクセスしたときにPage1を表示 */}

        {page1Routes.map((route, index) => (
          <Route key={index} path={route.path} element={route.children} />
        ))}

      </Route>
      <Route path="/page2" element={<Page2 />} />
    </Routes>
  );
};

```

```.Page1Routes.jsx
import { Page1DetailA } from "../Page1DetailA";
import { Page1DetailB } from "../Page1DetailB";

export const page1Routes = [
  {
    path: "/detailA", // ← ここが原因のようです
    children: <Page1DetailA />,
  },
  {
    path: "/detailB",
    children: <Page1DetailB />,
  },
];

```

# 解決方法
パスの記述を修正
```.Page1Routes.jsx
import { Page1DetailA } from "../Page1DetailA";
import { Page1DetailB } from "../Page1DetailB";

export const page1Routes = [
  {
    path: "detailA",
    children: <Page1DetailA />,
  },
  {
    path: "detailB",
    children: <Page1DetailB />,
  },
];
```

# おわりに
意図した挙動になってくれました。
<br>

[<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3707255/8bfacf61-7d8d-6d27-cb07-98d1f8f27fcd.png"  width=100%>](https://projisou.jp)
AzureのログをDatadogで監視する方法

# はじめに

Azure環境で発生するログを効率的に収集・監視することは、システムの可視性を向上させ、トラブルシューティングを迅速化するために重要です。本記事では、Datadogを利用してAzureのログを収集・監視する流れを説明します。
詳細な手順ではなく、全体的なイメージを掴みたい場合などにお役に立つかと思いまとめてます。

詳細な手順については、[公式Docs](https://docs.datadoghq.com/ja/logs/guide/azure-logging-guide/?tab=%E8%87%AA%E5%8B%95%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)をご覧ください。

# Datadogを使用したAzureログの監視手順

## DatadogとAzureの統合

DatadogはAzureとの連携機能を提供しており、Azureリソースからのログを簡単に取り込むことができます。統合の手順は以下のとおりです。

1. Datadogアカウントの作成
・Datadogの公式サイトでアカウントを作成し、APIキーを取得します。

2. Azureポータルでの設定
・Azureポータルにログインし、「Azure Monitor」→「Diagnostic settings」へ移動。
・Datadogの統合サービスを有効化し、ログの出力先として選択。

3. Datadogの設定
・Datadogの統合ページで「Microsoft Azure」を選択し、APIキーを入力。
・監視対象のサブスクリプションやリソースを選択。

## ログの収集方法

Datadogでは、以下の2つの方法でAzureのログを収集できます。

### 自動インストール（推奨）

Datadogが提供する自動セットアップスクリプトを使用すると、簡単に設定が完了します。

・開始するには、[公式Docs内のDeploy to Azureボタン](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2FDataDog%2Fdatadog-serverless-functions%2Fmaster%2Fazure%2Fdeploy-to-azure%2Fparent_template.json)をクリックし、Azure Portal のフォームに入力します。Datadog アカウントにアクティビティログをストリーミングするために必要な Azure リソースが、自動的にデプロイされます。
・必要な権限を持つサービスプリンシパルを作成し、Datadogと接続します。
・Azureのリソースごとにログを収集し、Datadogに送信されます。

![Screenshot 2025-03-05 at 15.26.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81226/1efb67ee-68c3-4222-a406-b5007246e224.png)

### 手動設定

手動での設定も可能ですが、より多くのステップが必要です。

・Azure Event Hub を作成します。
・Event Hub トリガー付き Datadog-Azure 関数を設定して、ログを Datadog に転送します。
・診断設定を作成して、Azure のアクティビティログ、リソースログ、またはその両方を Event Hub に転送します。
・Datadogの「Logs」セクションでデータを可視化します。

![Screenshot 2025-03-05 at 15.32.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81226/bd72ddc5-ee45-4c7f-8f09-38d34bf6bc5e.png)

## ログの分析とアラート設定

Datadogでは、収集したAzureのログを分析し、アラートを設定できます。

・ログフィルタリング: 重要なログのみを表示。
・ダッシュボード作成: Azureのリソースごとのメトリクスを視覚化。
・アラート設定: 重大なエラーや異常なパターンを検出し、通知を受け取る。

![Screenshot 2025-03-05 at 15.35.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81226/6da6049d-f80e-4d00-b734-0bacc5c6fd3c.png)

## Automated Log Forwarding for Azure （プレビュー版）
ログ自動転送のプレビュー版が公開されました！
Azure環境全体のログ転送を自動的に設定します。手動設定は必要ありません。
この機能は、ログ転送サービスを自動的に管理し、スケーリングします。
プレビュー版のリクエストは[こちら](https://docs.google.com/forms/d/e/1FAIpQLSeZkmqTwBQ43zR9SZoyf_oUDCFDsth00lb4jRKjfn-vKNW4dA/viewform)から！

![Screenshot 2025-03-05 at 15.17.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81226/efcb30b1-472f-4ed0-828f-3a3f5608cc7f.png)
※ Docsの表示を日本語にしているとプレビューのリクエストボタンが表示されません。言語設定をEnglishにしてください。

このプレビュー版は、以下のような方にお勧めです：

・新しいAzure環境をDatadogにオンボードする場合。
・Azureプラットフォームのログを転送するオーバーヘッドやコストを削減したい。

# まとめ

Datadogを活用することで、Azure環境のログ監視を簡単に実現できます。

・自動インストールを活用すると、迅速にセットアップ可能。
・詳細なログ分析やアラート通知を活用し、システムの可視性を向上。
・ダッシュボードを活用して、Azureリソースの監視を効率化。

Azure環境の可視性を高め、システムの安定運用を実現するために、Datadogの活用を検討してみてください。
Intelligent Speech Interactionを使う

[前回](https://qiita.com/ysic/items/9e6a873fa64f651705a2)はCosyVoice 2を試しました。

本記事ではAlibaba Cloudが提供しているサービスの1つであるIntelligent Speech Interactionを使ってみたいと思います。

https://www.alibabacloud.com/ja/product/intelligent-speech-interaction

## Intelligent Speech Interactionで何ができるのか

おおまかには音声認識、音声合成、自然言語理解などの最先端の技術に基づいており、次の機能が提供されています。

- リアルタイム音声認識: 音声データストリームをリアルタイムでテキストに変換
- 短文認識: 音声検索、音声コマンド入力、ショートメッセージなど向けの短い音声テキスト変換
- 録音ファイル認識: ユーザーがアップロードした音声ファイルをテキストに変換
- 音声合成: 最大100,000文字までのテキストを自然な音声に変換(さまざまな話者、発話速度、イントネーション、音量などの調整が可能)
- 自己学習型プラットフォーム: ユースケースに合わせた認識精度の向上のためのモデルカスタマイズ機能

また、上記は多言語対応で、順次その他の言語も追加されていく予定だそうです。

- 中国語
- 広東語
- 英語
- 日本語
- 韓国語
- フランス語
- インドネシア語

特徴としては高い認識精度と処理速度、多種多様な業界向けに利用できる製品設計である点などメリットが多そうです。

## 実際に使ってみる

前回CosyVoice 2を試したときはTTS(Text-to-Speech)を試しました。ここでもTTSを使ってみたいと思います。

### Intelligent Speech Interactionへアクセスする

次のURLからアクセスできます

[https://nls-portal.console.aliyun.com](https://nls-portal.console.aliyun.com/overview)

未アクティベートであるメッセージが表示されるので迷わずActivate Nowをクリックします。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/8bb1afd2-95a9-4b58-989f-a4680212571b.png)

**Activate Now**をクリック

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/791fd2e7-bb0e-41d7-b937-e2956de523b2.png)

サービスが有効化されました。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/92fc5118-2c97-4db8-aa0a-04c9fec20c38.png)

日本語ページはまだ工事中だそうで、表示言語をENに切り替えました。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/8bfb54b0-fe01-4ac0-abb0-56189b23668f.png)

### プロジェクトを作成する

サイドバーからプロジェクトへ飛び、

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/a6190a30-1c69-48f1-b34e-d27c7ba0771d.png)

新しいプロジェクトを作成します。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/ea0832ca-a290-41d7-b309-7f7ca7bc719c.png)

ここで表示されるAppkeyはAPIアクセス時に指定する値です(今回はAlibaba Cloudコンソール内で試すだけなので不必要ですがマスクしています)。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/e5c33558-9595-4f7b-a316-5aee319395ff.png)

### プロジェクト設定ページへアクセスする

早速読み上げを試せそうな……

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/fd636eb8-9c58-49c6-af23-160a70f3c64e.png)

まずはモデルを選択しないといけないようです。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/a8d8c9d1-782e-4810-99f8-232c1b276b54.png)

※注: ページの表示言語が日本語設定の場合、カテゴリ名やモデル名・説明が表示されないので注意(2025年2月現在)。

多言語のモデルを選択し、テキストを入力してスピーカーボタンを押すだけで即座に生成された音声が再生されます。簡単！

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/493706f1-5cec-4993-9a0a-d18e761fdc9c.png)

パラメーターパネル

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804814/ffef86b0-9a43-45a2-92dc-b02f3115bd56.png)

聞き取りやすさなどを確認しながら調整することができます。

---

思ったよりも簡単に試せてしまいました。

このサービス内でもおそらく[CosyVoice](https://funaudiollm.github.io/cosyvoice2/)が使われていると思われるのですが、どうやらユーザーがアップロードした音声をもとに喋らせることはまだできないようです。

当然ながらAPIの仕様やSDKも[提供](https://www.alibabacloud.com/help/en/isi/developer-reference/speech-synthesis-1/)されているので、自分たちのアプリケーションへ音声機能を組み込むことが気軽にできる良いサービスだと思いました。
スプレッドシートをwrapしたアプリはSaaSを代替できるか

## まとめ
1. 管理業務をスプレッドシートだけで運用すると「壊れる」
1. だから壊れないように、シートの中身を読み書きできるwebアプリを作ればいい
1. 生成AI登場で、webアプリ生成コストが爆下がりしたので、作れる

## 背景: スプシは有能だが使いづらい
Googleスプレッドシートは

1. それ自体がDatabaseである
1. それ自体がViewerである
1. それ自体がEditorである

という性質をもっているので、理論上はたくさんの管理系アプリの代わりになる。
しかし以下の弱点により、実運用は難しい。

* 1つのセルにおかしな値を入れただけで壊れる
* 壊れたときにその原因を探しづらい
* UIが美しくない
* 細かい編集/閲覧権限の設定がしづらい

## 解決策: WebアプリをAIに作らせよう
**スプレッドシートの内容を表示/編集できるWebアプリをつくる**

いや、SaaS使えば済む時代に、自前で管理アプリ作るとかおかしい、と思うかもしれない。
それは一理あるが、以下の事情を考慮すると選択肢の俎上に上げる価値はある。

* **生成AI**によって開発速度が著しく向上
* (円安等を背景にした)**SaaSの高騰**
* SaaSに**ロックイン**される
* メンテナンスもAIがやればいい
* wrapperなので、メンテできなくなっても最悪スプレッドシートを使えばよい

試しにCursorと対話しながら3時間やってみると、
それなりのビジュアルのViewer/Editorができた。
ホスティングやアクセス権限管理もGASで完結できるので、
自前でサーバー立てたりログインつくったりDB接続したりとか、
面倒なことを考えることはない。

## 「全部SaaSでいい時代」の均衡点を変化させる生成AI
振り返ると、SaaS使ったほうがどんどん便利になっていった10年だった。
余計な仕事はアウトソースすればいいという発想は今もあるし今後も残る。

一方で、生成AIというバランス破壊者が現れたことに注目すべきだ。
生成AIの衝撃的な開発力によって、
全部SaaSでいいじゃんというスタンスから、
ちょっと自前でもいいよね、というスタンスに均衡点が移っていく。
経営者はこの変化を踏まえてアクションをとりたい。
ほぼ単機能しか使っていないSaaSがあれば、さっさとexportしてスプシ運用に切り替えていける。

## 求められる力量は3つ
生成AIが書いてくれるとはいえ、担当者には以下の3つの力量は必要と考える。

1. ソフトウェアを設計する力
1. コードを評価する力
1. UI/デザインを評価する力

こう書くとちょっとハードルが上がるかんじもあるが、
ある程度経験を積んだエンジニアならいけるとおもう。

## まとめ(再掲)
1. 管理業務をスプレッドシートだけで運用すると「壊れる」
1. だから壊れないように、シートの中身を読み書きできるwebアプリを作ればいい
1. 生成AI登場で、webアプリ生成コストが爆下がりしたので、作れる
1. 作れるぞという選択肢を持つことが経営上もｄ
エターナルブルーの深淵（前編）～「CVE-2017-0145」歴史的脆弱性について徹底解説～


Yo,諸君！今回は、サイバーセキュリティ史に悪名を轟かせたCVE-2017-0145、通称「エターナルブルー」脆弱性について、徹底的に解説していくぜ！
この脆弱性がもたらした歴史的な影響から、技術的な深層、そして実演まで、闇に潜むやつらの手口を暴き、その対策を学ぶんだ！
中の人の環境と業務の都合で実演は後編に回すが
仕組み等を頭に入れて後編を見てくれたらうれしいぜ！

２０１７年で古いんじゃないか？？？？
故きを温ねて新しきを知る！だぜ！！
(ちなみに２０２５年3月現在smbv1を利用しているIPは全世界で５７万件日本では２万件)



# CVE-2017-0145とは？：SMBv1の致命的な脆弱性
CVE-2017-0145は、WindowsのSMBv1（Server Message Block version 1）プロトコルに存在するリモートコード実行（RCE）の脆弱性だ。この脆弱性を悪用することで、攻撃者は標的のWindowsシステムに任意のコードを実行させることができちまったんだ。

### SMBv1とは？
SMBv1は、Windowsネットワークにおけるファイル共有やプリンター共有などに使用されるプロトコルだ。
古いプロトコルであり、セキュリティ上の問題が多数存在した。

### 脆弱性の原因：バッファオーバーフロー
CVE-2017-0145は、SMBv1プロトコルの処理におけるバッファオーバーフローに起因する。
攻撃者は、不正なSMBパケットを送信することで、バッファオーバーフローを発生させ、任意のコードを実行する。

### エターナルブルーの影響：WannaCryとNotPetya
CVE-2017-0145は、2017年のWannaCryランサムウェアやNotPetyaなどの大規模なサイバー攻撃で使用され、世界中に甚大な被害をもたらした。

# WannaCryランサムウェア
エターナルブルー（ ~~名前が中二心をくすぐられる~~ ）を悪用して感染を拡大し、標的のシステムを暗号化して身代金を要求した。
世界中の組織に甚大な被害をもたらし、社会的な混乱を引き起こした。

# NotPetyaマルウェア
ウクライナを中心に甚大な被害をもたらし、世界中の企業にも影響を与えた。
単なるランサムウェアではなく、システム破壊を目的としたマルウェアである可能性が指摘された。

# CVE-2017-0145の技術的深層：SMBv1の脆弱性解析
CVE-2017-0145の脆弱性は、SMBv1プロトコルの処理におけるバッファオーバーフローに起因する。

### トランザクション処理の脆弱性
SMBv1のトランザクション処理において、パケットのサイズを適切に検証していないことが原因だ。
攻撃者は、大きなサイズのパケットを送信することで、バッファオーバーフローを発生させ、任意のコードを実行する。

### プールオーバーフローの悪用
SMBv1のカーネルモードコンポーネントにおけるプールオーバーフロー脆弱性を悪用する。
特定のSMBリクエストを送信することでカーネルメモリの解放後使用（Use-After-Free）を誘発し、任意のコード実行に繋がる。

# 対策

### Windowsアップデートの適用
Microsoftは、CVE-2017-0145を修正するセキュリティ更新プログラム（MS17-010）を公開した。
Windowsアップデートを適用することで、脆弱性を修正できる。
### SMBv1の無効化
SMBv1は、セキュリティ上の問題が多数存在するため、無効化することが推奨される。
Windows PowerShellで以下のコマンドを実行することで、SMBv1を無効化できる。

```powershell:powershell
Set-SmbServerConfiguration -EnableSMB1Protocol $false
```

### ファイアウォールの設定
ファイアウォールでSMBポート（139/445）をブロックすることで、外部からの不正なアクセスを防ぐことができる。

### ネットワーク分離
重要なシステムをネットワークから分離することで、被害の拡大を防ぐことができる。
### 侵入検知システム（IDS）/侵入防止システム（IPS）の導入
IDS/IPSを導入することで、不正なSMBパケットを検知し、攻撃をブロックできる。
### セキュリティソフトの利用
セキュリティソフトを導入することで、マルウェアの感染を防ぐことができる。

# まとめ：CVE-2017-0145の教訓を未来に活かす
CVE-2017-0145は、過去の大規模なサイバー攻撃で使用され、セキュリティの重要性を再認識させる事例となった歴史的な脆弱性なんだぜ！！！
この脆弱性が露呈させたSMBv1の脆弱性は、現代のシステムが抱えうる様々なリスクを象徴している。
この教訓を未来に活かして、より安全なデジタル社会を築いていくことが、私たちセキュリティ戦士に課せられた使命だ！！共に戦おう！！



:::note
バッファーオーバーフローとプールオーバーフローについて補足
この二つは名前が似てますが発生する場所が違います。
ざっくりとプログラム領域（バッファ）とカーネル領域（メモリプール）で発生する脆弱性と覚えておけば大丈夫です。いずれレベルアップした時に改めて学びましょう
:::

# あいさつ

こんにちは！株式会社ギグーのtkmiiiです
いきなりキャラ変わってすみません
マンネリ化がいやでキャラ変頑張りました。
後編ではWindows環境を用意してハッキングができたらと思います！
お楽しみに！！
Dockerイメージのタグ上書きで見えた！mirror.gcr.ioキャッシュの落とし穴

# Dockerイメージのタグ上書きで見えた！mirror.gcr.ioキャッシュの落とし穴

今回は、同じタグで異なるイメージ（nginx と busybox）を push したときに、mirror.gcr.io 側のキャッシュがどう動作するのかを実験しました。

---

## 実験の概要

1. **Step 1: nginx のイメージを push**  
   - docker.io から `nginx:latest` を pull  
   - `kahiro/nginx:latest` として tag し、 push  
   - mirror.gcr.io から pull して、digest が **`sha256:2cdfd36070a281c568ef9639b00ba906210a708d8a0f3fa87f91718384a67fc4`** と一致

2. **Step 2: busybox のイメージで上書き push**  
   - docker.io から `busybox:latest` を pull  
   - 同じ `kahiro/nginx:latest` タグで tag し、 push  
   - mirror.gcr.io から pull したが、**古い nginx のdigestがそのまま返却**（`sha256:2cdfd36070a281c568ef9639b00ba906210a708d8a0f3fa87f91718384a67fc4`）となる

---

## 何が起こったのか？

- **正常動作（Step 1）**  
  docker.io からの nginx イメージを push すると、mirror.gcr.io も正しくキャッシュし、同じdigestを返しました。

- **キャッシュの罠（Step 2）**  
  同一タグ（`kahiro/nginx:latest`）に busybox イメージを push して上書きしたはずなのに、mirror.gcr.io 側はキャッシュが残っており、**更新前の nginx のdigest**を返し続けています。

---

## まとめ

- **タグの上書きには注意！**  
  同じタグで異なるイメージを push すると、mirror.gcr.io のキャッシュが更新されず、古いイメージの情報が残る可能性があります。 (Cacheがいつpurgeされるかは不明です

- **運用のポイント**  
  - キャッシュ更新のタイミングの確認が必須  
  - 異なるイメージは可能な限り別のタグを利用するなど、運用ルールの見直しが必要

---

今回の実験結果から、**mirror.gcr.io のタグキャッシュは常に最新ではなく**、タグ名の上書きによるイメージ更新がすぐには反映されないことが分かりました。これを踏まえ、今後のDockerイメージ運用時はキャッシュの挙動に十分注意してください！