상황은 이렇다.

  1. docker image 를 이용해서 mongodb container 를 띄웠다.
  2. 이전에 설정해놓은 firewall 이 갑자기 뻥 뚫렸다.
  3. iptables 를 봤더니 내가 세팅하지않은 값들로 변경이 되있다.
  4. 옵션들중에 모르는게 보인다.

사실 실제로 iptables 를 건드는건 테스트서버 작업할 때 제외하곤 거의 안해서 세세하게 보지 않았다.

하지만 해야할 일이 생겨버려서 이제는 해야한다.(ㅜ.ㅜ)

그리고 당연한 이야기지만 도커가 내부적으로 통신하기 위해선 포트간 연결에대한 정책이 있어야하는데

이를 위해 docker 실행시 iptables 를 변경해버린다.

이 부분은 실행 스크립트를 변경하면 되는데 일단 그전에 변경된 iptables 에서 몇몇 모르는 옵션들이 보여서

하는 김에 이왕이면 정리해놓고 나중에 잊어버리면 다시 봐야겠다는 마음으로 하나하나 정리해본다.

정리하는데 참고하는 자료는 레드햇 문서이다.

정리가 정말 깔끔하게 잘 되어있다.( 좀 배우고 싶을 정도로)

일단 iptables 의 명령어 구조에 대해서 본다.

iptables [-t <table-name>] <command> <chain-name> <parameter-1> \
         <option-1> <parameter-n> <option-n>

하나씩 본다.

table-name

패킷을 필터하는데 리눅스 커널이 내장하고 있는 3개의 테이블의 이름

  • filter : 네트워크 패킷을 제어하는 기본 테이블
  • nat : 새로운 커넥션을 만들고 네트워크 주소를 변환하는데 사용되는 패킷을 변환하는데 사용된다.
  • mangle : 특정 유형의 패킷 변경에 사용된다.
기본 테이블 말고도 테이블을 작성할 수있다.

위치는 아래 경로를 따라야 한다.

/lib/modules/<kernel-version>/kernel/net/ipv4/netfilter/ directory
command
  • -A : 체인에 해당 룰이 없을 때 특정 체인의 끝에 룰을 추가한다.
  • -C : 유저의 특정 룰들을 더하기 전에 체크한다. iptables 의 구조를 완벽하게 작성하는데 도움을 준다.
  • -D : 룰을 삭제한다.
  • -E : 룰의 이름을 변경한다.
  • -F : 룰을 삭제하는데 특정 룰을 지정안할 시 전체 룰을 삭제한다.
  • -h : 커맨드 구조의 리스트를 제공한다. 헬프
  • -I : 유저가 체인의 특정 포인트를 정수값으로 지정한곳에 룰을 삽입한다. 포인트 미지정시 탑에 추가
  • -L : 체인에 있는 모든 룰의 리스트를 반환한다.(default 는 filter table) -L chainname -t tablename의 경우는 특정 테이블의 룰리스트
  • -N : 새로운 체인을 생성한다. 파라미터로 제공한 name 으로
  • -P : 특정 체인의 기본 정책을 정한다. 룰에 매칭안된 것들을 특정 타겟으로 보낸다.
  • -R : 체인에서 룰을 변경한다. 룰의 넘버는 체인 이름 뒤에 특정되야 한다.
  • -X : 사용자 정의 체인을 삭제한다. 테이블의 내장체인은 삭제 할 수 없다.
  • -Z : 테이블의 모든 체인에서 바이트 및 패킷 카운터를 0으로 설정한다.
The built in chains for filter table

위의 1 번에서 이야기한 리눅스 커널이 내장하고 있는 3개의 테이블중 filter 테이블에 내장된 체인들을 살펴본다.

  • INPUT : 호스트를 타겟으로하는 네트워크 패킷에 적용한다.
  • OUTPUT : 로컬호스트에서 생성된 네트워크 패킷에 적용한다.
  • FORWARD : 호스트를 통해 라우트된 네트워크 패킷을 변경한다.
The built in chains for nat table

위의 1번에서 이야기한 리눅스 커널이 내장하고 있는 3개의 테이블중 nat 테이블에 내장된 체인들을 살펴본다.

  • PREROUTING : 네트워크 패킷이 도착하면 변경한다.
  • OUTPUT : 로컬에서 생성된 네트워크 패킷을 밖으로 보내기전에 변경한다.
  • POSTROUTING : 네트워크 패킷을 밖으로 보내기전에 변경한다.
The built in chains for mangle table
  • INPUT : 호스트를 대상으로 하는 패킷을 변경한다.
  • OUTPUT : 로컬에서 생성된 패킷들을 내보내기전에 변경한다.
  • FORWARD : 호스트를 통해 라우트된 네트워크 패킷을 변경한다.
  • PREROUTING : 들어오는 네트워크 패킷을 라우팅되기전에 변경한다.
  • POSTROUTING : 네트워크 패킷을 내보내기전에 변경한다.
iptables 의 방화벽 정책 정의에 도메인을 사용하면 안된다.
이유는 iptables 의 시작이 DNS 관련 서비스들의 시작 이전에 시작되기 때문이다.

iptables Parameter options

-c : 특정 규칙에 대한 카운터를 재설정 한다. PKTS 와 BYTES 옵션을 이용하여 재설정할 카운터를 지정한다.

-d : 대상 호스트, ip, 네트워크 를 지정한다. 네트워크 일치시 ip/netmask 를 지원한다.

  • N.N.N.N/M.M.M.M 일 경우 N.N.N.N 에서 M.M.M.M 의 레인지를 가지는 넷마스크이다.
  • N.N.N.N/M 일 경우 M 비트 넷마스크이다.
  • 넷마스크는 호스트 아이피에서 서브넷으로 나누고 네트워크의 사용가능한 호스트를 지정하는데 사용되는 32비트 마스크이다. 2비트는 항상 자동할당되는데 0, 255이다. 이 주소는 사용 불가하다. 보통 24비트 넷마스크를 사용하는데 이는 각기 다른 호스트에 192.0.1.x to 223.255.254.x 의 범위의 ip 를 할당 가능하다.

-f : 조각난 패킷에만 해당 룰을 적용한다. 이 매개변수 이후에 (!) 옵션을 사용하면 조각나지 않은 패킷만 적용한다.

-i : 들어오는 네트워크 인터페이스를 설정한다(ex : eth0, ppp0, …). filter 테이블의 INPUT, FORWARD 체인과 nat, mangle 테이블의 PREROUTING 체인과 함께 사용할 때 사용가능하다.

  • (!) 옵션을 사용시 지정된 인터페이스 eth0는 해당 규칙을 적용하지 않는다는 의미이다.
  • (+) 옵션을 사용하면 예를 들어 -i eth+ 를 주게 되면 eht0,eht1,eth… 에 해당하는 모든 인터페이스에 해당 규칙을 적용한다.
  • 인터페이스를 특정하지 않으면 모든 인터페이스가 영향을 받는다.

-j : 패킷이 특정 규칙에 일치할 경우 특정 타겟으로 건너뛴다.

  • -j 옵션 다음에 사용할 유효한 타겟은 표준 옵션 (ACCEPT, DROP, QUEUE 및 RETURN)뿐만 아니라 LOG, MARK와 같은 Red Hat Enterprise Linux iptables RPM 패키지에서 기본적으로로드되는 모듈을 통해 사용할 수있는 확장 옵션이 있고 REJECT 등의 옵션을 사용 가능하다.
  • 규칙에 일치한 패킷은 사용자 정의 체인으로 전달하여 다른 규칙을 적용할 수도 있다.
  • 타겟이 정해지지 않으면 패킷은 어떤 처리 없이 규칙을 지나간다. 그러나 이 규칙의 카운터는 1 증가한다.

-o : 나가는 인터페이스를 설정한다. filter 테이블의 OUTPUT, FORWARD 체인과 nat, mangle 테이블의 POSTROUTING 체인과 함께 사용할 때 사용가능하다.

  • 옵션은 -i 와 동일하다.

-p : icmp, tcp, udp 또는 all 일 수있는 규칙에 대한 IP 프로토콜을 지원되는 모든 프로토콜과 일치하도록 설정한다. 또한 /etc/protocols 에 나열된 프로토콜을 사용할 수도 있다 규칙을 만들 때이 옵션을 생략하면 all 옵션이 기본값이다.(초기 리눅스세팅 all)

-s : -d 와 동일한 구문을 사용하여 특정 패킷의 소스를 설정한다.


iptables Match Options

Match option 들은 각각의 프로토콜 별로 제공된다. 그래서 iptables 에서 먼저 사용할 프로토콜을 지정해줘야한다.

위의 Parameter options 에 있는 -p 파라미터가 iptables 에게 해당 프로토콜을 사용하겠다는 파라미터이다.

tcp 를 사용할 경우는 -p tcp, udp 를 사용할 경우는 -p udp 와 같다.

  1. TCP Match Options
    • --dport : 패킷의 목적지 포트를 설정한다. 이 옵션은 네트워크 서비스 이름( 예를들어 www, smtp), 포트 번호, 포트 번호 범위를 사용하여 구성한다. 네트워크 서비스들의 이름 혹은 별칭 그리고 그것들이 사용하는 포트 번호는 /etc/services 파일에서 볼 수 있다. --destination-port-dport 는 동일하다. 포트 번호의 범위를 지정할 때는 두 번호를 : 으로 분리한다. 예를 들어서 -p tcp --dport 3000:3200 와 같이 사용 가능하며 최대 유효 범위는 0:65535이다. --dport ! 와 같이 느낌표 문자를 사용할 경우에는 해당 네트워크 서비스 또는 포트를 사용하지 않는 모든 패킷이 해당한다.
    • --sport : 패킷의 출발지 포트를 설정한다. 나머지 옵션은 --dport 와 동일하다.
    • --syn : 모든 TCP 패킷(SYN 패킷을 이용하여 통신을 시작하는)에 적용된다. 단 데이터 페이로드를 전달하는 패킷은 영향을 받지 않는다. 옵션 다음에 ! 를 사용하면 SYN 을 제외한 모든 패킷이 해당한다.
    • --tcp-flags : 규칙에 부합하는 특정 비트들, 기호들에 해당하는 패킷을 허용한다. 두개의 파라미터를 받는데 첫번째는 검사할 플래그를 설정하는 마스크, 두번째는 일치해야할 플래그이다. 예를 들어서 -p tcp --tcp-flags ACK,FIN,SYN SYN 이 있다면 SYN 플래그가 set 되고 나머지 ACK,FIN 플래그는 셋되지 않은 TCP 패킷만이 일치한다. ! 를 사용하게 되면 해당 규칙이 반전된다. 사용 가능한 플래그는 ACK, FIN, PSH, RST, SYN, URG, ALL, NONE 이 있다.
    • --tcp-option : 특정 패킷 내에서 설정할 수 있는 TCP 관련 옵션과 일치시키려고 시도한다. ! 를 이용하여 반전될 수 있다.
  2. UDP Match Options
    • --dport : TCP 옵션과 동일하다. 단 UDP 패킷에 대해서 적용된다.
    • --sport : TCP 옵션과 동일하다. 단 UDP 패킷에 대해서 적용된다.
  3. ICMP Match Options
    • --icmp-type : 규칙과 일치하도록 ICMP 타입의 이름 혹은 번호를 설정한다. 유효한 ICMP 리스트는 iptables -p icmp -h 검색할 수 있다.
  4. 추가 옵션 모듈들

추가 옵션 모듈들은 iptables 명령어로 로드할 수 있는 것들이다. 모듈을 로드할 때는 -m 모듈이름으로 사용할 수 있다. 보통 자주 사용되는 모듈들은 아래와 같다.

  • limit 모듈

    규칙에 일치하는 패킷을 제한할 수 있다. 시스템 로그 같은것이 넘쳐서 시스템 자원을 사용 못하는 경우등을 막을 때 유용하다.

    • --limit : 시간 범위 내의 예를 들어서 --limit 5/hour 와같은 포맷으로 규칙이 일치하는 제한 숫자를 설정한다. 앞은 숫자 뒤는 시간 정의자이며 이를 사용하지 않을 시 기본값은 3/hour 이다.
    • --limit-burst : 하나의 룰에 한번씩 일치 할 수 있는 패킷의 제한을 숫자로 설정한다. 이 옵션을 --limit 와 같이 사용하여야 하며 버스트 임계값을 설정한다. 숫자를 입력하지 않으면 기본적으로 5개의 패킷만 규칙에 일치 할 수 있다.
  • state 모듈

    패킷의 커넥션 상태에 따라 규칙을 적용할 때 사용한다.

    state 들은 , 로 구분하여 조합하여 사용할 수 있다. 예를 들어서 -m state --state INVALID,NEW와 같이 사용가능하다.

    • --state : 아래 커넥션 상태들에따라 패킷을 일치시킨다.

      • ESTABLISHED : 일치하는 패킷은 설정된 커넥션의 다른 패킷과 연관된다.
      • INVALID : 일치하는 패킷을 알려진 커넥션에 연결할 수 없다.
      • NEW : 일치하는 패킷이 새 연결을 만들거나 이전에 표시되지않은 양방향 연결의 일부이다.
      • RELATED : 일치하는 패킷은 기존 연결과 관련된 새로운 커넥션을 시작한다.
  • mac 모듈

    하드웨어 MAC 주소에 따라 규칙을 적용한다.

    • --mac-source : 패킷을 보낸 네트워크 인터페이스 카드의 맥주소에 따라 적용한다. 규칙에서 맥주소를 제외하려면 맥주소 뒤에 ! 를 넣어준다.

iptables Target Options

패킷이 특정 규칙과 일치하면 규칙은 해당 패킷을 허용할지 드랍할지등의 결정을 하고 가능하면 추가 작업을 수행하는 여러 대상으로 지시 할 수 있다.

각 체인에는 해당 체인의 규칙이 패킷과 일치하지 않거나 해당 패킷과 일치하는 규칙 중 대상을 지정하지 않은 경우에 사용되는 기본 대상이 있다.

아래는 표준 타겟 리스트이다.

  • user-defined-chain : 테이블내의 사용자 정의 체인이름을 입력하게 되면 패킷을 사용자 정의 체인으로 전달한다.
  • ACCEPT : 패킷이 대상 또는 다른체인으로 성공적으로 이동하도록 허용한다.
  • DROP : 패킷을 보낸 요청자에게 응답하지 않고 패킷을 드랍한다. 패킷을 보낸 시스템에는 오류등 이유가 통보되지 않는다.
  • QUEUE : 패킷이 사용자 공간 응용프로그램의 처리를 대기한다.
  • RETURN : 현제 체인의 규칙에 대해 패킷 검사를 중단한다. RETURN 대상이있는 패킷이 다른 체인에서 호출 된 체인의 규칙과 일치하면 첫 번째 체인으로 패킷이 반환되어 중단 된 규칙 검사를 다시 시작한다. RETURN 규칙이 내장 체인에서 사용되고 패킷이 이전 체인으로 이동할 수없는 경우 현재 체인의 기본 대상이 수행 할 작업을 결정한다.

표준 타깃 이외에도 다양한 확장 타깃 모듈과 사용가능하다.

레드햇 엔터프라이즈 리눅스에 내장되있는 많은 사용자가 사용하는 몇가지 모듈은 다음과 같다.

  • LOG : 규칙에 맞는 모든 패킷을 로깅한다. 패킷은 커널에 의해 로그되므로 /etc/syslog.conf 파일이 로그가 기록되는 위치를 지정한다. 기본적으로 /var/log/messages 파일에 기록된다.

로깅이 발생하는 방식을 지정하기 위해 LOG 대상 다음에 추가 옵션을 사용할 수 있다.

  • --log-level : 로깅 이벤트의 우선 순위 수준을 설정한다. 우선 순위 수준 목록은 syslog.conf 메뉴얼 페이지에서 찾을 수 있다.
  • --log-ip-options : IP 패킷의 헤더에 설정된 options 를 기록한다.
  • --log-prefix : 기록 될 때 로그 행 앞에 최대 29 자의 문자열을 넣는다. 이것은 패킷 로깅과 함께 사용할 syslog 필터를 작성하는 데 유용하다.
  • --log-tcp-options : TCP 패킷의 헤더에 설정된 options 를 기록한다.
  • --log-tcp-sequence : 패킷에 대한 TCP 시퀀스 번호를 기록한다.

  • REJECT : 요청자 혹은 원격 시스템에 오류 패킷을 보내고 해당 패킷은 삭제한다. REJECT 는 --reject-with 오류타입 을 같이 사용할 수 있는데 거절된 자세한 내용이 오류타입에 들어가게된다. 미설정시 기본적으로 port-unreachable 메시지가 날라간다.

nat 테이블을 사용하여 IP masquerading 하거나 mangle 테이블을 사용하여 패킷을 변경하는 데 유용한 여러 가지 대상 확장은 iptables 매뉴얼 페이지에서 찾을 수 있다.

대략 여기까지가 기본적인 옵션 및 명령어 작성에 대한 내용이었다.

이제 DNAT, Masquerade 등 추가적인 내용은 docker 및 firewall 설정하면서 업데이트 해야겠다.

다음번 포스팅은 실제 라즈베리 파이에 docker 이미지로 mongodb 설치한 내용과 docker 컨테이너 포트 설정 및 방화벽 설정을 작업하는 내용을 정리한다.

할게 많아서 좋긴한데 ㅎㅎ 그냥 DbaaS 사용했으면 서비스 개발은 진즉 끝났지 싶다.

ㅋㅋㅋㅋㅋ ㅜ.ㅜ