루트가 아닌 프로세스가 Linux의 "권한있는"포트에 바인딩 할 수있는 방법이 있습니까?
저 외에 다른 사용자가 없을 때 개발 상자 에이 제한이 있다는 것은 매우 성가신 일입니다.
표준 해결 방법을 알고 있지만 아무도 내가 원하는 것을 정확하게 수행하지 않습니다.
- authbind (데비안 테스트 버전 1.0, IPv4 만 지원)
- iptables REDIRECT 대상을 사용하여 낮은 포트를 높은 포트로 재 지정합니다 ( "nat"테이블은 iptables의 IPv6 버전 인 ip6tables에 대해 아직 구현되지 않았습니다)
- sudo (루트로 실행하는 것은 피하려고하는 것입니다)
- 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
있습니다.
이제주의 사항 :
- 최소한 2.6.24 커널이 필요합니다
- 파일이 스크립트 인 경우 작동하지 않습니다. (즉, #! 행을 사용하여 인터프리터를 시작하십시오). 이 경우, 내가 이해하는 한, 인터프리터를 사용하는 모든 프로그램에는 기능이 있기 때문에 인터프리터 실행 파일 자체에 기능을 적용해야합니다. 물론 보안 악몽입니다. 이 문제를 해결할 깨끗하고 쉬운 방법을 찾을 수 없었습니다.
- 리눅스는 어떤에서 LD_LIBRARY_PATH를 사용할 수 없게됩니다
program
같은 권한을 상승했다고setcap
나suid
. 따라서 자신program
만을 사용하는 경우.../lib/
포트 전달과 같은 다른 옵션을 조사해야 할 수도 있습니다.
자원:
- capability (7) 매뉴얼 페이지 . 프로덕션 환경에서 기능을 사용하려는 경우이 내용을 자세히 읽어보십시오. 여기에 자세히 설명 된 exec () 호출에서 기능이 상속되는 방법에 대한 까다로운 세부 정보가 있습니다.
- setcap 맨 페이지
- "GNU / Linux의 루트없이 1024 아래 바인드 포트" 처음으로 저를 지적 문서 :
setcap
.
참고 : RHEL은 먼저 이것을 v6에 추가했습니다 .
표준 방법은 루트로 시작하도록 "setuid"로 설정 한 다음 포트에 바인딩 되 자마자 연결을 수락하기 전에 루트 권한을 버리는 것입니다. Apache와 INN의 소스 코드에서 좋은 예를 볼 수 있습니다. Lighttpd가 또 다른 좋은 예라고 들었습니다.
또 다른 예는 파이프를 통해 통신하는 여러 데몬을 사용하는 Postfix이며, 그 중 하나 또는 두 개 (바이트 허용 또는 방출 제외)는 루트로 실행되고 나머지는 낮은 권한으로 실행됩니다.
포트 리디렉션을 수행 할 수 있습니다. 이것이 Linux 상자에서 실행되는 Silverlight 정책 서버에 수행하는 작업입니다.
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 943 -j REDIRECT --to-port 1300
또는 커널을 패치하고 검사를 제거하십시오.
(마지막 수단 옵션, 권장하지 않음).
에서 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
이는 스크립트 서버 작업과 매우 간단하다는 장점이 있습니다.
파일 기능은 패키지 업데이트 후 중단 될 수 있으므로 이상적이지 않습니다.
이상적인 솔루션 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로 변경합니다. 이것은capsh
GID를 변경하지 않고 그대로두고 필요하지 않기 때문에 필요 합니다.- 비트 '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"
다른 두 가지 간단한 가능성 :
"낮은 포트에 바인딩하고 데몬을 제어하는 데몬"에 대한 오래된 (유행 할 수없는) 솔루션이 있습니다. 이를 inetd (또는 xinetd)라고합니다. 단점은 다음과 같습니다.
- 데몬은 stdin / stdout에서 대화해야합니다 (데몬을 제어하지 않으면-소스가없는 경우-아마도 일부 서비스에 inetd-compatibility 플래그가있을 수 있지만 showtopper 일 수 있습니다)
- 모든 데몬마다 새로운 데몬 프로세스가 발생합니다.
- 그것은 체인에 하나의 추가 링크입니다
장점 :
- 이전 UNIX에서 사용 가능
- sysadmin이 구성을 설정 한 후에는 개발에 착수해야합니다 (데몬을 다시 빌드 할 때 setcap 기능이 손실 될 수 있습니까? 그런 다음 관리자에게 다시 문의하십시오. " ")
- 데몬은 그 네트워킹에 대해 걱정할 필요가 없으며 stdin / stdout에서 이야기하면됩니다.
- 요청에 따라 데몬을 루트가 아닌 사용자로 실행하도록 구성 할 수 있습니다.
다른 대안 : 권한이있는 포트에서 대상 데몬을 실행할 수있는 임의의 높은 번호의 포트에 이르는 해킹 된 프록시 (netcat 또는 더 강력한 것 ). (Netcat은 분명히 프로덕션 솔루션이 아니라 "단지 내 개발 상자"입니다.). 이 방법으로 네트워크 가능 서버 버전을 계속 사용할 수 있으며, 부팅시 프록시를 시작하기 위해 루트 / 스도 만 필요하며 복잡하고 잠재적으로 취약한 기능에 의존하지 않습니다.
2017 업데이트 :
authbind 사용
CAP_NET_BIND_SERVICE 또는 사용자 정의 커널보다 훨씬 낫습니다.
- CAP_NET_BIND_SERVICE는 바이너리에 트러스트를 부여하지만 포트 별 액세스를 제어하지는 않습니다.
Authbind는 사용자 / 그룹에 신뢰를 부여하고 포트 별 액세스를 제어하며 IPv4 및 IPv6을 모두 지원합니다 (IPv6 지원은 최근 추가됨).
설치:
apt-get install authbind
모든 사용자 및 그룹에 대한 관련 포트 (예 : 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다음을 통해 명령을 실행하십시오
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를 사용 하고이 제한이 다시는 귀찮게하지 않도록 커널을 컴파일하십시오.
내 "표준 해결 방법"은 socat을 사용자 공간 리디렉터로 사용합니다.
socat tcp6-listen:80,fork tcp6:8080
이것이 확장되지 않으며 포크는 비싸지 만 socat이 작동하는 방식입니다.
Linux는 "이 응용 프로그램은 루트로 실행"보다 더 세분화 된 권한을 지원 하는 기능 을 지원 합니다 . 이러한 기능 중 하나는 CAP_NET_BIND_SERVICE
권한있는 포트 (<1024)에 바인딩하는 것입니다.
불행히도 응용 프로그램을 계속 제공하면서 루트가 아닌 응용 프로그램을 실행하는 방법을 알지 못합니다 CAP_NET_BIND_SERVICE
(아마도을 사용 setcap
하지만 기존 솔루션이 있어야합니다).
나는 이것이 오래된 질문이라는 것을 알고 있지만, 최근 (> = 4.3) 커널로 마침내 이것에 대한 좋은 대답이 있습니다.
빠른 대답은 git에서 최신 (출시되지 않은) libcap 버전의 복사본을 가져 와서 컴파일하는 것입니다. 결과 progs/capsh
바이너리를 어딘가에 복사하십시오 ( /usr/local/bin
좋은 선택). 그런 다음 루트로 프로그램을 시작하십시오.
/usr/local/bin/capsh --keep=1 --user='your-service-user-name' \
--inh='cap_net_bind_service' --addamb='cap_net_bind_service' \
-- -c 'your-program'
우리는
- 사용자를 전환 할 때 현재 기능 세트를 유지하려고합니다.
- 사용자 및 그룹을 'your-service-user-name'으로 전환
cap_net_bind_service
상속 및 주변 세트에 기능 추가- 분기
bash -c 'your-command'
(이후capsh
의 인수로 bash를 자동으로 시작 하므로--
)
여기 후드 아래에 많은 일이 있습니다.
먼저 루트로 실행 중이므로 기본적으로 모든 기능을 사용할 수 있습니다. 여기에는 setuid
및 setgid
syscalls로 uid & gid를 전환하는 기능이 포함되어 있습니다. 그러나 일반적으로 프로그램 이이 작업을 수행하면 기능 세트가 손실됩니다. 이렇게하면 루트를 삭제하는 오래된 방법이 setuid
여전히 작동합니다. 이 --keep=1
플래그는 syscall capsh
을 발행하도록 지시 하여 prctl(PR_SET_KEEPCAPS)
사용자를 변경할 때 기능이 삭제되지 않도록합니다. 에 의한 실제 사용자 변경은 및 을 실행 capsh
하는 --user
플래그 와 함께 발생합니다 .setuid
setgid
우리가 해결해야 할 다음 문제는 exec
자녀 를 쫓아가는 방식으로 기능을 설정하는 방법입니다 . 기능 시스템은 항상 '상속 된'기능 세트를 가졌으며, 이는 "execve (2)에 걸쳐 보존 된 기능 세트"[ capability (7) ]입니다. 이것이 문제를 해결하는 것처럼 들리지만 ( cap_net_bind_service
기능을 상속받은 것으로 설정 했습니까?) 실제로 이것은 권한있는 프로세스에만 적용됩니다. 우리는 이미 사용자를 --user
플래그로 변경했기 때문에 더 이상 권한이 없습니다 .
새로운 주변 기능 세트는이 문제를 해결합니다. "특권이없는 프로그램의 execve (2)에 걸쳐 유지되는 기능 세트입니다." exec가 서버 프로그램 cap_net_bind_service
일 때 앰비언트 세트 를 넣으면 capsh
프로그램은이 기능을 상속하고 리스너를 낮은 포트에 바인딩 할 수 있습니다.
자세한 내용은 기능 매뉴얼 페이지 에서 자세히 설명합니다. 실행 capsh
을 통해하는 것은 strace
매우 유익!
어떤 이유로 sysctl net.ipv4.ip_unprivileged_port_start를 필요한 값으로 낮추는 것에 대해서는 아무도 언급하지 않았습니다. 예 : 앱을 443 포트에 바인딩해야합니다.
sysctl net.ipv4.ip_unprivileged_port_start=443
권한이없는 사용자는 이제 다른 권한있는 포트 (444-1024)에 바인딩 할 수 있습니다. 그러나 다른 포트를 차단하여 iptables로이 문제를 쉽게 해결할 수 있습니다.
iptables -I INPUT -p tcp --dport 444:1024 -j DROP
iptables -I INPUT -p udp --dport 444:1024 -j DROP
다른 방법과 비교 이 방법:
- 응용 프로그램이 전혀 설정되지 않았기 때문에 (실제로 기능이 있기 때문에) CAP_NET_BIND_SERVICE / setuid를 설정하는 것보다 (IMO) 훨씬 안전합니다. 예를 들어, 기능 기반 응용 프로그램의 코어 덤프를 캡처하려면 sysctl fs.suid_dumpable을 변경해야합니다 (이로 인해 다른 잠재적 인 보안 문제가 발생할 수 있음). 또한 CAP / suid가 설정되면 / proc / PID 디렉토리가 루트에 의해 소유됩니다. 루트가 아닌 사용자는 실행중인 프로세스에 대한 완전한 정보 / 제어 권한이 없습니다. 예를 들어, 사용자는 / proc / PID / fd / (netstat -aptn | grep를 통해 어떤 연결이 응용 프로그램에 속하는지 판별 할 수 없습니다) PID).
- 보안상의 단점이 있습니다. 어떤 이유로 앱 (또는 포트 443-1024를 사용하는 모든 앱)이 다운 된 경우 다른 앱이 포트를 사용할 수 있습니다. 그러나이 문제는 CAP / suid (예 : java / nodejs와 같은 인터프리터에서 설정 한 경우) 및 iptables-redirect에도 적용될 수 있습니다. systemd-socket 방법을 사용하여이 문제를 배제하십시오. authbind 메소드를 사용하여 특수 사용자 바인딩 만 허용하십시오.
- 새 버전의 응용 프로그램을 배포 할 때마다 CAP / suid를 설정할 필요가 없습니다.
- 시스템 소켓 방법과 같은 응용 프로그램 지원 / 수정이 필요하지 않습니다.
- 커널 재 구축이 필요하지 않습니다 (실행중인 버전이이 sysctl 설정을 지원하는 경우)
- authbind / privbind 메소드와 같은 LD_PRELOAD를 수행하지 않으면 성능, 보안, 동작에 영향을 줄 수 있습니다 (테스트되지 않았습니까?). 나머지는 실제로 유연하고 안전한 방법입니다.
- 주소 변환, 연결 상태 추적 등이 필요하지 않으므로 iptables REDIRECT / DNAT 방법을 과도하게 수행합니다. 이는 고부하 시스템에서만 눈에 notice니다.
상황에 따라 sysctl, CAP, authbind 및 iptables-redirect 중에서 선택합니다. 그리고 이것은 우리에게 많은 옵션이 있다는 점에서 좋습니다.
TLDR : "답변"에 대해 (이것이 보듯이)이 대답에서 >> TLDR << 부분으로 이동하십시오.
좋아, 나는 (이번에)이 질문에 대한 답을 알아 냈으며, 나의 대답은 또한 "최고라고 생각한 또 다른 대답 (여기 및 트위터 모두) 을 홍보하는 것에 대해 사과하는 방법입니다. ", 그러나 그것을 시도한 후에, 나는 그것에 대해 착각했다는 것을 발견했다. 내 실수에서 배우십시오. 실제로 직접 시도하기 전에는 무언가를 홍보하지 마십시오!
다시, 나는 여기에 모든 답변을 검토했습니다. 나는 그중 일부 를 시도 했다 (그리고 나는 단순히 해결책을 좋아하지 않기 때문에 다른 것을 시도하지 않기로 선택했다). 나는 솔루션을 사용하는 것이라고 생각 systemd
그와 Capabilities=
및 CapabilitiesBindingSet=
설정. 한동안 이것과 씨름 한 후에, 나는 이것이 해결책이 아니라는 것을 알았습니다 .
기능은 루트 프로세스를 제한하기위한 것입니다!
OP가 현명하게 언급했듯이 항상 가능한 한 모든 데몬에 대해 피하는 것이 가장 좋습니다.
당신은 옵션과 관련된 기능 사용할 수 없습니다 User=
와 Group=
의 systemd
기능이 있기 때문에, 유닛 파일을 항상 할 때 리셋 execev
(또는 어떤 기능이)라고합니다. 즉, systemd
포크를 펌핑하고 파마를 떨어 뜨리면 기능이 재설정됩니다. 이 문제를 해결할 방법이 없으며 커널의 모든 바인딩 논리는 기능이 아닌 uid = 0을 기본으로합니다. 이는 기능이이 질문에 대한 정답 일 것 같지 않다는 것을 의미합니다 (적어도 조만간). 우연히도 setcap
다른 사람들이 언급했듯이 해결책은 아닙니다. 그것은 나를 위해 작동하지 않았고 스크립트와 잘 작동하지 않으며 파일이 변경 될 때마다 스크립트가 재설정됩니다.
나는 빈약 한 방어에서 James의 iptables 제안 (OP도 언급)이 "두 번째 최선의 해결책"이라고 진술했습니다 (현재 삭제 한 의견에서 ). :-피
>> TLDR <<
해결책은 다음 과 같은 systemd
즉시 iptables
명령 과 결합 하는 것입니다 (DNSChain에서 가져옴 ).
[Unit]
Description=dnschain
After=network.target
Wants=namecoin.service
[Service]
ExecStart=/usr/local/bin/dnschain
Environment=DNSCHAIN_SYSD_VER=0.0.1
PermissionsStartOnly=true
ExecStartPre=/sbin/sysctl -w net.ipv4.ip_forward=1
ExecStartPre=-/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=-/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStartPre=/sbin/iptables -A INPUT -p udp --dport 5333 -j ACCEPT
ExecStartPre=/sbin/iptables -t nat -A PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
ExecStopPost=/sbin/iptables -D INPUT -p udp --dport 5333 -j ACCEPT
ExecStopPost=/sbin/iptables -t nat -D PREROUTING -p udp --dport 53 -j REDIRECT --to-ports 5333
User=dns
Group=dns
Restart=always
RestartSec=5
WorkingDirectory=/home/dns
PrivateTmp=true
NoNewPrivileges=true
ReadOnlyDirectories=/etc
# Unfortunately, capabilities are basically worthless because they're designed to restrict root daemons. Instead, we use iptables to listen on privileged ports.
# Capabilities=cap_net_bind_service+pei
# SecureBits=keep-caps
[Install]
WantedBy=multi-user.target
여기서 우리는 다음을 달성합니다.
- 데몬은 5333에서 수신 대기하지만 다음으로 인해 53에서 연결이 성공적으로 승인됩니다
iptables
- 단위 파일 자체에 명령을 포함시켜 사람들의 두통을 줄일 수 있습니다.
systemd
데몬이 실행되지 않을 때 제거하도록 방화벽 규칙을 정리합니다. - 우리는 절대로 루트로 실행하지 않으며
systemd
, 데몬이 손상되어 설정되어 있어도 권한 상승을 불가능하게합니다 (적어도 주장)uid=0
.
iptables
불행히도 여전히 추악하고 사용하기 어려운 유틸리티입니다. 예를 들어, 데몬이 수신 대기 eth0:0
하지 않는 eth0
경우 명령이 약간 다릅니다 .
systemd 는 특정 기능을 가진 데몬을 시작하는 옵션이있는 sysvinit 교체입니다. systemd.exec (5) 맨 페이지의 옵션 Capabilities =, CapabilityBoundingSet =
포트 리다이렉션이 우리에게 가장 합리적 이었지만 우리는 애플리케이션이 다시 라우팅해야하는 로컬에서 URL을 해결할 수있는 문제가 발생했습니다. ( 신디 를 의미 함 ).
로컬 컴퓨터의 URL에 액세스 할 때 리디렉션 될 수도 있습니다.
iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -A OUTPUT -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
시작시 :
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
그런 다음 전달할 포트에 바인딩 할 수 있습니다.
systemd를 사용하면 사전 활성화 된 소켓을 허용하도록 서비스를 약간 수정하면됩니다.
나중에 systemd socket activate를 사용할 수 있습니다 .
기능, iptables 또는 기타 트릭이 필요하지 않습니다.
이것은 간단한 파이썬 http 서버의 예제에서 관련 시스템 파일의 내용입니다.
파일 httpd-true.service
[Unit]
Description=Httpd true
[Service]
ExecStart=/usr/local/bin/httpd-true
User=subsonic
PrivateTmp=yes
파일 httpd-true.socket
[Unit]
Description=HTTPD true
[Socket]
ListenStream=80
[Install]
WantedBy=default.target
현대 리눅스는 지원합니다 /sbin/sysctl -w net.ipv4.ip_unprivileged_port_start=0
.
'djb way'도 있습니다. 이 방법을 사용하여 tcpserver의 모든 포트에서 루트로 실행중인 프로세스를 시작할 수 있으며 프로세스가 시작된 직후 지정한 사용자에게 프로세스 제어를 전달합니다.
#!/bin/sh
UID=`id -u yourusername`
GID=`id -g yourusername`
exec tcpserver -u $UID -g $GID -RHl0 0 portnumber /path/to/your/process &
자세한 내용은 다음을 참조하십시오 : http://thedjbway.b0llix.net/daemontools/uidgid.html
privbind 유틸리티를 사용하십시오. 권한이없는 응용 프로그램이 예약 된 포트에 바인드 할 수 있습니다.
OP는 개발 / 테스트 일 뿐이므로 매끄러운 솔루션보다 도움이되지 않을 수 있습니다.
setcap을 스크립트의 통역사에서 사용하여 스크립트에 기능을 부여 할 수 있습니다. 글로벌 인터프리터 바이너리의 setcaps가 허용되지 않으면 바이너리의 로컬 사본 (모든 사용자가 할 수 있음)을 작성하고이 사본에서 setcap의 루트를 가져 오십시오. Python2 (적어도)는 스크립트 개발 트리에서 인터프리터의 로컬 복사본과 올바르게 작동합니다. 루트 사용자가 사용자가 액세스 할 수있는 기능을 제어 할 수 있도록 suid가 필요하지 않습니다.
인터프리터에 대한 시스템 전체 업데이트를 추적해야하는 경우 다음과 같은 쉘 스크립트를 사용하여 스크립트를 실행하십시오.
#!/bin/sh
#
# Watch for updates to the Python2 interpreter
PRG=python_net_raw
PRG_ORIG=/usr/bin/python2.7
cmp $PRG_ORIG $PRG || {
echo ""
echo "***** $PRG_ORIG has been updated *****"
echo "Run the following commands to refresh $PRG:"
echo ""
echo " $ cp $PRG_ORIG $PRG"
echo " # setcap cap_net_raw+ep $PRG"
echo ""
exit
}
./$PRG $*
iptables PREROUTING REDIRECT 방법을 시도했습니다. 이전 커널에서는이 유형의 규칙 이 IPv6에 대해 지원되지 않은 것 같습니다 . 그러나 이제는 ip6tables v1.4.18 및 Linux 커널 v3.8에서 지원됩니다.
또한 PREROUTING REDIRECT가 시스템 내에서 시작된 연결에서 작동하지 않는 것을 발견했습니다. 로컬 시스템에서 연결에 대해 작업하려면 OUTPUT 규칙도 추가하십시오. iptables 포트 리디렉션이 localhost에 대해 작동하지 않음을 참조하십시오 . 예를 들면 다음과 같습니다.
iptables -t nat -I OUTPUT -o lo -p tcp --dport 80 -j REDIRECT --to-port 8080
또한 PREROUTING REDIRECT가 전달 된 패킷에도 영향을 미친다 는 것을 알았습니다 . 즉, 머신이 인터페이스간에 패킷을 전달하는 경우 (예 : 이더넷 네트워크에 연결된 Wi-Fi 액세스 포인트 역할을하는 경우) iptables 규칙은 연결된 클라이언트의 인터넷 연결에 대한 연결을 포착하여 리디렉션합니다. 기계. 그것은 내가 원하는 것이 아닙니다. 기계 자체로 향한 연결 만 리디렉션하고 싶었습니다. 추가하여 상자로 주소가 지정된 패킷에만 영향을 줄 수 있다는 것을 알았습니다 -m addrtype --dst-type LOCAL
. 예를 들면 다음과 같습니다.
iptables -A PREROUTING -t nat -p tcp --dport 80 -m addrtype --dst-type LOCAL -j REDIRECT --to-port 8080
또 다른 가능성은 TCP 포트 전달을 사용하는 것입니다. 예 socat
:
socat TCP4-LISTEN:www,reuseaddr,fork TCP4:localhost:8080
그러나이 방법의 한 가지 단점은 포트 8080에서 수신 대기하는 응용 프로그램은 들어오는 연결의 소스 주소를 알지 못합니다 (예 : 로깅 또는 기타 식별 목적).
2015 년 9 월 답변 :
ip6tables는 이제 IPV6 NAT를 지원합니다 : http://www.netfilter.org/projects/iptables/files/changes-iptables-1.4.17.txt
커널 3.7 이상이 필요합니다
증명:
[09:09:23] root@X:~ ip6tables -t nat -vnL
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 REDIRECT tcp eth0 * ::/0 ::/0 tcp dpt:80 redir ports 8080
0 0 REDIRECT tcp eth0 * ::/0 ::/0 tcp dpt:443 redir ports 1443
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 6148 packets, 534K bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 6148 packets, 534K bytes)
pkts bytes target prot opt in out source destination
'Programing' 카테고리의 다른 글
Ajax를 사용하여 데이터와 파일을 모두 한 형태로 업로드 하시겠습니까? (0) | 2020.02.29 |
---|---|
가치에서 C # 열거 형 설명을 얻는 방법은 무엇입니까? (0) | 2020.02.29 |
줄 끝에 줄 번호와 적중 횟수를 표시하도록 grep 출력을 어떻게 형식화 할 수 있습니까? (0) | 2020.02.29 |
CMake 출력을 지우는 'cmake clean'명령 찾기 (0) | 2020.02.29 |
예외를 일으킨 예외 설명 및 스택 추적을 모두 문자열로 가져옵니다. (0) | 2020.02.29 |