![setcap을 사용하여 포트 80의 원격 포트를 로컬 호스트로 어떻게 전달할 수 있습니까?](https://linux55.com/image/23478/setcap%EC%9D%84%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20%ED%8F%AC%ED%8A%B8%2080%EC%9D%98%20%EC%9B%90%EA%B2%A9%20%ED%8F%AC%ED%8A%B8%EB%A5%BC%20%EB%A1%9C%EC%BB%AC%20%ED%98%B8%EC%8A%A4%ED%8A%B8%EB%A1%9C%20%EC%96%B4%EB%96%BB%EA%B2%8C%20%EC%A0%84%EB%8B%AC%ED%95%A0%20%EC%88%98%20%EC%9E%88%EC%8A%B5%EB%8B%88%EA%B9%8C%3F.png)
NAT를 수행할 때 단기 개발 연결을 허용하고 싶기 때문에 다음을 시도합니다.
$ ssh [email protected] -R 80:localhost:80
낮은 포트를 바인딩하려고 하면 실패합니다.
Warning: remote port forwarding failed for listen port 80
setcap 'cap_net_bind_service=+ep' /my/application
그래서 1024보다 낮은 포트에서 수신 대기 할 수 있다는 것을 알았습니다 . 그래서 저는 suders crontab에 이것을 얻었습니다:
@reboot setcap 'cap_net_bind_service=+ep' /usr/sbin/sshd
하지만 여전히 포트 80을 바인딩하는 것은 허용되지 않습니다. 내가 뭘 잘못했나요? 저는 nginx를 사용하여 8080이나 iptables 등을 프록시할 계획이지만, 제가 하려는 일이 왜 작동하지 않는지 여전히 궁금합니다.
답변1
@dwurf에서 설명했듯이수락된 답변, ssh
1024보다 작은 포트만 사용자에게 바인딩됩니다 root
.
socat
그렇지 않은 경우 이는 훌륭한 사용 사례입니다 root
.
먼저 8080
원격 시스템의 포트(또는 다른 허용된 포트)로 원격으로 전달합니다.
ssh [email protected] -R 8080:localhost:80
그런 다음 원격 시스템에서 포트를 80
포트에 매핑합니다 8080
.
sudo socat TCP-LISTEN:80,fork TCP:localhost:8080
노트:
Dirk Hoffman의 제안에 따라 이 두 명령을 한 줄로 결합할 수 있습니다.
ssh -t [email protected] -R 8080:localhost:80 sudo socat TCP-LISTEN:80,fork TCP:localhost:8080
( 비밀번호 -t
입력을 위해 대화형 단말기가 필요한 경우 sudo
필수입니다 .)
답변2
OpenSSH는 로그인한 사용자의 사용자 ID가 0(루트)이 아닌 한 권한 있는 포트에 대한 바인딩을 절대적으로 거부합니다. 관련 코드 줄은 다음과 같습니다.
if (!options.allow_tcp_forwarding ||
no_port_forwarding_flag ||
(!want_reply && listen_port == 0) ||
(listen_port != 0 && listen_port < IPPORT_RESERVED &&
pw->pw_uid != 0)) {
success = 0;
packet_send_debug("Server has disabled port forwarding.");
원천:http://www.openssh.com/cgi-bin/cvsweb/src/usr.bin/ssh/serverloop.c?annotate=1.162라인 1092-1098
궁금하다면 pw
is 유형 struct passwd *
과 Linux의 경우에 정의되어 있습니다./usr/include/pwd.h
답변3
비슷한 문제가 있었기 때문에 최종 해결책은 DNAT
테이블 체인에 규칙을 추가하는 것이었습니다.OUTPUT
nat
iptables -t nat -A OUTPUT -d 127.0.0.0/8 -p tcp --dport 80 \
-j DNAT --to-destination :8080
이 규칙은 로컬에서 생성된 모든 TCP 패킷에 대해 대상 포트 80을 8080으로 효과적으로 대체합니다.
들어오는 연결이 전달되도록 허용하려면 체인에 추가 규칙을 추가하세요 PREROUTING
nat
.
iptables -t nat -A PREROUTING -d 10.0.0.200 -p tcp --dport 80 \
-j REDIRECT --to-port 8080
10.0.0.200
들어오는 연결을 웹 서비스로 전달하는 인터페이스의 IP 주소는 어디에 있습니까?
답변4
솔루션에 대해 자세히 설명하세요.벤 마레스이상,
아래는 다음과 같은 라이너입니다.
두 개의 원격 포트 전달 열기:
1. 원격 포트 8888에서 로컬 포트 80으로
2. 원격 포트 8443에서 로컬 포트 443으로
원격 시스템에서 socat는 무엇이든 연결합니다.
1. 포트 80에 도착하여 포트 8888로 스트리밍한
다음 localhost 포트 80으로 터널링합니다
. 2. 포트 443에 도착하고 포트 8443으로 스트리밍한
다음 localhost 포트 443으로 터널링합니다.
ssh -t -i ~/.ssh/id_rsa \
-R 0.0.0.0:8888:0.0.0.0:80 \
-R 0.0.0.0:8443:0.0.0.0:443 \
remoteUser@remoteMachine \
-- "(sudo socat TCP-LISTEN:80,fork TCP:localhost:8888) & \
sudo socat TCP-LISTEN:443,fork TCP:localhost:8443"
따라서 명령을 실행하는 경우 원격 시스템의 루트 비밀번호를 제공해야 하며(포트 80/443에 나열할 수 있도록) 그런 다음 (터널이 설정되어 있는 한) 포트 80에서 원격 호스트에 도달하는 모든 항목을 제공해야 합니다. 또는 443은 각각 로컬 컴퓨터 포트 80 또는 443으로 터널링됩니다.
기억하다! !
모든 네트워크 인터페이스(0.0.0.0)에 바인딩하려면 원격 컴퓨터를 편집하고 또는 /etc/ssh/sshd_config
설정 해야 합니다.GatewayPorts clientspecified
GatewayPorts yes
원격 시스템에서 이를 확인할 수 있으며 netstat -tlpn | grep -E '8888|8443'
다음이 표시되어야 합니다.
tcp 0 0 0.0.0.0:8888 0.0.0.0:* LISTEN -
tcp 0 0 0.0.0.0:8443 0.0.0.0:* LISTEN -
설마
tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:8443 0.0.0.0:* LISTEN -