서론: 로봇 통신에도 보안이 필요하다
ROS1은 보안이 없었다. 같은 네트워크에 있으면 누구나 모든 토픽을 읽고 쓸 수 있었다. 자율주행차나 산업용 로봇에 이 구조를 그대로 쓰면 원격 조작 공격에 무방비다. SROS2는 DDS Security 표준 위에 구축된 ROS2 보안 레이어다.
1. SROS2가 제공하는 것
1
2
3
4
5
6
7
8
9
10
11
| 인증 (Authentication)
- 노드마다 X.509 인증서
- 서로를 검증한 노드만 통신 허용
암호화 (Encryption)
- 토픽 데이터를 TLS로 암호화
- 네트워크 스니핑 방어
접근 제어 (Access Control)
- 어떤 노드가 어떤 토픽을 publish/subscribe 할 수 있는지 정책으로 관리
- 카메라 노드가 /cmd_vel을 publish하는 것을 정책으로 차단
|
2. 키스토어 생성
1
2
3
4
5
6
7
8
9
10
| # 키스토어 초기화
ros2 security create_keystore ~/sros2_keystore
# 구조
~/sros2_keystore/
enclaves/ ← 노드별 인증서 디렉터리
public/
ca.cert.pem ← 루트 CA 인증서
private/
ca.key.pem ← 루트 CA 키 (비공개)
|
3. 노드별 인증서 생성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # talker 노드용 인증서
ros2 security create_enclave \
~/sros2_keystore /talker_listener/talker
# listener 노드용 인증서
ros2 security create_enclave \
~/sros2_keystore /talker_listener/listener
# 생성 결과
~/sros2_keystore/enclaves/talker_listener/talker/
cert.pem ← 노드 인증서
key.pem ← 노드 개인키
identity_ca.cert.pem
permissions_ca.cert.pem
permissions.xml ← 접근 제어 정책
permissions.p7s ← 서명된 정책
governance.xml ← 도메인 보안 정책
governance.p7s
|
4. 접근 제어 정책 (permissions.xml)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| <!-- enclaves/talker_listener/talker/permissions.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<dds xmlns:xsi="...">
<permissions>
<grant name="talker_permissions">
<subject_name>CN=talker</subject_name>
<validity>
<not_before>2026-01-01T00:00:00</not_before>
<not_after>2027-01-01T00:00:00</not_after>
</validity>
<allow_rule>
<!-- talker는 /chatter에만 publish 가능 -->
<domains><id>0</id></domains>
<publish>
<topics><topic>rt/chatter</topic></topics>
</publish>
<!-- subscribe는 불가 -->
</allow_rule>
<default>DENY</default>
</grant>
</permissions>
</dds>
|
<default>DENY</default>가 핵심이다. 명시적으로 허용하지 않은 토픽은 모두 차단된다.
5. 보안 활성화 환경변수
1
2
3
4
5
6
7
8
9
10
11
| export ROS_SECURITY_KEYSTORE=~/sros2_keystore
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce # 인증서 없으면 실행 거부
# talker 실행 (인증서 경로를 enclave로 지정)
ros2 run demo_nodes_py talker \
--ros-args --enclave /talker_listener/talker
# listener 실행
ros2 run demo_nodes_py listener \
--ros-args --enclave /talker_listener/listener
|
1
2
3
4
| ROS_SECURITY_STRATEGY 옵션:
Enforce - 인증서 없으면 노드 실행 실패 (프로덕션 권장)
Permissive - 인증서 없으면 보안 없이 실행 (개발용)
NodeIsolation - 보안 노드끼리만 통신
|
6. 거버넌스 정책 (governance.xml)
도메인 전체의 보안 수준을 설정한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| <!-- governance.xml -->
<dds>
<domain_access_rules>
<domain_rule>
<domains><id>0</id></domains>
<!-- 발견 정보 보호 -->
<enable_discovery_protection>true</enable_discovery_protection>
<!-- 리우 정보 암호화 -->
<enable_liveliness_protection>true</enable_liveliness_protection>
<!-- RTF 메타데이터 보호 -->
<enable_read_access_control>true</enable_read_access_control>
<enable_write_access_control>true</enable_write_access_control>
<topic_access_rules>
<topic_rule>
<topic_expression>*</topic_expression>
<!-- 페이로드 암호화 -->
<encryption_algorithm>AES-256-GCM</encryption_algorithm>
</topic_rule>
</topic_access_rules>
</domain_rule>
</domain_access_rules>
</dds>
|
7. 런치 파일에서 보안 적용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| from launch import LaunchDescription
from launch_ros.actions import Node
def generate_launch_description():
security_env = {
'ROS_SECURITY_KEYSTORE': '/home/user/sros2_keystore',
'ROS_SECURITY_ENABLE': 'true',
'ROS_SECURITY_STRATEGY': 'Enforce',
}
return LaunchDescription([
Node(
package='demo_nodes_py',
executable='talker',
ros_arguments=['--enclave', '/talker_listener/talker'],
additional_env=security_env,
),
Node(
package='demo_nodes_py',
executable='listener',
ros_arguments=['--enclave', '/talker_listener/listener'],
additional_env=security_env,
),
])
|
8. 보안 적용 확인
1
2
3
4
5
6
7
8
| # 보안 없는 노드에서 토픽 도청 시도 (차단 확인)
# ROS_SECURITY_ENABLE 없이 실행
ros2 topic echo /chatter
# → 메시지가 보이지 않아야 정상 (암호화됨)
# 키스토어 인증서 만료일 확인
openssl x509 -in ~/sros2_keystore/enclaves/talker_listener/talker/cert.pem \
-noout -dates
|
9. Day 2 체크리스트
ros2 security create_keystore로 CA와 키스토어를 생성했다.- 노드마다
create_enclave로 X.509 인증서를 발급했다. permissions.xml에 허용할 토픽 publish/subscribe를 명시했다.ROS_SECURITY_STRATEGY=Enforce로 인증서 없는 노드를 차단했다.governance.xml에서 페이로드 암호화 알고리즘을 설정했다.
다음 글 예고
Day 3에서는 실시간 ROS2를 다룬다. RTOS 환경에서 Executor 선택, 스레드 우선순위 설정, 데드라인 미스 탐지로 결정론적 실행을 달성하는 방법을 정리한다.