Linux를 사용하다보면 80포트와 같이 자주 사용되면서 일반사용자는 포트허용이 불가능하게 막혀있는 Well-Known-Ports 라는 것이

시스템에서 정의 되어 있습니다. 간단한 예제로 보자면 많이 사용되는 WAS 중 Tomcat 이라는 프로그램을 설치했을때 일반사용자로

실행하여 8080 포트가 아닌 80 포트로 통신을 하기위해 설정을 하면 허가 거부에 대한 메세지 출력과 함께 포트가 열리지 않겠되죠.

 

이러한 Well-Known-Ports 라는 것을 리눅스는 여러가지 방법을 제공하는데요. 아래와 같이 정의해드립니다. (더 많은 방법이 있어요.)

1. 실행 스크립트 SetUid 적용

-> 가장 쉬운 설정방법이지만 보안상의 이유로 추천하지 않습니다.

2. IPTables 를 활용한 포트 바인딩

-> 쉬운 설정방법이지만 네트웍 망분리 작업을 한 회사내 시스템에는 추천하지 않습니다.

3. capabilities 설정으로 포트개방 허용정책 설정

-> 어려운 방법이지만 보안상 가장 안전하다고 볼 수 있습니다.

 

위 안내해드린 3가지의 방법을 차근히 적용할 수 있게 Fallow ME~!!

 

방법1. 실행 스크립트 SetUid 적용

누구나 아는 방법일거라 생각하고 간략하게만 설명해드립니다. 권한설정 명령어인 chown/chmod 를 이용합니다.

   - #chown root.[UserGroup] 실행파일

-> 실행파일의 소유권을 root 로 설정하여 권한을 위임받도록합니다. UserGroup 부분은 실행하고자 하는 User 가 속한 그룹을 지정하여

    입력하시면 되지만 입력하지 않는 경우는 중간 구분 기호인 "."도 사용하지 않습니다.


   - #chmod 4775 실행파일

-> 실행파일에 SetUid 를 적용하는 부분인데. 퍼미션이 775 입니다. 이유는 그룹에 대한 사용자도 쓰기권한이 있어야 실행하려는 유저가

    해당 파일의 수정이 가능하기 때문에 SetUid 설정 퍼미션 4000과 함께 사용합니다.

 

 

방법2. IPTables 를 활용한 포트 바인딩

리눅스 사용하시면서 IPTables 를 모르시는건 아니겠죠? 방법2 또한 간략하게만 설명드립니다.

   - #iptables -t nat -A PREROUTING -i {네트웍장치} -p tcp --dport {목적포트} -j REDIRECT --to-ports {원본포트}

-> 정책을 추가하는 명령어로 Tomcat 서비스의 8080 포트를 80으로 적용하는 예제를 함께 넣어드립니다.

ex) #iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-ports 8080

 

 

방법3. capabilities 설정으로 포트개방 허용정책 설정

capabilities 설정은 setcap 명령으로 설정하고, getcap 명령으로 확인을 할 수 있습니다.

또한 해당 설정을 하기 위해 커널은 2.6.24이상 가능하며, 필요한 패키지는 "libcap" Ver 2.X.X (ubuntu/Debian:libcap2-bin) 입니다.

패키지부터 모두 설치하시고 진행하시기 바라며, 아래의 내용은 패키지 설치가 완료되었다는 전제로 진행합니다.

 

우선 적용해야 하는 옵션을 알아보기 위해 "man capabilities" 를 열람합니다.

==========================================================================================================

[중략] 
CAP_NET_BIND_SERVICE
        Bind a socket to Internet domain privileged ports (port numbers less than 1024).
[중략]

==========================================================================================================

위 내용을 보시면 알겠지만, CAP_NET_BIND_SERVICE 옵션이 1024 미만의 포트 허용정책을 줄 수 있습니다.

 

먼저 명령어들의 형식을 알아봅시다.

ㄱ. setcap

Usage : setcap [-q] [-v] (-r|-|<caps>) <filename>

※ 유의사항 : 심볼링 링크는 적용할 수 없다.

 

<caps> => "CapOption=[+-=Values]"

 

Capability Sets Values

  - Permitted(p) : 허용정책

  - Inheritable(i) : execve 시 권한 상속

  - Effective(e) : 효력

 

설정 ex) # setcap 'cap_net_bind_service=+eip' /usr/bin/nc

※ nc 명령은 TCP/UDP 임의 포트를 열어줄 때 사용하는 명령으로써 테스트용도로 적용함.

※ capabilities 항목의 'cap_net_bind_service' 는 대/소문자 구별이 없고, Values 는 소문자만 사용가능

    연산자는 추가(+), 삭제(-), 동일(=)로 chmod 와 동일하다.

 

해제 ex) # setcap -r /usr/bin/nc

 

ㄴ. getcap

Usage : getcap [-r] [-v] [-h] <filename>

 

Option

  - r : 재귀 검색을 할 수 있음.

  - v : 모든 정보를 출력

  - h : help 출력

 

ex) # getcap /usr/bin/nc

/usr/bin/nc = cap_net_bind_service+eip

※설정된 값이 있으면 위 처럼 출력되고, 설정된 값이 없으면 아무내용이 출력되지 않는다.


다음은 999포트를 오픈한 예이다. 일반 유저로 실행된 것을 확인할 수 있다.

 
 [ 일반 유저가 999포트 바인딩 ]
 $ nc -l 999 (데비안 또는 우분투에서는 nc -l -p 999)

 [ root로 확인 ]
 # netstat -anp
 Active Internet connections (servers and established)
 Proto Recv-Q Send-Q Local Address     Foreign Address     State      PID/Program name
 tcp        0      0 0.0.0.0:999       0.0.0.0:*           LISTEN     18021/nc        <--- 999포트를 18021 PID가
... 생략 ...
 # ps auxww|grep "[n]c "
 coffeenix 18021  0.0  0.0   1728   612 pts/15   S+   18:59   0:00 nc -l 999 <--- 18021 PID 실행유저는 coffeenix
  

 

4. Linux에서 capabilities 좀 더 알기

1) PAM 모듈

pam_cap.so PAM 모듈도 제공하므로, 로긴을 하거나 su 이용시 '유저별'로 다른 권한을 부여할 수 있다. /etc/security/capability.conf 에 capabilities를 설정한다.
CentOS에서 libcap2 소스를 가져다 PAM 모듈을 설치할 경우 먼저 pam-devel 패키지가 설치되어 있어야 한다.

2) 프로세스의 capabilities set 상태 확인

capabilities의 Effective/Inheritable/Permitted set(집합)은 각각 32bit로 이뤄져 있다. 그리고, 각 bit별로 어떤 권한(자격)을 갖는지 지정되어 있다. CAP_NET_BIND_SERVICE 은 11번째 bit(0100 0000 0000 => hex 0400)에 해당한다. 나머지 권한들이 몇 번째 bit인지는 /usr/include/linux/capability.h에 자세히 나와있으니 생략한다.

프로세스의 capabilities set 상태 확인해보자. setcap으로 설정해둔 프로그램을 실행한다. 그리고 해당 프로세스의 PID를 확인한다. cat /proc//status|grep Cap 명령으로 bitmap 결과를 확인할 수 있다.


 
 # cat /proc/26494/status|grep cap
 CapInh:   0000000000000000         <-- Inheritable capabilities
 CapPrm:   0000000000000400         <-- Effective   capabilities (Hex 0400. 즉, CAP_NET_BIND_SERVICE이 set되었음을 확인할수 있다.)
CapEff:   0000000000000400         <-- Permitted   capabilities (Hex 0400)
 CapBnd:   ffffffffffffffff

AND