Direcționarea unei gazde virtuale Subversion către o adresă VPN schimbă ce site răspunde la o cerere, nu cine are voie să o trimită. Verificarea accesului are loc mai târziu, după regulile din secțiunea care s-a potrivit cu URL-ul, iar numele gazdei nu intră niciodată în acea decizie. Dacă ServerName a fost singura modificare, depozitul este exact la fel de accesibil ca ieri. Două întrebări separate trebuie lămurite în configurație: ce socket a acceptat conexiunea și ce identitate purta cererea.

Ce decide de fapt ServerName

Găzduirea virtuală bazată pe nume compară antetul Host cu intrările ServerName și ServerAlias, alege o gazdă și o lasă să trateze cererea. Conexiunea în sine fusese acceptată mai devreme de un socket Listen care aparține serverului, nu gazdei. De aceea un nume care pare privat nu oferă nicio protecție: orice client care ajunge la socket poate trimite acel antet Host. Numele este o cheie de rutare, iar cheile de rutare sunt alese de cel care apelează.

Puteți vedea maparea fără să ghiciți. apachectl -S afișează fiecare gazdă, portul și numele ei și marchează care este implicită pentru adresă.

RequireAll este containerul care face ambele verificări obligatorii

Apache 2.4 învelește directivele Require ale unei singure secțiuni într-un RequireAny implicit, așa că două directive goale înseamnă că oricare dintre ele este suficientă. Adăugați containerul și sensul se inversează:

<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 cere ambele condiții: o adresă de sursă în intervalul tunelului și un utilizator pe care depozitul îl acceptă. Asta ar trebui să însemne doar-VPN pentru un URL Subversion. Referința mod_authz_core documentează regulile containerului. Păstrați blocul în Location existent al depozitului și lăsați pe loc directivele DAV care funcționează deja, pentru că acest fragment nu înlocuiește nici AuthType, nici fișierul de parole, nici autorizarea la nivel de cale.

Testul sursei vine de la mod_authz_host, așa că confirmați că este încărcat înainte de a depana orice altceva: apachectl -M | grep authz_host.

Adresa pe care o evaluează Apache este adresa socketului

Require ip compară cu adresa pe care Apache a înregistrat-o pentru conexiune, iar aceasta nu este întotdeauna adresa pe care clientul crede că o are.

Când VPN-ul își rutează adresele fără traducere, Apache vede adresa tunelului și 10.8.0.0/24 se potrivește. Când o poartă traduce, Apache vede poarta și regula nu se potrivește în liniște cu nimic; același lucru se întâmplă în spatele unui balansator care termină TLS în fața gazdei. Pentru acel caz există mod_remoteip. RemoteIPHeader X-Forwarded-For împreună cu RemoteIPTrustedProxy pentru balansator înlocuiește adresa înregistrată, și abia atunci intervalul are cu ce compara.

A avea încredere într-un antet de redirecționare arbitrar este mai rău decât a nu avea nicio regulă. Orice client poate trimite X-Forwarded-For care conține 10.8.0.9 și poate satisface o verificare de interval care nu a fost niciodată ancorată de un salt de încredere.

Suprapuneți ascultătorul și politica depozitului

Legarea este un control separat și adesea cel mai simplu. Listen 10.8.0.1:443 decide ce socketuri există, iar o cerere nu poate alege o gazdă pe un socket care nu a fost niciodată deschis. Costul este ordinea de pornire: dacă interfața tunelului este oprită când pornește Apache, legarea eșuează și serviciul nu pornește. Asociați-o cu ordinea unităților sau legați-o la o adresă care există independent de tunel.

Permisiunile de cale rămân în AuthzSVNAccessFile. Un cont valid pentru site nu este aceeași concesie ca accesul de scriere la o cale de proiect, iar regula de rețea nu schimbă asta.

Atenție la fuziunea secțiunilor când blocul se află într-un fișier inclus. Apache fuzionează containerele de autorizare prin secțiuni imbricate, iar cea mai specifică secțiune potrivită poate înlocui cerința în loc să o completeze, așa că o regulă pe /svn poate să nu ajungă la /svn/repo/trunk odată ce o secțiune mai îngustă o definește pe a sa.

Demonstrați ambele refuzuri înainte de a-l numi terminat

Testați patru cereri, nu una. În interiorul VPN-ului cu un cont valid ar trebui să primiți lista depozitului. În interiorul VPN-ului cu o parolă greșită ar trebui să primiți 401 în loc de listă. Din afara VPN-ului cu acreditări valide ar trebui să primiți 403, iar aceeași cerere publică către un nume de gazdă alternativ trebuie să eșueze la fel.

O comandă pe caz este suficientă: curl -sI -u user:pass https://svn.example.com/svn/repo/, apoi citiți linia de stare. Repetați și cazul care funcționează prin clientul real, pentru că svn info exersează metodele DAV pe care le vor folosi commit-urile și actualizările.

Dacă oricare dintre cele patru rezultate contrazice politica dorită, configurația nu este terminată, iar redenumirea gazdei nu va schimba asta.

Articole similare