커피닉스, 시스템 엔지니어의 쉼터 커피향이 나는 *NIX
커피닉스
시스템/네트웍/보안을 다루는 곳
* HanIRC의 #coffeenix 방
[ 장비 및 회선 후원 ]
HOME > 네트워크(network) 도움말
검색 : 사이트 WHOIS 웹서버 종류

TCP/IP, 프로토콜, 포트 (11, 글 2, 자료 25)
인터넷 접속 (1, 글 3)
웹 서버(web, httpd, apache) (48, 글 42, 자료 31)
메일 서버(mail) (31, 글 42, 자료 23)
네임서버(name server, dns, bind) (15, 글 18, 자료 4)
FTP 서버 / rsync / 미러링 / CVSup (12, 글 13, 자료 9)
망관리 / SNMP / QoS (13, 자료 16)
삼바 (samba) (4, 글 1, 자료 5)
프락시 서버(프록시, proxy server) (6, 글 3, 자료 2)
네트워크 툴 (15, 글 1, 자료 11)
클러스터링(cluster) (6, 자료 1)
장비 / 라우터 / 스위칭 (8, 글 3, 자료 8)
IRC (Internet Relay Chat) / 메신저 (6)
ssh / telnet (10, 글 3, 자료 2)
NFS / SHFS (5, 자료 2)
VPN 서버, FreeS/WAN (4)
DHCP (1, 자료 1)
LDAP (3, 자료 1)
SAN / NAS / 스토리지 (4, 글 2, 자료 6)
음악방송 / icecast (3, 글 1)

  일반유저가 1024이하 포트를 사용하려면 작성일 : 2010/11/11 20:54
 
  • 글쓴이 : 좋은진호 ( http://coffeenix.net/ )
  • 조회수 : 8079
          [ 이전화면 / 수정 ]   비밀번호 :     인쇄용 화면
      제  목 : 일반유저가 1024이하 포트를 사용하려면
    작성자 : 좋은진호(truefeel, http://coffeenix.net/ )
    작성일 : 2010.10.26(화)


    리눅스/유닉스 기본 환경에서는 1024 이하 포트(privileged ports)는 root만 사용할 수가 있다. OS별로 각각 다음 기능을 사용하면 일반유저가 1024이하 포트를 사용할 수 있다.

    1) FreeBSD : MAC 인증 매커니즘 (FreeBSD 5.x 이상)
    2) Linux   : capabilities 설정 (File capabilities를 설정하기 위해서는 커널 2.6.24 이상)
    3) Solaris : RBAC로 권한 부여  (Solaris 8 이상)


    1. FreeBSD에서 MAC 모듈 로딩



    FreeBSD에서는 커널의 MAC(Mandatory Access Control) 인증 매커니즘을 사용하면 일반유저가 1024이하 포트 bind를 쉽게 처리할 수 있다. 먼저 MAC portacl 모듈을 로딩한다.

     
    # kldload mac_portacl
    # kldstat
    Id Refs Address    Size     Name
    1    4 0xc0400000 b7ffe8   kernel
    2    1 0xca62f000 3000     mac_portacl.ko
     


    부팅때 자동으로 로딩되도록 /boot/loader.conf에 mac_portacl_load="YES" 를 추가한다. 모듈 로딩시 syslog에는 다음과 같은 로그가 남는다.

     
    Oct 22 14:04:29 ?????? kernel: Security policy loaded: TrustedBSD MAC/portacl (mac_portacl)
     


    만약 모듈 로딩시 다음과 같은 에러가 생겼다면 커널에서 MAC 모듈을 지원하지 않는 경우이다.

     
    # kldload mac_portacl
    kldload: can't load mac_portacl: No such file or directory
     


    이 때 /var/log/messages 에는 다음과 같이 로그가 남는다.

     
    Oct 22 13:17:26 ?????? kernel: KLD mac_portacl.ko: depends on kernel_mac_support - not available
     


    커널 설정 파일에 다음을 추가하고 재컴파일한다. FreeBSD 8.x부터는 기본 포함되어 있다.

     
    options         MAC
     


    sysctl로 관련 속성들을 살펴보자.

     
    # sysctl security.mac
    security.mac.labeled: 0
    security.mac.max_slots: 4
    security.mac.version: 4
    security.mac.mmap_revocation_via_cow: 0
    security.mac.mmap_revocation: 1
    security.mac.portacl.rules:                    <-- 여기서 부터 모듈 로딩 후 추가된 설정
    security.mac.portacl.port_high: 1023
    security.mac.portacl.autoport_exempt: 1
    security.mac.portacl.suser_exempt: 1
    security.mac.portacl.enabled: 1
     



    2. FreeBSD에서 일반유저가 1024이 bind하는 예

    999포트를 uid 1005가 실행할 수 있도록 해보자.

     
    # sysctl security.mac.portacl.rules=uid:1005:tcp:999
    security.mac.portacl.rules:  -> uid:1005:tcp:999

    [ UID 1005 일반 유저로 실행 ]
    % nc -l 999 (테스트를 위해 nc명령을 사용했다. CentOS는 동일한 옵션이고, 데비안 또는 우분투는 nc -l -p 999)
    nc: Operation not permitted
     


    그런데, 권한이 없다고 한다. 그렇다. 기존의 유닉스 bind 제한 설정을 해제해야 한다. reserved port 최대치를 0으로 바꾸거나 998(999포트를 일반 유저가 오픈할 것이므로 998임)로 바꾼다. 998로 설정했다면, 998까지는 기존의 유닉스 bind 제한 설정을 따르겠다는 것이다.

     
    # sysctl net.inet.ip.portrange.reservedhigh
    net.inet.ip.portrange.reservedhigh: 1023
    # sysctl net.inet.ip.portrange.reservedhigh=998
    net.inet.ip.portrange.reservedhigh: 1023 -> 998
     


    만약 UID 1005가 999포트와 1000포트를 모두 사용할 수 있게 하려면 다음과 같이 설정한다.
     
    # sysctl security.mac.portacl.rules=uid:1005:tcp:999,uid:1005:tcp:1000
     



    3. Linux에서 setcap 명령으로 capabilities 설정



    리눅스의 capabilities 설정을 통해서 일반 유저가 1024이하 포트 사용이 가능하다. capabilities란 무엇일까? 전통적인 유닉스/리눅스에서는 root가 모든 권한을 가진다. 일반유저가 root의 일부 권한을 갖기 위해서는 SetUID/SetGID나 sudo 등 기초적인 방법으로 권한을 부여할 수 밖에 없었다. 하지만 capabilities는 root의 권한을 세분화(커널 모듈 load/remove, 파일 소유자/소유그룹 변경, kill권한, ping 허용(ICMP허용), 리부팅 등)하여, 일반 유저도 root의 다양한 권한을 갖도록 만든 보안 모델이다. 일반 유저에게 패킷 모니터링툴을 사용할 수 있도록 허용할 수 있다. PAM 모듈을 사용하면 user를 지정하여 권한 부여도 할 수 있다.

    capabilities은 커널에서 지원해야 하며, File capabilities를 위해서는 2.6.24이상을 사용하면 된다. 설정은 setcap, getcap 명령을 사용한다.

    capabilities 맨페이지를 보면, CAP_NET_BIND_SERVICE이 1024이하 포트(privileged ports)에 대해 권한 부여 역할을 한다.

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


    1) capabilities 설정을 위해 libcap2가 패키지가 필요하다.
       ① 데비안/우분투는 libcap2-bin 패키지(setcap, getcap 등의 명령을 갖고 있음)를 설치한다.
       ② CentOS는 http://www.kernel.org/pub/linux/libs/security/linux-privs/libcap2/ 에서 소스를 받는다.
          이 소스 컴파일을 위해서는 libattr-devel 패키지가 설치되어 있어야 한다.
    2) setcap명령으로 CAP_NET_BIND_SERVICE를 1024이하 포트를 사용할 파일명에 설정을 해주면 된다. 심볼릭 링크 파일은 지정할 수가 없다.
    3) 설정을 확인하려면 getcap을, 그리고 설정을 다시 빼려면 -r 옵션을 사용하면 된다.

     
    [ 명령 형식 ] setcap capability1[,capability2][=-+][value] <filename>
    # setcap 'cap_net_bind_service=+ep' /usr/bin/nc (테스트를 위해 nc명령을 사용했다.)
    # getcap /usr/bin/nc
    /usr/bin/nc = cap_net_bind_service+ep
    #
    # setcap -r /usr/bin/nc (설정 빼기)
    # getcap /usr/bin/nc
    #
     


    capabilities 이름인 cap_net_bind_service은 대소문자 구별이 없지만, set 해당하는 ep는 소문자만 사용해야 한다.
    연산자는 +, -, = 3가지로, chmod의 연산자와 동일한 의미를 갖는다. 각각 추가(+), 삭제(-), 지정한 권한으로 동일(=)하게 변경한다.
    file capabilities set에는 다음 3가지가 있다.

    - e : effective   -> 효력부여
    - p : Permitted   -> 허용
    - i : Inheritable -> exec 할 때 권한 상속 여부

    capabilities manpage에서 각 set에 대한 자세한 설명있다. 파일에 cap_net_bind_service 권한을 부여하려면 ep 또는 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
     



    5. Solaris에서 RBAC로 권한 부여



    전통적인 유닉스 시스템에서는 root가 모든 권한을 갖는다. 그러나 이 root의 권한 일부를 다른 유저에게 할당하는 것이 쉽지 않았다.
    RBAC(Role Based Access Control, 롤 기반  접근 제어)는 root가 갖는 권한 중 일부를 묶은 후, 그 권한 묶음을 유저에게 부여할 수가 있는 보안모델이다. 권한의 묶음을 '롤(Role)'이라는 부른다.

    ① 롤을 생성(roleadd)하고, (roleadd)
    ② 그 롤이 어떤 권한을 갖는 롤인지를 정의를 한다. (roleadd, rolemod)
    ③ 그리고, 그 롤에 속하는 유저를 설정하면 된다. (usermod)

    이런 롤 기반 접근 제어는 업무 역할별로 권한 묶음을 만들어 유저에게 권한을 분산할 수가 있다. 예를 들어, 파일시스템 mount를 할 수 있는 권한을 'disk'라는 롤명(롤명은 ID처럼 임의로 만들면 됨)으로 만들었다고 하자. 그리고 이 롤에 유저를 할당하면 해당 유저는 mount 권한을 부여받게 된다.

    자세한 권한 목록은 privileges man page 또는 /etc/security/priv_names에서 확인할 수 있다.
    다음은 coffeenix유저가 1024이하 포트를 열수 있는 권한(권한명 : PRIV_NET_PRIVADDR)을 갖는 예이다. 롤 생성 방법으로 시도해봤지만 쉽게 되지 않아서, 롤 생성없이 유저에게 직접 권한을 부여하는 방법으로 처리를 했다. 설정 후 재로긴하면 권한을 갖는다.

     
    # usermod -K defaultpriv=basic,net_privaddr coffeenix
     


    /etc/user_attr에서 다음을 확인할 수 있다.
     
    coffeenix::::type=normal;defaultpriv=basic,net_privaddr
     



    6. 참고자료

    * FreeBSD Handbook - 16.10 The MAC portacl Module
      http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/mac-portacl.html

    * Is there a way for non-root processes to bind to “privileged” ports (<1024) on Linux?
      http://stackoverflow.com/questions/413807/is-there-a-way-for-non-root-processes-to-bind-to-privileged-ports-1024-on-linux
    * Linux : capabilities man page
      http://www.kernel.org/doc/man-pages/online/pages/man7/capabilities.7.html
    * Linux : setcap man page
      http://manpages.ubuntu.com/manpages/lucid/man8/setcap.8.html
    * Linux Security Capabilities
      http://fpmurphy.blogspot.com/2009/05/linux-security-capabilities.html
    * [Linux] POSIX capability (한글)
      http://studyfoss.egloos.com/5338802

    * Solaris 10 Non-Root User...Port 80
      http://blogs.sun.com/tls/entry/solaris_10_non_root_user
    * Custom Roles Using RBAC in the Solaris OS
      http://www.sun.com/bigadmin/content/submitted/custom_roles_rbac.jsp
      커피닉스 카페 최근 글
    [06/22] 100 Amateur Sex Gra
    [01/26] Re: wget으로 다른서버에있는 디렉토리를 가져오려고합니다.
    [01/25] wget으로 다른서버에있는 디렉토리를 가져오려고합니다.
    [01/11] 특정 안드로이드 WebView 버전에서 SSL 문제 (WebView 버그)
    [08/01] DNS forwarder (전달자) 서버를 통해서 쿼리하면 역방향을 받아오질 못합니다.
    [05/16] (주)후이즈 시스템엔지니어 (경력자) 모집
    [02/15] [AWS] Cloudfront edge 확인하기
    [01/20] Mobile Service/eCommerce 기업에서 Server / Java / PHP 개발자 구인
    [01/11] 탄탄한 퍼블리싱 모바일기업에서 Mobile 개발자를 모십니다.
    [01/11] 탄탄한 퍼블리싱 모바일기업에서 Web Front 개발자를 모십니다.
    [01/11] 탄탄한 퍼블리싱 모바일기업에서 Server 개발 팀장을 모십니다.
    [12/21] 브라우저별 SHA1 퇴출 시점
    [09/15] [구인] 시스템엔지니어 (경력)
    [08/05] Re: 칼리리눅스 텔넷관련
    [08/04] 칼리리눅스 텔넷관련
      New!   최근에 등록한 페이지
      KiCad EDA Suite project (Free/Libre/Open-Source EDA Suite) (CAD)
      오픈캐스케이드 캐드 (OpenCASCADE CAD)
      QCad for Windows --- GNU GPL (Free Software)
      The Hello World Collection
      IPMI를 활용한 리눅스 서버관리
      DNS 설정 검사
      nagiosgraph 설치 방법
      Slony-I 설치 방법 (postgresql replication tool)
      Qmail기반의 Anti spam 시스템 구축하기
      clusterssh

    [ 함께하는 사이트 ]




    운영진 : 좋은진호(truefeel), 야수(yasu), 범냉이, sCag
    2003년 8월 4일~