# 파이어월(방화벽) 및 포트 설정 기초

#### 파이어월의 정의와 목적

파이어월(방화벽, Firewall)은 외부 네트워크로부터 들어오거나 나가는 트래픽을 통제하여, 시스템이 노출될 수 있는 보안 위험을 최소화하는 역할을 한다. 물리적인 차단벽과 유사한 개념으로 이해할 수 있으며, 네트워크 계층과 전송 계층 수준에서 패킷 필터링을 수행하거나, 사용자 정의 규칙을 통해 특정 트래픽만 허용하거나 차단하는 기능을 제공한다.

* **트래픽 흐름 제어**: 네트워크 트래픽을 세밀하게 모니터링하고 제어한다.
* **보안 정책 적용**: IP 주소, 포트, 프로토콜과 같은 패킷 정보를 기반으로 접근제어(ACL, Access Control List)를 수행한다.
* **외부 공격 방어**: DDoS나 스캐닝 공격과 같은 외부 공격을 사전에 방어하거나, 내부에서 발생하는 이상 트래픽을 제한할 수도 있다.

#### ROS2 DDS 통신과 파이어월

ROS2는 DDS(Data Distribution Service) 프로토콜을 기반으로 통신을 수행한다. DDS는 노드끼리 Peer-to-Peer(P2P) 연결을 맺어 신뢰성 있는 메시지 교환을 진행하는데, 이 때 여러 포트를 동적으로 할당한다. 따라서 멀티머신 환경에서 ROS2 노드끼리 통신하기 위해서는 DDS가 사용하는 포트를 적절히 개방해야 한다.

* **Discovery 포트**: DDS Participant Discovery, Topic Discovery 등에 사용된다.
* **Data 포트**: 실제 ROS2 메시지 데이터를 송수신할 때 사용된다.
* **Multicast 포트**: 노드 간 통신 발견(Discovery)에 멀티캐스트가 사용될 수 있으며, 네트워크 구성에 따라 멀티캐스트 트래픽을 허용해줘야 한다.

다만, DDS 벤더(예: Fast DDS, Cyclone DDS, Connext RTI 등)에 따라 어떤 포트를 사용하는지 세부 설정이 다를 수 있다. 기본 설정이 상당히 넓은 범위의 UDP 포트를 열어두어야 하므로, 방화벽 정책이 엄격하게 적용된 환경에서는 반드시 관련 포트를 사전에 확인하고 열어두어야 한다.

#### 포트와 프로토콜 기초

TCP와 UDP는 모두 전송 계층 프로토콜이지만, 그 특성이 다르다. ROS2 DDS 통신은 주로 UDP를 사용한다. 특히 Participant 간 Discovery 과정에서 랜덤 포트가 할당되기도 하여, 사용되는 포트 범위가 동적으로 결정된다.

* **TCP**(Transmission Control Protocol) 연결 기반 프로토콜로 신뢰성 보장이 필요할 때 사용한다.
* **UDP**(User Datagram Protocol) 비연결형 프로토콜이며 빠른 전송이 가능하지만, 손실에 대한 재전송을 보장하지 않는다.

멀티머신 ROS2 노드 통신을 위해서는 내부 네트워크에서 특정 UDP 포트 범위를 열어주어야 하며, 상호 통신이 가능하도록 파이어월 규칙을 수정해야 한다. 일반적으로 DDS 구현체마다 UDP 포트 범위가 다르나, 아래 예시는 Fast DDS의 기본 포트 할당 예시를 간단히 나타낸 것이다(실제 범위는 DDS QoS, 도메인 ID에 따라 변동 가능).

$$
1024 \le p \le 65535
$$

위와 같이 거의 모든 범위가 사용 가능할 수 있으나, 실제 구현체는 도메인 ID에 따라 포트 범위를 산술적으로 계산한다. 가령 도메인 ID가 0, 1, 2 등으로 증가할 때, 특정 간격만큼 할당 포트가 달라지는 식이다.

#### 파이어월 설정 시 유의사항

1. **양방향 트래픽 허용**: ROS2 DDS는 P2P 구조로 동작하므로, 한 쪽만 포트를 열어두어서는 통신 문제가 발생할 수 있다. 양방향(ingress/egress)에 대해 동일하게 열어둘 필요가 있다.
2. **멀티캐스트 허용 여부**: Discovery 과정에서 멀티캐스트를 사용한다면, 멀티캐스트 패킷이 차단되지 않도록 설정한다.
3. **IPv4, IPv6 혼합 환경**: ROS2는 IPv4, IPv6를 모두 지원할 수 있다. 방화벽에서도 사용하지 않는 IP 버전은 과감히 막고, 사용하는 IP 버전만 허용하는 것도 한 가지 방법이다.
4. **도메인 ID 별 포트 범위**: 멀티머신 환경에서 여러 도메인 ID를 동시에 사용하는 경우, 각 도메인 ID가 사용하는 포트 범위를 정확히 파악해야 한다.
5. **테스트 환경 구성**: 방화벽 설정 후, 실제 노드가 통신 가능한지 `ping`, `netcat`, `ros2 topic list` 등으로 테스트한다.

#### 리눅스 파이어월 규칙 설정 예시

**Ubuntu(UFW 사용 시)**

Ubuntu의 기본 방화벽 도구인 UFW(Uncomplicated Firewall) 예시로, 특정 포트를 UDP로 열어두는 규칙을 추가할 수 있다.

```bash
sudo ufw allow 7400:7500/udp
sudo ufw enable
sudo ufw status
```

* `7400:7500/udp` 범위를 허용한다면 7400번부터 7500번까지의 UDP 포트를 개방한다.
* 실제 DDS 구현체에서 요구하는 포트 범위에 맞추어 동일하게 설정하면 된다.
* `sudo ufw enable`로 방화벽을 활성화하면, 지정된 규칙이 반영된다.

**CentOS(RHEL 계열, firewalld 사용 시)**

RHEL(CentOS, Rocky Linux 등) 계열 배포판에서는 firewalld를 주로 사용한다.

```bash
sudo firewall-cmd --zone=public --add-port=7400-7500/udp --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
```

* `--add-port=7400-7500/udp` 옵션으로 7400\~7500 UDP 포트를 허용한다.
* `--permanent` 옵션을 사용하면 방화벽 영구 설정이 적용된다.
* `--reload` 후 설정 상태를 확인한다.

#### 파이어월 동작 흐름 요약 (mermaid 예시)

{% @mermaid/diagram content="flowchart TB
A\[(외부 네트워크)] --> B\[파이어월]
B -->|허용된 UDP 포트| C\[ROS2 멀티머신 노드]
B -->|차단된 포트| D\[(Drop)]" %}

* 외부 네트워크에서 파이어월을 거쳐 특정 UDP 포트만 통신이 허용된다.
* 허용되지 않은 포트로 들어오는 패킷은 Drop되거나 Reject 처리된다.

#### NAT와 포트 포워딩

로컬 네트워크 안에서 ROS2 노드가 동작하는 경우, 외부 네트워크와 통신하기 위해서는 종종 NAT(Network Address Translation) 또는 포트 포워딩 설정이 필요할 때가 있다. 예컨대 방화벽이 NAT 게이트웨이를 겸하거나, DMZ(비무장 지대) 영역이 따로 존재하는 네트워크 구조라면, 외부에서 내부로 들어오는 트래픽을 특정 내부 IP로 포워딩해야 한다.

* NAT 구조
  * 외부 네트워크에 노출되는 공인 IP 주소가 내부(사설망)로 들어올 때, 목적지 IP 주소를 내부 IP로 변환해준다.
  * 로컬 네트워크에서 여러 호스트가 공인 IP 하나로만 외부와 통신할 수 있도록 해준다.
* 포트 포워딩(Port Forwarding)
  * 특정 공인 IP의 특정 포트로 들어오는 트래픽을 내부 IP의 특정 포트로 전달한다.
  * ROS2 DDS 통신에서 외부와 연결해야 할 때(예: 클라우드 호스팅 환경), 필요한 포트를 지정하여 포워딩해줘야 한다.

이러한 NAT와 포트 포워딩 설정은 방화벽 정책과 긴밀하게 연관된다. NAT 방화벽이 활성화된 상태에서 ROS2 DDS 통신을 정상적으로 수행하기 위해서는 DDS가 사용하는 포트 범위를 NAT 규칙에 포함시켜야 한다. 다만 DDS 특성상, P2P 구조로 다양한 포트가 동적으로 할당되므로 포트 포워딩이 쉽지 않을 수 있다.

#### Iptables를 이용한 방화벽 설정

여전히 많은 리눅스 배포판에서 iptables(혹은 nftables)를 사용하여 방화벽을 구성하는 경우가 있다. iptables의 필터 테이블에서 INPUT, OUTPUT, FORWARD 체인을 적절히 설정하면, ROS2 통신에 필요한 포트를 열 수 있다.

**간단한 예시**

```bash
# 예: UDP 7400~7500 포트 범위를 외부로부터 허용
sudo iptables -A INPUT -p udp --dport 7400:7500 -j ACCEPT
sudo iptables -A OUTPUT -p udp --sport 7400:7500 -j ACCEPT

# 모든 설정을 저장(배포판 별도 명령어 다를 수 있음)
sudo netfilter-persistent save
sudo netfilter-persistent reload
```

* `-A INPUT`은 들어오는(Inbound) 트래픽에 대한 규칙을 추가한다.
* `-A OUTPUT`은 나가는(Outbound) 트래픽에 대한 규칙을 추가한다.
* `--dport`, `--sport` 옵션으로 특정 포트를 지정한다.
* UDP 프로토콜 `-p udp`를 명시적으로 지정했다.

#### IPv4와 IPv6 방화벽

ROS2 DDS는 IPv4와 IPv6 모두를 지원할 수 있다. IPv6 네트워크를 사용하는 경우, iptables가 아닌 ip6tables 설정을 사용하거나, firewalld, ufw 등에서 IPv6에 대한 별도 규칙을 설정해야 한다.

* **IPv4만 사용**할 예정이라면, IPv6 트래픽을 아예 막거나 비활성화하는 방법도 가능하다.
* **IPv6 환경**이라면, 필요 포트에 대해 ip6tables(firewalld, ufw의 IPv6 규칙) 설정을 반드시 해줘야 한다.

```bash
# ip6tables 예시
sudo ip6tables -A INPUT -p udp --dport 7400:7500 -j ACCEPT
sudo ip6tables -A OUTPUT -p udp --sport 7400:7500 -j ACCEPT
```

#### 방화벽 예외(Whitelist)와 Blacklist

* **Whitelist(허용 목록)**: 기본적으로 모든 트래픽을 차단하고, 특정 호스트나 포트만 예외로 허용한다.
* **Blacklist(차단 목록)**: 기본적으로 모든 트래픽을 허용하고, 특정 호스트나 포트를 차단한다.

ROS2 DDS 통신은 다양한 UDP 포트를 필요로 하므로, whitelist 방식의 방화벽 설정을 사용하는 경우 상당히 넓은 범위를 허용해야 할 수도 있다. 기업 보안 정책상 whitelist만 허용되면, DDS 포트 범위 전체를 허용해야 하기에 관리가 까다로울 수 있다.

#### QoS에 따른 포트 활용

ROS2 DDS 통신에서 QoS(Quality of Service) 프로파일은 메시지 신뢰성, 이행 보증, 히스토리 옵션 등을 설정한다. QoS 옵션에 따라 통신 패턴이 달라지므로, 방화벽 설정에도 영향을 줄 수 있다. 예를 들어 Reliable 모드(신뢰성 보장)에서 재전송이 많이 발생한다면, 특정 포트 범위를 빈번하게 사용하게 될 수 있다.

* Reliable vs Best-Effort
  * Reliable: 수신 측에서 누락된 패킷을 재요청(retransmit)하며, 통신이 더 안정적이다.
  * Best-Effort: 누락된 패킷을 재요청하지 않으며, 상대적으로 빠르지만 신뢰성이 낮다.

따라서 QoS 설정값에 따라 트래픽 패턴이 달라지고, 방화벽이나 NAT 장치가 상태 정보를 제대로 추적하지 못하면 통신 지연, 패킷 손실이 발생할 가능성이 있다.

#### 커맨드라인 도구를 활용한 테스트

방화벽 설정 후 통신에 문제가 없는지 확인하려면, 다양한 커맨드라인 도구를 사용할 수 있다.

**ping**: IP 레벨에서 호스트 간 기본 통신이 되는지 확인한다.

netcat(nc): 특정 포트로 데이터 전송이 가능한지 확인한다.

```bash
# 호스트 A(서버 역할) - UDP 8000 포트 대기
nc -ul 8000

# 호스트 B(클라이언트 역할) - UDP 8000 포트로 메시지 전송
echo "test message" | nc -u <Host A IP> 8000
```

ros2 topic: 실제 ROS2 통신이 되는지 확인한다.

```bash
ros2 topic list
ros2 run demo_nodes_py talker
```

위와 같이 talker 노드를 실행한 뒤, 다른 호스트에서 listener를 실행했을 때 메시지를 받으면 일단 DDS 레벨 통신이 정상 작동하고 있다고 볼 수 있다.

#### 파이어월 로그 및 문제 해결

방화벽(iptables, firewalld, ufw 등)은 트래픽을 허용/차단할 뿐만 아니라, 로그(Logging)를 남길 수 있다. 이를 통해 DDS 통신이 제대로 허용되고 있는지, 아니면 방화벽에 의해 차단되고 있는지를 확인할 수 있다.

로그 활성화

iptables 예시

```bash
sudo iptables -A INPUT -p udp --dport 7400:7500 -j LOG --log-prefix "ROS2 DDS DROP: "
```

이렇게 설정하면, 해당 포트 범위 트래픽이 INPUT 체인에서 차단 혹은 허용될 때마다 로그가 남길 수 있다.

firewalld의 rich rule 또는 커스텀 로깅 옵션을 사용해 로그를 남길 수도 있다.

문제 해결(트러블슈팅)

1. **로그 모니터링**: `dmesg`, /var/log/syslog, /var/log/messages 파일 등을 통해 방화벽 규칙에 의해 차단된 패킷 로그가 있는지 확인한다.
2. **포트 확인**: 실제로 DDS 통신에서 열어야 하는 포트 범위가 제대로 열려 있는지, `netstat -tuln` 또는 `ss -tuln` 명령어로 서비스 포트를 확인한다.
3. **방화벽 규칙 순서**: iptables나 nftables는 체인에 따라 패킷 처리 순서가 결정된다. 특정 규칙이 더 먼저 적용되어 트래픽이 차단되는 경우도 있다.

#### Docker 또는 컨테이너 환경에서의 방화벽

ROS2 노드를 Docker 컨테이너(또는 Podman 등)로 실행할 때, 추가적인 방화벽 고려 사항이 존재한다. 컨테이너가 자체적으로 bridge 네트워크를 사용하거나, 호스트 네트워크 모드를 사용하는지에 따라 포트 개방 방식이 달라진다.

* Bridge 네트워크 사용 시
  * 호스트에서 컨테이너로 들어가는 트래픽은 Docker의 기본 NAT/포워딩 규칙을 거친다.
  * “-p 7400:7400/udp”와 같은 방식으로 포트 바인딩을 해야 외부에서 해당 포트로 접근 가능하다.
  * 이 때 호스트 방화벽에서도 7400 UDP 포트를 허용해야 한다.
* Host 네트워크 사용 시
  * 컨테이너가 호스트의 네트워크 스택을 직접 사용한다.
  * 호스트와 동일한 IP 주소, 동일한 인터페이스를 사용하기 때문에 별도의 포트 바인딩 없이도 동일하게 방화벽 정책이 적용된다.

컨테이너 오케스트레이션 도구(Kubernetes 등)를 사용하는 경우, 서비스 타입(NodePort, LoadBalancer) 및 CNI(Container Network Interface) 플러그인 설정에 따라 개방해야 하는 포트와 방화벽 규칙이 달라지므로, ROS2 DDS 통신에 필요한 포트 범위를 반드시 고려해야 한다.

#### Windows OS 방화벽 예시

멀티머신 ROS2 환경에 Windows 노드가 포함될 수도 있다. Windows 방화벽은 제어판이나 명령줄(netsh, PowerShell)을 통해 설정 가능하다.

```powershell
# PowerShell 예시: UDP 7400~7500 포트 인바운드 허용
New-NetFirewallRule `
  -DisplayName "ROS2 DDS Ports" `
  -Direction Inbound `
  -Protocol UDP `
  -LocalPort 7400-7500 `
  -Action Allow
```

* *Inbound Rule*로 7400\~7500 UDP 포트를 열어준다.
* 아웃바운드 역시 필요하다면 동일하게 규칙을 추가한다.

#### 고정 포트 설정(DDS 구현체별)

DDS 구현체마다 동적으로 포트를 할당하지 않고, 특정 범위를 강제하거나 고정 포트를 지정할 수도 있다. 예를 들어 Cyclone DDS, Fast DDS, RTI Connext DDS 등에선 XML 설정 파일(또는 환경 변수)로 포트 범위를 축소할 수 있는 옵션이 제공된다.

* **장점**: 파이어월 설정이 단순화된다. (예: 7400\~7420만 열면 됨)
* **단점**: 여러 도메인 ID나 여러 참가자(Participant)가 동시에 동작할 때 포트 충돌 가능성이 있다.

이처럼 ROS2 멀티머신 통신 시 “어떤 DDS 구현체를 쓰는가?”와 “어떤 포트를 사용하는가?”에 대한 명확한 이해가 필수이며, 방화벽 설정도 그에 맞추어 세밀하게 구성해야 한다.
