El siguiente es un ejemplo de configuración para implementar una VPN AnyConnect en un firewall Cisco ASA (WebVPN, en lenguaje ASA) con su propio GroupPolicy y donde podemos limitar los accesos a los recursos internos de la red de acuerdo a los perfiles de cada usuario, evitando enrutar todo el tráfico de su red hacia nuestra infraestructura.
Paso 1: Habilitación de WebVPN.
En este caso habilitaremos la vpn en la interface OUTSIDE (tengo la costumbre de definir las variables en dispositivos Cisco con letras mayúsculas, así que probablemente muchos de ustedes deberán reemplazar por "outside" simplemente. Otra cosa relevante es que es necesario descargar los respectivos paquetes (.pkg) de los sistemas operativos donde correrán AnyConnect los usuarios. En este caso usaremos la versión 4.9 que es compatible con BigSur en Mac. Para descargarla deben ir a su cuenta Cisco.com en el link https://software.cisco.com/download/home/286281283/type/282364313/release/4.9.06037 y de alguna manera (SCP, USB, etc) subirla al disco duro del ASA.
sysopt connection permit-vpn
webvpn
enable OUTSIDE
anyconnect-essentials
anyconnect image disk0:/anyconnect-macos-4.9.06037-webdeploy-k9.pkg
anyconnect image disk0:/anyconnect-win-4.9.06037-webdeploy-k9.pkg
anyconnect enable
no tunnel-group-list enable
http redirect outside 80
2. Creación del Pool de IP que se entregarán a los usuarios
Este es el bloque IP que obtendrán los usuarios al conectarse a la VPN. Es importante que sea único dentro de la infraestructura y no se tope con alguno existente. En este caso estoy dándole el nombre Pool_VPN_AnyConnect_GRUPO1 y asignaré direcciones desde la 172.21.17.1 a la .10. Si tienen más usuarios en este grupo pueden ampliar el rango a su antojo. Otra cosa que haremos será crear un objeto llamado VPN_GRUPO1 con la subred que asignaremos a los usuarios. Esto nos permitirá referenciar más fácilmente a ese objeto luego en la configuración.
ip local pool POOL_VPN_AnyConnect_GRUPO1 172.21.17.1-172.21.17.10 mask 255.255.255.0
object network VPN_GRUPO1
subnet 172.21.17.0 255.255.255.0
3. Excepción de NAT
Algo importante es negar que el tráfico de la VPN pase por el proceso de NAT del firewall. Eso se logra con un solo comando:
nat (INSIDE,OUTSIDE) source static any any destination static VPN_GRUPO1 VPN_GRUPO1 no-proxy-arp route-lookup
4. Creación de las ACL para restringir/permitir acceso a recursos internos
Normalmente no queremos que un usuario a quien le damos acceso por una VPN tenga autorización a toda la infraestructura interna de la red. Para restringir este acceso se implementa una lista de acceso. En este caso estoy creando una única ACL de tipo estándar llamada SplitTunnel_GRUPO1_AnyConnect. Aparte de restringir el acceso, esta ACL también servirá para inyectarle al usuario las rutas específicas hacia nuestros recursos, evitando enviarle una ruta por defecto que generaría que todo su tráfico pase por nuestra infraestructura.
Esta lista de acceso está permitiendo que se genere una ruta hacia la red 172.16.0.0/16 y hacia un host 10.10.58.149. como es una ACL estándar, todo el tráfico IP hacia esos destinos estará permitido. Si buscan restringir el acceso en base a IP de origen/destino y puertos TCP/IDP en ese caso convendría una ACL extendida.
access-list SplitTunnel_GRUPO1_AnyConnect standard permit 172.16.0.0 255.255.255.0
access-list SplitTunnel_GRUPO1_AnyConnect standard permit host 10.10.58.149
5. Creación del GroupPolicy
El paso siguiente es crear una política de grupo, ya que luego todos los usuarios que asociemos a este grupo se regirán por los parámetros que pongamos a continuación. Esto permite crear diversos grupos de usuarios con diferentes opciones y limitaciones de acceso.
Algo relevante es poner atención en el valor de la opción dns-server, ya que este será el servidor DNS que utilicen los usuarios en sus PC cuando se conecten a la infraestructura. (Es probable que la CLI envíe un mensaje de advertencia de que no hemos creado el tunnel-group respectivo. Por ahora ignoraremos el mensaje ya que lo crearemos más adelante)
group-policy GroupPolicy_GRUPO1 internal
group-policy GroupPolicy_GRUPO1 attributes
wins-server value 10.1.1.1
dns-server value 10.1.1.2
vpn-tunnel-protocol ssl-client
group-lock value GRUPO1
split-tunnel-policy tunnelspecified
split-tunnel-network-list value SplitTunnel_GRUPO1_AnyConnect
default-domain value netlayer.cl
webvpn
anyconnect keep-installer installed
anyconnect ask none default anyconnect
anyconnect dpd-interval client 30
6. Creación del Tunnel-Group
En el Tunnel Group asociaremos el bloque IP que creamos en el paso 2 con el Group Policy que creamos en el paso 5.
tunnel-group GRUPO1 type remote-access
tunnel-group GRUPO1 general-attributes
address-pool POOL_VPN_AnyConnect_GRUPO1
default-group-policy GroupPolicy_GRUPO1
tunnel-group GRUPO1 webvpn-attributes
group-alias GRUPO1 enable
7. Creación y asignación de usuarios
Finalmente, una vez creados los parámetros de la VPN, debemos crear nuestros usuarios. Como estamos trabajando por grupos de VPN, podemos agregar N usuarios a cada grupo, y estos heredarán los valores que se le han asignado. Como ejemplo crearé 2 usuarios que añadiré al grupo GRUPO1
username usuario1 password dx4n/mRGCNwhQQ==
username usuario1 attributes
vpn-group-policy GroupPolicy_GRUPO1
vpn-filter value SplitTunnel_GRUPO1_AnyConnect
group-lock value GRUPO1
service-type remote-access
username usuario2 password JNzf5we9nZRdNA
username usuario2 attributes
vpn-group-policy GroupPolicy_GRUPO1
vpn-filter value SplitTunnel_GRUPO1_AnyConnect
group-lock value GRUPO1
service-type remote-access
Nota: Para crear contraseñas aleatorias rápidamente me gusta usar el siguiente comando de OpenSSL (disponible en Linux/Mac pero también en Windows si se instala esta aplicación)
paulocolomes@macbook % openssl rand -base64 10
JNzf5we9nZRdNA==
8. Opcional (Acceso a DMZ)
Con los pasos configurados anteriormente estamos permitiendo el acceso remoto a nuestra red interna, pero en el caso de tener una DMZ conectada al mismo ASA, se puede permitir el tráfico con un comando adicional.
nat (DMZ,OUTSIDE) source static DMZ DMZ destination static VPN_GRUPO1 VPN_GRUPO1
Y con eso queda listo. Cada vez que necesitemos crear un grupo nuevo se debe replicar el mismo procedimiento. Esta es la configuración de resumen realizada:
sysopt connection permit-vpn
webvpn
enable OUTSIDE
anyconnect-essentials
anyconnect image disk0:/anyconnect-macos-4.9.06037-webdeploy-k9.pkg
anyconnect image disk0:/anyconnect-win-4.9.06037-webdeploy-k9.pkg
anyconnect enable
no tunnel-group-list enable
http redirect outside 80
ip local pool POOL_VPN_AnyConnect_GRUPO1 172.21.17.1-172.21.17.10 mask 255.255.255.0
object network VPN_GRUPO1
subnet 172.21.17.0 255.255.255.0
nat (INSIDE,OUTSIDE) source static any any destination static VPN_GRUPO1 VPN_GRUPO1 no-proxy-arp route-lookup
access-list SplitTunnel_GRUPO1_AnyConnect standard permit 172.16.0.0 255.255.255.0
access-list SplitTunnel_GRUPO1_AnyConnect standard permit host 10.10.58.149
group-policy GroupPolicy_GRUPO1 internal
group-policy GroupPolicy_GRUPO1 attributes
wins-server value 10.1.1.1
dns-server value 10.1.1.2
vpn-tunnel-protocol ssl-client
group-lock value GRUPO1
split-tunnel-policy tunnelspecified
split-tunnel-network-list value SplitTunnel_GRUPO1_AnyConnect
default-domain value netlayer.cl
webvpn
anyconnect keep-installer installed
anyconnect ask none default anyconnect
anyconnect dpd-interval client 30
tunnel-group GRUPO1 type remote-access
tunnel-group GRUPO1 general-attributes
address-pool POOL_VPN_AnyConnect_GRUPO1
default-group-policy GroupPolicy_GRUPO1
tunnel-group GRUPO1 webvpn-attributes
group-alias GRUPO1 enable
username usuario1 password dx4n/mRGCNwhQQ==
username usuario1 attributes
vpn-group-policy GroupPolicy_GRUPO1
vpn-filter value SplitTunnel_GRUPO1_AnyConnect
group-lock value GRUPO1
service-type remote-access
username usuario2 password JNzf5we9nZRdNA
username usuario2 attributes
vpn-group-policy GroupPolicy_GRUPO1
vpn-filter value SplitTunnel_GRUPO1_AnyConnect
group-lock value GRUPO1
service-type remote-access
nat (DMZ,OUTSIDE) source static DMZ DMZ destination static VPN_GRUPO1 VPN_GRUPO1