Как настроить удаленную переадресацию порта 80 на мой локальный хост с помощью setcap?

Как настроить удаленную переадресацию порта 80 на мой локальный хост с помощью setcap?

Я хотел бы временно принимать соединения для разработки, когда я нахожусь под 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. Итак, у меня в crontab suders есть следующее:

@reboot setcap 'cap_net_bind_service=+ep' /usr/sbin/sshd

Но он все еще не позволяет мне привязаться к порту 80. Что я делаю не так? Я просто собираюсь использовать nginx для проксирования на 8080 или iptables или что-то еще вместо этого, но мне все еще интересно, почему то, что я пытался сделать, не сработало.

решение1

Как объяснил @dwurf'sпринятый ответ, sshбудет привязан только к портам пользователя меньше 1024 root.

Это отличный вариант использования, socatесли вы не root.

Сначала выполните удаленную переадресацию на порт 8080(или любой другой разрешенный порт) удаленной машины:

ssh [email protected] -R 8080:localhost:80

Затем на удаленной машине сопоставьте порт 80с портом 8080:

sudo socat TCP-LISTEN:80,fork TCP:localhost:8080

Примечания:

Как предложил Дирк Хоффман, эти две команды можно объединить в одну строку:

ssh -t [email protected] -R 8080:localhost:80 sudo socat TCP-LISTEN:80,fork TCP:localhost:8080

(Это -tнеобходимо в случае, если вам нужен интерактивный терминал для ввода sudoпароля.)

решение2

OpenSSH категорически откажется привязываться к привилегированным портам, если идентификатор вошедшего в систему пользователя не равен 0 (root). Соответствующие строки кода:

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это тип 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

Это правило фактически заменяет порт назначения 80 на 8080 для всех локально сгенерированных TCP-пакетов.

Если вы хотите разрешить пересылку любых входящих соединений, добавьте в 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
   , который затем туннелируется на локальный порт хоста 80
2. поступает на порт 443 для потоковой передачи на порт 8443
   , который затем туннелируется на локальный порт хоста 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"

Итак, если вы выполните команду, вам придется указать свой пароль root удаленной машины (чтобы иметь возможность просматривать порты 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      -

Связанный контент