Att peka en virtuell Subversion-värd mot en VPN-adress ändrar vilken webbplats som svarar på en begäran, inte vem som får skicka den. Åtkomstkontrollen sker senare, enligt reglerna i det avsnitt som matchade URL:en, och ett värdnamn ingår aldrig i det beslutet. Om ServerName var din enda ändring är förrådet exakt lika nåbart som i går. Två separata frågor måste besvaras i konfigurationen: vilken socket som tog emot anslutningen och vilken identitet begäran bar.

Vad ServerName faktiskt avgör

Namnbaserad virtuell hosting jämför Host-huvudet med ServerName- och ServerAlias-poster, väljer en värd och låter den hantera begäran. Själva anslutningen togs tidigare emot av en Listen-socket som tillhör servern, inte värden. Därför ger ett namn som ser privat ut inget skydd: varje klient som når socketen kan skicka det Host-huvudet. Namnet är en routingnyckel, och routingnycklar väljs av den som anropar.

Du kan se mappningen utan att gissa. apachectl -S skriver ut varje värd, dess port och namn och markerar vilken som är standard för adressen.

RequireAll är behållaren som gör båda kontrollerna obligatoriska

Apache 2.4 lindar in Require-direktiven i ett avsnitt i en implicit RequireAny, så två nakna direktiv betyder att ett av dem räcker. Lägg till behållaren och betydelsen vänds:

<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 kräver båda villkoren: en källadress inom tunnelintervallet och en användare som förrådet accepterar. Det är vad endast-VPN bör betyda för en Subversion-URL. Referensen för mod_authz_core dokumenterar behållarreglerna. Låt blocket ligga kvar i den befintliga Location för förrådet och låt de DAV-direktiv som redan fungerar stå kvar, eftersom det här fragmentet varken ersätter AuthType eller lösenordsfilen eller auktorisering på sökvägsnivå.

Källtestet kommer från mod_authz_host, så bekräfta att det är laddat innan du felsöker något annat: apachectl -M | grep authz_host.

Adressen som Apache utvärderar är socketadressen

Require ip jämför med adressen som Apache registrerade för anslutningen, och det är inte alltid adressen som klienten tror sig ha.

När VPN:en routar sina adresser utan översättning ser Apache tunneladressen och 10.8.0.0/24 matchar. När en gateway översätter ser Apache gatewayen och regeln matchar tyst ingenting; samma sak händer bakom en lastbalanserare som avslutar TLS framför värden. För det fallet finns mod_remoteip. RemoteIPHeader X-Forwarded-For tillsammans med RemoteIPTrustedProxy för balanseraren ersätter den registrerade adressen, och först då har intervallet något att jämföra med.

Att lita på ett godtyckligt vidarebefordringshuvud är värre än att inte ha någon regel alls. Varje klient kan skicka X-Forwarded-For med 10.8.0.9 och uppfylla en intervallkontroll som aldrig var förankrad i ett betrott hopp.

Varva lyssnaren och förrådspolicyn

Bindning är en separat kontroll och ofta den enklare. Listen 10.8.0.1:443 avgör vilka sockets som finns, och en begäran kan inte välja en värd på en socket som aldrig öppnades. Priset är startordningen: om tunnelgränssnittet är nere när Apache startar misslyckas bindningen och tjänsten kommer inte upp. Koppla den till enhetsordningen, eller bind till en adress som finns oberoende av tunneln.

Sökvägsbehörigheter stannar i AuthzSVNAccessFile. Ett giltigt konto för webbplatsen är inte samma beviljande som skrivåtkomst till en projektsökväg, och nätverksregeln ändrar inte det.

Se upp med avsnittssammanslagning när blocket ligger i en inkluderad fil. Apache slår samman auktoriseringsbehållare över nästlade avsnitt och det mest specifika matchande avsnittet kan ersätta kravet i stället för att lägga till, så en regel på /svn når kanske inte /svn/repo/trunk när ett snävare avsnitt definierar sitt eget.

Bevisa båda avslagen innan du kallar det klart

Testa fyra begäranden, inte en. Inne i VPN:en med ett giltigt konto bör du få förrådets lista. Inne i VPN:en med fel lösenord bör du få 401 i stället för en lista. Utanför VPN:en med giltiga uppgifter bör du få 403, och samma offentliga begäran mot ett alternativt värdnamn måste misslyckas på samma sätt.

Ett kommando per fall räcker: curl -sI -u user:pass https://svn.example.com/svn/repo/, läs sedan statusraden. Upprepa också det fungerande fallet genom den riktiga klienten, eftersom svn info övar de DAV-metoder som commits och uppdateringar kommer att använda.

Om något av de fyra resultaten inte stämmer med policyn du avsåg är konfigurationen inte klar, och att byta namn på värden ändrar inte det.

Relaterade artiklar