Modbus/TCP Security
Modbus 자체에는 인증도 암호화도 없습니다. 같은 네트워크의 누구나 요청을 보낼 수 있고, 오가는 값을 그대로 볼 수 있습니다. Modbus/TCP Security는 Modbus TCP의 ADU를 TLS(Transport Layer Security) 연결 안에 넣어 이 문제를 해결합니다. MBAP 헤더와 PDU는 바뀌지 않습니다. 이 페이지는 MODBUS/TCP Security Protocol Specification을 근거로 합니다.
무엇을 보호하는가
섹션 제목: “무엇을 보호하는가”| 위협 | Modbus/TCP Security의 대응 |
|---|---|
| 도청 | TLS가 내용을 암호화합니다. |
| 변조 | TLS가 메시지 무결성을 검사합니다. |
| 위장 | 클라이언트와 서버가 서로 X.509v3 인증서를 검증하는 상호 인증(mutual authentication)을 합니다. |
| 권한 없는 조작 | 서버가 클라이언트 인증서의 역할(role)에 따라 기능 코드별로 허용 여부를 정합니다. |
- TLS 1.2 이상을 씁니다.
- 표준 포트는 802입니다. 일반 Modbus TCP의 502와 구분합니다.
- 포트만 802로 바꾼다고 TLS가 켜지지는 않습니다. 양쪽 모두 보안 설정이 필요합니다.
역할 기반 권한
섹션 제목: “역할 기반 권한”명세는 클라이언트의 역할을 인증서 확장(extension)에 담습니다.
- 확장의 OID는
1.3.6.1.4.1.50316.802.1입니다. - 값은 ASN.1 UTF8String 하나입니다. 예를 들어
reader,operator입니다. - 역할 이름의 뜻은 표준이 정하지 않습니다. 서버의 권한 규칙이 역할마다 허용할 기능을 정합니다.
- 서버가 요청을 허용하지 않으면 예외 01(Illegal Function)로 응답합니다. TLS 연결은 유지됩니다.
클라이언트 인증서 서버의 권한 규칙 role = "reader" --> reader : FC 1, 2, 3, 4 operator : FC 3, 6, 16요청 FC 06 (쓰기) --> reader에 06 없음 --> 예외 응답 86 01인증서 준비
섹션 제목: “인증서 준비”TLS 연결 하나에 다음 파일이 필요합니다.
| 파일 | 서버 | 클라이언트 |
|---|---|---|
| 신뢰할 CA 인증서(trust) | 클라이언트 인증서를 발급한 CA | 서버 인증서를 발급한 CA |
| 자신의 인증서 체인(chain) | 서버 인증서 + 중간 CA + 루트 CA | 클라이언트 인증서 + 중간 CA + 루트 CA |
| 개인 키(private key) | 서버 인증서의 키 | 클라이언트 인증서의 키 |
- 서버 인증서의 SAN(Subject Alternative Name)에는 클라이언트가 접속할 때 쓰는 이름이나 IP 주소가 들어 있어야 합니다.
- 클라이언트 인증서에는 쓸 역할을 확장으로 넣습니다. 역할이 없는 인증서도 연결할 수 있으며, 이때는 서버의 “역할 없음” 규칙이 적용됩니다.
- 개인 키는 각 호스트에만 두고 다른 곳에 복사하지 않습니다.
PDComm의 보안 설정
섹션 제목: “PDComm의 보안 설정”PDComm은 구성의 security 객체로 Modbus/TCP Security를 켭니다. 이 객체에는 파일 경로만 들어가며 키 내용은 들어가지 않습니다. 프로젝트 파일에 저장해도 같습니다.
| 필드 | 설명 |
|---|---|
mode |
encrypted(기본) 또는 authentication_only |
chain, private_key, trust |
PEM 파일 경로. chain은 자신의 인증서로 시작해 루트 CA로 끝나야 합니다. |
hostname |
클라이언트가 서버 인증서에서 확인할 이름이나 IP 주소. 기본값은 localhost입니다. |
roles |
서버 전용. 역할 이름별로 허용할 기능 코드 목록 |
null_role |
서버 전용. 역할 확장이 없는 클라이언트에게 허용할 기능 코드 목록. 기본값은 빈 목록입니다. |
crls, require_revocation |
폐기 목록(CRL) 파일과 폐기 확인 강제 여부 |
두 모드는 다음과 같습니다.
| 모드 | TLS 버전과 암호 | 보호 |
|---|---|---|
encrypted |
TLS 1.3(AES-GCM), TLS 1.2(ECDHE, AES-GCM) | 암호화, 무결성, 상호 인증 |
authentication_only |
TLS 1.2, NULL-SHA256(RSA 인증서 필요) | 무결성과 상호 인증. 내용은 암호화하지 않습니다. |
- 양쪽의 모드가 같아야 합니다. PDComm은
encrypted연결이 실패했을 때authentication_only나 일반 TCP로 자동으로 낮추지 않습니다. - 서버는 항상 클라이언트 인증서를 요구합니다. 인증서 검증은 끌 수 없습니다.
- 표준 정의 밖의 역할 정책(예: 역할 이름을 쉼표로 나눠 여러 역할로 해석)은 하지 않습니다. 역할 확장 값 전체가 역할 이름 하나입니다.
- 역할 확장이 있지만 UTF8String 하나로 읽을 수 없으면 서버가 연결을 거부합니다.
직접 인증서를 만들고 역할별 권한을 확인하려면 튜토리얼: Modbus/TCP Security를 따라 합니다.