AEGLOSLAB ROS 2 Jazzy 대전

제13부 보안

13.3 DDS-Security 플러그인 상세

13.3.1 이 장에서 배우는 것 / 선수 지식

13.2에서 SROS 2를 도구로 다뤘다. 이 장은 그 아래 — 실제로 인증하고 암호화하는 메커니즘이다.

이 층을 알아야 하는 이유는 세 가지다. 첫째, SROS 2가 만드는 파일들이 무엇을 의미하는지 알아야 정책을 제대로 쓸 수 있다. 둘째, 성능 비용이 어디서 발생하는지(13.5) 이해하려면 무엇이 암호화되는지 알아야 한다. 셋째, 문제가 생겼을 때 어느 층인지 구분해야 한다.

배우는 것:

  • 플러그인 구조 — 다섯 가지 서비스 플러그인.
  • 인증 — 신원 확인 과정.
  • 접근 제어 — 권한서와 거버넌스.
  • 암호화 — 무엇이 어떻게 보호되는가.
  • 보호 수준 — 선택지와 의미.
  • 디스커버리 보호 — 놓치기 쉬운 부분.
  • 구현별 차이 — 정직한 확인 사항.

선수 지식: 13.2(SROS 2), 3.1~3.3(DDS·RTPS·디스커버리), 3.5(RMW 구현).

정직: 거버넌스 파일의 실물과 스키마는 Jazzy에서 직접 생성·확인했다(실행 확인 — 13.3.11). 구현별 지원 범위·성숙도는 여전히 다르며, 벤더별 설정 방법은 확인하지 않았다. 여기서는 표준의 개념 구조를 다루며, 실제 사용은 선택한 RMW·DDS 구현의 문서를 따라야 한다. 암호 알고리즘·키 길이 등 구체적 선택은 조직의 보안 정책과 전문가 판단의 영역이며, 이 책은 그에 관한 조언을 제공하지 않는다. 성능 수치는 제시하지 않는다(3.6.1). 이 환경에서 검증하지 않았다(목차 3).

13.3.2 플러그인 구조

DDS-Security는 다섯 가지 서비스 플러그인으로 정의된다.

DDS-Security ① Authentication 신원 확인 ② Access Control 권한 검사 ③ Cryptographic 암호화 · 서명 ④ Logging 보안 이벤트 ⑤ Data Tagging 데이터 분류
플러그인역할SROS 2와의 관계
① 인증참여자가 누구인가신원 인증서
② 접근 제어무엇을 할 수 있는가권한서·거버넌스
③ 암호기밀성·무결성보호 수준 설정
④ 로깅보안 이벤트 기록SROS 2가 생성하는 설정에 없다(실행 확인)
⑤ 데이터 태깅분류 표시거버넌스 스키마에 항목이 없다(실행 확인)

④·⑤는 SROS 2 경로에 나타나지 않는다(실행 확인). sros2가 배포하는 거버넌스 스키마(governance.xsd)에 로깅·태깅 항목이 없고, 생성되는 파일에도 없다. 표준에는 정의되어 있으나 ROS 2에서 쓰는 경로로는 닿지 않는다 — 실무에서 쓰이는 것은 ①②③이다.

견해: "인증 → 접근 제어 → 암호"의 순서로 이해하면 구조가 정리된다. 먼저 상대가 누구인지 확인하고(①), 그 신원이 무엇을 해도 되는지 정하고(②), 오가는 데이터를 보호한다(③). 각각 다른 파일과 설정에 대응한다.

13.3.3 인증

참여자가 그래프에 들어올 때 서로를 확인한다.

성공 실패 참여자 A 발견 신원 인증서 교환 CA 서명 검증 참여 거부 상호 인증 핸드셰이크 공유 비밀 수립 암호화된 통신 시작
요소설명
신원 CA신원 인증서를 서명한 루트
신원 인증서참여자의 공개 신원
개인키비밀 — 신원의 근거
핸드셰이크상호 확인·키 합의

견해: 인증이 통과하지 못하면 그 참여자는 존재하지 않는 것과 같다. 그래프에 나타나지 않으므로 ros2 node list에도 안 보인다. "노드가 안 보인다"의 원인 목록에 인증 실패를 추가해야 한다(13.2.9).

함정: 인증서 유효기간과 시계(13.2.9의 반복). 로봇이 오래 꺼져 있다가 켜졌을 때 시계가 틀리면(RTC 배터리 방전 등) 인증이 실패한다. 시계 동기가 되기 전에는 통신이 안 될 수 있다는 점을 부팅 순서 설계(1.12)에서 고려해야 한다.

견해: CA를 어떻게 구성할 것인가가 규모의 문제가 된다. 로봇 한 대면 단순하지만, 수십~수백 대의 플릿에서는 발급·갱신·폐기를 자동화한 인증 기관 운영이 필요해진다. 이것은 IT 보안 인프라의 영역이며, 로봇 팀이 혼자 설계할 일이 아니다.

13.3.4 접근 제어 — 거버넌스와 권한

두 종류의 서명된 XML 파일이 있다.

파일범위내용
거버넌스(governance)도메인 전체어떤 토픽을 어떻게 보호할지
권한(permissions)참여자별무엇을 발행·구독할 수 있는지
<!-- 실제 sros2 가 생성하는 거버넌스와 동일한 형태다 (실행 확인 — 13.3.11) -->
<domain_access_rules>
  <domain_rule>
    <domains><id>0</id></domains>
    <allow_unauthenticated_participants>false</allow_unauthenticated_participants>
    <enable_join_access_control>true</enable_join_access_control>
    <discovery_protection_kind>ENCRYPT</discovery_protection_kind>
    <liveliness_protection_kind>ENCRYPT</liveliness_protection_kind>
    <rtps_protection_kind>SIGN</rtps_protection_kind>
    <topic_access_rules>
      <topic_rule>
        <topic_expression>*</topic_expression>
        <enable_discovery_protection>true</enable_discovery_protection>
        <enable_read_access_control>true</enable_read_access_control>
        <enable_write_access_control>true</enable_write_access_control>
        <metadata_protection_kind>ENCRYPT</metadata_protection_kind>
        <data_protection_kind>ENCRYPT</data_protection_kind>
      </topic_rule>
    </topic_access_rules>
  </domain_rule>
</domain_access_rules>
설정의미
allow_unauthenticated_participantstrue면 인증 없는 참여자 허용 — 위험
enable_join_access_control도메인 참여 자체를 통제
discovery_protection_kind디스커버리 보호(13.3.6)
rtps_protection_kindRTPS 메시지 수준
metadata_protection_kind메타데이터
data_protection_kind데이터 페이로드

함정: allow_unauthenticated_participants를 true로 두면 보안이 사실상 무력화된다. 개발 편의로 켜 두고 잊는 경우가 있으므로, 배포 점검에서 확인해야 한다(13.4).

견해: 거버넌스는 "무엇을 보호할지", 권한은 "누가 무엇을 할지"를 정한다. 이 둘을 혼동하면 설정이 충돌한다. 거버넌스는 도메인당 하나, 권한은 참여자마다 하나라는 대응을 기억하면 정리된다.

견해: 토픽별로 보호 수준을 달리할 수 있다는 점이 실무에 중요하다. 명령 토픽은 강하게, 대용량 센서 토픽은 성능을 고려해 다르게 설정할 수 있다(13.5). topic_expression으로 규칙을 나누는 것이 그 수단이다.

13.3.5 보호 수준

기본은 세 가지이고, 항목에 따라 두 가지가 더 있다(실행 확인 — 전체 목록과 항목별 적용 범위는 13.3.11.2).

수준제공비용
NONE없음없음
SIGN무결성·인증(변조 탐지)중간
ENCRYPT기밀성 + 무결성높음
SIGN_WITH_ORIGIN_AUTHENTICATION+ 보낸 참여자까지 검증높음
ENCRYPT_WITH_ORIGIN_AUTHENTICATION위 둘을 합친 것가장 높음

뒤의 둘은 data_protection_kind에는 쓸 수 없다(스키마가 그 항목만 세 가지로 제한한다 — 13.3.11.2). 페이로드는 양이 가장 많아 매 메시지에 참여자별 인증을 추가하는 비용이 감당되지 않기 때문이다.

보호 대상 데이터 페이로드 data_protection_ kind 메타데이터 metadata_ protection_kind RTPS 메시지 rtps_protection_ kind 디스커버리 discovery_ protection_kind 라이브라인스 liveliness_ protection_kind
대상보호하지 않으면
데이터내용 노출
메타데이터타이밍·크기·시퀀스 노출
디스커버리그래프 구조 노출(13.1.5)
RTPS하위 계층 조작

견해: "어떤 위협을 막으려는가"에서 수준을 정하라. 데이터 노출이 문제면 ENCRYPT, 변조가 문제면 SIGN으로 충분할 수 있다. 명령 토픽은 변조·사칭이 핵심 위협이므로 최소한 SIGN, 카메라 데이터는 기밀성이 문제이므로 ENCRYPT가 맞다.

견해: 모든 것을 ENCRYPT로 두는 것이 안전하지만 비용이 크다(13.5). 특히 대용량 고빈도 토픽(포인트클라우드·이미지)에서 비용이 두드러진다. 위협 모델(13.1)에 근거해 차등하는 것이 합리적이며, 근거 없이 낮추는 것은 위험하다.

정직: 어떤 암호 알고리즘이 쓰이는지·설정 가능한지는 구현 의존이다(확인 필요). 알고리즘 선택과 키 길이에 관한 판단은 보안 전문가의 영역이며, 이 책은 조언하지 않는다.

13.3.6 디스커버리 보호

놓치기 쉬운 부분이다.

디스커버리 미보호 참여자 목록 노출 토픽 이름 · 타입 노출 QoS 설정 노출 ★ 시스템 구조 파악 가능 디스커버리 보호 인증된 참여자만 정보 열람
노출되는 것의미
참여자·노드 목록시스템 구성
토픽 이름·타입기능 추정
QoS구현 세부
엔드포인트공격 대상 식별

견해: 데이터를 암호화해도 디스커버리가 열려 있으면 시스템 구조가 드러난다. 13.1.5에서 "디스커버리 자체가 정보를 준다"고 한 것이 이것이다. discovery_protection_kind를 확인하라.

함정: 디스커버리 보호는 상호운용성에 영향을 준다. 보호된 도메인에는 비보안 참여자가 접근할 수 없으므로, 개발 도구·모니터링 시스템도 인증 자료가 필요해진다. 운영 편의와의 절충을 미리 설계해야 한다(13.2.7의 도구용 enclave).

13.3.7 구현별 확인 사항

표준이 있어도 구현이 다르다.

확인 항목왜 중요
DDS-Security 지원 여부미지원 구현도 있음(확인 필요)
지원 플러그인 범위④⑤는 흔히 제한
설정 파일 위치·형식구현별 차이
성능 특성암호화 비용(13.5)
폐기(CRL) 지원침해 대응(13.2.8)
공유 메모리 전송과의 상호작용제로 카피 영향(확인 필요)
로깅·감사사후 분석

정직: 3.5·3.6에서 RMW를 비교했듯, 보안 기능도 구현 선택의 축이 된다. 보안이 요구사항이라면 RMW 선택 시점에 지원 범위를 확인해야 하며, 나중에 바꾸는 것은 비용이 크다(3.6.7).

함정: 제로 카피·공유 메모리 전송과 암호화가 함께 동작하는지 확인하라(확인 필요). 성능을 위해 도입한 최적화가 보안 설정에서 무효화되거나, 반대로 보안이 적용되지 않는 경로가 생길 수 있다. 12.3.5의 최적화와 이 장의 보호가 충돌하지 않는지는 반드시 확인할 사항이다.

견해: "보안을 켜고 성능을 다시 측정하라"(11.7). 12.4의 지연 예산은 보안 없이 측정한 것이라면 무효다. 보안 활성 상태의 측정값이 실제 운영 값이다.

13.3.8 진단

증상확인
참여자가 안 보임인증 실패·CA 불일치
인증은 되는데 토픽 없음권한서
전체가 갑자기 실패인증서 만료·시계
일부 토픽만거버넌스 규칙·topic_expression
성능 저하보호 수준(13.5)
비보안 노드가 연결됨allow_unauthenticated_participants
# DDS 구현별 보안 로그 활성화 (확인 필요: 방법)
# 구현 문서를 따라 상세 로깅을 켜고 핸드셰이크 실패 원인 확인

견해: 보안 문제 진단은 DDS 구현의 로그에 의존한다. ROS 2 층에서는 "노드가 안 보인다"로만 보이므로, 구현별 상세 로깅을 켜는 방법을 미리 알아 두라. 이것을 모르면 진단이 추측이 된다.

견해: 문제를 좁히는 순서는 아래에서 위다(11.1.2). ① 두 참여자가 서로를 인증하는가 → ② 권한이 해당 토픽을 허용하는가 → ③ QoS가 맞는가. 보안을 끄고 되면 ①②, 꺼도 안 되면 ③.

13.3.11 거버넌스 파일의 실물과 스키마 — 실측

13.3.4가 보인 거버넌스 예시가 실제와 얼마나 같은지, 그리고 각 항목에 넣을 수 있는 값이 무엇인지를 확인했다. ros2 security create_keystore가 만든 파일과, sros2가 배포하는 XSD 스키마를 직접 열었다(실행 확인 — Jazzy · sros2 0.13.6 · ros:jazzy-ros-base 컨테이너). 파일 내용은 sros2 버전에 매인다(확인 필요).

13.3.11.1 기본 거버넌스는 이렇게 나온다

create_keystore 직후 <keystore>/enclaves/governance.xml의 전문이다(실행 확인 — 서명본은 governance.p7s):

<dds xsi:noNamespaceSchemaLocation="http://www.omg.org/spec/DDS-SECURITY/20170901/omg_shared_ca_governance.xsd">
    <domain_access_rules>
        <domain_rule>
            <domains><id>0</id></domains>
            <allow_unauthenticated_participants>false</allow_unauthenticated_participants>
            <enable_join_access_control>true</enable_join_access_control>
            <discovery_protection_kind>ENCRYPT</discovery_protection_kind>
            <liveliness_protection_kind>ENCRYPT</liveliness_protection_kind>
            <rtps_protection_kind>SIGN</rtps_protection_kind>
            <topic_access_rules>
                <topic_rule>
                    <topic_expression>*</topic_expression>
                    <enable_discovery_protection>true</enable_discovery_protection>
                    <enable_liveliness_protection>true</enable_liveliness_protection>
                    <enable_read_access_control>true</enable_read_access_control>
                    <enable_write_access_control>true</enable_write_access_control>
                    <metadata_protection_kind>ENCRYPT</metadata_protection_kind>
                    <data_protection_kind>ENCRYPT</data_protection_kind>
                </topic_rule>
            </topic_access_rules>
        </domain_rule>
    </domain_access_rules>
</dds>

기본값이 꽤 엄격하다. 인증 안 된 참가자를 거부하고(allow_unauthenticated_participants: false), 모든 토픽(*)에 읽기·쓰기 접근 제어를 걸며, 데이터와 메타데이터를 암호화한다.

정확히 한 곳만 SIGN이다 — rtps_protection_kind. 나머지는 전부 ENCRYPT인데 RTPS 계층만 서명이다.

견해: 이 비대칭이 우연이 아니다. RTPS는 패킷을 실어 나르는 바깥 계층이라, 완전히 암호화하면 중간 장비가 헤더를 읽지 못해 라우팅·진단이 막힌다. 서명은 변조를 막으면서 헤더는 열어 두는 절충이다. 즉 "안쪽(데이터·메타데이터)은 감추고, 바깥(전송 계층)은 위조만 막는다"로 읽으면 된다. wireshark로 RTPS 패킷을 볼 수 있는 것도 이 설정 덕이다(3.2.8).

함정: 여기도 도메인이 0으로 고정된다. 13.2.12.2에서 권한 파일에 대해 본 것과 같은 문제다. ROS_DOMAIN_ID를 바꿔 쓰면 거버넌스와 권한 양쪽을 고쳐야 한다.

13.3.11.2 보호 수준은 다섯 단계다 — 한 항목만 세 단계

sros2가 배포하는 governance.xsd가 값을 명시해 두었다(실행 확인). 두 가지 타입이 있다.

타입가능한 값
ProtectionKind(5종)NONE · SIGN · ENCRYPT · SIGN_WITH_ORIGIN_AUTHENTICATION · ENCRYPT_WITH_ORIGIN_AUTHENTICATION
BasicProtectionKind(3종)NONE · SIGN · ENCRYPT

어느 항목이 어느 타입인지가 중요하다:

항목타입즉
discovery_protection_kindProtectionKind5단계
liveliness_protection_kindProtectionKind5단계
rtps_protection_kindProtectionKind5단계
metadata_protection_kindProtectionKind5단계
data_protection_kindBasicProtectionKind3단계 — origin authentication 불가

_WITH_ORIGIN_AUTHENTICATION은 "보낸 참여자가 맞는지까지 검증"한다. 여러 참여자가 같은 키를 공유하는 상황에서 그중 누가 보냈는지를 구분하려는 것인데, 그만큼 서명 연산이 늘어난다.

데이터 페이로드에만 그 옵션이 없다는 점이 설계 의도를 드러낸다. 페이로드는 양이 가장 많은 부분이라, 매 메시지에 참여자별 인증까지 추가하면 비용이 감당되지 않는다. 보내는 쪽을 가려야 한다면 메타데이터 계층에서 하라는 뜻이다.

함정: NONE이 값 목록에 있다는 것을 기억하라. 성능 문제로 data_protection_kind를 NONE으로 낮추는 선택이 가능한데, 그러면 접근 제어는 유효하지만 페이로드는 평문이 된다. 네트워크를 신뢰할 수 있는 구간(유선 내부망)에서 의도적으로 쓸 수 있는 절충이지만, 무선 구간이 하나라도 끼면 그 순간 무의미해진다(3.9.3).

13.3.11.3 로깅·데이터 태깅 플러그인은 이 경로에 없다

13.3.2가 다섯 플러그인 중 ④로깅·⑤데이터 태깅을 (확인 필요)로 남겨 두었다. governance.xsd에 해당 항목이 전혀 없고, create_keystore가 만드는 어떤 파일에도 나타나지 않는다(실행 확인).

즉 표준에는 정의되어 있으나 SROS 2가 생성·서명하는 설정 경로로는 닿지 않는다. 보안 이벤트 로그가 필요하면 DDS 벤더가 따로 제공하는 설정(Fast DDS의 XML 프로파일 등, 3.7)을 찾아야 하며, ROS 2 표준 도구로는 켤 수 없다.

13.3.9 함정 카탈로그

#함정증상대처
1allow_unauthenticated_participants 방치보안 무력화배포 점검
2디스커버리 미보호구조 노출discovery_protection_kind
3거버넌스·권한 혼동설정 꼬임역할 구분
4전부 ENCRYPT성능 비용위협 근거 차등
5근거 없이 보호 완화위험위협 모델 기반
6시계 오차인증 실패동기화·부팅 순서
7도구용 자료 미발급모니터링 불가도구 enclave
8RMW 보안 지원 미확인도입 실패선택 시점 확인
9제로 카피와 충돌 미확인최적화 무효·보안 공백확인
10보안 전 성능값 사용예산 무효재측정
11구현 로그 모름진단 불가방법 확보
12폐기 수단 미확인침해 대응 제한사전 확인
13성능 때문에 data_protection_kind: NONE접근 제어는 살아도 페이로드 평문무선 구간이 있으면 금지(13.3.11.2)

13.3.10 체크포인트

  • DDS-Security의 다섯 플러그인과, 실무에서 주로 쓰이는 셋은?
  • "인증 → 접근 제어 → 암호"의 순서로 구조를 설명할 수 있는가.
  • 인증 실패 시 그래프에서 어떻게 보이는가. 진단 목록에 무엇을 추가해야 하는가.
  • 인증서 유효기간과 시계의 관계, 그리고 부팅 순서 설계에의 함의는?
  • 거버넌스와 권한 파일의 범위·내용 차이는?
  • allow_unauthenticated_participants가 위험한 이유는?
  • 보호 수준의 값은 몇 가지이며, data_protection_kind만 선택지가 적은 이유는?
  • 보호 대상 다섯 가지와, 각각을 보호하지 않으면 무엇이 노출되는가.
  • 모든 것을 ENCRYPT로 하는 것의 문제와, 차등의 근거는?
  • 디스커버리 보호가 왜 놓치기 쉬우면서 중요한가. 그 대가는?
  • 구현별 확인 사항 일곱 가지와, RMW 선택 시점에 확인해야 하는 이유는?
  • 제로 카피와 암호화의 관계에서 확인해야 할 것은?
  • 보안 활성 후 성능을 재측정해야 하는 이유는?
  • 보안 문제 진단의 순서와, 보안을 끄고 비교하는 것의 의미는?
  • 보호 수준의 값은 몇 가지이며 data_protection_kind만 다른 이유는? 기본 거버넌스에서 rtps_protection_kind만 SIGN인 까닭은(13.3.11).

다음 장 13.4은 미들웨어 밖 — 운영 보안이다. 네트워크 격리, 시스템 강화, 업데이트, 비밀 관리.