Een virtuele Subversion-host naar een VPN-adres wijzen verandert welke site een verzoek beantwoordt, niet wie er een mag sturen. De toegangscontrole gebeurt later, volgens de regels in de sectie die bij de URL paste, en een hostnaam komt nooit in die beslissing. Als ServerName uw enige wijziging was, is de repository precies zo bereikbaar als gisteren. Twee afzonderlijke vragen moeten in de configuratie worden beantwoord: welke socket de verbinding aannam en welke identiteit het verzoek droeg.

Wat ServerName feitelijk bepaalt

Naamgebaseerde virtuele hosting vergelijkt de Host-header met ServerName- en ServerAlias-vermeldingen, kiest één host en laat die het verzoek afhandelen. De verbinding zelf werd eerder aangenomen door een Listen-socket die bij de server hoort, niet bij de host. Daarom biedt een privé lijkende naam geen bescherming: elke client die de socket bereikt, kan die Host-header sturen. De naam is een routeringssleutel, en routeringssleutels kiest de aanroeper.

U kunt de toewijzing zien zonder te gissen. apachectl -S drukt elke host, zijn poort en zijn namen af en markeert welke de standaard is voor het adres.

RequireAll is de container die beide controles verplicht maakt

Apache 2.4 wikkelt de Require-richtlijnen van één sectie in een impliciete RequireAny, dus twee kale richtlijnen betekenen dat een van beide volstaat. Voeg de container toe en de betekenis keert om:

<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 vereist beide voorwaarden: een bronadres binnen het tunnelbereik en een gebruiker die de repository accepteert. Dat zou alleen-VPN moeten betekenen voor een Subversion-URL. De mod_authz_core-referentie documenteert de containerregels. Houd het blok in de bestaande Location voor de repository en laat de DAV-richtlijnen die al werken staan, want dit fragment vervangt niet AuthType, niet het wachtwoordbestand en niet de autorisatie op padniveau.

De brontest komt van mod_authz_host, dus bevestig dat het geladen is voordat u iets anders debugt: apachectl -M | grep authz_host.

Het adres dat Apache evalueert, is het socketadres

Require ip vergelijkt met het adres dat Apache voor de verbinding vastlegde, en dat is niet altijd het adres dat de client denkt te hebben.

Wanneer de VPN zijn adressen zonder vertaling routeert, ziet Apache het tunneladres en 10.8.0.0/24 komt overeen. Wanneer een gateway vertaalt, ziet Apache de gateway en de regel komt stilzwijgend met niets overeen; hetzelfde gebeurt achter een load balancer die TLS voor de host beëindigt. Voor dat geval bestaat mod_remoteip. RemoteIPHeader X-Forwarded-For samen met RemoteIPTrustedProxy voor de balancer vervangt het vastgelegde adres, en pas dan heeft het bereik iets om mee te vergelijken.

Een willekeurige doorstuurheader vertrouwen is erger dan helemaal geen regel hebben. Elke client kan X-Forwarded-For met 10.8.0.9 sturen en een bereikcontrole vervullen die nooit aan een vertrouwde hop was verankerd.

Laag de listener en het repositorybeleid

Binding is een aparte controle en vaak de eenvoudigste. Listen 10.8.0.1:443 bepaalt welke sockets bestaan, en een verzoek kan geen host kiezen op een socket die nooit is geopend. De prijs is de opstartvolgorde: staat de tunnelinterface omlaag wanneer Apache start, dan mislukt de binding en komt de dienst niet omhoog. Koppel dit aan de unit-volgorde, of bind aan een adres dat onafhankelijk van de tunnel bestaat.

Padrechten blijven in AuthzSVNAccessFile. Een geldig account voor de site is niet dezelfde toekenning als schrijftoegang tot een projectpad, en de netwerkregel verandert dat niet.

Let op het samenvoegen van secties wanneer het blok in een ingevoegd bestand staat. Apache voegt autorisatiecontainers samen over geneste secties en de meest specifieke overeenkomende sectie kan de eis vervangen in plaats van aanvullen, dus een regel op /svn bereikt mogelijk niet /svn/repo/trunk zodra een engere sectie de eigen regel definieert.

Bewijs beide weigeringen voordat u het klaar noemt

Test vier verzoeken, niet één. Binnen de VPN met een geldig account hoort u de repositorylijst te krijgen. Binnen de VPN met een verkeerd wachtwoord hoort u 401 te krijgen in plaats van een lijst. Van buiten de VPN met geldige inloggegevens hoort u 403 te krijgen, en hetzelfde openbare verzoek naar een alternatieve hostnaam moet op dezelfde manier mislukken.

Eén opdracht per geval is genoeg: curl -sI -u user:pass https://svn.example.com/svn/repo/, lees dan de statusregel. Herhaal het werkende geval ook via de echte client, omdat svn info de DAV-methoden oefent die commits en updates zullen gebruiken.

Als een van de vier resultaten niet overeenkomt met het beleid dat u bedoelde, is de configuratie niet klaar, en het hernoemen van de host verandert dat niet.

Gerelateerde artikelen