How can I set up a remote port forward on port 80 to my localhost with the help of setcap?
OpenSSH will flat-out refuse to bind to privileged ports unless the user id of the logged in user is 0 (root). The relevant lines of code are:
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.");
Source: http://www.openssh.com/cgi-bin/cvsweb/src/usr.bin/ssh/serverloop.c?annotate=1.162 lines 1092-1098
If you're curious, pw
is of type struct passwd *
and on linux is defined in /usr/include/pwd.h
This is a great use case for socat
.
First, do a remote forward to port 8080
(or any other allowed port) of the remote machine:
ssh [email protected] -R 8080:localhost:80
Then on the remote machine, map port 80
to port 8080
:
sudo socat TCP-LISTEN:80,fork TCP:localhost:8080
Notes:
As suggested by Dirk Hoffman, these two commands can be combined into a single line:
ssh -t [email protected] -R 8080:localhost:80 sudo socat TCP-LISTEN:80,fork TCP:localhost:8080
(The -t
is necessary in case you need an interactive terminal to enter your sudo
password.)
I meet the similar problem, so the solution I ended up is to add DNAT
rule to the OUTPUT
chain of nat
table:
iptables -t nat -A OUTPUT -d 127.0.0.0/8 -p tcp --dport 80 \
-j DNAT --to-destination :8080
This rule effectively replaces the destination port 80 with 8080 for all locally generated tcp packets.
If you wish to allow any incoming connections to be forwarded as well then add one extra rule to the PREROUTING
nat
chain:
iptables -t nat -A PREROUTING -d 10.0.0.200 -p tcp --dport 80 \
-j REDIRECT --to-port 8080
where 10.0.0.200
is the IP address of the interface that should be forwarding incoming connections to your web service