javaでのAD連携


※ 個人的メモです。流用、参考にされた際の責任は負いかねます。

# 目的・背景
LDAPでAD連携を行いたい。
操作内容は、グループの管理/グループメンバーの管理。

# 目標
- 上記の操作ができるメソッドを準備できること
- LDAPsで通信が行えること
- 認証方式はユーザー名/PWを使う（一旦）


# 参照
https://docs.oracle.com/javase/jndi/tutorial/ldap/security/ldap.html?utm_source=chatgpt.com

https://docs.oracle.com/javase/tutorial/jndi/ldap/rename.html

https://docs.oracle.com/javase/jp/8/docs/technotes/guides/jndi/jndi-ldap.html

https://dev.java/learn/

https://learn.microsoft.com/en-us/windows/win32/ad/creating-groups-in-a-domain



# EC2 上に Active Directory (AD DS) を構築する手順書（日本語）

## 【前提】

* 目的: JavaからのLDAP/グループ操作等を検証するためのサンドボックスAD環境をAWS EC2上に構築
* 環境: AWS EC2 (Windows Server 2019/2022)
* 実行方: 手動構築

---

## 【1. EC2 インスタンスの設定】

### 1-1. EC2インスタンスの生成

* パブリックIP: **自動割り当てを有効化（RDP接続のために必要）**
* EC2コンソールより「インスタンス設定」
* プラットフォーム: **Windows Server 2019/2022 Base**
* インスタンスタイプ: `t3.small` (検証用なら小さくてもOK。`t3.micro`でも動作はするが、メモリ不足で不安定になるため非推奨)
* ストレージ: 30GB EBS / **汎用SSD（gp3推奨）**
* キーペア: **RDP接続に必要。新規作成または既存のキーペアを選択**

### 1-2. セキュリティ設定（この段階で実施）

* セキュリティグループを新規作成し、以下のポートを許可：

  * TCP 3389（RDP）
  * TCP 389（LDAP）
  * TCP 636（LDAPS）
* 許可元IPは **自身のグローバルIPアドレス/32 に限定するのが推奨**（`0.0.0.0/0`はセキュリティ上非推奨）

---

## 【2. Windows Server で AD DS を構築】

### 2-1. RDPでログイン

* Mac/Windowsから RDP でEC2に接続（キーペアを使ってパスワードを取得）

#### 【Macからの接続手順】

1. Mac App Storeから「Microsoft Remote Desktop」をインストール（無料）
2. EC2管理画面の「接続」から、Windowsログオンパスワードを復号（キーペアを使用）
3. Microsoft Remote Desktopを起動し、以下の情報で新規接続を作成：

   * PC名：EC2インスタンスのパブリックIPアドレス（例：`54.xxx.xxx.xxx`）
   * ユーザー名：`Administrator`
   * パスワード：手順2で復号したもの
4. 接続を開始し、Windows Serverのログイン画面が表示されれば成功

#### 【Windows Server の日本語化手順】

1. RDP接続後、「設定」>「時刻と言語」>「言語」へ移動
2. 「言語を追加する」>「日本語」を選択してインストール
3. インストール後、「Windowsの表示言語」に日本語を設定し、サインアウト／再サインイン
4. 必要に応じて「地域」設定も日本に変更
   ※ 再起動後、UIが日本語化される

* Mac/Windowsから RDP でEC2に接続（キーペアを使ってパスワードを取得）

#### 【Macからの接続手順】

1. Mac App Storeから「Microsoft Remote Desktop」をインストール（無料）
2. EC2管理画面の「接続」から、Windowsログオンパスワードを復号（キーペアを使用）
3. Microsoft Remote Desktopを起動し、以下の情報で新規接続を作成：

   * PC名：EC2インスタンスのパブリックIPアドレス（例：`54.xxx.xxx.xxx`）
   * ユーザー名：`Administrator`
   * パスワード：手順2で復号したもの
4. 接続を開始し、Windows Serverのログイン画面が表示されれば成功

* Mac/Windowsから RDP でEC2に接続（キーペアを使ってパスワードを取得）

### 2-2. AD DSの設定

1. 「サーバーマネージャ」を開く
2. 「ロールとフィーチャの追加」 > `Active Directory Domain Services` を追加

   * 途中で表示される「Add features that are required for Active Directory Domain Services?」はそのまま「Add Features」を選択
3. 再起動
4. ドメインコントローラ化ウィザードを実行（「このサーバーをドメインコントローラに昇格」リンクをクリック）

   * 新しいフォレストとして `sandbox.local` を指定
   * DSRM（Directory Services Restore Mode）パスワードを設定
   * DNSサーバーは自動で追加（デフォルト）
   * その他の設定（NetBIOS名・パス等）は基本デフォルトでOK
   * 最終的に再起動され、ドメインコントローラとしての構成が完了
5. 「サーバーマネージャ」を開く
6. 「ロールとフィーチャの追加」 > `Active Directory Domain Services` を追加
7. 再起動
8. ドメインコントローラ化ウィザード

   * 新しいドメイン: `sandbox.local`
   * インスタンスは初期ドメインコントローラとして設定

### 2-3. ユーザー/グループ作成

* 「Active Directory ユーザーとコンピューター（Active Directory Users and Computers）」が見つからない場合：

  * Win + R を押して「dsa.msc」と入力 → **エラーが出る場合は、管理ツールが未インストールの可能性あり**
  * 「サーバーマネージャ」>「役割と機能の追加」> `Remote Server Administration Tools` > `AD DS and AD LDS Tools` > `AD DS Tools` > `AD DS Snap-ins and Command-Line Tools` にチェックを入れて追加する
  * インストール後、`dsa.msc` を実行するか、「サーバーマネージャ」>「ツール」メニューから「Active Directory ユーザーとコンピューター」を起動できるようになる
  * **なお、これでも表示されない場合は PowerShell や `mmc` からのスナップイン追加、または `Install-WindowsFeature RSAT-ADDS` コマンドによるCLIインストールが最終手段として有効です**

* 管理ツールを起動後、左側のツリーで `sandbox.local` ドメインを展開し、「Users」コンテナを右クリック > 「新規作成」から以下を実行：

#### 【ユーザー作成手順】

1. 「ユーザー」 > 氏名・ログオン名（例：`testuser`）を入力
2. パスワードを設定（任意で「次回ログオン時にパスワード変更を要求」なども設定）
3. 完了でユーザーが作成される

#### 【グループ作成手順】

1. 「グループ」 > グループ名（例：`Developers`）を入力
2. グループのスコープ：`Global`、グループの種類：`Security` を選択（デフォルト）
3. 完了後に作成されたグループを開き、メンバータブから先ほど作成したユーザーを追加可能

※ このユーザー・グループは、JavaからLDAP検索・追加・削除の対象として利用できます

---

## 【3. Java の LDAP 接続検証】

### 3-1. Java側のサンプル接続（ローカルPCからEC2上のADに接続する）

#### 【前提条件】

##### 【Windows FirewallでLDAPポート (389) を許可する方法】

1. Windows Server 内で「スタート」→「Windows Defender Firewall」を開く
2. 左メニューの「詳細設定」をクリック（Windows Defender Firewall with Advanced Security）
3. 左メニュー「受信の規則」→ 右ペイン「新しい規則」をクリック
4. 種類：「ポート」を選択 → 次へ
5. プロトコルとポート：「TCP」かつ「特定のローカルポート：389」→ 次へ
6. 操作：「接続を許可する」→ 次へ
7. プロファイル：「ドメイン」「プライベート」「パブリック」すべてチェック→ 次へ
8. 名前：「Allow LDAP TCP 389」などを入力して完了

* EC2にパブリックIPが割り当てられている（例：`54.xxx.xxx.xxx`）
* セキュリティグループでポート389（LDAP）が**ローカルPCのグローバルIP**に対して許可されている
* Windows FirewallでもLDAPポート（389）が許可されている（必要に応じて確認）

#### 【サンプルコード】

```java
Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://<EC2のパブリックIP>:389");  // 例: ldap://54.xxx.xxx.xxx:389
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "CN=admin,CN=Users,DC=sandbox,DC=local");
env.put(Context.SECURITY_CREDENTIALS, "your-password");
DirContext ctx = new InitialDirContext(env);
```

### 3-1-補足. Jshellでグループ情報を取得するサンプル

以下は、JavaのJNDI APIを使用して、特定のグループ情報（例：Developersグループ）をLDAPから取得する`jshell`用スクリプトです：

```java
import javax.naming.*;
import javax.naming.directory.*;
import java.util.Hashtable;

Hashtable<String, String> env = new Hashtable<>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.PROVIDER_URL, "ldap://<EC2のパブリックIP>:389");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "CN=Administrator,CN=Users,DC=sandbox,DC=local");
env.put(Context.SECURITY_CREDENTIALS, "your-password");

DirContext ctx = new InitialDirContext(env);
String baseDN = "CN=Users,DC=sandbox,DC=local";
String filter = "(&(objectClass=group)(cn=Developers))";
SearchControls controls = new SearchControls();
controls.setSearchScope(SearchControls.SUBTREE_SCOPE);

NamingEnumeration<SearchResult> results = ctx.search(baseDN, filter, controls);
while (results.hasMore()) {
    SearchResult sr = results.next();
    System.out.println("Group DN: " + sr.getNameInNamespace());
    Attributes attrs = sr.getAttributes();
    Attribute members = attrs.get("member");
    if (members != null) {
        for (int i = 0; i < members.size(); i++) {
            System.out.println("  Member: " + members.get(i));
        }
    }
}
ctx.close();
```

> ※ EC2のパブリックIPや管理者のDN、パスワードはご自身の環境に合わせて差し替えてください

---

### 3-2. LDAPS (セキュアプロト接続)

* 自己署名証明書を作成
* Windowsにサーバ証明書を追加
* Java側: `keytool` で truststore に追加

---

## 【4. 補足情報】

* Windows Server の評価版は180日利用可

* **180日経過後、自動的にライセンス課金が発生することはありません**が、

  * 評価版の機能制限が有効になり、ログイン制限やシャットダウンが発生します
  * インスタンスはAWS側で継続して稼働している限り、**EC2・EBSの利用料金は引き続き発生**します
  * 評価版ライセンスの有効期限はOS内部の問題であり、AWSの課金管理とは無関係

* **EC2インスタンスは「シャットダウン」しても、**

  * **「停止（Stop）」状態にならなければ課金され続けます**
  * 「OS内からのシャットダウン（終了）」はAWS的には「稼働中」として扱われるケースがあります
  * AWSコンソールで明示的に「停止（Stop）」することが推奨されます

* 検証終了後はインスタンス削除 or スナップして保存推奨

* Windows Server の評価版は180日利用可

* **180日経過後、自動的にライセンス課金が発生することはありません**が、

  * 評価版の機能制限が有効になり、ログイン制限やシャットダウンが発生します
  * インスタンスはAWS側で継続して稼働している限り、**EC2・EBSの利用料金は引き続き発生**します
  * 評価版ライセンスの有効期限はOS内部の問題であり、AWSの課金管理とは無関係

* 検証終了後はインスタンス削除 or スナップして保存推奨

* Windows Server の評価版は180日利用可

* AWSでは使用時間に応じて費用発生

* 検証終了後はインスタンス削除 or スナップして存管

---

## ✅ まとめ

| 項目     | 内容                                      |
| ------ | --------------------------------------- |
| 環境     | EC2 (t3.small) + Windows Server + AD DS |
| ドメイン   | sandbox.local (本番分離)                    |
| Java接続 | JNDIでLDAP(増減の検証)                        |
| セキュリティ | セキュリティグループで3389/389/636開放（IP制限）         |
| 経済     | 月額2,000円前後で検証可                          |

https://github.com/Takahiro-Kaji/springboot-demo/settings



# キーストアに登録

sudo keytool -importcert \
  -keystore "$( /usr/libexec/java_home )/lib/security/cacerts" \
  -alias my-ldap \
  -file server-cert.cer \
  -storepass changeit


https://youtu.be/Q-GKwUD-e4Q