Restrinxir un host de Subversion aos usuarios de VPN con Apache 2.4
ServerName elixe un host virtual; non limita quen se conecta. Esixa o rango de VPN e un usuario real do repositorio, e despois demostre ambas as denegacións.
Apuntar un host virtual de Subversion a un enderezo de VPN cambia que sitio responde a unha petición, non quen ten permiso para enviarlle unha. A comprobación de acceso ocorre despois, segundo as regras da sección que coincidiu co URL, e o nome do host nunca entra nesa decisión. Se ServerName foi o seu único cambio, o repositorio é exactamente igual de accesible ca onte. Hai que responder dúas preguntas separadas na configuración: que socket aceptou a conexión e que identidade levaba a petición.
Que decide realmente ServerName
O aloxamento virtual baseado en nome compara a cabeceira Host coas entradas ServerName e ServerAlias, escolle un host e deixa que ese host atenda a petición. A conexión en si xa fora aceptada por un socket Listen que pertence ao servidor, non ao host. Por iso un nome que parece privado non ofrece ningunha protección: calquera cliente que acade o socket pode enviar esa cabeceira Host. O nome é unha clave de encamiñamento, e as claves de encamiñamento escólleas quen chama.
Pode ver a asignación sen adiviñar. apachectl -S imprime cada host, o seu porto e os seus nomes, e marca cal é o predeterminado para o enderezo.
RequireAll é o contedor que fai obrigatorias ambas as comprobacións
Apache 2.4 envolve as directivas Require dunha soa sección nun RequireAny implícito, así que dúas directivas espidas significan que calquera das dúas abonda. Engada o contedor e o significado invértese:
<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 necesita ambas as condicións: un enderezo de orixe dentro do rango do túnel e un usuario que o repositorio acepte. Iso é o que debería significar só-VPN para un URL de Subversion. A referencia de mod_authz_core documenta as regras do contedor. Manteña o bloque dentro do Location existente do repositorio e deixe no seu sitio as directivas DAV que xa funcionan, porque este fragmento non substitúe nin AuthType nin o ficheiro de contrasinais nin a autorización a nivel de ruta.
A proba de orixe vén de mod_authz_host, así que confirme que está cargado antes de depurar calquera outra cousa: apachectl -M | grep authz_host.
O enderezo que Apache avalía é o enderezo do socket
Require ip compara co enderezo que Apache rexistrou para a conexión, que non sempre é o enderezo que o cliente cre ter.
Cando a VPN encamiña os seus enderezos sen tradución, Apache ve o enderezo do túnel e 10.8.0.0/24 coincide. Cando unha pasarela traduce, Apache ve a pasarela e a regra non coincide silenciosamente con nada; o mesmo ocorre detrás dun balanceador que remata TLS diante do host. Para ese caso existe mod_remoteip. RemoteIPHeader X-Forwarded-For xunto con RemoteIPTrustedProxy para o balanceador substitúe o enderezo rexistrado, e só entón o rango ten con que comparar.
Confiar nunha cabeceira de reenvío arbitraria é peor que non ter ningunha regra. Calquera cliente pode enviar X-Forwarded-For con 10.8.0.9 e satisfacer unha comprobación de rango que nunca estivo ancorada a un salto de confianza.
Superpoña o oínte e a política do repositorio
A vinculación é un control aparte e a miúdo o máis simple. Listen 10.8.0.1:443 decide que sockets existen, e unha petición non pode escoller un host nun socket que nunca se abriu. O custo é a orde de arranque: se a interface do túnel está caída cando Apache arrinca, a vinculación falla e o servizo non levanta. Emparelládea coa orde de unidades, ou vincule a un enderezo que exista independentemente do túnel.
Os permisos de ruta quedan en AuthzSVNAccessFile. Unha conta válida para o sitio non é a mesma concesión que o acceso de escritura a unha ruta de proxecto, e a regra de rede non o cambia.
Vixíe a fusión de seccións cando o bloque está nun ficheiro incluído. Apache fusiona contedores de autorización entre seccións aniñadas e a sección coincidente máis específica pode substituír o requisito en lugar de engadirse a el, así que unha regra en /svn pode non chegar a /svn/repo/trunk en canto unha sección máis estreita defina a súa.
Demostre ambas as denegacións antes de dalo por feito
Probe catro peticións, non unha. Dentro da VPN cunha conta válida debería obter a listaxe do repositorio. Dentro da VPN cun contrasinal incorrecto debería obter 401 en lugar dunha listaxe. Desde fóra da VPN con credenciais válidas debería obter 403, e a mesma petición pública contra un nome de host alternativo debe fallar igual.
Un comando por caso abonda: curl -sI -u user:pass https://svn.example.com/svn/repo/, e despois lea a liña de estado. Repita tamén o caso que funciona co cliente real, porque svn info exercita os métodos DAV que usarán os commits e as actualizacións.
Se calquera dos catro resultados non concorda coa política que pretendía, a configuración non está rematada, e cambiar o nome do host non o cambiará.