Modbus TCP Packet


Modbus TCP는 산업용 프로토콜인 Modbus를 Ethernet(TCP 502 Port)으로 보내는 방식 이다.
구조가 단순해서 Wireshark로 보면 바로 읽히는데 그만큼 보안에는 약하다.

1. 프레임 구조

Function Code + Data 부분을 PDU(Protocol Data Unit)라고 하고 Serial(RTU)이든 TCP든 PDU는 똑같다.
여기에 앞뒤로 뭘 붙이냐 에 따라서 RTU , TCP가 나뉜다.
A. PDU : 최대 253 Byte
B. RTU ADU = Slave Address(1) + PDU + CRC(2) → 최대 256 Byte
C. TCP ADU = MBAP Header(7) + PDU → 최대 260 Byte

* MBAP Header (Modbus Application Protocol Header)
A. Transaction ID (2 Byte) : 요청 , 응답 짝을 맞추는 번호. 응답은 요청이랑 같은 값으로 돌아온다.
B. Protocol ID (2 Byte) : Modbus는 항상 0x0000
C. Length (2 Byte) : 뒤에 따라오는 Byte수 [Unit ID + PDU]
D. Unit ID (1 Byte) : Gateway 뒤에 있는 Serial Slave를 구분할때 쓴다. [PLC에 직접 붙을때는 보통 1 이나 0xFF]

2. 프레임 예제
EX1) Unit ID 1 장비의 Holding Register 40001 ~ 40002 (2개)를 FC 03(Read Holding Registers)으로 읽는다.
[40001은 실제 Packet에서 주소 0x0000 이다. 40001 = 온도 x 10 , 40002 = 습도(%) 라고 가정]

[Request]  Client -> Server
00 01   00 00   00 06   01    03   00 00   00 02
-----   -----   -----   --    --   -----   -----
TID     PID     Len     UID   FC   Addr    Qty

Len 0x0006 : Unit ID(1) + FC(1) + 시작주소(2) + 개수(2) = 6

[Response]  Server -> Client
00 01   00 00   00 07   01    03   04      00 E6   00 19
-----   -----   -----   --    --   --      -----   -----
TID     PID     Len     UID   FC   Bytes   Val1    Val2

A. Len 0x0007 : Unit ID(1) + FC(1) + Byte Count(1) + 데이터(4) = 7
B. 0x00E6 = 230 → 온도 23.0℃ , 0x0019 = 25 → 습도 25%

3. 보안 취약점
Modbus는 원래 폐쇄된 Serial망 에서 쓰려고 만든거라 보안을 거의 고려하지않았다.
A. 인증이 없다 : 502 Port에 접속만 되면 누구나 읽고 쓸수 있다
B. 암호화가 없다 : 평문이라 위 예제 값도 Wireshark로 그대로 다보인다.
C. Replay 공격 : 캡처한 쓰기 Packet을 그대로 다시 보내도 장비는 정상 명령 으로 처리한다.
[Shodan 같은 검색엔진 에서 port:502로 검색해보면 인터넷에 그대로 노출된 Modbus 장비가 생각보다 많이 나온다.]

4. 대응 방법
A. 망 분리 : Modbus 장비는 OT망 안에만 두고 인터넷 , 사무망에서 직접 접근이 안되게 한다.
B. DPI(산업용 Firewall) : Function Code 단위로 필터링 해서 읽기(01 ~ 04)만 허용하고 쓰기(05 , 06 , 15 , 16)는 Engineering Workstation에서만 허용한다.
C. Modbus/TCP Security : Modbus Organization이 발표한 TLS 적용 버전 이다. TCP 802 Port를 쓰고 X.509 인증서로 서로 인증한다 [아직 지원하는 장비가 많지는 않다]

Spanning Tree Protocol


Switch끼리 연결할때 Link가 하나 밖에 없으면 그 Link가 끊어졌을때 통신이 안된다.
그래서 이중화를 하는데 이렇게 하면 Loop가 생겨 버린다
이 Loop를 막아주는게 STP 이다.

1. Switching Loop 문제
                    SW1
              |              |
           SW2---------SW3
              |
           PC-A
[SW1 , SW2 , SW3가 삼각형으로 연결된 상태에서 PC-A가 ARP Broadcast를 보내면 SW1 → SW3 → SW2 → SW1 ... 이렇게 양쪽 방향으로 계속 돈다]
A. Broadcast Storm : L2 Frame에는 TTL이 없어서 Broadcast Frame이 Loop를 계속 돌게된다. 결국 대역폭 , CPU를 다써버려서 네트워크가 마비 된다.
B. MAC Table 불안정 : 같은 Source MAC이 여러 Port로 들어와서 MAC Table이 계속 바뀐다 [MAC Flapping]
C. 중복 Frame : 목적지가 같은 Frame을 여러번 받게 된다.

2. STP 란?
IEEE 802.1D 표준 이다. Loop가 생기는 Port중에 하나를 Blocking 시켜서 논리적으로 Loop가 없는 Tree구조를 만든다.
사용중인 Link가 끊어지면 Blocking Port를 다시 열어주기 때문에 이중화도 할수 있다.

3. BPDU
Bridge Protocol Data Unit , Switch끼리 STP정보를 주고 받는 Frame 이다.
A. Root Bridge가 2초 마다(Hello Time) 만들어서 보내고 나머지 Switch는 이걸 받아서 Designated Port로 전달 한다
B. 목적지 MAC : 0180.C200.0000 [Cisco PVST+는 0100.0CCC.CCCD]
C. 종류 : Configuration BPDU , TCN BPDU(Topology Change Notification)

4. Bridge ID (BID)

Switch를 구분하는 8 Byte값 이다.
A. Bridge Priority (2 Byte) + MAC Address (6 Byte)
B. Priority 기본값은 32768 이고 4096단위로만 바꿀수 있다. (0 ~ 61440)
C. Extended System ID : Priority 16bit 중에 하위 12bit를 VLAN 번호로 쓴다. 그래서 VLAN 1은 32768 + 1 = 32769가 된다.
[PVST+는 VLAN마다 STP가 따로 돌아서 VLAN 별로 Root Bridge가 다를수 있다.]

5. Root Bridge 선출
A. BID가 제일 낮은 Switch 하나가 Root Bridge가 된다.
B. Priority가 같으면 MAC이 낮은 쪽이 된다
C. 처음에는 모든 Switch가 자기가 Root라고 BPDU를 보내다가 더 낮은 BID를 받으면 그 Switch를 Root로 인정한다.
[Root Bridge를 직접 정할려면 아래 명령어 중 하나를 쓴다.]

spanning-tree vlan 1 priority 4096
!
spanning-tree vlan 1 root primary

6. RSTP (Rapid Spanning Tree Protocol)
IEEE 802.1w 이고 802.1D 보다 수렴이 훨씬 빠르다. (보통 몇초 이내)
A. Port 상태 : Discarding , Learning , Forwarding 3개로 줄었다. [802.1D는 Blocking , Listening , Learning , Forwarding , Disabled 5개]
B. Port 역할 : 기존 Root Port , Designated Port 에 Alternate , Backup이 추가 됐다.
[Cisco 장비 에서는 spanning-tree mode rapid-pvst 명령어로 Rapid PVST+로 바꿀수 있다.]

'네트워크 > 스위칭' 카테고리의 다른 글

트렁크(Trunk) 와 VLAN 간 라우팅(Inter-VLAN Routing)  (0) 2026.10.28
브이랜(VLAN) 란?  (0) 2026.10.24

Trunk & Inter-VLAN Routing


Trunk는 여러 VLAN의 Frame을 Link 하나로 보내는 Port이고 802.1Q Tag로 어느 VLAN Frame인지 구분한다.
다른 VLAN끼리는 Broadcast Domain이 달라서 L3장비 없이는 통신이 안된다

1. Native VLAN
A. Trunk에서 Tag를 안붙이고 보내는 VLAN 이다. 기본값은 VLAN 1
B. Tag 없는 Frame을 받으면 Native VLAN으로 처리 한다.
C. 양쪽 Switch의 Native VLAN이 같아야 한다. 다르면 CDP에서 Native VLAN mismatch 메시지가 뜨고 VLAN끼리 Frame이 섞여 버릴수 있다.
[보안상 Native VLAN은 안쓰는 VLAN으로 바꿔 두는게 좋다. (VLAN Hopping 방지)]

2. DTP (Dynamic Trunking Protocol)
Cisco 전용 Protocol로 Trunk를 자동으로 협상 한다. 양쪽 mode 조합에 따라 결과가 달라진다.

- dynamic auto ↔ dynamic auto : Access
- dynamic auto ↔ dynamic desirable : Trunk
- dynamic auto ↔ trunk : Trunk
- dynamic auto ↔ access : Access
- dynamic desirable ↔ dynamic auto : Trunk
- dynamic desirable ↔ dynamic desirable : Trunk
- dynamic desirable ↔ trunk : Trunk
- dynamic desirable ↔ access : Access
- trunk ↔ dynamic auto : Trunk
- trunk ↔ dynamic desirable : Trunk
- trunk ↔ trunk : Trunk
- trunk ↔ access : 설정 오류 (사용 X)
- access ↔ dynamic auto : Access
- access ↔ dynamic desirable : Access
- access ↔ trunk : 설정 오류 (사용 X)
- access ↔ access : Access

[2960은 기본값이 dynamic auto 라서 양쪽다 기본값이면 Trunk가 안된다.]
[switchport nonegotiate로 DTP를 끌수 있고 실무에서는 왠만하면 mode를 직접 지정한다]

3. Trunk 설정 예제
                                  Trunk                                          Trunk
R1--------------------------------SW1--------------------------------SW2
                                       |          |                                      |          |
                                    PC1     PC2                                 PC3     PC4
[R1 Fa0/0 ↔ SW1 Fa0/23 , SW1 Fa0/24 ↔ SW2 Fa0/24 는 Trunk]
[PC1 13.13.10.1 , PC3 13.13.10.2 : VLAN 10 (Fa0/1) / PC2 13.13.20.1 , PC4 13.13.20.2 : VLAN 20 (Fa0/2)]
[R1 Fa0/0.10 : 13.13.10.254 , Fa0/0.20 : 13.13.20.254]
EX1) 위 구성도에서 SW1 , SW2에 VLAN 10 , 20을 만들고 PC를 연결한 다음 Switch 사이는 Trunk로 설정한다. (R1은 아직 연결 안한 상태)

# SW1
vlan 10
 name SALES
vlan 20
 name DEV
!
interface fastethernet 0/1
 switchport mode access
 switchport access vlan 10
!
interface fastethernet 0/2
 switchport mode access
 switchport access vlan 20
!
interface fastethernet 0/24
 switchport mode trunk
!

[SW2도 똑같이 설정 한다.]
[2960은 802.1Q만 지원해서 switchport trunk encapsulation dot1q 명령어가 없다. 3560같은 L3 Switch는 이 명령어를 먼저 입력 해야 Trunk 설정이 된다.]

SW1#show interfaces trunk

Port        Mode             Encapsulation  Status        Native vlan
Fa0/24      on               802.1q         trunking      1

Port        Vlans allowed on trunk
Fa0/24      1-4094

Port        Vlans allowed and active in management domain
Fa0/24      1,10,20

Port        Vlans in spanning tree forwarding state and not pruned
Fa0/24      1,10,20

Mode가 on 인건 switchport mode trunk로 직접 지정했기 때문이다.
[Trunk Port인 Fa0/24는 show vlan brief에 안나온다.]
PC1 → PC3 ping은 된다. (같은 VLAN 10)
하지만 PC1 → PC2 ping은 안된다. Router가 없어서 다른 VLAN끼리는 통신할 방법이 없기때문이다

4. Inter-VLAN Routing (Router-on-a-stick)

Router의 물리 Interface 하나를 Sub-interface로 나눠서 VLAN마다 Gateway를 만드는 방식 이다.
EX2) SW1 Fa0/23에 R1을 연결해서 VLAN 10 , 20 사이를 Routing 한다.

# R1
interface fastethernet 0/0
 no shutdown
!
interface fastethernet 0/0.10
 encapsulation dot1Q 10
 ip address 13.13.10.254 255.255.255.0
!
interface fastethernet 0/0.20
 encapsulation dot1Q 20
 ip address 13.13.20.254 255.255.255.0
!
# SW1
interface fastethernet 0/23
 switchport mode trunk
!

[PC1 , PC3의 Gateway는 13.13.10.254 , PC2 , PC4는 13.13.20.254로 설정 한다.]

SW1#show interfaces trunk

Port        Mode             Encapsulation  Status        Native vlan
Fa0/23      on               802.1q         trunking      1
Fa0/24      on               802.1q         trunking      1

Port        Vlans allowed on trunk
Fa0/23      1-4094
Fa0/24      1-4094

Port        Vlans allowed and active in management domain
Fa0/23      1,10,20
Fa0/24      1,10,20

Port        Vlans in spanning tree forwarding state and not pruned
Fa0/23      1,10,20
Fa0/24      1,10,20

이제 PC1 → PC2 ping도 R1을 거쳐서 된다.
[Link 하나로 모든 VLAN트래픽이 지나가서 트래픽이 많으면 병목이 생길수 있다. 그래서 실무 에서는 L3 Switch의 SVI를 많이쓴다.]

'네트워크 > 스위칭' 카테고리의 다른 글

스패닝 트리(Spanning Tree) 프로토콜(STP) 란?  (0) 2026.10.28
브이랜(VLAN) 란?  (0) 2026.10.24

+ Recent posts