Назначэнне віртуальнага хоста Subversion на адрас VPN змяняе, які сайт адказвае на запыт, а не тое, каму дазволена яго адпраўляць. Праверка доступу адбываецца пазней, паводле правілаў у раздзеле, які супаў з URL, і імя хоста ніколі не ўдзельнічае ў гэтым рашэнні. Калі ServerName быў вашым адзіным змяненнем, рэпазіторый даступны гэтак жа, як учора. У канфігурацыі трэба адказаць на два асобныя пытанні: які сокет прыняў злучэнне і якую асобу несла запыт.

Што насамрэч вызначае ServerName

Віртуальны хостынг на аснове імя параўноўвае загаловак Host з запісамі ServerName і ServerAlias, выбірае адзін хост і дазваляе яму апрацаваць запыт. Само злучэнне было прынята раней сокетам Listen, які належыць серверу, а не хосту. Таму імя, якое выглядае прыватным, не дае абароны: любы кліент, які дасягае сокета, можа адправіць гэты загаловак Host. Імя — гэта ключ маршрутызацыі, а ключы маршрутызацыі выбірае той, хто выклікае.

Вы можаце ўбачыць адпаведнасць без здагадак. apachectl -S друкуе кожны хост, яго порт і імёны і адзначае, які з іх прадвызначаны для адраса.

RequireAll — гэта кантэйнер, які робіць абедзве праверкі абавязковымі

Apache 2.4 абгортвае дырэктывы Require аднаго раздзела ў неявны RequireAny, таму дзве голыя дырэктывы азначаюць, што дастаткова любой з іх. Дадайце кантэйнер, і сэнс змяняецца на адваротны:

<Location /svn/repo>
    AuthType Basic
    AuthName "Subversion"
    AuthBasicProvider file
    AuthUserFile /etc/apache2/svn.htpasswd
    <RequireAll>
        Require ip 10.8.0.0/24
        Require valid-user
    </RequireAll>
</Location>

RequireAll патрабуе абедзвюх умоў: адрас крыніцы ўнутры дыяпазону тунеля і карыстальніка, якога прымае рэпазіторый. Менавіта гэта павінна азначаць «толькі праз VPN» для URL Subversion. Даведка mod_authz_core апісвае правілы кантэйнера. Пакіньце блок унутры існуючага Location для рэпазіторыя і не чапайце дырэктывы DAV, якія ўжо працуюць, бо гэты фрагмент не замяняе ні AuthType, ні файл пароляў, ні аўтарызацыю на ўзроўні шляху.

Праверка крыніцы паходзіць з mod_authz_host, таму пераканайцеся, што ён загружаны, перш чым што-небудзь адладжваць: apachectl -M | grep authz_host.

Адрас, які ацэньвае Apache, — гэта адрас сокета

Require ip параўноўвае з адрасам, які Apache запісаў для злучэння, а гэта не заўсёды адрас, які кліент лічыць сваім.

Калі VPN маршрутызуе свае адрасы без трансляцыі, Apache бачыць адрас тунеля, і 10.8.0.0/24 супадае. Калі шлюз транслюе адрасы, Apache бачыць шлюз, і правіла ціха не супадае ні з чым; тое ж адбываецца за балансіроўшчыкам нагрузкі, які завершае TLS перад хостам. Для гэтага выпадку існуе mod_remoteip. RemoteIPHeader X-Forwarded-For разам з RemoteIPTrustedProxy для балансіроўшчыка замяняе запісаны адрас, і толькі тады дыяпазону ёсць з чым параўноўваць.

Давяраць адвольнаму загалоўку перасылкі горш, чым не мець ніякага правіла. Любы кліент можа адправіць X-Forwarded-For з 10.8.0.9 і задаволіць праверку дыяпазону, якая ніколі не была прывязана да даверанага крока.

Слаі: слухач і палітыка рэпазіторыя

Прывязка — асобны элемент кіравання і часта больш просты. Listen 10.8.0.1:443 вызначае, якія сокеты існуюць, і запыт не можа выбраць хост на сокеце, які ніколі не адкрываўся. Кошт — парадак запуску: калі інтэрфейс тунеля не працуе падчас старту Apache, прывязка не ўдаецца і служба не ўзнімаецца. Спалучыце яе з парадкам юнітаў або прывязвайце да адраса, які існуе незалежна ад тунеля.

Дазволы шляхоў застаюцца ў AuthzSVNAccessFile. Сапраўдны ўліковы запіс для сайта — не тое ж самае, што права запісу ў шлях праекта, і сеткавае правіла гэтага не змяняе.

Сачыце за аб'яднаннем раздзелаў, калі блок знаходзіцца ўключаным файле. Apache аб'ядноўвае кантэйнеры аўтарызацыі праз укладзеныя раздзелы, і найбольш канкрэтны адпаведны раздзел можа замяніць патрабаванне, а не дадаць да яго, таму правіла на /svn можа не дайсці да /svn/repo/trunk, як толькі вузейшы раздзел вызначыць сваё.

Дакажыце абодва адмовы, перш чым лічыць справу зробленай

Праверце чатыры запыты, а не адзін. Унутры VPN з сапраўдным уліковым запісам вы павінны атрымаць спіс рэпазіторыя. Унутры VPN з няправільным паролем вы павінны атрымаць 401, а не спіс. Звонку VPN з сапраўднымі дадзенымі ўваходу вы павінны атрымаць 403, і такі ж публічны запыт да альтэрнатыўнага імя хоста павінен праваліцца гэтак жа.

Дастаткова адной каманды на выпадак: curl -sI -u user:pass https://svn.example.com/svn/repo/, затым прачытайце радок стану. Паўтарыце працоўны выпадак і праз сапраўдны кліент, бо svn info практыкуе метады DAV, якія будуць выкарыстоўваць каміты і абнаўленні.

Калі любы з чатырох вынікаў супярэчыць палітыцы, якую вы задумалі, канфігурацыя не скончана, і перайменаванне хоста гэтага не зменіць.

Падобныя артыкулы