Из руководство по mod_proxy Я настроил обратный прокси с аутентификацией пользователя.
# Set reverse proxy
ProxyPass "/" "http://localhost:10080/"
ProxyPassReverse "/" "http://localhost:10080/"
ProxyRequests On
ProxyVia On
<Proxy *>
Order deny,allow
Allow from all
AuthType Basic
AuthName "Password Required"
AuthUserFile /home/secure/.passwords
Require user ivy
</Proxy>
Это работает следующим образом: Пользователь обращается к серверу -> Сервер запрашивает имя пользователя / пароль -> Пользователь вводит свои учетные данные -> Если учетные данные в порядке для пользователя ivy, тогда обратный прокси работает для порта 10080 на локальном хосте.
Все пользователи добавляются с помощью htpasswd. Я запускаю apache2.4 поверх Linux.
Что мне нужно сделать: я хочу, чтобы разные пользователи использовали прокси. На сервере открыто количество обратных туннелей с портами 10080, 10081, 10082 и так далее ... Я хочу назначить каждого пользователя использовать отдельный порт прокси. То есть:
Если я напишу Require user ivy joe doe
затем я перенаправляю всех пользователей на один порт 10080.
Кажется, уловка где-то в строках ProxyPass "/" "http://localhost:10080/"
и <Proxy *>
. Или где?
Обновить: Следуя предложению Дженни, попробовал:
LoadModule rewrite_module modules/mod_rewrite.so
<IfModule mod_rewrite.c>
RewriteEngine On
#RewriteCond %{REMOTE_USER} ivy # Unconditional redirect for testing.
RewriteRule ^/(.*)$ "http://localhost:10080/test.html" [R=301,L]
</IfModule>
Пробовал это с включенным прокси (прокси сильнее, чем перезапись) и отключенным прокси (отображается локальный index.html).
Пробовал использовать флаги [R,L]
, [L,R]
, [L,R=301]
- не повезло.
Пытался добавить в <Directory "/var/www/html">
и в <Proxy *>
:
RewriteEngine On
RewriteRule ^/(.*)$ "http://localhost:10080/test.html" [R=301,L]
Пробовал это с включенным прокси (прокси сильнее, чем перезапись) и отключенным прокси (отображается локальный index.html).
Глубокие раскопки нашли этот трюк:
RedirectMatch ^/.*$ /test.html
Это работает, но не условно: то есть я все еще не могу назначить разные перенаправления для каждого пользователя.
Обновление2: Пробовал решение Седрика Найта тоже безуспешно. Решил отказаться от Apache, перешел на nginx. Работает нормально. Конфигурация сервера для отдельного обратного прокси для каждого пользователя:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
set $auth_status 100;
server_name localhost;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ =404;
auth_basic "Restricted content";
auth_basic_user_file "/home/secure/.passwords";
auth_request_set $auth_status $upstream_status;
if ($remote_user = "ivy") {
proxy_pass http://localhost:10080;
break; # break is essential since proxy_pass in 'if' isn't allowed.
}
if ($remote_user = "joe") {
proxy_pass http://localhost:10081;
break;
}
}
}
Это решение методом перебора. На следующем шаге я добавлю чтение пользователя карты: порт из файла.
Да, идея Дженни имеет смысл. Не используйте директиву ProxyPass, просто используйте mod_proxy через mod_rewrite с использованием флага P тогда вы можете в качестве следующего этапа дополнительных пользователей вверх с участием RewriteMap
.
<IfModule mod_proxy.c>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REMOTE_USER} ivy
RewriteRule ^/(.*)$ "http://localhost:10080/$1" [P]
RewriteCond %{REMOTE_USER} joe
RewriteRule ^/(.*)$ "http://localhost:10081/$1" [P]
#etc.
# optional step: set up RewriteMap
RewriteMap user-to-port txt:/home/proxy-ports.txt
# contains one entry per line 'doe 10082' etc
RewriteCond %{REMOTE_USER} ^(.*)$
RewriteRule ^/(.*)$ "http://localhost:${user-to-port:%1|10080}/$1" [P]
# 10080 is default port for other users
</IfModule>
</IfModule>
И если вы избавитесь от <Proxy>
разделите проблему аутентификации соответствующим образом, используя директивы Apache 2.4:
<Location "/">
AuthType Basic
AuthName "Password Required"
AuthUserFile /home/secure/.passwords
<RequireAll>
Require valid-user
</RequireAll>
</Location>
Я не вижу необходимости в ProxyVia
в ситуации обратного прокси; хотя вы можете захотеть регистрировать локальные и удаленные порты. Я не тестировал ничего из вышеперечисленного, просто хотел указать направление того, что вы хотите сделать.