[linux] 루트가 아닌 프로세스가 Linux의 “권한있는”포트에 바인딩 할 수있는 방법이 있습니까?

저 외에 다른 사용자가 없을 때 개발 상자 에이 제한이 있다는 것은 매우 성가신 일입니다.

표준 해결 방법을 알고 있지만 아무도 내가 원하는 것을 정확하게 수행하지 않습니다.

  1. authbind (데비안 테스트 버전 1.0, IPv4 만 지원)
  2. iptables REDIRECT 대상을 사용하여 낮은 포트를 높은 포트로 재 지정합니다 ( “nat”테이블은 iptables의 IPv6 버전 인 ip6tables에 대해 아직 구현되지 않았습니다)
  3. sudo (루트로 실행하는 것은 피하려고하는 것입니다)
  4. SELinux (또는 유사) (이것은 단지 내 dev 상자입니다. 많은 추가 복잡성을 도입하고 싶지 않습니다.)

sysctl루트가 아닌 프로세스가 Linux에서 “권한이있는”포트 (1024보다 작은 포트)에 바인딩 할 수 있는 간단한 변수가 있습니까?

편집 : 경우에 따라 기능사용 하여이 작업을 수행 할 수 있습니다 .



답변

기능 시스템과 CAP_NET_BIND_SERVICE기능 을 지적한 사람들 덕분 입니다. 최근 커널이 있다면, 이것을 루트를 사용하지 않고 낮은 포트를 바인딩하는 서비스로 시작하는 것이 가능합니다. 짧은 대답은 당신이하는 것입니다 :

setcap 'cap_net_bind_service=+ep' /path/to/program

그런 다음 언제든지 program실행될 수 CAP_NET_BIND_SERVICE있습니다. setcap데비안 패키지에 libcap2-bin있습니다.

이제주의 사항 :

  1. 최소한 2.6.24 커널이 필요합니다
  2. 파일이 스크립트 인 경우 작동하지 않습니다. (즉, #! 행을 사용하여 인터프리터를 시작하십시오). 이 경우 이해하는 한 해석기 실행 기능 자체에 기능을 적용해야합니다. 통역사를 사용하는 모든 프로그램에는 기능이 있기 때문에 보안 악몽입니다. 이 문제를 해결할 수있는 깨끗하고 쉬운 방법을 찾을 수 없었습니다.
  3. Linux는 또는 program과 같은 상승 된 권한이 있는 모든 LD_LIBRARY_PATH를 비활성화 합니다. 따라서 자체를 사용하는 경우 포트 전달과 같은 다른 옵션을 조사해야 할 수도 있습니다.setcapsuidprogram.../lib/

자원:

참고 : RHEL은 먼저 이것을 v6에 추가했습니다 .


답변

포트 리디렉션을 수행 할 수 있습니다. 이것이 Linux 상자에서 실행되는 Silverlight 정책 서버에 수행하는 작업입니다.

iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300


답변

표준 방법은 루트로 시작하도록 “setuid”로 설정 한 다음 포트에 바인딩 되 자마자 연결을 수락하기 전에 루트 권한을 버리는 것입니다. Apache와 INN의 소스 코드에서 그 좋은 예를 볼 수 있습니다. Lighttpd가 또 다른 좋은 예라고 들었습니다.

또 다른 예는 파이프를 통해 통신하는 여러 데몬을 사용하는 Postfix이며, 그 중 하나 또는 두 개 (바이트 허용 또는 방출 제외)는 루트로 실행되고 나머지는 낮은 권한으로 실행됩니다.


답변

또는 커널을 패치하고 검사를 제거하십시오.

(마지막 수단 옵션, 권장하지 않음).

에서 net/ipv4/af_inet.c읽은 두 줄을 제거하십시오.

      if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
              goto out;

커널은 더 이상 권한있는 포트를 확인하지 않습니다.


답변

예를 들어 포트 80이 앱에 3000으로 바인딩되도록 로컬 SSH 터널을 설정할 수 있습니다.

sudo ssh $USERNAME@localhost -L 80:localhost:3000 -N

이는 스크립트 서버 작업과 매우 간단하다는 이점이 있습니다.


답변

2017 년 업데이트 :

authbind 사용

CAP_NET_BIND_SERVICE 또는 사용자 정의 커널보다 훨씬 낫습니다.

  • CAP_NET_BIND_SERVICE는 바이너리에 트러스트를 부여하지만 포트 별 액세스를 제어하지는 않습니다.
  • Authbind는 사용자 / 그룹에 신뢰를 부여하고 포트 별 액세스를 제어하며 IPv4 및 IPv6을 모두 지원합니다 (IPv6 지원은 최근 추가됨).

    1. 설치: apt-get install authbind

    2. 모든 사용자 및 그룹에 대한 관련 포트 (예 : 80 및 443)에 대한 액세스를 구성하십시오.

      sudo touch / etc / authbind / byport / 80
      sudo touch / etc / authbind / byport / 443
      sudo chmod 777 / etc / authbind / byport / 80
      sudo chmod 777 / etc / authbind / byport / 443

    3. 다음을 통해 명령을 실행하십시오 authbind
      (선택적 --deep또는 다른 인수, 매뉴얼 페이지 참조).

      authbind --deep /path/to/binary command line args
      

      예 :

      authbind --deep java -jar SomeServer.jar
      

커널 해킹에 대한 Joshua의 멋진 추천 (= 당신이하는 일을 알지 못한다면 권장하지 않음) :

먼저 여기에 게시했습니다 .

단순한. 정상적인 커널이나 오래된 커널로는 그렇지 않습니다.
다른 사람들이 지적했듯이 iptables는 포트를 전달할 수 있습니다.
다른 사람들이 지적한 것처럼 CAP_NET_BIND_SERVICE도 작업을 수행 할 수 있습니다.
물론 CAP_NET_BIND_SERVICE는 스크립트에서 프로그램을 시작하면 실패합니다. 쉘 인터프리터에 제한을 설정하지 않으면 서비스를 루트로 실행할 수 있습니다.
예를 들어 Java의 경우이를 적용해야합니다. 자바 JVM으로

sudo /sbin/setcap 'cap_net_bind_service=ep' /usr/lib/jvm/java-8-openjdk/jre/bin/java

분명히 이것은 모든 Java 프로그램이 시스템 포트를 바인딩 할 수 있음을 의미합니다.
모노 /.NET 용 Dito

또한 xinetd가 최고의 아이디어는 아니라고 확신합니다.
그러나 두 방법 모두 해킹이므로 제한을 해제하여 한계를 높이 지 않는 이유는 무엇입니까?
아무도 당신이 정상적인 커널을 실행해야한다고 말하지 않았으므로, 당신은 당신 자신을 실행할 수 있습니다.

최신 커널 (또는 현재 가지고있는 커널)의 소스를 다운로드하기 만하면됩니다. 이후에 다음으로 이동합니다.

/usr/src/linux-<version_number>/include/net/sock.h:

이 라인을 찾으십시오

/* Sockets 0-1023 can't be bound to unless you are superuser */
#define PROT_SOCK       1024

로 변경

#define PROT_SOCK 0

안전하지 않은 ssh 상황을 원하지 않으면 다음과 같이 변경하십시오. #define PROT_SOCK 24

일반적으로 http의 경우 79, 포트 25에서 SMTP를 사용할 때 24와 같이 필요한 가장 낮은 설정을 사용합니다.

그게 다야
커널을 컴파일하고 설치하십시오.
재부팅하십시오.
완료-바보 같은 한계는 사라졌고 스크립트에서도 작동합니다.

커널을 컴파일하는 방법은 다음과 같습니다.

https://help.ubuntu.com/community/Kernel/Compile

# You can get the kernel-source via package linux-source, no manual download required
apt-get install linux-source fakeroot

mkdir ~/src
cd ~/src
tar xjvf /usr/src/linux-source-<version>.tar.bz2
cd linux-source-<version>

# Apply the changes to PROT_SOCK define in /include/net/sock.h

# Copy the kernel config file you are currently using
cp -vi /boot/config-`uname -r` .config

# Install ncurses libary, if you want to run menuconfig
apt-get install libncurses5 libncurses5-dev

# Run menuconfig (optional)
make menuconfig

# Define the number of threads you wanna use when compiling (should be <number CPU cores> - 1), e.g. for quad-core
export CONCURRENCY_LEVEL=3
# Now compile the custom kernel
fakeroot make-kpkg --initrd --append-to-version=custom kernel-image kernel-headers

# And wait a long long time

cd ..

간단히 말해서, 보안을 유지하려면 iptables를 사용하고,이 제한이 다시는 귀찮게하지 않도록하려면 커널을 컴파일하십시오.


답변

파일 기능은 패키지 업데이트 후 중단 될 수 있으므로 이상적이지 않습니다.

이상적인 솔루션 IMHO는 상속 가능한 CAP_NET_BIND_SERVICE집합 으로 셸을 만드는 기능이어야합니다 .

이 작업을 수행하는 다소 복잡한 방법이 있습니다.

sg $DAEMONUSER "capsh --keep=1 --uid=`id -u $DAEMONUSER` \
     --caps='cap_net_bind_service+pei' -- \
     YOUR_COMMAND_GOES_HERE"

capsh이 유틸리티는 데비안 / 우분투 배포판의 libcap2-bin 패키지에 있습니다. 진행중인 작업은 다음과 같습니다.

  • sg유효 그룹 ID를 데몬 사용자의 유효 그룹 ID로 변경합니다. 이것은 capshGID를 변경하지 않고 그대로두고 필요하지 않기 때문에 필요 합니다.
  • 비트 ‘UID 변경시 기능 유지’를 설정합니다.
  • UID를 다음으로 변경 $DAEMONUSER
  • --keep=1상속 가능한 것을 제외하고 모든 캡을 삭제합니다 (이 시점에서 모든 캡은 여전히 ​​존재하므로 ).cap_net_bind_service
  • 명령을 실행합니다 ( ‘-‘은 구분 기호입니다)

결과는 지정된 사용자 및 그룹과 cap_net_bind_service권한을 가진 프로세스입니다 .

예를 들어 ejabberd시작 스크립트 의 줄은 다음과 같습니다.

sg $EJABBERDUSER "capsh --keep=1 --uid=`id -u $EJABBERDUSER` --caps='cap_net_bind_service+pei' -- $EJABBERD --noshell -detached"