PKI와 신뢰 설정
- 서버와 클라이언트의 응용 프로그램 인스턴스 인증서(application instance certificate)와 개인 키를 만듭니다.
- 인증서에 필요한 확장(extension)이 들어갔는지 검사합니다.
- 상대 인증서를 신뢰할 때와 신뢰하지 않을 때 연결이 어떻게 되는지 확인합니다.
준비물
섹션 제목: “준비물”- 실습 환경의 1~3단계: 패키지를 풀고 환경 변수를 설정합니다.
- OpenSSL 3 명령행 도구
1. 인증서 템플릿 살펴보기
섹션 제목: “1. 인증서 템플릿 살펴보기”SDK의 examples/opcua/pki에는 OpenSSL 설정 템플릿이 두 개 있습니다.
# Self-signed OPC UA application instance certificate for the example server.# Change the URI to your server ApplicationUri and the DNS/IP names to the host# names used in the endpoint URL.[req]prompt = nodistinguished_name = subjectx509_extensions = application
[subject]CN = PDComm OPC UA Example ServerO = Example Organization
[application]basicConstraints = critical, CA:FALSEkeyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyCertSignextendedKeyUsage = serverAuth, clientAuthsubjectAltName = URI:urn:pdcomm:opcua:server, DNS:localhost, IP:127.0.0.1subjectKeyIdentifier = hashauthorityKeyIdentifier = keyid# Self-signed OPC UA application instance certificate for the example client.# The URI must equal the client ApplicationUri (default urn:pdcomm:opcua:client).[req]prompt = nodistinguished_name = subjectx509_extensions = application
[subject]CN = PDComm OPC UA Example ClientO = Example Organization
[application]basicConstraints = critical, CA:FALSEkeyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyCertSignextendedKeyUsage = serverAuth, clientAuthsubjectAltName = URI:urn:pdcomm:opcua:client, DNS:localhostsubjectKeyIdentifier = hashauthorityKeyIdentifier = keyid| 설정 | 의미 |
|---|---|
CN, O |
주체 이름. 비어 있으면 PDComm이 인증서를 거부합니다. |
basicConstraints = critical, CA:FALSE |
응용 프로그램 인증서이며 인증 기관(CA)이 아닙니다. |
keyUsage |
OPC UA가 요구하는 키 용도. 자체 서명이므로 keyCertSign을 포함합니다. |
extendedKeyUsage |
서버 인증(serverAuth)과 클라이언트 인증(clientAuth) |
subjectAltName |
URI:는 ApplicationUri, DNS:와 IP:는 이 서버에 접속할 때 쓰는 호스트 이름과 주소 |
2. 서버 인증서의 호스트 이름 정하기
섹션 제목: “2. 서버 인증서의 호스트 이름 정하기”클라이언트는 endpoint URL의 호스트가 서버 인증서의 DNS: 또는 IP: 항목과 일치하는지 검사합니다. 템플릿은 localhost와 127.0.0.1만 담고 있습니다. 다른 컴퓨터나 컴퓨터 이름으로 접속할 계획이면 그 이름을 추가합니다.
컴퓨터 이름을 확인합니다.
hostname$PKI/server.cnf의 subjectAltName 줄에 이름을 추가합니다. 이 튜토리얼에서는 컴퓨터 이름을 my-pc라고 가정합니다. 실제 이름으로 바꿉니다.
subjectAltName = URI:urn:pdcomm:opcua:server, DNS:localhost, DNS:my-pc, IP:127.0.0.1일부 Windows 클라이언트는 endpoint URL의 localhost를 컴퓨터 이름으로 바꿔 접속합니다. 서버가 Windows에서 실행되거나 Windows 클라이언트가 접속한다면 컴퓨터 이름을 꼭 넣습니다. 자세한 내용은 인증서 문제에서 설명합니다.
3. 인증서와 개인 키 만들기
섹션 제목: “3. 인증서와 개인 키 만들기”cd "$PKI"openssl req -x509 -new -config server.cnf -newkey rsa:2048 -sha256 -days 365 -noenc \ -keyout server.key.pem -out server.cert.pemopenssl x509 -in server.cert.pem -outform DER -out server.deropenssl req -x509 -new -config client.cnf -newkey rsa:2048 -sha256 -days 365 -noenc \ -keyout client.key.pem -out client.cert.pemopenssl x509 -in client.cert.pem -outform DER -out client.derchmod 600 server.key.pem client.key.pemls -1결과:
client.cert.pemclient.cnfclient.derclient.key.pemserver.cert.pemserver.cnfserver.derserver.key.pem파일의 쓰임은 다음과 같습니다.
| 파일 | 형식 | 누가 쓰나 |
|---|---|---|
server.der |
DER 인증서 | 서버의 신원. 클라이언트가 신뢰할 인증서로도 지정합니다. |
server.key.pem |
PEM 개인 키 | 서버만 읽습니다. |
server.cert.pem |
PEM 인증서 | 시뮬레이터 서버의 신원 파일로 씁니다. |
client.der |
DER 인증서 | 클라이언트의 신원. 서버가 신뢰할 인증서로도 지정합니다. |
client.key.pem |
PEM 개인 키 | 클라이언트만 읽습니다. |
client.cert.pem |
PEM 인증서 | 시뮬레이터 클라이언트의 신원 파일로 씁니다. |
SDK는 인증서를 DER로, 개인 키를 PEM으로 받습니다. 각 파일은 64 KiB 이하여야 합니다. 시뮬레이터는 DER과 PEM을 모두 읽습니다.
4. 인증서 검사하기
섹션 제목: “4. 인증서 검사하기”서버 인증서의 주체와 확장을 확인합니다.
openssl x509 -in server.cert.pem -noout -subject -ext subjectAltName,keyUsage,extendedKeyUsagesubject=CN=PDComm OPC UA Example Server, O=Example OrganizationX509v3 Key Usage: critical Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Certificate SignX509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client AuthenticationX509v3 Subject Alternative Name: URI:urn:pdcomm:opcua:server, DNS:localhost, DNS:my-pc, IP Address:127.0.0.1유효 기간도 확인합니다. 템플릿 명령은 1년짜리 인증서를 만듭니다.
openssl x509 -in server.cert.pem -noout -datesnotBefore=Oct 14 16:56:03 2026 GMTnotAfter=Oct 14 16:56:03 2027 GMT5. 신뢰가 맞을 때
섹션 제목: “5. 신뢰가 맞을 때”예제를 빌드하지 않았다면 실습 환경의 5단계를 먼저 실행합니다. 첫 번째 터미널에서 서버를 실행합니다. 서버는 client.der만 신뢰합니다.
cd "$OPCUA_SDK"build/opcua_server 127.0.0.1:4840 opc.tcp://localhost:4840/pdcomm "$PKI/server.der" "$PKI/server.key.pem" "$PKI/client.der"두 번째 터미널에서 클라이언트를 실행합니다. 클라이언트는 server.der만 신뢰합니다.
cd "$OPCUA_SDK"build/opcua_client opc.tcp://localhost:4840/pdcomm "$PKI/client.der" "$PKI/client.key.pem" "$PKI/server.der"엔드포인트 목록 뒤에 다음 줄이 나오면 서로를 신뢰한 것입니다.
Session activated (anonymous)Read ns=2;i=1001 value=42 service=0x00000000 status=0x00000000Session closedURL의 호스트를 127.0.0.1로 바꿔도 연결됩니다. 서버 인증서에 IP:127.0.0.1이 있기 때문입니다.
6. 신뢰가 틀릴 때
섹션 제목: “6. 신뢰가 틀릴 때”신뢰하지 않는 인증서를 하나 더 만듭니다.
cd "$PKI"openssl req -x509 -new -config client.cnf -newkey rsa:2048 -sha256 -days 365 -noenc \ -keyout other.key.pem -out other.cert.pemopenssl x509 -in other.cert.pem -outform DER -out other.derchmod 600 other.key.pemcd "$OPCUA_SDK"클라이언트가 서버를 신뢰하지 않을 때. 신뢰할 서버 인증서로 other.der를 지정합니다.
build/opcua_client opc.tcp://localhost:4840/pdcomm "$PKI/client.der" "$PKI/client.key.pem" "$PKI/other.der"Error: connect failed (SDK status 5): OPC UA security CertificateUntrusted클라이언트가 서버 인증서를 검증하다 거부했으므로 오류 이름이 그대로 보입니다. 종료 코드는 3입니다.
서버가 클라이언트를 신뢰하지 않을 때. 클라이언트 신원으로 other.der와 other.key.pem을 씁니다.
build/opcua_client opc.tcp://localhost:4840/pdcomm "$PKI/other.der" "$PKI/other.key.pem" "$PKI/server.der"Error: connect failed (SDK status 5): OPC UA status: 0x801300000x80130000은 BadSecurityChecksFailed입니다. 서버는 보안을 위해 거부 이유를 자세히 알려 주지 않습니다. 이 오류가 나면 서버 쪽 신뢰 설정을 먼저 확인합니다.
인증서와 개인 키가 짝이 맞지 않을 때.
build/opcua_client opc.tcp://localhost:4840/pdcomm "$PKI/client.der" "$PKI/other.key.pem" "$PKI/server.der"Error: connect failed (SDK status 5): OPC UA security InvalidKey7. 개인 키 관리
섹션 제목: “7. 개인 키 관리”- 개인 키 파일은 실행 계정만 읽게 합니다(
chmod 600). - 개인 키를 패키지, 저장소, 로그에 넣지 않습니다. PDComm SDK와 예제는 개인 키와 암호를 출력하지 않습니다.
- SDK는 연결할 때 키를 복사합니다. 연결 직후 응용 프로그램의 키 버퍼를 지웁니다. 예제의
example_wipe가 그 예입니다. - 인증서가 만료되기 전에 새로 만들고, 상대 쪽의 신뢰 설정도 새 인증서로 바꿉니다.
서버 터미널에서 Ctrl+C를 누릅니다. 시험용 인증서를 지웁니다.
rm "$PKI"/other.*server.*와 client.*는 다른 튜토리얼에서 계속 씁니다.
다음 단계
섹션 제목: “다음 단계”- C 클라이언트
- 보안과 사용자 구성: 시뮬레이터에 이 인증서를 설정합니다.