Tuesday, December 19, 2017
Cisco ASA SSL VPN with Active Directory
Cisco ASA SSL VPN with Active Directory
There is little doubt the bring-your-own-device (BYOD) strategy is becoming a popular method to access company resources. As technical professionals, it is our responsibility to allow the flexibility of BYOD without compromising too much on security. This post will provide a sample solution of how to configure the Cisco ASA device to utilize Active Directory authentication and authorization for SSL VPN remote access.
The following components are used for this configuration:
- Cisco 5500 Series ASA that runs ASA 8.4(2)
- Apple iPhone 4S with iOS 6.0.1
- Cisco AnyConnect Secure Mobility Client v3.0.09097
- Active Directory Domain Controller (Microsoft Windows Server 2012)
| Device | Interface | IP Address | Name |
|---|---|---|---|
| ASA | G0/0 (outside) | 203.0.113.251/24 | vpn.example.com |
| - | G0/1 (inside) | 192.168.206.1/24 | ciscoasa.corp.example.com |
| ISP | - | 203.0.113.1/24 | - |
| DC01 | Ethernet | 192.168.206.11/24 | dc01.corp.example.com |

Active Directory and DNS
This post may seem verbose, but the objective is to outline a sample lab for anyone to reconstruct in their own testing environment. That being stated, our scenario will start with a clean build of Windows Server 2012 in Server Core mode.
Tip: You can open a separate console window (for PowerShell) from the default cmd.exe shell by running the command start powershell.
The following table displays the properties and the values we will set for the initial configuration of the server:
| Name | Value |
|---|---|
| Computer Name | dc01 |
| IP Address and Subnet Mask | 192.168.206.11/24 |
| Default Gateway | 192.168.206.1 |
| DNS Servers | 208.67.222.222 208.67.220.220 |
# Time Zone
Use the tzutil command to display/list/set the time zone. First, display the current setting. Run the following command from an elevated PowerShell prompt:
PS> tzutil /g
To list (with pager) all valid time zone IDs and display names, run the following pipeline of commands from an elevated PowerShell prompt:
PS> tzutil /l | Out-Host -Paging
Set the time zone. For example, if your computer is currently located in the Eastern Standard Time time zone you would run the following command from an elevated PowerShell prompt:
PS> tzutil /s Eastern Standard Time
# Network Configuration and Hostname
Assign a static IPv4 address, netmask, and gateway to the network interface. Run the following command from an elevated PowerShell prompt:
PS> New-NetIPAddress -IPAddress 192.168.206.11 -PrefixLength 24 -DefaultGateway 192.168.206.1 -InterfaceIndex (Get-NetAdapter).ifindex
We will initially be using the external OpenDNS name servers for name resolution in our scenario. After we install the DNS Server role in the upcoming steps, these servers will then be set automatically as forwarders for our internal DNS. Run the following command from an elevated PowerShell prompt:
PS> Set-DNSClientServerAddress -InterfaceIndex (Get-NetAdapter).ifindex -ServerAddresses ("208.67.222.222","208.67.220.220")
Rename the server. This operation will also reboot the computer for the change to take effect. Run the following command from an elevated PowerShell prompt:
PS> Rename-Computer -NewName dc01 -Restart -Force
# Active Directory Domain Services Role
After our base configuration is complete, the next step is to install the AD Domain Services role. Run the following command from an elevated PowerShell prompt:
PS> Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
# AD Forest
Install a new AD Forest at the Windows 2012 Domain and Forest Functional Level. This operation will also install and configure the AD-integrated DNS Server role by default. Run the following command from an elevated PowerShell prompt:
PS> Install-ADDSForest -DomainName "corp.example.com" -DomainNetbiosName "EXAMPLE" -ForestMode 5 -DomainMode 5
You will be prompted to create a Directory Services Restore Mode (DSRM) password, and the server will be rebooted after the operation is complete.
# DNS
This step is not required, but it is a best practice to create a DNS reverse lookup zone (or zones) for your AD domain. Run the following command from an elevated PowerShell prompt:
PS> Add-DnsServerPrimaryZone -ReplicationScope "Forest" -NetworkId "192.168.206.0/24" -DynamicUpdate "Secure"
Add DNS resource records for the Cisco ASA device. The following pipeline of commands will add a single DNS A (and associated PTR) resource record type to both the primary forward and reverse lookup zones. Run the following from an elevated PowerShell prompt:
PS> Get-DnsServerZone corp.example.com | Add-DnsServerResourceRecordA -Name ciscoasa -IPv4Address 192.168.206.1 -CreatePtr
As stated earlier, we can verify the external OpenDNS servers are now set as forwarders for the DNS server. Run the following command from an elevated PowerShell prompt:
PS> Get-DnsServerForwarder
UseRootHint : True
Timeout(s) : 3
EnableReordering : True
IPAddress : {208.67.222.222, 208.67.220.220}
ReorderedIPAddress : {208.67.222.222, 208.67.220.220}
# Login Distinguished Name (DN) User
The Login DN represents a user record in the LDAP server (Active Directory) that the administrator uses for binding from the ASA device. When binding, the ASA authenticates to the server using the Login DN and the Login Password.
The following command will create the asa-ldapq AD user in the default AD Users container. Since were creating this user account in a test environment, we will simply set some �weak� password options. Run the following command from an elevated PowerShell prompt:
PS> New-ADUser -Name asa-ldapq -SamAccountName asa-ldapq -DisplayName ASA LDAP Query -CannotChangePassword $true -PasswordNeverExpires $true -AccountPassword (ConvertTo-SecureString Pa$$worD1 -AsPlainText -Force) -Enabled $true
# VPN Security Group
We need to create a global security group that will �filter� the users who have remote access via VPN. Our upcoming ASA configuration will reference the memberOf attribute for this specific security group. Run the following command from an elevated PowerShell prompt:
PS> New-ADGroup -Name VPN -GroupScope Global -GroupCategory Security -DisplayName VPN -samAccountName VPN
# Test User Accounts
Lets create three normal domain user account objects. We can compose a simple CSV file for our user objects and their "core" properties. Run the following commands from an elevated PowerShell prompt:
PS> SamAccountName,GivenName,Surname,DisplayName > $HOMEDocumentsusers.csv
PS> "jsmith,Joe,Smith,Joe Smith" >> $HOMEDocumentsusers.csv
PS> "sjackson,Sally,Jackson,Sally Jackson" >> $HOMEDocumentsusers.csv
PS> "fbeans,Frank,Beans,Frank Beans" >> $HOMEDocumentsusers.csv
Now lets verify the CSV file is syntactically correct. Run the following command from an elevated PowerShell prompt:
PS> cat $HOMEDocumentsusers.csv
SamAccountName,GivenName,Surname,DisplayName
jsmith,Joe,Smith,Joe Smith
sjackson,Sally,Jackson,Sally Jackson
fbeans,Frank,Beans,Frank Beans
With the CSV file successfully created, we will move on to creating the accounts in AD. Run the following command from an elevated PowerShell prompt:
PS> $userpw = Pa$$worD1
PS> Import-CSV "$HOMEDocumentsusers.csv" | % { New-ADUser -Name $_.SamAccountName -GivenName $_.GivenName -SurName $_.SurName -DisplayName $_.DisplayName -AccountPassword (ConvertTo-SecureString $userpw -AsPlainText -Force) -Enabled $true }
Add the first two users as members of the VPN security group. We will leave Frank Beans out to test the requirement that a normal domain user, that is not a member of the VPN security group, will not be able to successfully establish a remote access VPN connection. Run the following command from an elevated PowerShell prompt:
PS> Add-ADGroupMember VPN -Members jsmith,sjackson
Verify the users were added to the VPN security group. Run the following command from an elevated PowerShell prompt:
PS> Get-ADGroupMember -Id vpn | select Name
Name
----
jsmith
sjackson
Cisco ASA
We are now ready to configure our Cisco ASA device. This tutorial assumes youve already done the basic configuration for the ASA (users, enable password, remote administration access, etc.).
# Names
Lets start by setting our domain name followed by an alias for the domain controller. Note: The domain name may already be set if you already configured SSH on the device. Run the following commands:
ciscoasa# conf t
ciscoasa(config)# domain-name corp.example.com
ciscoasa(config)# name 192.168.206.11 dc01
# Interfaces
If you havent already done so, configure the interfaces with a logical address and place in the proper security zone. Run the following commands (and subcommands):
ciscoasa(config)# int g0/0
ciscoasa(config-if)# nameif outside
ciscoasa(config-if)# security-level 0
ciscoasa(config-if)# ip address 203.0.113.251 255.255.255.0
ciscoasa(config-if)# no shut
ciscoasa(config-if)# int g0/1
ciscoasa(config-if)# nameif inside
ciscoasa(config-if)# security-level 100
ciscoasa(config-if)# ip address 192.168.206.1 255.255.255.0
ciscoasa(config-if)# no shut
ciscoasa(config-if)# exit
# Network Address Translation (NAT)
We will use the "network object NAT" method for our implementation. We will also be using Dynamic Port Address Translation (PAT) for our configuration.
Create the address translation for our internal LAN network. Run the following command (and subcommands):
ciscoasa(config)# object network OBJ-LAN
ciscoasa(config-network-object)# subnet 192.168.206.0 255.255.255.0
ciscoasa(config-network-object)# description INTERNAL_LAN
ciscoasa(config-network-object)# nat (inside,outside) dynamic interface
ciscoasa(config-network-object)# exit
Create a NAT exemption for traffic between the internal LAN network behind the ASA (192.168.206.0/24) and the VPN IP address pool. This is required because the encrypted traffic should not go through a NAT operation. Run the following commands (and subcommands):
ciscoasa(config)# object network OBJ-VPN
ciscoasa(config-network-object)# subnet 192.168.200.0 255.255.255.0
ciscoasa(config-network-object)# description VPNADDR
ciscoasa(config-network-object)# exit
ciscoasa(config)# nat (inside,outside) source static any any destination static OBJ-VPN OBJ-VPN
# Routing
The most preferred routing method on a perimeter appliance is to to have a default route pointing to the router connected to the outside interface. This would be the ISP router for our scenario. Create the default route. Run the following command:
ciscoasa(config)# route outside 0 0 203.0.113.1
# VPN Pool
Our AnyConnect clients will need to be assigned IP addresses when they connect, so we need to define a local pool of addresses on the ASA. Run the following command:
ciscoasa(config)# ip local pool VPNPOOL 192.168.200.1-192.168.200.254 mask 255.255.255.0
# LDAP Attribute Map
The LDAP attribute map will be used to link the members of our VPN AD security group (from the memberOf attribute) to the AAA server host defined in the next step. If we didn�t configure this, all users in AD would be able to have VPN remote access by default. Run the following command (and subcommands):
ciscoasa(config)# ldap attribute-map LAM-VPN
ciscoasa(config-ldap-attribute-map)# map-name memberOf Group-Policy
ciscoasa(config-ldap-attribute-map)# map-value memberOf CN=VPN,CN=Users,DC=corp,DC=example,DC=com GP-AllowVPN
ciscoasa(config-ldap-attribute-map)# exit
# AAA Server Group and Host
We will use LDAP for authentication and authorization with our AD domain controller when our AnyConnect clients establish a connection. Notice the asa-ldapq user we created earlier will be the specific account that connects and queries the LDAP server (AD). Remember to use the same password you set earlier when creating the asa-ldapq account. Run the following commands (and subcommands):
ciscoasa(config)# aaa-server ASG-LDAP protocol ldap
ciscoasa(config-aaa-server-group)# exit
ciscoasa(config)# aaa-server ASG-LDAP host 192.168.206.11
ciscoasa(config-aaa-server-host)# server-type microsoft
ciscoasa(config-aaa-server-host)# ldap-base-dn DC=corp,DC=example,DC=com
ciscoasa(config-aaa-server-host)# ldap-scope subtree
ciscoasa(config-aaa-server-host)# ldap-naming-attribute sAMAccountName
ciscoasa(config-aaa-server-host)# server-port 389
ciscoasa(config-aaa-server-host)# ldap-login-dn CN=asa-ldapq,CN=Users,DC=corp,DC=example,DC=com
ciscoasa(config-aaa-server-host)# ldap-login-password Pa$$worD1
ciscoasa(config-aaa-server-host)# ldap-attribute-map LAM-VPN
ciscoasa(config-aaa-server-host)# exit
Tip: You can get the ldap-login-dn attribute value for our asa-ldapq user by running the following PowerShell command (requires ActiveDirectory PowerShell module):
PS> Get-ADUser -Id asa-ldapq | fl dist*
DistinguishedName : CN=asa-ldapq,CN=Users,DC=corp,DC=example,DC=com
# Group Policies
We will be creating two group policies. The first (GP-AllowVPN) will be for members of the VPN AD global security group. The second will be the default "deny" policy for members who dont have remote access VPN privileges (i.e. not members of the VPN group). Both policies will be linked to the Tunnel Group that will be created in the next step. Run the following commands (and subcommands):
ciscoasa(config)# group-policy GP-AllowVPN internal
ciscoasa(config)# group-policy GP-AllowVPN attributes
ciscoasa(config-group-policy)# dns-server value 192.168.206.11
ciscoasa(config-group-policy)# vpn-simultaneous-logins 2
ciscoasa(config-group-policy)# vpn-tunnel-protocol ssl-client
ciscoasa(config-group-policy)# default-domain value corp.example.com
ciscoasa(config-group-policy)# webvpn
ciscoasa(config-group-webvpn)# anyconnect keep-installer installed
ciscoasa(config-group-webvpn)# anyconnect ask none default anyconnect timeout 30
ciscoasa(config-group-webvpn)# exit
ciscoasa(config-group-policy)# exit
ciscoasa(config)# group-policy GP-DenyVPN internal
ciscoasa(config)# group-policy GP-DenyVPN attributes
ciscoasa(config-group-policy)# vpn-simultaneous-logins 0
ciscoasa(config-group-policy)# exit
# Connection Profile (Tunnel Group)
Tunnel groups are used to more easily assign policies and attributes to a common group of users. Run the following commands (and subcommands):
ciscoasa(config)# tunnel-group TG-Corp type remote-access
ciscoasa(config)# tunnel-group TG-Corp general-attributes
ciscoasa(config-tunnel-general)# address-pool VPNPOOL
ciscoasa(config-tunnel-general)# authentication-server-group ASG-LDAP LOCAL
ciscoasa(config-tunnel-general)# authorization-server-group ASG-LDAP
ciscoasa(config-tunnel-general)# default-group-policy GP-DenyVPN
ciscoasa(config-tunnel-general)# exit
ciscoasa(config)# tunnel-group TG-Corp webvpn-attributes
ciscoasa(config-tunnel-webvpn)# group-alias SSL-VPN enable
ciscoasa(config-tunnel-webvpn)# end
# Test the Configuration
At this stage, I would recommend we test our AAA configuration. We will attempt to authenticate with our jsmith user. Run the following command and verify the output:
ciscoasa# test aaa-server auth ASG-LDAP host dc01 user jsmith pass Pa$$worD1
INFO: Attempting Authentication test to IP address(timeout: 12 seconds)
INFO: Authentication Successful
# AnyConnect
Transfer the Windows AnyConnect client package from your local computer to the ASA device. I will use the scp (Secure Copy) method in my example.
We first need to enable the secure copy functionality on the ASA before we can copy packages over via scp. Run the following commands:
ciscoasa# conf t
ciscoasa(config)# ssh scopy enable
For the secure copy transfer, the command/utility will vary depending on what client OS youre using. I recommend WinSCP or PSCP if using a Windows client. From a Linux or Mac OS X client, we can use the cli scp command in a terminal. For my configuration, I would like to note I already have a user named marc created on the ASA with a privilege level of 15. The following command will copy the Windows AnyConnect client package to the ASAs flash from a Linux or Mac OS X client:
$ scp anyconnect-win-3.1.00495-k9.pkg marc@192.168.206.1:
After the file has been transferred to flash, it must be unpackaged. Run the following command (and subcommand):
ciscoasa(config)# webvpn
ciscoasa(config-webvpn)# anyconnect image disk0:/anyconnect-win-3.1.00495-k9.pkg
The preceding steps will be followed by enabling WebVPN on the outside interface and globally enabling the WebVPN tunnel mode. We also want to enable the group drop-down list for Tunnel Group selection. Run the following subcommands:
ciscoasa(config-webvpn)# enable outside
ciscoasa(config-webvpn)# tunnel-group-list enable
ciscoasa(config-webvpn)# anyconnect enable
ciscoasa(config-webvpn)# end
We can verify the AnyConnect package has been correctly set by running the following command:
ciscoasa# sh webvpn anyconnect
1. disk0:/anyconnect-win-3.1.00495-k9.pkg 1 dyn-regex=/Windows NT/
CISCO STC win2k+
3,1,00495
Hostscan Version 3.1.00495
Fri 08/03/2012 14:06:41.27
1 AnyConnect Client(s) installed
Now would be a great point to save our configuration. Run the following command:
ciscoasa# copy run start
# AnyConnect for iPhone (optional)
We will perform testing and verification with the Cisco AnyConnect Secure Mobility Client on the iPhone 4S. Lets first check to make sure we have the required license for our ASA. Run the following command:
ciscoasa# sh ver | grep Mobile
AnyConnect for Mobile : Enabled perpetual
The Cisco AnyConnect Secure Mobility Client for iOS is available from Apples App Store. Cisco doesnt charge money for the client itself; instead, the number of SSL tunnels is controlled by the license installed on the ASA.
After the AnyConnect client has been downloaded and installed on the iPhone device, we need to configure the attributes for the VPN connection.
- Open the AnyConnect app.
- Select Add VPN Connection.
- Enter a description that labels the connection.
- Enter the server address. The value should be the FQDN of the outside interface. I will be using vpn.example.com.
- Push the Save button to save the connection.

- From the Home tab of the AnyConnect app, push the slider to transition the state from Off to On to initiate the Authentication screen.
- The Group field should already by populated with our Tunnel Group alias that we configured earlier.
- Enter the user jsmith for the Username field.
- Enter the password Pa$$worD1 in the Password field.
- Push the Done button to close the virtual keyboard.
- Then push the Connect button to initiate the connection.


Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment