# OpenSearch 3.1 클러스터 구축 가이드 (3-Node) 본 문서는 Ubuntu 24.04 환경에서 3대의 서버를 이용하여 OpenSearch 3.1 클러스터를 구축하고, 최종적으로 로드 밸런서(LB) 중심의 안정적인 프로덕션 아키텍처로 전환하는 전체 과정을 상세히 기술한다. ## 버전 히스토리 * **v1.0:** 개별 노드 직접 접속 방식의 초기 클러스터 구축 * **v2.0:** 로드 밸런서(LB)를 도입하여 고가용성 및 단일 접속점을 확보한 프로덕션 아키텍처로 전환 ## 목차 1. [사전 정보](#1-사전-정보) 2. [**v1.0: 초기 클러스터 구축 (LB 미사용)**](#v10-초기-클러스터-구축-lb-미사용) 1. [1단계: 설치](#1단계-설치) 2. [2단계: 사전 준비](#2단계-사전-준비) 3. [3단계: OpenSearch 설정 (`opensearch.yml`)](#3단계-opensearch-설정-opensearchyml) 4. [4단계: JVM 및 시스템 설정](#4단계-jvm-및-시스템-설정) 5. [5단계: 보안 플러그인 설정](#5단계-보안-플러그인-설정) 6. [6단계: 클러스터 시작 및 적용](#6단계-클러스터-시작-및-적용) 7. [7단계: Dashboards 설정](#7단계-dashboards-설정) 8. [8단계: Dashboards 시작 및 확인](#8단계-dashboards-시작-및-확인) 9. [9단계: JWT 인증 테스트](#9단계-jwt-인증-테스트) 3. [**v2.0: LB 중심 아키텍처로 전환**](#v20-lb-중-심-아키텍처로-전환) 1. [10단계: 아키텍처 목표](#10단계-아키텍처-목표) 2. [11단계: LB 준비 및 Nginx 프록시 구축](#11단계-lb-준비-및-nginx-프록시-구축) 3. [12단계: OpenSearch 및 Dashboards 재구성](#12단계-opensearch-및-dashboards-재구성) 4. [13단계: 최종 전환 및 테스트](#13단계-최종-전환-및-테스트) 4. [**부록: 운영 및 관리**](#부록-운영-및-관리) 1. [주요 트러블슈팅 및 교훈](#주요-트러블슈팅-및-교훈) 2. [추가 권장 사항 및 팁](#추가-권장-사항-및-팁) 3. [사용자/역할 추가 (Dashboards UI)](#사용자역할-추가-dashboards-ui) 4. [인증서에서 정확한 DN 추출하기](#인증서에서-정확한-dn-추출하기) 5. [`-nameopt RFC2253` 옵션 상세 설명](#-nameopt-rfc2253-옵션-상세-설명) --- ## 1. 사전 정보 ### 서버 사양 (3대 공통) * **CPU:** 8 vCPU * **Memory:** 65 GB * **Disk:** 2 TB SSD * **OS:** Ubuntu 24.04 * **SSH Port:** 42894 ### 노드 정보 | 항목 | Node1 | Node2 | Node3 | | :--- | :--- | :--- | :--- | | **호스트네임** | ds-opensearch001 | ds-opensearch002 | ds-opensearch003 | | **외부 DNS (v1.0)** | ds-osearch001.oneunivrs.com | ds-osearch002.oneunivrs.com | ds-osearch003.oneunivrs.com | | **내부 DNS** | ds-osnode001.oneunivrs.com | ds-osnode002.oneunivrs.com | ds-osnode003.oneunivrs.com | | **Private IP** | 10.0.10.8 | 10.0.10.9 | 10.0.10.10 | ### SSL 인증서 * **종류:** 와일드카드 `*.oneunivrs.com` * **초기 위치:** Node1의 `/data/cert/` * **파일:** `oneunivrs.pem`, `root.pem`, `oneunivrs_key.pem` * **DN:** `C=KR, ST=Seoul, O="ONEUNIVERSE Co.,Ltd.", CN=*.oneunivrs.com` ### JWT 인증 * **방식:** 대칭키 (HS256) * **서명키:** `UGdiOTdLVjFBTWtndTRNRiZmVjdwMDdCRW1lSSUxTnA=` --- ## v1.0: 초기 클러스터 구축 (LB 미사용) 이 버전은 로드 밸런서 없이 각 노드에 직접 접속하는 방식의 기본 클러스터를 구축한다. ### 1단계: 설치 모든 작업은 `root` 계정으로 진행. **[모든 노드]** APT 저장소 설정 후 OpenSearch 설치. 초기 admin 비밀번호 지정. ```bash # APT 저장소 설정 (공식 문서 참조) # OpenSearch 설치 (3.1.0) env OPENSEARCH_INITIAL_ADMIN_PASSWORD='DHp5#r#GYQ9d' apt-get install opensearch=3.1.0 # Dashboards도 미리 설치 apt-get install opensearch-dashboards=3.1.0 ``` ### 2단계: 사전 준비 **[모든 노드]** #### 2.1. 데이터/로그 디렉토리 생성 ```bash mkdir -p /data/opensearch/{data,logs} chown -R opensearch:opensearch /data/opensearch ``` #### 2.2. 인증서 복사 및 권한 설정 **[Node1]** ```bash mkdir -p /etc/opensearch/certs cp /data/cert/*.pem /etc/opensearch/certs/ # 다른 노드로 전송 scp -P 42894 /etc/opensearch/certs/*.pem root@ds-osnode002.oneunivrs.com:/etc/opensearch/certs/ scp -P 42894 /etc/opensearch/certs/*.pem root@ds-osnode003.oneunivrs.com:/etc/opensearch/certs/ ``` **[모든 노드]** ```bash chown -R opensearch:opensearch /etc/opensearch/certs chmod 600 /etc/opensearch/certs/oneunivrs_key.pem # 개인키 권한 축소 chmod 644 /etc/opensearch/certs/oneunivrs.pem /etc/opensearch/certs/root.pem ``` ### 3단계: OpenSearch 설정 (`opensearch.yml`) **[모든 노드]** 기존 파일 백업 후, 각 노드에 맞게 `/etc/opensearch/opensearch.yml` 작성. ```yaml # 클러스터 이름 cluster.name: ds-cluster # [중요] node.name은 내부 DNS와 일치시킬 것 (클러스터링 실패 방지) # Node1: node.name: ds-osnode001.oneunivrs.com # Node2: node.name: ds-osnode002.oneunivrs.com # Node3: node.name: ds-osnode003.oneunivrs.com node.name: ds-osnode001.oneunivrs.com # 각 노드에 맞게 수정 # 역할 node.roles: [ cluster_manager, data ] # 경로 path.data: /data/opensearch/data path.logs: /data/opensearch/logs # 메모리 잠금 bootstrap.memory_lock: true # 네트워크 network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 # 클러스터링 discovery.seed_hosts: - ds-osnode001.oneunivrs.com - ds-osnode002.oneunivrs.com - ds-osnode003.oneunivrs.com # [중요] 최초 마스터 후보 목록. node.name과 일치해야 함. cluster.initial_cluster_manager_nodes: - ds-osnode001.oneunivrs.com - ds-osnode002.oneunivrs.com - ds-osnode003.oneunivrs.com # 보안 플러그인 plugins.security.ssl.transport.enabled: true plugins.security.ssl.transport.pemcert_filepath: certs/oneunivrs.pem plugins.security.ssl.transport.pemkey_filepath: certs/oneunivrs_key.pem plugins.security.ssl.transport.pemtrustedcas_filepath: certs/root.pem plugins.security.ssl.transport.enforce_hostname_verification: false plugins.security.ssl.http.enabled: true plugins.security.ssl.http.pemcert_filepath: certs/oneunivrs.pem plugins.security.ssl.http.pemkey_filepath: certs/oneunivrs_key.pem plugins.security.ssl.http.pemtrustedcas_filepath: certs/root.pem # [주의] DN의 쉼표(,)는 백슬래시 두 개(\\)로 이스케이프 plugins.security.nodes_dn: - "CN=*.oneunivrs.com,O=ONEUNIVERSE Co.\\,Ltd.,ST=Seoul,C=KR" plugins.security.authcz.admin_dn: - "CN=*.oneunivrs.com,O=ONEUNIVERSE Co.\\,Ltd.,ST=Seoul,C=KR" plugins.security.allow_default_init_securityindex: true plugins.security.audit.type: internal_opensearch plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"] ``` ### 4단계: JVM 및 시스템 설정 **[모든 노드]** #### 4.1. JVM 힙 메모리 `/etc/opensearch/jvm.options` 파일 수정. 31GB로 설정. ```bash sed -i 's/^-Xms1g/#-Xms1g/' /etc/opensearch/jvm.options sed -i 's/^-Xmx1g/#-Xmx1g/' /etc/opensearch/jvm.options echo -e "\n-Xms31g\n-Xmx31g" >> /etc/opensearch/jvm.options ``` #### 4.2. Systemd 오버라이드 메모리 잠금과 경로 권한 부여. ```bash mkdir -p /etc/systemd/system/opensearch.service.d cat < /etc/systemd/system/opensearch.service.d/override.conf [Service] LimitMEMLOCK=infinity ReadWritePaths=/data/opensearch/ EOF systemctl daemon-reload systemctl enable opensearch.service ``` ### 5단계: 보안 플러그인 설정 **[Node1에서 작업 후 다른 노드로 복사]** #### 5.1. 인증 방식 설정 (`config.yml`) `/etc/opensearch/opensearch-security/config.yml` 수정. JWT 우선, Basic 차선. ```yaml --- _meta: type: "config" config_version: 2 config: dynamic: http: anonymous_auth_enabled: false authc: # [중요] order: 0(JWT) -> order: 1(Basic) jwt_auth_domain: http_enabled: true order: 0 http_authenticator: type: jwt challenge: false config: signing_key: "UGdiOTdLVjFBTWtndTRNRiZmVjdwMDdCRW1lSSUxTnA=" jwt_header: "Authorization" # "Bearer " 접두사는 자동 처리됨 subject_key: sub roles_key: roles authentication_backend: type: noop basic_internal_auth_domain: http_enabled: true order: 1 http_authenticator: type: basic challenge: true authentication_backend: type: internal ``` #### 5.2. 역할 매핑 (`roles_mapping.yml`) `/etc/opensearch/opensearch-security/roles_mapping.yml` 수정. ```yaml # ... (기존 내용 유지) all_access: reserved: false users: - "admin" # 내부 사용자 backend_roles: - "admin" # JWT를 통해 온 사용자 # ... (기존 내용 유지) ``` #### 5.3. 파일 복사 및 권한 설정 **[Node1]** ```bash scp -P 42894 /etc/opensearch/opensearch-security/config.yml root@ds-osnode002.oneunivrs.com:/etc/opensearch/opensearch-security/ scp -P 42894 /etc/opensearch/opensearch-security/roles_mapping.yml root@ds-osnode002.oneunivrs.com:/etc/opensearch/opensearch-security/ scp -P 42894 /etc/opensearch/opensearch-security/config.yml root@ds-osnode003.oneunivrs.com:/etc/opensearch/opensearch-security/ scp -P 42894 /etc/opensearch/opensearch-security/roles_mapping.yml root@ds-osnode003.oneunivrs.com:/etc/opensearch/opensearch-security/ ``` **[모든 노드]** ```bash chown -R opensearch:opensearch /etc/opensearch find /etc/opensearch -type d -exec chmod 750 {} \; find /etc/opensearch -type f -exec chmod 640 {} \; chmod 600 /etc/opensearch/certs/oneunivrs_key.pem chmod -R 600 /etc/opensearch/opensearch-security/* ``` ### 6단계: 클러스터 시작 및 적용 #### 6.1. 클러스터 시작 마스터가 아닌 노드부터 순차적으로 시작. ```bash systemctl start opensearch.service # Node3 -> Node2 -> Node1 순으로 실행 ``` #### 6.2. 개인키 변환 (PKCS#8) `securityadmin.sh`는 PKCS#8 형식을 요구함. **[Node1]** ```bash openssl pkcs8 -topk8 -inform PEM -outform PEM -in /etc/opensearch/certs/oneunivrs_key.pem -out /etc/opensearch/certs/oneunivrs_key.p8.pem -nocrypt chown opensearch:opensearch /etc/opensearch/certs/oneunivrs_key.p8.pem chmod 600 /etc/opensearch/certs/oneunivrs_key.p8.pem ``` #### 6.3. 보안 설정 적용 **[Node1]** ```bash # [중요] 3.1 버전은 REST 포트(9200)와 변환된 키(.p8.pem) 사용 /usr/share/opensearch/plugins/opensearch-security/tools/securityadmin.sh \ -cd /etc/opensearch/opensearch-security/ \ -cacert /etc/opensearch/certs/root.pem \ -cert /etc/opensearch/certs/oneunivrs.pem \ -key /etc/opensearch/certs/oneunivrs_key.p8.pem \ -h ds-osnode001.oneunivrs.com \ -p 9200 \ -icl \ -nhnv ``` ### 7단계: Dashboards 설정 **[Node1]** #### 7.1. 대시보드용 인증서 복사 ```bash mkdir -p /etc/opensearch-dashboards/certs cp /etc/opensearch/certs/*.pem /etc/opensearch-dashboards/certs/ chown -R opensearch-dashboards:opensearch-dashboards /etc/opensearch-dashboards/certs ``` #### 7.2. `opensearch_dashboards.yml` 설정 ```yaml server.port: 5601 server.host: "0.0.0.0" server.name: "oneunivrs-opensearch-dashboards" # 고가용성을 위해 클러스터 노드 모두 기재 opensearch.hosts: - https://ds-osearch001.oneunivrs.com:9200 - https://ds-osearch002.oneunivrs.com:9200 - https://ds-osearch003.oneunivrs.com:9200 # [중요] 2.x 이후 버전의 설정 키 이름 opensearch.requestHeadersWhitelist: [ "securitytenant", "authorization" ] # 대시보드 HTTPS server.ssl.enabled: true server.ssl.certificate: /etc/opensearch-dashboards/certs/oneunivrs.pem server.ssl.key: /etc/opensearch-dashboards/certs/oneunivrs_key.pem # [중요] 2.x 이후 버전의 설정 키 이름 (배열) opensearch.ssl: verificationMode: full certificateAuthorities: [ "/etc/opensearch-dashboards/certs/root.pem" ] # 서비스 계정 opensearch.username: "kibanaserver" opensearch.password: "kibanaserver" # 보안 연동 opensearch_security: multitenancy.enabled: true auth.anonymous_auth_enabled: false cookie.password: "강력하고_랜덤한_문자열_사용" ``` ### 8단계: Dashboards 시작 및 확인 **[Node1]** ```bash systemctl start opensearch-dashboards.service systemctl enable opensearch-dashboards.service ``` 브라우저에서 `https://ds-osearch001.oneunivrs.com:5601` 접속. `admin` / `DHp5#r#GYQ9d` 로그인 확인. ### 9단계: JWT 인증 테스트 #### 9.1. 서버에서 직접 토큰 생성 외부 도구의 키 처리 방식 문제로 서버에서 직접 생성하는 것이 가장 확실. **[Node1]** ```bash pip install pyjwt vi create_token.py ``` ```python # create_token.py import jwt, time, base64 base64_secret = "UGdiOTdLVjFBTWtndTRNRiZmVjdwMDdCRW1lSSUxTnA=" # [핵심] Base64 디코딩 decoded_secret = base64.b64decode(base64_secret) payload = { "sub": "admin", "roles": ["admin"], "exp": int(time.time()) + 3600 } token = jwt.encode(payload, decoded_secret, algorithm="HS256") print(token) ``` ```bash python3 create_token.py # 토큰 생성 후 복사 ``` #### 9.2. `curl`로 API 호출 ```bash curl -k -H "Authorization: Bearer <방금_생성한_토큰>" "https://ds-osearch001.oneunivrs.com:9200" ``` 성공 응답 확인. --- ## v2.0: LB 중심 아키텍처로 전환 초기 구축된 클러스터를 프로덕션 환경에 적합하도록 로드 밸런서(LB) 중심의 고가용성 아키텍처로 전환한다. ### 10단계: 아키텍처 목표 * **AS-IS:** 클라이언트가 개별 노드(`ds-osearch001` 등)에 직접 접속. * **TO-BE:** 클라이언트는 LB의 단일 대표 주소(`ds-opensearch.oneunivrs.com`)에만 접속. 노드들은 내부망에 격리되어 보안 강화. ### 11단계: LB 준비 및 Nginx 프록시 구축 LB의 헬스 체크 제약(200 OK만 허용)을 우회하기 위해, 모든 OpenSearch 노드에 헬스 체크 전용 Nginx 프록시를 설치한다. **[모든 노드 (Node1, Node2, Node3)에서 실행]** ```bash # Nginx 설치 apt-get update && apt-get install nginx -y # Nginx용 SSL 디렉토리 생성 및 인증서 복사 mkdir -p /etc/nginx/ssl cp /etc/opensearch/certs/*.pem /etc/nginx/ssl/ # 기본 설정 비활성화 rm /etc/nginx/sites-enabled/default # 헬스 체크용 설정 파일 생성 vi /etc/nginx/sites-available/opensearch-healthcheck ``` `opensearch-healthcheck` 파일에 아래 내용을 작성한다. ```nginx server { listen 9201 ssl; # [주의] IPv6 비활성화 환경에서는 아래 라인 주석 처리 # listen [::]:9201 ssl; # 각 노드의 내부 DNS 또는 IP로 설정 server_name ds-osnode001.oneunivrs.com; # Node2에서는 ds-osnode002... ssl_certificate /etc/nginx/ssl/oneunivrs.pem; ssl_certificate_key /etc/nginx/ssl/oneunivrs_key.pem; location / { # 헬스 체크 요청에 무조건 200 OK 응답 return 200 'Healthy'; add_header Content-Type text/plain; add_header Content-Length 7; } } ``` ```bash # 설정 활성화 및 재시작 ln -s /etc/nginx/sites-available/opensearch-healthcheck /etc/nginx/sites-enabled/ nginx -t systemctl restart nginx systemctl enable nginx ``` ### 12단계: OpenSearch 및 Dashboards 재구성 **[로드 밸런서 설정]** * **대표 DNS:** `ds-opensearch.oneunivrs.com`을 생성하여 LB의 Public IP에 연결. * **리스너:** `HTTPS:9200` (API용), `HTTPS:5601` (Dashboards용) 생성. * **SSL 인증서:** `oneunivrs.com` 인증서를 LB에 설치. * **`opensearch-api` 타겟 그룹:** * **대상:** `10.0.10.8:9200`, `10.0.10.9:9200`, `10.0.10.10:9200` * **헬스 체크:** `HTTPS`, Port `9201`, Path `/`, Method `GET` * **`opensearch-dashboard` 타겟 그룹:** * **대상:** `10.0.10.8:5601` * **헬스 체크:** `HTTPS`, Port `9201`, Path `/`, Method `GET` (API와 동일한 프록시 사용) **[Node1의 Dashboards 설정 변경]** `/etc/opensearch-dashboards/opensearch_dashboards.yml`을 수정하여 LB를 바라보게 한다. ```yaml # opensearch.hosts를 새로운 LB 대표 DNS로 변경 opensearch.hosts: ["https://ds-opensearch.oneunivrs.com:9200"] # [중요] LB <-> Dashboards 간 SNI 문제 해결을 위한 옵션 추가 opensearch.ssl: alwaysPresentCertificate: true verificationMode: full certificateAuthorities: [ "/etc/opensearch-dashboards/certs/root.pem" ] ``` ```bash # Dashboards 서비스 재시작 systemctl restart opensearch-dashboards.service ``` ### 13단계: 최종 전환 및 테스트 1. LB 콘솔에서 `opensearch-api`와 `opensearch-dashboard` 타겟 그룹의 상태가 모두 `healthy`로 바뀌는지 확인한다. 2. 모든 클라이언트의 접속 주소를 `https://ds-opensearch.oneunivrs.com`으로 변경한다. 3. API와 Dashboards 접속이 모두 정상적으로 이루어지는지 최종 확인한다. ```bash curl -k -H "Authorization: Bearer <최종_토큰>" "https://ds-opensearch.oneunivrs.com:9200" ``` 4. (선택 사항) 전환이 안정화되면, 개별 노드의 외부 IP를 제거하고 방화벽을 강화하여 보안 수준을 높인다. --- ## 부록: 운영 및 관리 ### 주요 트러블슈팅 및 교훈 1. **클러스터 형성 실패 (`cluster-manager not discovered`):** `opensearch.yml`의 `node.name`과 `cluster.initial_cluster_manager_nodes` 목록의 이름이 불일치. 클러스터링 관련 설정의 이름은 정확히 일치해야 함. 2. **`securityadmin.sh` 실행 실패:** * **원인 1 (`InvalidKeySpecException`):** `securityadmin.sh`는 PKCS#8 형식의 개인키를 필요로 함. `openssl pkcs8` 명령으로 변환하여 해결. * **원인 2 (포트 오류):** OpenSearch 2.12 이후 `securityadmin.sh`는 REST 포트(9200)를 사용. 3. **Dashboards 시작 실패:** 2.x 버전 이후 변경된 설정 키 이름 문제 (`requestHeadersWhitelist`, `ssl.ca`). 버전업 시 공식 문서의 Breaking Changes를 반드시 확인해야 함. 4. **JWT 인증 실패 (`Unauthorized`):** * **근본 원인:** `signing_key`를 Base64 문자열 그대로 사용. * **해결:** `signing_key`를 **Base64 디코딩**한 바이너리 값을 실제 비밀키로 사용하여 토큰을 생성해야 함. 5. **LB 헬스 체크 실패 (`503`, `401`, `405` 등):** * **원인:** 사용하는 LB가 헬스 체크 성공 기준으로 `200 OK`만 허용하는데, 보안이 활성화된 OpenSearch/Dashboards는 인증되지 않은 요청에 `200 OK`를 반환하지 않음. * **해결:** 모든 노드에 Nginx를 헬스 체크 전용 프록시로 설치. LB는 Nginx의 `9201` 포트로 헬스 체크를 요청하고, Nginx는 무조건 `200 OK`를 응답하여 문제를 우회함. ### 추가 권장 사항 및 팁 1. **롤링 리스타트 시 샤드 재배치 중단:** `/_cluster/settings` API를 통해 `cluster.routing.rebalance.enable`을 `none`으로 설정하면 재시작 속도를 높일 수 있음. 2. **인덱스 템플릿 및 ILM:** 데이터가 많아지기 전에 Dashboards의 `Index Management` 메뉴에서 인덱스 템플릿과 ILM(수명 주기 관리) 정책을 설정하여 운영을 자동화할 것. 3. **스냅샷 및 복구:** 데이터 유실 방지를 위해 Dashboards의 `Snapshots` 메뉴에서 외부 저장소(S3 등)로의 주기적인 백업을 반드시 설정할 것. 4. **방화벽 설정:** LB 전환 후 노드들의 외부 IP를 제거하고, OS 방화벽(UFW 등)을 사용해 신뢰할 수 있는 내부 IP 대역에서의 접속만 허용하여 보안을 강화할 것. ### 사용자/역할 추가 (Dashboards UI) `admin` 계정으로 Dashboards에 로그인 후, `Security` 메뉴에서 YAML 파일 수정 없이 직관적으로 사용자, 역할, 역할 매핑을 관리할 수 있다. 일회성 작업은 UI를 사용하는 것이 편리하다. * **역할 생성:** `Security > Roles > Create role` * **사용자 생성:** `Security > Internal Users > Create internal user` * **역할 매핑:** `Security > Roles > (역할 선택) > Mapped users > Manage mapping` ### 인증서에서 정확한 DN 추출하기 `opensearch.yml`의 `nodes_dn`, `admin_dn` 설정 시, `openssl` 명령어로 정확한 DN을 추출하여 사용하면 실수를 방지할 수 있다. ```bash # [권장] RFC2253 형식으로 출력 openssl x509 -in /data/cert/oneunivrs.pem -noout -subject -nameopt RFC2253 ``` **출력 예시:** `CN=*.oneunivrs.com,O=ONEUNIVERSE Co.\,Ltd.,ST=Seoul,C=KR` **`opensearch.yml` 적용 시:** YAML 문자열 내에서 백슬래시(`\`)는 이스케이프해야 하므로 `\\`로 변경해야 한다. `"CN=*.oneunivrs.com,O=ONEUNIVERSE Co.\\,Ltd.,ST=Seoul,C=KR"` ### `-nameopt RFC2253` 옵션 상세 설명 이 옵션은 기계가 파싱하기 좋은 표준 형식으로 DN을 출력한다. * `subject=` 같은 불필요한 접두사가 없다. * 쉼표(`,`)로만 구분되며 불필요한 공백이 없다. * **가장 중요:** DN 값 자체에 포함된 특수 문자(예: `Co.,Ltd.`의 쉼표)를 백슬래시(`\`)로 자동으로 이스케이프 처리해준다. * OpenSearch 보안 플러그인은 이 형식을 가장 안정적으로 인식하므로, DN 설정 시 반드시 사용하는 것이 좋다.