Nasměrování virtuálního hostitele Subversion na adresu VPN mění, která stránka odpoví na požadavek, nikoli kdo jej smí poslat. Kontrola přístupu probíhá později, podle pravidel v sekci, která odpovídala URL, a název hostitele do tohoto rozhodnutí nikdy nevstupuje. Pokud byl ServerName vaší jedinou změnou, je repozitář přístupný přesně jako včera. V konfiguraci je třeba odpovědět na dvě oddělené otázky: který socket spojení přijal a jakou identitu požadavek nesl.

Co ServerName skutečně rozhoduje

Virtuální hostování založené na názvu porovnává hlavičku Host se záznamy ServerName a ServerAlias, vybere jednoho hostitele a nechá jej požadavek obsloužit. Samotné spojení už dříve přijal socket Listen, který patří serveru, nikoli hostiteli. Proto název, který vypadá soukromě, neposkytuje žádnou ochranu: každý klient, který dosáhne na socket, může tuto hlavičku Host poslat. Název je směrovací klíč a směrovací klíče vybírá volající.

Mapování můžete vidět bez hádání. apachectl -S vypíše každého hostitele, jeho port a názvy a označí, který je pro adresu výchozí.

RequireAll je kontejner, který činí obě kontroly povinnými

Apache 2.4 zabaluje direktivy Require jedné sekce do implicitního RequireAny, takže dvě holé direktivy znamenají, že stačí kterákoli. Přidejte kontejner a význam se obrátí:

<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 vyžaduje obě podmínky: zdrojovou adresu uvnitř rozsahu tunelu a uživatele, kterého repozitář přijme. To by mělo znamenat pouze-VPN pro URL Subversion. Reference mod_authz_core dokumentuje pravidla kontejneru. Ponechte blok uvnitř stávajícího Location pro repozitář a nechte na místě direktivy DAV, které už fungují, protože tento fragment nenahrazuje ani AuthType, ani soubor hesel, ani autorizaci na úrovni cesty.

Test zdroje pochází z mod_authz_host, takže před laděním čehokoli jiného potvrďte, že je načtený: apachectl -M | grep authz_host.

Adresa, kterou Apache vyhodnocuje, je adresa socketu

Require ip porovnává s adresou, kterou Apache pro spojení zaznamenal, a to není vždy adresa, o níž si klient myslí, že ji má.

Když VPN směruje své adresy bez překladu, Apache vidí adresu tunelu a 10.8.0.0/24 odpovídá. Když brána překládá, Apache vidí bránu a pravidlo tiše neodpovídá ničemu; totéž se děje za vyvažovačem, který ukončuje TLS před hostitelem. Pro tento případ existuje mod_remoteip. RemoteIPHeader X-Forwarded-For spolu s RemoteIPTrustedProxy pro vyvažovač nahrazuje zaznamenanou adresu, a teprve pak má rozsah s čím porovnávat.

Věřit libovolné předávací hlavičce je horší než nemít žádné pravidlo. Každý klient může poslat X-Forwarded-For s 10.8.0.9 a splnit kontrolu rozsahu, která nikdy nebyla ukotvena k důvěryhodnému skoku.

Vrstvěte posluchač a politiku repozitáře

Vazba je samostatná kontrola a často ta jednodušší. Listen 10.8.0.1:443 rozhoduje, které sockety existují, a požadavek nemůže vybrat hostitele na socketu, který nebyl nikdy otevřen. Cenou je pořadí spouštění: pokud je rozhraní tunelu při startu Apache vypnuté, vazba selže a služba nenaběhne. Spárujte ji s pořadím jednotek, nebo ji navázejte na adresu, která existuje nezávisle na tunelu.

Oprávnění cest zůstávají v AuthzSVNAccessFile. Platný účet pro web není totéž oprávnění jako zápis do cesty projektu a síťové pravidlo to nemění.

Sledujte slučování sekcí, když blok leží ve vloženém souboru. Apache slučuje autorizační kontejnery přes vnořené sekce a nejspecifičtější odpovídající sekce může požadavek nahradit místo aby jej doplnila, takže pravidlo na /svn se nemusí dostat na /svn/repo/trunk, jakmile užší sekce definuje vlastní.

Dokažte obě odmítnutí, než to označíte za hotové

Otestujte čtyři požadavky, ne jeden. Uvnitř VPN s platným účtem byste měli dostat výpis repozitáře. Uvnitř VPN s chybným heslem byste měli dostat 401, nikoli výpis. Zvenčí VPN s platnými údaji byste měli dostat 403 a stejný veřejný požadavek na alternativní název hostitele musí selhat stejně.

Jeden příkaz na případ stačí: curl -sI -u user:pass https://svn.example.com/svn/repo/, pak přečtěte stavový řádek. Zopakujte i fungující případ skutečným klientem, protože svn info procvičuje metody DAV, které budou používat commity a aktualizace.

Pokud kterýkoli ze čtyř výsledků neodpovídá politice, kterou jste zamýšleli, konfigurace není hotová a přejmenování hostitele to nezmění.

Související články