For the last few years, Cisco has been attempting to do away with what they call the Cisco EZVPN client. This has been the solution used by many corporate users in the mobile workforce for secure access to enterprise data. The need for mobility certainly isn’t going away and Cisco has a new solution for this called Anyconnect. While the EZVPN client used IPSec, Anyconnect uses SSL to create a secure tunnel. From the wire, this connection looks very much like accessing any ecommerce site and alleviates some of the challenges of using IPSec in an adhoc basis. In this article, we will start with a very basic ASA configuration and add a very basic Anyconnect configurations. There is actually a command that we can use to show us many of the configuration steps. We will also look at some of the additional items that typically need to be configured to achieve a basic Anyconnect environment.
Let’s start with the simplest possible ASA configuration. This can be achieved by using the “configure factory-default” command followed by configuring an outside IP address and default route. The relevant configuration is posted below. This output is from an ASA5505, so it uses VLANs as the layer 3 interfaces.
! interface Ethernet0/0 switchport access vlan 2 ! interface Ethernet0/1 ! ! interface Vlan1 name if inside security-level 100 ip address 192.168.1.1 255.255.255.0 ! interface Vlan2 name if outside security-level 0 ip address 192.0.2.2 255.255.255.0 ! ! global (outside) 1 interface nat (inside) 1 0.0.0.0 0.0.0.0 route outside 0.0.0.0 0.0.0.0 192.0.2.1 1 ! !
The configuration above is sufficient in order to achieve the NAT and Firewall configuration for the following image.
Our challenge now is to configure a remote access VPN using Anyconnect for the mobile user. As I previously mentioned, the ASA has a command that will get us on the right track. This is the global configuration command “vpnsetup ssl-remote-access steps”. This command doesn’t do anything to the configuration, but is a way to see many of the steps necessary. It is good information to copy and paste into your favorite text editor.
ciscoasa(config)# vpnsetup ssl-remote-access steps Steps to configure a remote access SSL VPN remote access connection and AnyConnect with examples: 1. Configure and enable interface interface GigabitEthernet0/0 ip address 10.10.4.200 255.255.255.0 nameif outside no shutdown interface GigabitEthernet0/1 ip address 192.168.0.20 255.255.255.0 nameif inside no shutdown 2. Enable WebVPN on the interface webvpn enable outside 3. Configure default route route outside 0.0.0.0 0.0.0.0 10.10.4.200 4. Configure AAA authentication and tunnel group tunnel-group DefaultWEBVPNGroup type remote-access tunnel-group DefaultWEBVPNGroup general-attributes authentication-server-group LOCAL 5. If using LOCAL database, add users to the Database username test password [email protected] username test attributes service-type remote-access Proceed to configure AnyConnect VPN client: 6. Point the ASA to an AnyConnect image webvpn svc image anyconnect-win-2.1.0148-k9.pkg 7. enable AnyConnect svc enable 8. Add an address pool to assign an ip address to the AnyConnect client ip local pool client-pool 192.168.1.1-192.168.1.254 mask 255.255.255.0 9. Configure group policy group-policy DfltGrpPolicy internal group-policy DfltGrpPolicy attributes vpn-tunnel-protocol svc webvpn
In many of the commands above, we find reference to “svc”. In previous versions, Anyconnect was known as the SSL VPN Client (aka SVC). Some people also refer to it as the SSL Thick Client. Of these commands, we will need to make some modifications. First of all, we don’t need to do steps 1 or 3 at all. Our basic ASA configuration already had IP addresses configured and a default gateway. So let’s go through the other seven remaining steps.
First, we simply need to enable SSL VPN on the outside interface. This will enable our ASA to listen for connections to TCP port 443 for SSL/TLS and UDP port 443 for the preferred DTLS. When DTLS fails, the Anyconnect client utilizes SSL/DTLS
webvpn enable outside
The next set of commands that it looks like we should implement are found in step four.
tunnel-group DefaultWEBVPNGroup type remote-access tunnel-group DefaultWEBVPNGroup general-attributes authentication-server-group LOCAL
These commands will throw some warnings and are unnecessary because they are the default. Even if you enter them, you cannot see the output without doing “show running-config all”. Notice there is no output for “show running-config tunnel-group” even after entering the commands.
ciscoasa(config)# tunnel-group DefaultWEBVPNGroup type remote-access ^ ERROR: % Invalid input detected at '^' marker. ciscoasa(config)# ciscoasa(config)# tunnel-group DefaultWEBVPNGroup general-attributes ciscoasa(config-tunnel-general)# authentication-server-group LOCAL WARNING: local database is empty! Use 'username' command to define local users. ciscoasa(config-tunnel-general)# show run tunnel-group ciscoasa(config-tunnel-general)# exit ciscoasa(config)# show run tunnel-group ciscoasa(config)# show run all tunnel-group tunnel-group DefaultWEBVPNGroup general-attributes no address-pool no ipv6-address-pool authentication-server-group LOCAL ciscoasa(config)#
So we could have basically skipped this step. Cisco actually left out a critical configuration regarding the address pool attachment to the tunnel group, but we will return to that in a minute.
The next step is to configure a username and password. In the enterprise, we usually offload this to Radius or LDAP so the users can access the VPN using their primary credentials. In this case we’ll actually configure the username and password directly on the ASA. It is important to set their service type to “remote-access”. This keeps them from getting a shell prompt on the firewall.
username test password [email protected] username test attributes service-type remote-access
We will combine the next two steps. This is configuring the software image(s) that are to be used for the Anyconnect clients. The reason I said image(s) is that most environments need to support more than just Windows. The appropriate images can be downloaded from Cisco using your TAC credentials. Our configuration example will use the sequence numbers to demonstrate how to use multiple images. Also worth mentioning is that this “webvpn” should be entered from global configuration mode. If you are in user configuration mode from the previous step, webvpn is a subcommand in user attributes. So to get into the proper context, exit to global configuration mode.
webvpn svc image disk0:anyconnect-win-2.3.0254-k9.pkg 1 svc image disk0:yourmacimage.dmg 2 svc enable
Since this is a remote access VPN, the clients will need IP addresses. I always use a network range that is different than the interfaces on the ASA. Since the example pool will overlap with our internal address, we will change the addresses. Be careful to use a start AND end address. If an end address is not included, the pool only contains the single address listed.
ip local pool client-pool 192.168.2.1-192.168.2.254 mask 255.255.255.0
The final step in the example is to enable the default group policy for Anyconnect (aka SVC). The first command below is actually a default and will produce an error telling us this.
ciscoasa(config)# group-policy DfltGrpPolicy internal ERROR: Group Policy DfltGrpPolicy already exists. ERROR: Failed to add group-policy DfltGrpPolicy ciscoasa(config)# ciscoasa(config)# group-policy DfltGrpPolicy attributes ciscoasa(config-group-policy)# ciscoasa(config-group-policy)# vpn-tunnel-protocol svc webvpn
Attach The Address Pool
So what else? Cisco left a couple of things out of their configuration steps. The first thing is related to the ‘ip local pool’. Notice that it is called “client-pool”. However, “client-pool” isn’t attached to anything. Let’s attach it to our “DefaultWEBVPNGroup” tunnel-group.
tunnel-group DefaultWEBVPNGroup general-attributes address-pool client-pool
The next thing that is necessary based on our initial configuration is a nat exemption rule. Without this, traffic going toward the Anyconnect clients will be source address translated like all Internet bound traffic. That behavior causes the connections that go through the tunnel to be broken. To enable NAT exemption and resolve this, we create an ACL that identifies the traffic and attach it to a “nat 0” rule to instruct the ASA not to NAT the traffic.
access-list NONAT extended permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 nat (inside) 0 access-list NONAT
Another thing that may need to be considered is if the corporate DNS server and domain name should be used. If so, the following commands would instruct the Anyconnect clients to direct all requests to the indicated DNS server.
group-policy DfltGrpPolicy attributes dns-server value default-domain value
The default configuration tunnels all traffic back to the ASA by manipulating the PC’s routing table with a default route through the Anyconnect tunnel. This is often considered a more secure method since it may keep the vpn endpoint from participating in a botnet while it is connected to the vpn. If the situation dictates that the remote users have direct access to the internet, split tunneling needs to be configured. This requires creating a standard acl that indicates the networks to be tunneled. This route or routes is what is passed to VPN client and subsequently the client PC’s routing table. Whatever matches these entries are tunneled back to the ASA (as opposed to tunneling everything back to the ASA). Like the dns settings, the split tunnel acl is then attached to the group-policy.
access-list SPLIT standard permit 192.168.1.0 255.255.255.0 group-policy DfltGrpPolicy attributes split-tunnel-policy tunnelspecified split-tunnel-network value SPLIT
This initial configuration allows users to connect to the outside of the ASA via https. Once connected, they will have the choice to launch an Anyconnect session. If users are only using Anyconnect, the ASA can auto launch that for the users upon connection. To set Anyconnect as the default and launch it automatically, enter the following commands.
group-policy DfltGrpPolicy attributes webvpn svc ask none default svc
Self Signed Certificates
The final thing that I would mention is that the ASA has a habit of regenerating its certificate with each reboot. Ideally, we would use a trusted third party CA (like GoDaddy, Thawte, Verisign, Entrust, Comodo, etc) to decrease the possibility for a man-in-the-middle attack against VPN users and to produce a better end user experience. However, if a self-signed certificate is the only option, it should be statically configured and attached to the outside interface.
ciscoasa(config)# crypto ca trustpoint SELF ciscoasa(config-ca-trustpoint)# enroll ciscoasa(config-ca-trustpoint)# enrollment self ciscoasa(config-ca-trustpoint)# fqdn myasa.mydom.com ciscoasa(config-ca-trustpoint)# subject cn=myasa.mydom.com,dc=mycom,dc=com ciscoasa(config-ca-trustpoint)# exit ciscoasa(config)# crypto ca enroll SELF WARNING: The certificate enrollment is configured with an fqdn that differs from the system fqdn. If this certificate will be used for VPN authentication this may cause connection problems. Would you like to continue with this enrollment? [yes/no]: yes % The fully-qualified domain name in the certificate will be: myasa.mydom.com % Include the device serial number in the subject name? [yes/no]: no Generate Self-Signed Certificate? [yes/no]: yes ciscoasa(config)# ssl trust-point SELF outside
If you want to look at the certificate, the “show crypto ca certificates SELF” will show the certificate associated with the trustpoint “SELF”.
ciscoasa(config)# show crypto ca certificates SELF Certificate Status: Available Certificate Serial Number: 2c873d4f Certificate Usage: General Purpose Public Key Type: RSA (1024 bits) Issuer Name: hostname=myasa.mydom.com cn=myasa.mydom.com dc=mycom dc=com Subject Name: hostname=myasa.mydom.com cn=myasa.mydom.com dc=mycom dc=com Validity Date: start date: 00:47:47 UTC Feb 18 2012 end date: 00:47:47 UTC Feb 15 2022 Associated Trustpoints: SELF
Our final configuration looks like the following.
ciscoasa# show run ! ! interface Ethernet0/0 switchport access vlan 2 ! interface Ethernet0/1 ! ! ! interface Vlan1 nameif inside security-level 100 ip address 192.168.1.1 255.255.255.0 ! interface Vlan2 nameif outside security-level 0 ip address 192.0.2.2 255.255.255.0 ! access-list NONAT extended permit ip 192.168.1.0 255.255.255.0 192.168.2.0 255.255.255.0 access-list SPLIT standard permit 192.168.1.0 255.255.255.0 ! ! ip local pool client-pool 192.168.2.1-192.168.2.254 mask 255.255.255.0 ! ! global (outside) 1 interface nat (inside) 0 access-list NONAT nat (inside) 1 0.0.0.0 0.0.0.0 route outside 0.0.0.0 0.0.0.0 192.0.2.1 1 ! ! crypto ca trustpoint SELF enrollment self fqdn myasa.mydom.com subject-name cn=myasa.mydom.com,dc=mycom,dc=com crl configure crypto ca certificate chain SELF certificate 2c873d4f 30820243 308201ac a0030201 0202042c 873d4f30 0d06092a 864886f7 0d010105 05003066 31133011 060a0992 268993f2 2c640119 1603636f 6d311530 13060a09 92268993 f22c6401 1916056d 79636f6d 31183016 06035504 03130f6d 79617361 2e6d7964 6f6d2e63 6f6d311e 301c0609 2a864886 f70d0109 02160f6d 79617361 2e6d7964 6f6d2e63 6f6d301e 170d3132 30323138 30303437 34375a17 0d323230 32313530 30343734 375a3066 31133011 060a0992 268993f2 2c640119 1603636f 6d311530 13060a09 92268993 f22c6401 1916056d 79636f6d 31183016 06035504 03130f6d 79617361 2e6d7964 6f6d2e63 6f6d311e 301c0609 2a864886 f70d0109 02160f6d 79617361 2e6d7964 6f6d2e63 6f6d3081 9f300d06 092a8648 86f70d01 01010500 03818d00 30818902 818100c4 2824ae16 affee400 8df62cb3 d6b94269 3720ba46 61941b9e e97b7663 fe70b570 9660b396 58e57d2e 71b692d3 1ca62053 0b366da0 41efcc82 e2345d5c fda52514 ccce7a75 0fd98ec7 b72d8d7d 358ce7c4 1e20a06f 53a6ec61 13b870dc 30bfba54 7c416b26 a1247933 2839c955 7421bdc4 cb7201b1 d9c77999 28059050 d84b6302 03010001 300d0609 2a864886 f70d0101 05050003 81810065 9c1dd7b1 3c304910 01779541 0ee21e87 758c2f12 d98bd60f 1778550a b5dd986d d170f841 7ea48921 aed59caa b3211f7e 41fac227 f1da9bcb 9ba86bb3 d8ce32e3 bd8684af 33a9a828 b158221b 0ced4f13 4ff81b76 cb3d2f0b 43cd8e84 5f2b262e 862d4708 0443f6a3 2f956b5e 7eda1240 7bdcdd2b d84b0f06 06738adb f364e3 quit ssl trust-point SELF outside webvpn enable outside svc image disk0:/anyconnect-win-2.3.0254-k9.pkg 1 svc image disk0:/macimg.dmg 2 group-policy DfltGrpPolicy attributes dns-server value 192.168.1.100 vpn-tunnel-protocol svc webvpn split-tunnel-policy tunnelspecified split-tunnel-network-list value SPLIT default-domain value mydomain.com username test password YnRg/dbHpQ2tGlTq encrypted username test attributes service-type remote-access tunnel-group DefaultWEBVPNGroup general-attributes address-pool client-pool
Testing our Configuration
To test this configuration, we simply need to point the outside user’s web browser to the url that represents the outside of the ASA. For example “https://192.0.2.2” or preferably “https://myasa.example.com”. The user should be presented a login prompt. After authenticating, Anyconnect will attempt to install. The user may be prompted to accept this a couple of times. After Anyconnect installs, it will launch and connect. To test connectivity, the user can ping something inside (192.168.1.5 in this example is an inside host).
To further inspect the Anyconnect client, the user can double click the lock in the system tray. When it opens, a tabbed view will be presented. On the statistics tab, the “Datails” button presents a more verbose view.
Within this view the statistics tab will show input and output statistics which might provide clues if there are any issues.
The route tab show which destinations would have tunneled traffic. This should look familiar. It is derived from the split tunnel configuration.
This article covered very basic Anyconnect configuration. In future articles, I hope to go into more detail about certificate configuration, migration to 8.4 and AAA authentication.