pikesaku’s blog

個人的な勉強メモです。記載内容について一切の責任は持ちません。

Web技術メモ

キーワード

動的コンテンツ生成

機能 説明 補足
CGI リクエスト受信時にプロセス起動 ×性能
×HTML出力とロジック処理が混在
サーブレット 常駐デーモンがプログラム実行(Javaコードの中にHTMLを埋め込む) 〇性能
×HTML出力とロジック処理が混在
JSP 常駐デーモンがプログラム実行(HTMLの中にJavaコードを埋め込む) 〇性能

phpJSPと似てる。httpdに組み込まれたphpモジュールがphpコードを実行。別途プロセス起動せずhttpdプロセス内部で実行。

Webサーバへの情報送信方法

メソッド 送信方法
get クエリ文字列
post メッセージボディ

セッション管理

セッションIDをクエリ文字列 or Cookieに格納して行う。

* アプリケーションサーバ

提供する機能
・セッション管理
トランザクション管理
・データベースの管理
 コネクションプーリング
・可用性、性能の向上
 セッションレプリケーション

セキュリティ

攻撃 対策
SQLインジェクション 入力値チェック
プリペアードステートメント※1
XSS サニタイジング
(HTML出力時ブラウザがJavaスクリプトと解釈しないよう文字を置き換え)
セッションハイジャック XSS対策
通信暗号化
セッションタイムアウト短縮
セッションIDのランダム化
CSRF(クロスサイトリクエストフォージェリ)※2 ワンタイムトーケン
強制ブラウズ Webサーバ・アプリの不具合なくす
ディレクトリトラバーサル※3 ユーザー入力データを使って、ディレクトリアクセスする機能を実装しない
サニタイジング(ファイル名に含まれない/等の文字は削除する)


※1
プリペアドステートメント(prepared statement)とは - IT用語辞典 e-Words

※2
例)
掲示板サイトへの投稿をサブミットするHTMLを解析し、そのリクエストを行うJavaScriptを用意する。
そのJavaScriptが読み込みと同時に実行されるようonLoad属性をonにしたWebページを用意する。
上記のWebページへ何かしらの方法で被害者に読み込みさせる。→結果的に、被害者が投稿したことになる。
外部からサブミットさせる攻撃
ログインが必要なサイトでも、被害者が対象サイトのセッションIDを持つCookieを持ってれば実行できてしまう
正規のフォームでないところから、サブミットできるのが問題。フォームにhiddenパラメタでワンタイムトークンを埋め込むことで、正規のフォームからのサブミットリクエストか?を判断でき、防ぐことができる。

※3
ユーザーから入力された値で、ディレクトリアクセスする機能を悪用
readfile("/var/www/" + $HOGE)
仮に上記のようなコードがアプリにあり、$HOGEがユーザーから入力された値だったとする。
$HOGEに../../etc/passwdとかにしたら、意図しないファイルが読み取られる可能性あり。

PDU毎のフォーマット

イーサネット

VLANタグ・フレームのフォーマット - ネットワークエンジニアを目指して

項目 内容
PDU フレーム
ヘッダ長 18byte

~上記より引用~

タグ付きVLANの場合、1522byteとなり1518byte超えるが通信できる理由は?
Lesson4:VLANとジャンボ・フレーム,フレームを拡張する技術を学ぶ | 日経クロステック(xTECH)
→大体の機器は、フレーム長が1536バイトまたは2048バイトまでならOKなのでOK

IP

TCP/IP - IPとは

項目 内容
PDU パケット
ヘッダ長 20byte(オプション・パディングなし)

~上記より引用~

TCP

TCP/IP - TCPとは - TCPヘッダ

項目 内容
PDU セグメント
ヘッダ長 20byte

~上記より引用~

UDP

TCP/IP - UDPとは

項目 内容
PDU データグラム
ヘッダ長 8byte

~上記より引用~

ICMP(おまけ)

TCP/IP - ICMPとは

~上記より引用~

参考

TCPUDPの違い

TCP/IP - UDPとは
~上記より引用~

TCPの通信効率をよくする機能

TCP/IP - TCP ウィンドウ制御、フロー制御

ウィンドウ制御

~上記より引用~

3WHS時にお互いのサイズを知り、ACK待たずに送信

フロー制御

~上記より引用~

受信側がバッファが一杯になった場合に、送信を止めてもらう機能
下流
①受信側は、他ホストとも通信してるケースあり。バッファが一杯になったら、ウィンドウサイズ0で「もう送らないで!」を伝える。
②送信側は、メッセージを受けたら、一定期間待ってウィンドウプルーブで、「ウィンドウサイズの最新値は?」ときく。
③受信側は、最新のウィンドウサイズを通知する。

SACK (Selective ACK)

【図解】TCP のオプションと仕組み 〜SACK, Timestamp(PAWS), Window Scale, MSS〜 | SEの道標
~上記より引用~

ウィンドウ制御でACKを待たずに送信された複数セグメントのうち、一部でパケロスが発生した場合、SACK未使用だとパケロス発生した以降のパケットが全て再送される。SACKを利用すると、受信済みセグメントの情報を送信元に通知することででき、パケロスしたセグメントのみ再送させることが可能。
※昔、これに関するトラブルあり。FWがシーケンス番号をセキュリティ考慮し書き換えるけど、SACKの中のシーケンス番号を変えない不具合があった。たしかパケロス発生すると通信が失敗する動作だった。

Path MTU Discovery

【図解】Path MTU Discoveryの仕組み~ルータやWindows/Linuxでの設定確認/変更方法~ | SEの道標
~上記より引用~

MTA超過時にフラグメントを発生させずに通信をする仕組み。
下流れ。
①送信元ホストがDon't Flagmentフラグつけて送信
②途中NW機器がMTU超過検知時にICMP Type3 Code4で送信元に通知
③送信元はサイズを小さくして再送信
注意
送信元がICMP Type3 Code4をFirewallで受け取らない場合、MTU超過時に通信できない問題(ブラックホール問題)が発生する。

tracertとtraceroute

図解 tracert の見方 ~WindowsとLinuxの違い(icmp/udp),経路途中のIPが表示されない理由~ | SEの道標
tracert
~上記より引用~

traceroute
~上記より引用~

どちらもIP TTL Expiredの動きを利用した到達性を確認するツール。
TTLを1個づつ大きくしてICMP TTL Expiredを受信することで間のNW機器の情報を得る。
tracertはicmp echoで、tracerouteはUDPハイポート(33434から1づつ大きくする)
ゴールまで到達するとtracertがicmp reply、tracerouteはport unreachableを受信する。
※tracerouteも-Iオプションで、tracertと同様icmp echoになる。

AWS勉強メモ

[AWS Black Belt Online Seminar] Amazon EC2入門 - YouTube

  • スポットインスタンスがオンデマンドより安価。ホストサーバの余剰リソースを利用する。余剰リソースが無くなると、2分前に通知が送信されインスタンスは停止される。構築中のコストを低減を実現できる。

【AWS Black Belt Online Seminar】Amazon EC2 Auto Scaling and AWS Auto Scaling - YouTube

  • 希望容量(Desired Capacity: 数量)に従いスケールアウト(増)/スケールイン(減)
  • マルチAZ構成の場合、スケールイン/アウト時にAZ毎に台数が均一になるよう調整される。
  • スケールインがある為、特定インスタンスに特別な役割は持たせない。※特定インスタンスをスケールイン対象外にする保護設定も可能。
  • スケーリングは、動的スケーリング・予測スケーリング・スケジュールスケーリングの3つがあり。
  • ①動的スケーリング
    • 1) 簡易スケーリング
      • 1メトリクスに対し1スケジューリング調整値を指定。
      • 現在は非推奨でステップの方が推奨される。
      • 例) CPUUtilization 50%以上で1台追加
    • 2) ステップスケーリング
      • 1メトリクスに対し複数スケジューリング調整値を指定
      • 例) CPUUtilization 50~60%は1台追加、60~70%は2台追加
      • スケールアウト時にインスタンスが利用可能になる時間がウォームアップ期間。
      • この期間に次のスケールアウトが動く場合は、無駄にインスタンス起動しないよう調整される。
      • CPU50%超え1台追加されてウォームアップ期間中に、60%超えた場合、2台でなく1台だけ追加される。
    • 3) ターゲット追跡スケーリング
      • 1メトリクスに対し目標値を設定|CPU平均使用率を40%にする。
      • 自動的にスケールインとアウト用の2つのアラームが設定される。
      • スケールインは発生しづらくアラームが設定される。
  • ②予測スケーリング
    • 対象はEC2のみ。任意のメトリクスのデータを機械学習で分析。
    • 24時間毎に次の48時間の需要を予測。
    • 予測に基づきキャパシティ増減をスケジュールする。
    • 予測によるインスタンス起動時間より前にインスタンス起動させることも可能。デフォルト5分前。
    • 設定を実施するときは、「予測のみ」のモードに設定すれば、オートスケールは動作させず、予測結果の確認のみが可能。
  • ③スケジュールスケーリング
    • 一度限り or 定期的なスケジュールを設定。
  • 予測スケーリング & ターゲット追跡スケーリングがベストプラクティクス
    • 予測スケーリングでケアできない部分を、 ターゲット追跡スケーリングで対応

RDBMSの基本メモ

ポイントメモ

Innodbストレージエンジンの前提で記述する。

OS書き込み処理

処理 説明
同期I/O 書き込みAPIコールしAPIが完了したら制御が呼び出し元に戻る
非同期I/O 書き込みAPIコールしAPIが完了前に制御が呼び出し元に戻る
同期書き込み 書き込み要求がディスクに反映されるまで完了しない
MySQLではInnodbログとバイナリログの書き込みで利用
遅延書き込み 書き込み要求がキャッシュに反映されたら完了

トランザクション(ACID)対応

項目 和訳 説明
Atomicity 原子性 データ変更伴う一連のデータ操作が「全部成功」or「全部失敗」どちらかになることを保証する仕組み。COMMIT未完了の場合はROLLBACK
Consistency 一貫性 一連のデータ操作の前後で、各種整合性制約(ユニーク制約等)の状態を保つことを保証する仕組み。
Isolation 隔離性 一連のデータ操作が同時実行されたとき、処理が矛盾なく実行されることを保証する仕組み。select ~ for updateで行レベルロックし、該当行への後続操作をwaitさせる。MVCC(※1)でロック中の行に対してもselectのみなら実行可能。
Durability 持続性 COMMIT完了したデータの永続性を保証する仕組み。データ変更時、テーブルスペース(データ格納するファイル)への非同期IOに加え、WAL(Write Ahead Logging:ログ先行書き込み)をすることで、処理速度と持続性を両立。※2

※1
MultiVersion Concurrency Controlの略。
トランザクションによる書き込み処理が実行中に、他読み取りアクセスがあった場合、書き込み以前の状態(スナップショット)を処理結果として返す。

※2
テーブルスペースの更新はランダムIO。また同期I/O&非同期書き込みのため、ダーティページが発生し、持続性を実現できない。WALは、ログファイルに同期IO&同期書き込みで更新内容を追記(シーケンシャルIO)で記録するため、性能影響を軽減。また異常終了後の復旧時に、ログファイル内容をテーブルスペースに反映することで、データの永続性を保証する。

Innodbアーキテクチャの用語

No コンポーネント 説明
1 接続スレッド クライアント接続時に生成されるスレッド
2 クエリパーサ -
3 オプティマイザ -
4 クエリキャッシュ MySQL独自
5 Innodbバッファプール テーブルスペースのキャッシュ(メモリ)。非同期反映
6 テーブルスペース データが格納されるディスク領域
7 Innodbログバッファ Innodbログファイルへの書き込みデータを保持するメモリ領域
8 Innodbログファイル クラッシュリカバリ用の更新ログ
9 バイナリログキャッシュ バイナリログのキャッシュ
10 バイナリログ 更新ログ
11 バイナリログindex バイナリログ管理ファイル

Innodbログバッファについて
MySQL :: MySQL 8.0 リファレンスマニュアル :: 15.5.4 ログバッファ
DSAS開発者の部屋:5分でできる、MySQLのメモリ関係のチューニング!

データINSERT時の動作

※バイナリログ有効時

①接続スレッド
②クエリパーサ、オプティマイザ処理
③クエリ実行
④バイナリログ(ディスク上)に書き込み(同期書き込み)
Innodbログファイル(ディスク上)に書き込み(同期書き込み)
Innodbバッファプール(メモリ上)に書き込み
⑦⑥のデータがテーブルスペースに非同期で反映

★コミット前の更新データも、Innodbログファイル・テーブルスペースに書き込まれる★
以下動作を確認。
トランザクション開始しテーブルAにレコード追加
Innodbログファイル・テーブルスペースのファイルが更新されたことを確認。※見た目では同時。
③①のトランザクションをコミット
Innodbログファイルが更新された後に、テーブルスペースのファイルが更新されたことを確認。※1~2秒のラグ

バイナリログ有効時も確認する!

クラッシュリカバリ時の動作

「データINSERT時の動作」の⑤と⑦のデータを利用しREDO→UNDOする。
REDO・・・コミット済みでテーブルスペースに未反映データを適用
UNDO・・・未コミットデータのロールバック

REDOログは、innodbログファイルにあり。
UNDOログは、テーブルスペースの中のロールバックセグメントにあり。

Innodbログファイルとバイナリログの違い

どちらも更新データが書き込まれるファイル。
これらはトランザクションサポートしてるRDBMSの一般的な以下機能に関係あり。

機能 MySQLの場合 Oracleの場合
ロールフォーワードリカバリ バイナリログ利用 REDOログ利用
レプリケーション バイナリログ利用 REDOログ利用
クラッシュリカバリ Innodbログファイル利用 REDOログ利用

MySQLではInnodbログがクラッシュリカバリ専用。
※ロールフォワードリカバリは、バックアップしたテーブルスペースとバックアップ後のバイナリログでリカバリすること。

Innodbのインデックス実装

MySQL :: MySQL 5.6 リファレンスマニュアル :: 14.2.13.2 クラスタインデックスとセカンダリインデックス
MySQL で知っておきたいInnoDBのクラスタインデックスとセカンダリインデックス - Qiita
・全てのテーブルはクラスタインデックスを持つ
・主キー(PRIMARY KEY)が定義されたテーブルでは、主キーがクラスタインデックスとなる。
・主キー未定義のテーブルでは、NOT NULL の UNIQUE のインデックスがあれば、それをクラスタインデックスとする。
・主キー未定義でNOT NULL の UNIQUE のインデックスもないテーブルでは、内部的にAutoincrementなクラスタインデックスが生成される。
・上記のような内部的に自動生成されたクラスタインデックスはユーザーによる参照 & 利用は不可。
クラスタインデックス以外はセカンダリインデックスとなる。
クラスタインデックスの格納値はレコードのデータ
セカンダリインデックスの格納値はクラスタインデックス(主キー)
→主キー以外で検索すると、セカンダリインデックス参照→クラスタインデックス参照の流れとなり時間がかかる。主キーで検索すべし。

トランザクションの分離レベル

トランザクションは複数のSQLで構成された一連の処理。
全て実行(COMMIT) or 全て実行されない(ROLLBACK)のどちらかになる。
分離レベルは、読み込みを含むトランザクション中に別トランザクションで更新が行われた場合、最初のトランザクションでどの時点のデータが参照されるか?を決める。
読み込み含むトランザクション実行時に、分離レベルを指定できる。
分離レベルはRDBMSの概念として一般的に種類が定義されている。
MySQLの分離レベル対応状況は以下の通り。◎はデフォルト動作の意味。
No1→5の順で分離度合が強くなる。

No 分離レベル 対応状況 参照データ 補足
1 リードアンコミッテッド クエリ実行時点の非コミットデータ(正しさが保証されない) MVCC登場前に利用された機能でOracle・PosgreSQL・Firebirdでは未サポート。
MVCC登場前は非コミットデータにアクセスしてロックによりブロックされるより、不正確なデータでも参照したいニーズがあった為、利用された。
MVCC利用により読み取りはブロックされなくなった為、必要性は低下した。
2 リードコミッテッド クエリ実行時点でコミットされたデータ 同一トランザクション内で同クエリを2回実行する場合、結果が異なる可能性あり。
3 リピータブルリード 同一トランザクション内で同クエリを2回実行する前提
1回目はリードコミッテッドと同じ。
2回目は1回目と同じデータが参照される。
クエリの間に別トランザクションで更新されても、同じデータが参照される。
4 リアライザブル 同一トランザクション内で同クエリを2回実行する前提
リピータブルリードと同じ
クエリに合致するレコードがクエリ間で別トランザクションにより挿入された場合に、同一データ(挿入なし)を参照させる機能。
5 一貫性のあるスナップショット トランザクション開始時にコミットされてるデータ リピータブルリードは初回クエリ実行時のデータが参照される。
この場合、複数テーブルを参照する場合は整合性が合わない可能性あり。
テーブルAに対しては、初回クエリ実行時のデータが参照され整合性確保されるが、テーブルBも参照する場合、テーブルA初回参照時のテーブルBのデータが参照される保証がない。
「一貫性のあるスナップショット」を指定することでトランザクション開始時のテーブルA・Bのコミット済みのデータが参照される。

分離レベルの違いにより発生する事象

以下いずれも、同一トランザクション内で同一の参照クエリを複数回以上実行する場合の事象。
※参照クエリ1回、または更新クエリの場合は該当せず。

事象 説明
ファジーリード
※ノンリピータブルリード
2つの参照クエリが実行される間に別トランザクション更新・削除された場合、クエリ間で結果が異なってしまう。
避けたい場合は、リピータブルリードにする。
ファントムリード 2つの参照クエリが実行される間に別トランザクション参照クエリ条件に合致するレコードが挿入された場合、クエリ間で結果が異なってしまう。
避けたい場合は、シリアライザブルにする。
MySQLはリピータブルリードでも対策済み(ネクスキーロック)

Innodbトランザクションの特性

①更新と読込が互いにブロックしない。読込と読込も。
②読込は分離レベルにより内容変わる
③更新時は、行単位ロックを取得する。分離レベルや設定によりロック範囲が変わる。
④更新と更新は後の処理がブロックされる。一定時間後にタイムアウト
デッドロック時は影響少ない方が、ロールバックされる。

トランザクション実現の仕組み

行単位ロックとMVCCで実現

行単位ロックのポイント

・ロックは主キーもしくはセカンダリインデックスに対して行われる。→走査された行全てにロックがかかる。インデックススキャンされずテーブルスキャンされた場合、全行がロック対象になってしまう。
・ロックがかかる操作をする場合、インデックススキャンされるようケア必要
・ロックは以下2種類あり。

種類 説明
共有ロック 更新を禁止するロック。読込はブロックしない。
排他ロック 更新 & 読込どちらブロック

・ロックされる対象は以下3種類あり。
 該当レコードのみ
 直前のギャップのみ
 該当レコードと直前のギャップ
 ※ギャップはインデックスとインデックスの間にかかるロック。後述。
・行単位ロックは、種類と対象により6種類(2×3)と、INSERT時の特殊なギャップロックの合計7種類あり。

ギャップロックについて

 【MySQL】InnoDBの共有ロックと排他ロックの概要と挙動検証 | Enjoy IT Life
 良く分かるMySQL Innodbのギャップロック - Qiita
 LT:MySQLのギャップロックとネクストキーロックについて - Speaker Deck

 ギャップロック=インデックスとインデックスの間にかけられるロック
 この意味を動作確認で把握する。環境は以下の通り。

> CREATE TABLE test (id int(11) NOT NULL DEFAULT 0, data varchar(255) DEFAULT NULL, PRIMARY KEY (id)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
> INSERT INTO test (id, data) VALUES (2, 'bbb'), (3, 'ccc'), (4, 'ddd'), (5, 'eee'), (10, 'fff'), (20, 'ggg');
> select * from test;
+----+------+
| id | data |
+----+------+
|  2 | bbb  |
|  3 | ccc  |
|  4 | ddd  |
|  5 | eee  |
| 10 | fff  |
| 20 | ggg  |
+----+------+

上記環境に対し、2つのトランザクションで動作を確認。
片方でbegin; select * from test where [idで条件指定] for updateクエリを発行し、もう片方でinsert/updateでデータを登録できるか?でプロックの範囲を確認。

※上記表の確認方法は以下の通り。
例)条件式がid=0で、insert・updateの値が1の場合
トランザクション1で以下SQLを実行

begin; select * from test where id=0 for update;

トランザクション2で以下SQLを実行

INSERT INTO test (id, data) VALUES (1, 'XXX');

※上記SQLでロック待ちになるか?でロックを確認。
※1の部分をいろいろ変える。

例)条件式がid=2で、insert・updateの値が2の場合
トランザクション1で以下SQLを実行

begin; select * from test where id=2 for update;

トランザクション2で以下SQLを実行

update test set data='XXX' where id=2;

※条件式で指定した値と、対象レコードの値が同じ時は、updateでロック確認。

ギャップロックは指定した条件に対して直観的ではない。
ギャップロック=インデックスとインデックスの間にかけられるロック

SQLが空振りしても、ロックかかる!※空振り=select該当行なし

このように直感的でない動きは、デフォルトのリピータブルリードの為。※上述の通りmysqlネクスキーロック

上記を理解しておくこと!

MVCCについて

Multi Version Concurrency Controlの略
MVCCを実現するには、
トランザクションでコミットされるまで、変更前データを保持しておく必要がある。※上述の通り、コミットされる前に、テーブルスペースは更新される。
・またコミットされ、テーブルスペースへの反映が完了した後でも、トランザクションの分離レベルを維持する為、変更前のレコードを保持しておく必要がある。
これらを実現するため、Innodbはテーブルスペースのロールバックセグメントに複数のUNDOログ(行データのバージョン)を持っている。

ロックタイムアウトデッドロック

MySQLはグローバル設定 & プラグインによりセッション単位で設定できる。
Oracleはクエリ単位で設定できる。
Innodbでは、ロックタイムアウトが発生した場合、ロールバックされるのは、該当クエリのみ。トランザクション全体をロールバックさせるには、明示的にROLLBACKステートメント実行するか、innodb_rollback_on_timeoutを設定する。

Innodbではデッドロックが発生すると、すぐに検知しシステムに影響が少ない方をロールバックする。このロールバックは該当クエリだけでなくトランザクション単位で行われる。

一般的なRDBMSデッドロックを発生させないためにすべきこと

トランザクションを頻繁にコミットする。
・決まった順でテーブルにアクセスする。
 例) トランザクション1は、テーブルA→テーブルBの順でアクセス。トランザクション2は、テーブルB→テーブルAの順でアクセス。トランザクションによってアクセスする順を変えない。

Innodbデッドロックを発生させないためにすべきこと

・テーブルに適切にインデックスを付与し、ロック範囲の指定でインデックスが利用されるようにする。※行レベルロックの為。
・可能ならトランザクション分離レベルをリードコミッテッドにする。
・ロック読み取り(select for update)を不要に使わない。

トランザクションべからず集

・autocommitを使わない。
 例) ストアドプロシジャで大量レコード登録時、1レコードづつコミットされ時間がかかる。
  書籍記載の事例だと10万レコード登録で、autocommit有効の場合は150秒で、1万レコード毎にコミットする場合は7秒。
・大量処理を1トランザクション内で行わない。
 大量データ削除等をすると、大量のUNDOログが生成されテーブルスペースが肥大化する。UNDOログ削除されても、テーブルスペースのサイズは減らない。
・更新せずselectを実行するだけのトランザクションでも早期に終わらせる。リピータブルリードだと、初回select実行後、トランザクション終了までUNDOログが残る。
トランザクション中に対話処理を入れる。

トランザクション動作確認

トランザクションは、
トランザクション中に実行した更新操作が全て成功or失敗を制御する
上記だけでなく、
・分離レベルにより、トランザクション中の処理が扱うデータの整合性も制御する。
→一貫性のあるスナップショットなら、トランザクション内の処理は、開始時点のデータを、参照する。

上記踏まえ、以下の動作を検証する。
トランザクションaを一貫性のあるスナップショットで開始し、テープルaをセレクト
トランザクションbでテーブルaにレコード追加しコミット
トランザクションaでテーブルaをセレクトし、②のレコードか存在しないことを確認。②で追加したレコードを登録
→予想。登録は成功、コミット時にエラー?

データ型

4バイトの文字列型で整数を表現する場合、0~9999の9999通り。
同じく4バイトの整数型で整数を表現すると、0~2の32乗で42億ちょい通りを表現できる。また計算処理もしやすい。
→データ型により、格納サイズ・処理の最適化ができる。

データ型 説明
CHAR(N) 固定長文字列型
MySQLの場合癖があり。
固定長に満たないデータを入れると、空白が自動付与される。しかし取り出し時は、空白が除かれる。
※Nはバイト数の意味。PostgreSQLの場合は文字数。
VARCHAR 可変長文字列型
TEXT
※ラージオブジェクト文字列型
varcharで収まらない場合に利用
INT 整数を表現。符号つけることで負数の表現も可能。
SIGNED=符号あり(負数表現可)。UNSIGNED=符号なし(負数表現不可)。
INTは4バイト、BIGINTは8バイト。
FLOAT/DOUBLE
浮動小数
小数点が使える。INTよりも大きな数値を扱える。近似値を格納する為、演算で誤差が出る。
FLOATは4バイト、DOUBLEは8バイト。
NUMERIC/DECIMAL(P,S)
※固定小数点
SQL標準ではNUMERIC/DECIMALは異なるがMySQLでは同じ。Pは全桁数、Sは少数部分の桁数を意味する。デフォルトPは10でSは0。P、Sともに最大65。整数だけでなく小数点も使え、誤差なくBIGINT以上の数値を扱える。

※文字列型は、VARCHAR→TEXT→CHARの順で検討する。CHARは他DBからの移行等で互換性を維持する等、特別なニーズがない限り使わない方がよい。
※BIGINT以上の整数を誤差なく利用するには、NUMERIC型を使う。
※autoincrement列や主キーにはBIGINTを検討すべき。テストデータ出し入れでも、消費されるので、多めにとるべし。
※扱える数字の大きさの点では、BIGINT(19桁)→NUMERIC(65桁)→DOUBLE(308桁・誤差あり)

スレッドキャッシュとコネクションプーリングの違い

・クライアントからの接続要求毎にスレッドが生成される。
・スレッドキャッシュはMySQLサーバの機能で、生成されたスレッドをキャッシュし、次の接続時に再生成処理不要で利用可能にするもの。
・コネクションプーリングは、MySQL接続自体をプーリングする機能で、APサーバ側で実装される機能。接続認証はコネクション確立時のみでOK

Raw Deviceについて

ファイルシステムを使わずアクセスする方法
ファイルシステムオーバーヘッドやキャッシュを回避できるため高速化が可能
しかしデータの利用率や移動ができない。またファイルシステムの高速化に伴い必要性は低下
MySQLではテーブルスペースで利用可能。

データベースオブジェクトとは?

テーブルやビュー、トリガ、ストアドプロシジャのこと

スキーマとは

一般的なDBでは、データベースのこと。ユーザー名のスキーマが作成され、それが接続時のデフォルトDBになったりする。MySQLはこの概念がなく、use等でデータベースの指定が必要。

閉域網とは

閉域網とは? その仕組みやVPNについて解説 | フリービット株式会社

閉域網の「閉」はいわゆる閉じた状態で、インターネットが開かれた状態であるのに対し、不特定多数から直接アクセスを受けない、インターネットから物理的・論理的に分離されているネットワークを意味する概念

閉域網は以下に分類される。
専用線
・広域イーサネット
・IP-VPN

専用線

  • 1対1接続。複数拠点と接続したい場合、複数回線契約が必要。
  • 専用ケーブルを利用するイメージ。物理的に占有する為、共用はされない。
  • ある拠点から送り出された光信号や電気信号は、そのまま接続先の拠点まで伝わる→レイヤ1のWANサービス

 L2(データリンク層)以上は柔軟に使える

 イーサネット、ATM、HDLC、PPP、SONET/SDH ※SONETはプロバイダでなくプロトコル
 イーサネットが多いと思われる。「イーサネット専用線」のKWで各社サービスあり。
- 2つの意味があり。1対1で接続する専用船としての意味と、アクセス回線としての意味。
 ※アクセス回線は、拠点と通信事業者の間の回線
 ※後述のVPNでもアクセス回線として、専用線を利用する場合あり。

広域イーサネットとIP-VPN

名前 事業者内NW内で利用者識別する技術 利用プロトコル 備考
広域イーサネット 802.1Q
※タグVLAN・拡張仕様もあり
イーサネット 〇L2で動作するのでルーティングプロトコルを選べる
×ブロードキャストドメインが広い為、数百拠点を接続する場合等は通信制御設計要
〇IP-VPNより安い
IP-VPN MPLS IP 〇MPLSは事業者側NW機器で付与される為、利用者は考慮不要。
×事業者内NWでBGPが主流の為、利用者側のルーターでもBGP設定が必要
×MPLSがIP利用メインの為、IP以外のプロトコルは使えない。
QoS等付加サービスが多い。

※以前は、IP電話を使う=QoSのあるIP-VPNという時期があった。しかし、最近は広域イーサネットQoSに対応したサービスあり。

★重要★
ASCII.jp:通信事業者のVPNサービスを学ぶ (2/2) より引用

https://ascii.jp/img/2010/02/15/257504/o/5deb21e542679ec6.jpg

  • アクセス回線と通信網を分けて考える必要あり!

  • アクセス回線として、専用線でなくブロードバンド回線を使うこともできる!これがエントリーVPN。安いのがメリット

おまけ VPNの個人的な解釈

  • Virtual Private Networkの略
  • Publicなネットワークを使って、仮想的にPrivateなネットワーク接続を実現する技術

 ※Publicなネットワーク=複数の人・組織が共用するネットワーク。例) インターネットや通信事業者の提供する閉域網等
 ※Privateなネットワーク接続=自組織が占有したネットワーク。
 ※VPN利用せずインターネット経由で拠点間を接続できるが、拠点のゲートウェイには自組織以外のパケットも到達する。
  →Privateなネットワーク接続でない。

  • タイプにより1対1、1対n、n対nの接続が可能

 ※1対nはハブアンドスポーク方式。拠点間接続は、直接はできず、特定の1拠点を経由する必要あり。
  フレームリレーとは
 ※n対nは拠点間接続が直接可能。

OpenLDAPサーバ構築(Ver2.4・RHEL8)

ポイント

  • 設定もLDAPで管理(Configuration Backend)
  • 設定ディレクトリ(/etc/openldap/slapd.d/cn\=config)配下のldifファイルの内容が設定される。
  • 設定ディレクトリ配下のファイルの直接編集は推奨されない
  • バックエンドDBの推奨はmdb(Lightning Memory-Mapped Database (LMDB))
  • mdbはチューニング不要 ※DB_CONFIGはbdbの設定ファイル
  • デフォルトのOLCのディレクトリツリーは以下の通り。
ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config 2>/dev/null | grep "^dn"
dn: cn=config
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}monitor,cn=config
dn: olcDatabase={2}mdb,cn=config

f:id:pikesaku:20211120124238p:plain

セットアップ手順

①インストール

dnf install openldap-clients openldap-servers

②サービス起動

systemctl start slapd

③設定ディレクトリバックアップ

rsync -a /etc/openldap/slapd.d /etc/openldap/slapd.d_org

スキーマ追加

ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif

※必要に応じて追加
※以下で確認可能

ls /etc/openldap/slapd.d/cn\=config/cn\=schema/
cn={0}core.ldif  cn={1}cosine.ldif  cn={2}inetorgperson.ldif

⑤動的設定ディレクトリ設定

cat > ./config <<HERE
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootDN
olcRootDN: cn=config
-
add: olcRootPW
olcRootPW: {SSHA}XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
HERE
ldapadd -Y EXTERNAL -H ldapi:// -f ./config

※olcRootPWの値は、slappasswdで事前に生成した文字列を設定する。

⑥monitorディレクトリ設定

cat > ./monitor <<HERE
dn: olcDatabase={1}monitor,cn=config
changetype: modify
add: olcRootDN
olcRootDN: cn=monitor
-
add: olcRootPW
olcRootPW: {SSHA}XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-
replace: olcAccess
olcAccess: to *
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read
  by * none
HERE
ldapadd -Y EXTERNAL -H ldapi:// -f ./monitor

mdbディレクトリ設定

cat > ./mdb <<HERE
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=hoge,dc=com
-
replace: olcRootDN
olcRootDN: cn=Manager,dc=hoge,dc=com
-
add: olcRootPW
olcRootPW: {SSHA}XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-
add: olcDbIndex
olcDbIndex: uid eq
olcDbIndex: entryCSN,entryUUID eq
-
replace: olcAccess
olcAccess: to *
  by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" manage
  by * none
HERE
ldapadd -Y EXTERNAL -H ldapi:// -f ./mdb

ドメインやインデックスは環境に応じて変更する。

Syslog出力設定 & ログローテート

local4.*を指定ログファイルへ
ログローテート対象にログファイル追加

IPv6無効化

slapd起動オプションで-4を指定。(/etc/sysconfig/slapdがないので、serviceファイル直接修正しかない???)

Configuration Backendへの移行

RHEL6→RHEL8へのOpenLDAPのマイグレ作業時の考察

[前提]
RHEL6でConfiguration Backendを使わず、slapd.confで設定管理してた場合。方法は3つある。

①slapd.confの設定内容を、Configuration Backendのldifに置き換えて設定を入れる。

→LDIF慣れてないと大変。

②slapd.conf→Configuration Backendへの設定移行をslaptestでやる。
slaptest -f /etc/openldap/slapd.conf -F /etc/openldap/slapd.d
③Configuration Backendを使わず、slapd.confで管理する。

/etc/openldap/slapd.dを削除して、/etc/openldap/slapd.confだけにすればOK
ただ、updateした時、/etc/openldap/slapd.d配下のファイルが作られてしまい、そっちが有効になってしまうかも。しかも、obsoleteでいずれ使えなくなる。

上記より②が妥当だが注意が必要。

バックエンドDBは、RHEL8ではdbdでなくmdbがデフォルトである点

slaptest実行前に、RHEL6から持ってきたslapd.confのdatabaseをmdbに変更する。
あと、bdb関連パラメタを削除する。checkpoint等。

slaptestコマンドがエラー終了する点

slaptestコマンド実行時にslapd.confで定義されたドメインのデータベースのファイルを/var/lib/ldapに探しに行ってエラーになる。

mdb_db_open: database "dc=hoge,dc=com" cannot be opened: No such file or directory (2). Restore from backup!
backend_startup_one (type=mdb, suffix="hoge,dc=com"): bi_db_open failed! (2)
slap_startup failed (test would succeed using the -u switch)

エラーになっても、slapd.d配下にファイルは生成されており、正常にコンフィグ移行できてそう。ただエラーは気になる。
slapdを起動させれば、DBが生成されるので、以下でやれば、slaptestがエラーにならなくなる。
slaptest実行→エラー発生→slapd起動→slapd停止→slaptest再度実行→正常終了する

RHEL6のslapd.confでdatabase configをコメントアウトしてたら有効にする!これではまった。。。。。
slaptestコマンドでslapd.d配下にファイルが生成されるが、コマンド実行ユーザーがオーナーになる点。

chown -R ldap. /etc/openldap/slapd.d
をやる必要あり。slapaddと同じ。