Kubernetes의 Kube Proxy / Iptables의 동작

    Kubernetes의 Kube-Proxy

    Kube-Proxy는 쿠버네티스의 컴포넌트 중 하나다. Kube-Proxy는 쿠버네티스 클러스터 내부에서 Service와 관련된 모든 것을 처리하는 동작을 한다. Service의 IP로 전달되는 패킷들이 Pod로 전달되는 것은 바로 Kube-Proxy Pod가 해주는 일이다. Kube-Proxy의 동작 방식은 두 가지가 존재한다

    • userspace 프록시 모드(이전) : Kube Proxy가 패킷을 받아서 Pod로 전달해줌.
    • iptables 프록시 모드(현재) : Kube Proxy는 IpTables만 업데이트 해줌. 

    아래에서 대략적인 동작을 살펴볼 수 있다. kube-proxy의 Userspace Mode는 Iptables를 이용해 모든 패킷이 kube-proxy로 오게 만든 후, kube-proxy를 통해 Pod에게 패킷이 전달되도록 한다. kube-proxy는 다른 Pod이기 때문에 한번의 Network Hopping이 더 필요하며, 이에 따라 약간의 성능 저하가 있을 수 있다. 

    IpTables Mode는 조금 다르게 동작한다. kube-proxy는 쿠버네티스 API Server를 지속적으로 Watch하며 Pod, Service, Endpoints 정보를 받아오고, 이 정보를 단순히 각 노드의 Iptables에 업데이트만 해준다. 따라서 Iptables에 특정 패킷이 들어오면, iptables에 정해진 라우팅 룰에 따라 패킷이 바로 Pod로 전달되게 된다. 


    Kube-proxy는 DaemonSet

    kube-proxy는 DaemonSet으로 배포된다. 아래에서 볼 수 있듯이 Master + Worker Node에 모두 배포된다. 즉, Master + Worker Node의 모든 IpTables에 영향을 준다는 것이다. 아마 iptables를 살펴보게 되면 Master, Worker Node는 비슷한 정책이 설정되어 있을 것이란 것을 짐작할 수 있다. 

    # 노드의 개수는 4개
    root@master1:~# kubectl get nodes
    NAME      STATUS     ROLES           AGE   VERSION
    master1   Ready      control-plane   17d   v1.27.1
    worker1   Ready      <none>          17d   v1.27.1
    worker2   NotReady   <none>          17d   v1.27.1
    worker3   Ready      <none>          17d   v1.27.1
    
    $ kube-proxy의 DESIRED = 4
    root@master1:~# kubectl get ds -A
    NAMESPACE         NAME                       DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
    kube-system       kube-proxy                 4         4         3       4            3           kubernetes.io/os=linux   17d

    Iptables의 동작

    iptables는 다음과 같은 형태로 동작한다. 패킷이 들어오면 IP Table의 체이닝은 PREROUTING → FORWARD → POSTROUTING의 형태로 진행된다. 이 때 간단히 알아둬야 할 것은 다음과 같다.

    1. iptables에는 여러 규칙이 정의되어있다.
    2. 패킷은 정의된 규칙을 만족하는지 확인한다. 규칙을 만족하면, 해당 규칙이 적용된다. 
    3. 패킷은 종료 규칙을 만날 때 까지 규칙을 순회한다. 종료 규칙을 만나면 다음 체인으로 패킷이 전달된다.
      • 예를 들어 PREROUTING에서 종료 규칙을 만나면, 패킷은 FORWARD로 전달됨. 
    4. 종료 규칙은 다음이 존재한다.
      • ACCEPT
      • REJECT
      • DROP
      • SNAT
      • DNAT
      • MASQUERADE


    클러스터 내부에서 전달되는 트래픽

    먼저 아래의 상황을 가정한 다음, 각 워커 노드에 있는 파드끼리 트래픽이 전달되는 경우를 고려해보자. 

    $ kubectl get pod,svc -o wide
    NAME                                     READY   STATUS    RESTARTS   AGE     IP            NODE             NOMINATED NODE   READINESS GATES
    pod/nginx-test-bb98f4cb8-5dfvz           1/1     Running   0          3h2m    50.0.86.7     ubuntu-worker2   <none>           <none>
    pod/nginx-test-bb98f4cb8-hgmf6           1/1     Running   0          3h2m    50.0.86.44    ubuntu-worker2   <none>           <none>
    pod/nginx-test-bb98f4cb8-vblzn           1/1     Running   0          3h2m    50.0.91.215   ubuntu-worker1   <none>           <none>
    
    NAME                   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE     SELECTOR
    service/kubernetes     ClusterIP   40.0.0.1       <none>        443/TCP    6d      <none>
    service/nginx-test     ClusterIP   40.0.103.247   <none>        8888/TCP   3h2m    app=nginx-test

    nginx와 관련된 Service, Pod를 이용해서 nginx끼리 Pod끼리 트래픽을 주고 받는 상황을 가정해보자. 나는 50.0.91.215 Pod에서 nginx-test로 서비스를 전달하는 경우를 살펴보려고 한다. 

     

     

    PREROUTING 단계 

    Pod에서 Sevice로 요청을 보내면 (50.0.91.215 → 40.0.103.247:8888), 파드의 요청은 가장 먼저 Node의 Iptables로 전달되게 된다. Iptables에 전달된 패킷은 가장 먼저 PREROUTING 테이블 규칙이 적용된다. 

    iptables는 가장 위의 규칙부터 적용되기 시작하기 때문에 패킷은 cali-PREROUTING으로 전달된다. cali-PREROUTING 규칙을 따라가면 cali-fip-dnat까지 전달이 되는데, 여기서는 패킷이 해당되는 어떠한 규칙도 정의되어 있지 않다. 따라서 패킷은 KUBE-SERVICES로 점프하게 된다. (-j KUBE-SERVICES)

    $ iptables -t nat -S PREROUTING
    -P PREROUTING ACCEPT
    -A PREROUTING -m comment --comment "cali:6gwbT8clXdHdC1b1" -j cali-PREROUTING
    -A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
    -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
    
    # cali-PREROUTING을 따라가보면 처리규칙이 없음. 
    $ iptables -t nat -S cali-PREROUTING
    -N cali-PREROUTING
    -A cali-PREROUTING -m comment --comment "cali:r6XmIziWUJsdOK6Z" -j cali-fip-dnat
    
    $ iptables -t nat -S cali-fip-dnat
    -N cali-fip-dnat

    KUBE-SERVICES의 NAT 테이블을 살펴보자. iptables는 정의된 규칙 중 가장 먼저 정의된 규칙부터 실행한다. 따라서 위에서부터 iptables의 규칙에 맞는지를 확인한다. 전달되고 있는 패킷은 50.0.91.215 → 40.0.103.247:8888으로 구성되어있다. 이 때 가장 위의 규칙에는 -d 40.0.103.247/32라고 되어있는데, 목적지가 40.0.103.247인 경우를 의미한다. 따라서 패킷은 이 규칙에 부합하기 때문에 이 규칙이 가리키고 있는 KUBE-SVC-W67AXLFK7VEUVN6G으로 패킷이 전달된다. 

    $ iptables -t nat -S KUBE-SERVICES
    -N KUBE-SERVICES
    -A KUBE-SERVICES -d 40.0.103.247/32 -p tcp -m comment --comment "default/nginx-test cluster IP" -m tcp --dport 8888 -j KUBE-SVC-W67AXLFK7VEUVN6G
    -A KUBE-SERVICES -d 40.0.0.1/32 -p tcp -m comment --comment "default/kubernetes:https cluster IP" -m tcp --dport 443 -j KUBE-SVC-NPX46M4PTMTKRN6Y
    -A KUBE-SERVICES -m comment --comment "kubernetes service nodeports; NOTE: this must be the last rule in this chain" -m addrtype --dst-type LOCAL -j KUBE-NODEPORTS

     KUBE-SVC-W67AXLFK7VEUVN6G으로 넘어왔다. 여기서도 마찬가지로 위에서부터 규칙이 맞는지 확인한다.

    현재 패킷은 50.0.91.215 → 40.0.103.247:8888 이렇게 전달되고 있다. 여기서 -s 50.0.0.0/16이라고 되어있는데 CIDR 표기법이며, 이것은 50.0.0.0 ~ 50.0.255.255의 범위를 가리킨다. 가장 첫번째 규칙은 다음을 의미한다.

    • 출발 주소 : 50.0.0.0 ~ 50.0.255.255
    • 도착 주소 : 40.0.103.247:8888
    • 프로토콜 : TCP

    그런데 현재 전달하고 있는 패킷을 위의 규칙을 만족하기 때문에 KUBE-MARK-MASQ로 패킷을 전달해야한다. KUBE-MARK-MASQ에서는 패킷에 0x4000/0x4000라는 마킹을 한다. 여기서 -j MARK는 "마크를 남긴다"라는 의미고, "--set-xmark 0x4000/0x4000"은 마크값을 0x4000/0x4000으로 한다는 것이다. 이 마크 값은 쿠버네티스 내부에서 라우팅을 할 때 사용되는 값이 될 것이다. 

    마킹이 끝나고 나면 이후에 패킷이 처리되는 로직이 없기 때문에 다시 KUBE-SVC-W67AXLFK7VEUVN6G으로 돌아와서 다음 규칙에 해당되는지 확인한다. 딱히 어떠한 조건도 없기 때문에 패킷은 이곳으로 전달될 수 있으며, 0.33%의 확률로 KUBE-SEP-CQMQTKX4IR3NMZWQ로 다시 라우팅된다. 

    $ iptables -t nat -S KUBE-SVC-W67AXLFK7VEUVN6G
    -N KUBE-SVC-W67AXLFK7VEUVN6G
    -A KUBE-SVC-W67AXLFK7VEUVN6G ! -s 50.0.0.0/16 -d 40.0.103.247/32 -p tcp -m comment --comment "default/nginx-test cluster IP" -m tcp --dport 8888 -j KUBE-MARK-MASQ
    -A KUBE-SVC-W67AXLFK7VEUVN6G -m comment --comment "default/nginx-test -> 50.0.86.44:8888" -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-CQMQTKX4IR3NMZWQ
    -A KUBE-SVC-W67AXLFK7VEUVN6G -m comment --comment "default/nginx-test -> 50.0.86.7:8888" -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-PAXM6M3CSVUMJTP4
    -A KUBE-SVC-W67AXLFK7VEUVN6G -m comment --comment "default/nginx-test -> 50.0.91.215:8888" -j KUBE-SEP-FAV46QF2QY4KCK4S
    
    $ iptables -t nat -S KUBE-MARK-MASQ
    -N KUBE-MARK-MASQ
    -A KUBE-MARK-MASQ -j MARK --set-xmark 0x4000/0x4000

    KUBE-SEP-CQMQTKX4IR3NMZWQ 이곳으로 넘어왔다. 50.0.91.215 → 40.0.103.247:8888이 패킷 정보인데, iptables의 첫번째 규칙에는 맞지 않다. 다음 규칙에 맞는지 확인 했더니 -p tcp로 TCP이기만 하면 된다. 두번째 iptables 규칙은 DNAT --to-destination 50.0.86.44:8888이라고 되어있다. 이것은 도착 IP를 50.0.86.44:8888로 바꾼다는 의미가 된다. 

    두번째 규칙을 적용하게 되면 최초의 패킷은 이렇게 변경된다.

    • Before : 50.0.91.215 → 40.0.103.247:8888 (서비스 IP)
    • After : 50.0.91.215 → 50.0.86.44:8888 (파드 IP)

    IpTables를 통해서 서비스 IP로 전달되던 패킷이 Pod IP로 변경되게 된 것이다. 그리고 DNAT는 종료 규칙이다. 따라서 패킷은 PREROUTING의 체인에서 더 동작하지 않고 FORWARD 체인으로 넘어간다. 

    $ iptables -t nat -S KUBE-SEP-CQMQTKX4IR3NMZWQ
    -N KUBE-SEP-CQMQTKX4IR3NMZWQ
    -A KUBE-SEP-CQMQTKX4IR3NMZWQ -s 50.0.86.44/32 -m comment --comment "default/nginx-test" -j KUBE-MARK-MASQ
    -A KUBE-SEP-CQMQTKX4IR3NMZWQ -p tcp -m comment --comment "default/nginx-test" -m tcp -j DNAT --to-destination 50.0.86.44:8888
    
    
    $ route
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    default         _gateway        0.0.0.0         UG    600    0        0 wlan0
    50.0.86.0       192.168.0.202   255.255.255.192 UG    0      0        0 tunl0
    50.0.91.192     192.168.0.201   255.255.255.192 UG    0      0        0 tunl0
    ...

    DNAT를 통해서 Destination 주소가 50.0.86.44로 변경되었다. 현재 노드의 Routing 테이블을 살펴보면 50.0.86.0에 GEN MASK가 255.255.255.192다. 64개의 공간이 남으므로, 50.0.86.0의 주소 범위는 50.0.86.0 ~ 50.0.86.63이 된다. 따라서 50.0.86.44는 이 노드에서 tun10이라는 네트워크 인터페이스로 나가게 된다. 이것은 FORWARD 단계에서 규칙을 판단할 때 사용되므로 잘 알아둬야 한다. 

    패킷 정보는 다음과 같다.

    • src : 50.0.91.215 
    • dest : 50.0.86.44:8888  
    • out network : tun10
    • MARK : 0x4000/0x4000

     

     

    FORWARD 단계 

    PREROUTING이 끝났으면 패킷은 FORWARD 체인으로 전달된다. 여기서 -P DROP으로 만족하는 어떠한 규칙도 없는 경우 DROP이 된다. 위에서부터 패킷이 하나씩 규칙이 적용되는지 확인한다. 

    아래 규칙을 따라가보면 cali-FORWARD → KUBE-PROXY-FIREWALL → KUBE-FORWARD 순으로 패킷이 전달되고 마무리 된다. 자세한 과정을 따라가보자.

    1. cali-FORWARD
      1. 패킷은 cali-forward 규칙에 적용되기 때문에 cali-forward 필터로 전달된다.
      2. cali-FORWARD 첫번째 규칙에 적용되기 때문에 패킷에는 0x0/0xe0000이라는 마크가 적용된다. 그런데 앞서 적용된 0x4000/0x4000 마크가 있는데, chatgpt에 물어보니 연산이 완료되어도 각각 유지된다고 한다. (삐트 연산 결과)
      3. cali-FORWARD의 두번째 규칙은 0x0/0x10000 마크가 있어야 하는데, 그런 마크가 없으므로 무시된다.
      4. cali-FORWARD 세번째 규칙은 입력 네트워크 인터페이스가 cali로 시작되어야 하지만, LocalHost에서 시작되기 때문에 무시된다.
      5. cali-FORWARD의 네번째 규칙은 출력 네트워크 인터페이스가 cali로 시작되어야 하지만, 출력 네트워크 인터페이스는 tun10이다. 따라서 무시된다.
      6. cali-FORWARD 5~6번째 규칙은 적용되기 때문에 해당 필터로 가보지만, 어떠한 규칙도 정의되어있지 않다. 따라서 패킷은 아무런 작업을 하지 않고 cali-FOWARD를 통과한다. 
    2. cali-FORWARD에서 종료 동작이 나오지 않았으므로, 패킷은 FORWARD 테이블로 돌아온다. 다음 규칙은 KUBE-PROXY-FIREWALL이다.
      1. KUBE-PROXY-FIREWALL로 패킷이 전달되지만, 이 테이블에는 어떠한 규칙도 정의되어있지 않다. 
    3. KUBE-PROXY-FIREWALL에서 종료 동작이 나오지 않았으므로 패킷은 FORWARD 테이블로 돌아온다. 다음 규칙은 KUBE-FORWARD다.
      1. 첫번째 규칙은 INVALID한 패킷인 경우, DROP 하는 종료동작을 한다. 하지만 해당하지 않으므로 패킷은 통과한다.
      2. 두번째 규칙은 패킷에 0x4000/0x4000을 마킹이 있는 경우 ACCEPT를 한다. 앞서 마킹이 두번 되었지만, 0x4000/0x4000 마킹이 유지되기 때문에 패킷은 이 규칙이 적용된다. 여기서 종료 동작 ACCEPT를 만난다.
    4. KUBE-FORWARD에서 패킷은 ACCEPT라는 종료 동작을 만난다. ACCEPT는 패킷을 통과시켜주는 Action이기 때문에 패킷은 FORWARD 체인을 통과한다. 
    $ iptables -t filter -S FORWARD
    -P FORWARD DROP
    -A FORWARD -m comment --comment "cali:wUHhoiAYhphO9Mso" -j cali-FORWARD
    -A FORWARD -m conntrack --ctstate NEW -m comment --comment "kubernetes load balancer firewall" -j KUBE-PROXY-FIREWALL
    -A FORWARD -m comment --comment "kubernetes forwarding rules" -j KUBE-FORWARD
    -A FORWARD -m conntrack --ctstate NEW -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
    -A FORWARD -m conntrack --ctstate NEW -m comment --comment "kubernetes externally-visible service portals" -j KUBE-EXTERNAL-SERVICES
    
    -N cali-FORWARD
    -A cali-FORWARD -m comment --comment "cali:vjrMJCRpqwy5oRoX" -j MARK --set-xmark 0x0/0xe0000
    -A cali-FORWARD -m comment --comment "cali:A_sPAO0mcxbT9mOV" -m mark --mark 0x0/0x10000 -j cali-from-hep-forward
    -A cali-FORWARD -i cali+ -m comment --comment "cali:8ZoYfO5HKXWbB3pk" -j cali-from-wl-dispatch
    -A cali-FORWARD -o cali+ -m comment --comment "cali:jdEuaPBe14V2hutn" -j cali-to-wl-dispatch
    -A cali-FORWARD -m comment --comment "cali:12bc6HljsMKsmfr-" -j cali-to-hep-forward
    -A cali-FORWARD -m comment --comment "cali:NOSxoaGx8OIstr1z" -j cali-cidr-block
    
    -N cali-from-hep-forward
    -N cali-to-hep-forward
    -N cali-cidr-block
    -N KUBE-PROXY-FIREWALL
    
    -N KUBE-FORWARD
    -A KUBE-FORWARD -m conntrack --ctstate INVALID -j DROP
    -A KUBE-FORWARD -m comment --comment "kubernetes forwarding rules" -m mark --mark 0x4000/0x4000 -j ACCEPT
    -A KUBE-FORWARD -m comment --comment "kubernetes forwarding conntrack rule" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

    따라서 패킷은 FORWARD를 통과하고, 다음 단계인 POSTROUTING 체인으로 전달된다. 패킷 정보는 다음과 같다.

    • src : 50.0.91.215 
    • dest : 50.0.86.44:8888  
    • out network : tun10
    • MARK : 0x0/0xe0000 + 0x4000/0x4000

    POSTROUTING 단계

    FORWARD에서 패킷이 전달되었다. 전달된 패킷은 종료 동작을 만날 때 까지 POSTROUTING 테이블의 규칙을 방문한다. 아래에서 하나씩 살펴보고자 한다. 

    • cali-POSTROUTING
      1. 첫번째로 cali-fip-snat으로 간다. 하지만 아무 규칙이 설정되어 있지 않다. 다음으로 넘어간다.
      2. 두번째로 cali-nat-outgoing으로 간다. 이 규칙은 출발하는 IP가 cali40masq-ipam-pools에 속해야하고, 도착 IP가 해당 IP풀에 속하지 않아야 한다. ipset list 명령어로 살펴보면 IP가 cali40masq-ipam-pools 풀은 50.0.0.0/16을 가진다. 출발 / 도착 IP가 모두 해당 풀에 속하므로 만족하지 않는다. 
      3. 세번째 규칙을 살펴본다. 출력 네트워크 인터페이스가 tun10으로 만족하지만, -m으로 2개의 매치가 AND 조건으로 묶여잇다. 하지만 src type이 Local이면서 Local이 아니어야 하는데, 만족하지 않는다. 따라서 다음으로 전달된다.
    • KUBE-POSTROUTING
      1. 1. 첫번째 규칙은 패킷에 0x4000/0x4000이 마킹되어 있지 않으면 리턴하는 것이다. 하지만 마킹되어 있음으로 무시된다.
      2. 2. 두번째 규칙은 패킷에 0X4000/0x0을 마킹하는 것이다. 비트 연산 결과, 기존 마킹된 값에는 영향을 주지는 않는다.
      3. 3. 세번째 규칙은 별다른 조건이 없기 때문에 만족한다. 따라서 패킷은 MASQURADE 라는 종료 규칙을 만난다.
      4. MASQUARADE는 종료 규칙이다. 이 규칙을 만나게 되면 출발 주소를 출력 네트워크 인터페이스로 변경해준다. 즉, 출발 주소가 tun10이 되게 된다. 
    $ iptables -t nat -S POSTROUTING
    -P POSTROUTING ACCEPT
    -A POSTROUTING -m comment --comment "cali:O3lYWMrLQYEMJtB5" -j cali-POSTROUTING
    -A POSTROUTING -m comment --comment "kubernetes postrouting rules" -j KUBE-POSTROUTING
    -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
    
    -N cali-POSTROUTING
    -A cali-POSTROUTING -m comment --comment "cali:Z-c7XtVd2Bq7s_hA" -j cali-fip-snat
    -A cali-POSTROUTING -m comment --comment "cali:nYKhEzDlr11Jccal" -j cali-nat-outgoing
    -A cali-POSTROUTING -o tunl0 -m comment --comment "cali:SXWvdsbh4Mw7wOln" -m addrtype ! --src-type LOCAL --limit-iface-out -m addrtype --src-type LOCAL -j MASQUERADE --random-fully
    
    -N cali-fip-snat
    
    -N cali-nat-outgoing
    -A cali-nat-outgoing -m comment --comment "cali:flqWnvo8yq4ULQLa" -m set --match-set cali40masq-ipam-pools src -m set ! --match-set cali40all-ipam-pools dst -j MASQUERADE --random-fully
    
    
    -N KUBE-POSTROUTING
    -A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN
    -A KUBE-POSTROUTING -j MARK --set-xmark 0x4000/0x0
    -A KUBE-POSTROUTING -m comment --comment "kubernetes service traffic requiring SNAT" -j MASQUERADE --random-fully
    
    
    $ ipset list cali40masq-ipam-pools
    Name: cali40masq-ipam-pools
    Type: hash:net
    Revision: 6
    Header: family inet hashsize 1024 maxelem 1048576
    Size in memory: 512
    References: 1
    Number of entries: 1
    Members:
    50.0.0.0/16
    • src : 50.0.172.192 (tun10 IP 주소)
    • dest : 50.0.86.44:8888  
    • out network : tun10
    • MARK : 0x0/0xe0000 + 0x4000/0x4000

    정리

    Iptables를 따라가면서 살펴보면 다음과 같다

    1. Service로 가는 패킷은 PREROUTING 체인에 정의된 규칙에서 Pod의 주소로 변경된다. 이 때, 몇 퍼센트 확률로 분배가 되는지 정의되어있다. 여기서 정의가 완료되면 FORWARD 체인로 넘겨진다.
    2. FORWARD에서는 CNI를 타는지가 결정된다. 완료되면 POSTROUTING 체인으로 넘겨진다.
    3. POSTROUTING에서는 패킷의 출발 주소가 MASQUARADE로 정의된다. 이 때, 출발 주소가 출력 네트워크 인터페이스의 주소로 변경된다. 

    이 때, Service가 Pod의 주소로 바뀌는 과정을 살펴보면 이랬었다. 

    • Service 주소 + Service의 포트를 만족하는 경우, 특정 NAT 테이블로 점프하게 만들어져 있음.
    • 특정 NAT 테이블은 Service의 Endpoints와 관련된 Pod의 주소들로 Jump하도록 규칙이 작성되어있음. 이 때, 어떤 Pod를 선택하는지는 Possibility로 정의되어있음. 

    이렇게 구성되어있다. 따라서 Service라는 녀석이 가지는 CLUSTER IP는 그것만으로는 큰 의미가 없다. 왜냐하면 해당 IP에 대한 규칙이 정해져있지 않기 때문이다. Service는 IP와 Port가 함께 iptables에 규칙으로 정의되어있다. 


    참고 

    패킷에는 첫번째로 일치하는 규칙이 처리된다.
    iptables는 체인 내의 규칙들을 위에서 아래로 순서대로 검사하게 됩니다. 패킷이 특정 규칙과 일치하면, 그 규칙에 정의된 액션이 실행됩니다. 그러나, 이 액션이 패킷의 운명을 결정하는 경우 (ACCEPT, DROP, REJECT 등과 같은 터미널 규칙) 더 이상의 규칙 검사는 중단됩니다. 그러나, 액션이 패킷의 운명을 결정하지 않는 경우 (예: 로깅, 패킷 마크 등), 처리는 다음 규칙으로 계속됩니다.
    따라서 일반적으로 첫 번째로 일치하는 "종료" 규칙이 패킷에 적용되지만, 일치하는 모든 "비종료" 규칙이 처리될 수 있습니다. 따라서 특정 상황에 따라 두 가지 모두 가능할 수 있습니다.

    iptables에서 패킷 처리에 관한 "종료" 규칙은 다음과 같습니다:
    ACCEPT: 이 규칙과 일치하는 패킷은 허용되며, 더 이상 다른 규칙은 검사되지 않습니다.DROP: 이 규칙과 일치하는 패킷은 드롭되며, 더 이상 다른 규칙은 검사되지 않습니다.REJECT: 이 규칙과 일치하는 패킷은 거부되며, 패킷 발신자에게 ICMP 에러 메시지가 전송됩니다. 마찬가지로 이 규칙 후의 다른 규칙은 검사되지 않습니다.
    이러한 규칙들은 패킷이 체인을 통과할지 아니면 통과를 중지할지 결정하는 "종료" 규칙이며, 일치하는 규칙이 발견되면 그 이후의 규칙은 처리되지 않습니다.

    종료 규칙
    ACCEPT
    REJECT
    DROP
    SNAT
    DNAT
    MASQUERADE

     

     

    댓글

    Designed by JB FACTORY