Apuntar un amfitrió virtual de Subversion a una adreça de VPN canvia quin lloc respon una petició, no qui té permís per enviar-ne una. La comprovació d'accés passa després, segons les regles de la secció que va coincidir amb l'URL, i el nom de l'amfitrió no entra mai en aquesta decisió. Si ServerName va ser l'únic canvi, el repositori és exactament tan abastable com ahir. Cal respondre dues preguntes separades a la configuració: quin sòcol va acceptar la connexió i quina identitat portava la petició.

Què decideix realment ServerName

L'allotjament virtual basat en nom compara la capçalera Host amb les entrades ServerName i ServerAlias, tria un amfitrió i deixa que aquest atengui la petició. La connexió mateixa ja havia estat acceptada per un sòcol Listen que pertany al servidor, no a l'amfitrió. Per això un nom que sembla privat no ofereix cap protecció: qualsevol client que arribi al sòcol pot enviar aquella capçalera Host. El nom és una clau d'encaminament, i les claus d'encaminament les tria qui crida.

Podeu veure el mapatge sense endevinar. apachectl -S imprimeix cada amfitrió, el seu port i els seus noms, i marca quin és el predeterminat per a l'adreça.

RequireAll és el contenidor que fa obligatòries les dues comprovacions

Apache 2.4 embolcalla les directrius Require d'una sola secció en un RequireAny implícit, així que dues directrius nues volen dir que qualsevol de les dues n'hi ha prou. Afegiu el contenidor i el significat s'inverteix:

<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 necessita les dues condicions: una adreça d'origen dins del rang del túnel i un usuari que el repositori accepti. Això és el que hauria de voler dir només-VPN per a un URL de Subversion. La referència de mod_authz_core documenta les regles del contenidor. Manteniu el bloc dins del Location existent del repositori i deixeu al seu lloc les directrius DAV que ja funcionen, perquè aquest fragment no substitueix ni AuthType ni el fitxer de contrasenyes ni l'autorització a nivell de camí.

La prova d'origen ve de mod_authz_host, així que confirmeu que està carregat abans de depurar qualsevol altra cosa: apachectl -M | grep authz_host.

L'adreça que Apache avalua és l'adreça del sòcol

Require ip compara amb l'adreça que Apache va registrar per a la connexió, que no sempre és l'adreça que el client creu tenir.

Quan la VPN encamina les seves adreces sense traducció, Apache veu l'adreça del túnel i 10.8.0.0/24 coincideix. Quan una passarel·la tradueix, Apache veu la passarel·la i la regla no coincideix silenciosament amb res; el mateix passa darrere d'un balancejador que acaba TLS davant de l'amfitrió. mod_remoteip existeix per a aquest cas. RemoteIPHeader X-Forwarded-For juntament amb RemoteIPTrustedProxy per al balancejador substitueix l'adreça registrada, i només llavors el rang té amb què comparar-se.

Confiar en una capçalera de reenviament arbitrària és pitjor que no tenir cap regla. Qualsevol client pot enviar X-Forwarded-For amb 10.8.0.9 i satisfer una comprovació de rang que mai no es va ancorar en un salt de confiança.

Superposeu l'oient i la política del repositori

La vinculació és un control a part i sovint el més simple. Listen 10.8.0.1:443 decideix quins sòcols existeixen, i una petició no pot triar un amfitrió en un sòcol que mai no s'ha obert. El cost és l'ordre d'arrencada: si la interfície del túnel està caiguda quan Apache arrenca, la vinculació falla i el servei no s'aixeca. Aparelleu-lo amb l'ordre d'unitats, o vinculeu-lo a una adreça que existeixi independentment del túnel.

Els permisos de camí es queden a AuthzSVNAccessFile. Un compte vàlid per al lloc no és la mateixa concessió que l'accés d'escriptura a un camí de projecte, i la regla de xarxa no ho canvia.

Vigileu la fusió de seccions quan el bloc és en un fitxer inclòs. Apache fusiona contenidors d'autorització entre seccions niuades i la secció coincident més específica pot substituir el requisit en lloc d'afegir-s'hi, així que una regla a /svn pot no arribar a /svn/repo/trunk quan una secció més estreta defineix la seva.

Demostreu les dues denegacions abans de donar-ho per fet

Proveu quatre peticions, no una. Dins de la VPN amb un compte vàlid hauríeu d'obtenir el llistat del repositori. Dins de la VPN amb una contrasenya incorrecta hauríeu d'obtenir 401 en lloc d'un llistat. Des de fora de la VPN amb credencials vàlides hauríeu d'obtenir 403, i la mateixa petició pública contra un nom d'amfitrió alternatiu ha de fallar igual.

Una comanda per cas és suficient: curl -sI -u user:pass https://svn.example.com/svn/repo/, i després llegiu la línia d'estat. Repetiu el cas que funciona també amb el client real, perquè svn info exerceix els mètodes DAV que faran servir els commits i les actualitzacions.

Si qualsevol dels quatre resultats no coincideix amb la política que volíeu, la configuració no està acabada, i canviar el nom de l'amfitrió no ho canviarà.

Articles relacionats