How to Setup Amazon Workspaces With MFA

Zen Liu
11 min readJun 7, 2020

Due to the COVID-19, many companies need to find some ways to enable remote working. VDI solution is one of their choices. Amazon Workspaces can provide a quick win VDI solution but it still need to spend efforts to setup for some authentications and security settings, e.g. MFA. For some SME companies, they may not have their own RADIUS (Remote Authentication Dial-In User Service) server and OTP (one-time password) server to enable MFA for Amazon Workspaces. They can setup both servers on AWS and configure with AWS Directory service to enable MFA. In this post, I would like to go through how to setup the RADIUS server, OTP server, AWS Directory service and Amazon Workspaces with MFA on AWS.

Amazon Workspaces Quick setup VS Advance setup

Quick setup

Quick setup is like its name, it helps you setup the Amazon WorkSpaces in a quick way with predefined settings. You can use this option to setup a demo or have a trial for workspaces.
https://docs.aws.amazon.com/workspaces/latest/adminguide/getting-started.html
Quick Setup completes the following tasks on your behalf:

  • Creates an IAM role to allow the Amazon WorkSpaces service to create elastic network interfaces and list your Amazon WorkSpaces directories. This role has the name workspaces_DefaultRole.
  • Creates a virtual private cloud (VPC).
  • Sets up a Simple AD directory in the VPC that is used to store user and WorkSpace information. The directory has an administrator account and it is enabled for Amazon WorkDocs.
  • Creates the specified user accounts and adds them to the directory.
  • Creates WorkSpace instances. Each WorkSpace receives a public IP address to provide internet access. The running mode is AlwaysOn. For more information, see Manage the WorkSpace Running Mode.
  • Sends invitation emails to the specified users.

Note
The first user account created by Quick Setup is your Admin user account. You can’t update this user account from the Amazon WorkSpaces Console. Don’t share the information for this Admin account with anyone else. If you want to invite other users to use this WorkSpace, create new user accounts for them.

Advance setup

Advance setup needs to do all the steps by your own like select using which type of AD, network setup etc. We will use this to setup our Amazon WorkSpaces with MFA.

Create Directory service for Amazon Workspaces

When creating Amazon WorkSpaces, it requires to define the directory service of WorkSpace (WorkSpace only can communicate to AWS Directory service, it cannot directly communicate with your own AD). There are 4 ways of directory service that WorkSpace can use:

· Launch a WorkSpace Using AWS Managed Microsoft AD

· Launch a WorkSpace Using Simple AD

· Launch a WorkSpace Using AD Connector

· Launch a WorkSpace Using a Trusted Domain

You can use first two options if you don’t need to leverage your own AD. For the differences between Simple AD and Managed AD, you can have a look on this FAQ.

The third and forth are required to use your own AD. AD Connector is acted as a proxy only, it forwards sign-in requests to your AD domain controllers for authentication and provides the ability for applications to query the directory for data. The forth option is to use AWS Managed Microsoft AD to create trusted relationship to your AD. For more detail on choosing which AWS AD, you can have a look to Best Practices for Active Directory with AWS Workloads.

In this post, we will use AD Connector to connect with our own AD.

Create AD Connector

AD Connector Prerequisites: https://docs.aws.amazon.com/directoryservice/latest/admin-guide/prereq_connector.html

Some highlighted points need to be aware:

  • Service account (please make sure the account does not contain any special characters like “-“)
    You must have credentials for a service account in the existing directory which has been delegated the following privileges:
    1. Read users and groups — Required
    2. Join computers to the domain — Required
    3. Create computer objects — Required only when using Seamless Domain Join and Amazon WorkSpaces
  • Ports for subnets
    Make sure the ports of AD are reachable from the subnets selected for AD Connector

Let’s start to create the AD Connector

  1. Go to Directory Service and click Set up Directory on the right hand side
  2. Select AD Connector
  3. Choose the size:
    Small — Supports up to 500 users (approximately 2,000 objects including users, groups, and computers)
    Large — Supports up to 5,000 users (approximately 20,000 objects including users, groups, and computers)
    These two informations are from AWS China, I cannot find the exact number in AWS Global
  4. Select VPC and two subnets
  5. Enter your own AD’s information like Domain name, NetBIOS, IP of DNS and service account. Please be aware that the service account should have the required permission as mentioned in prerequisites.
  6. Review the settings and confirm to create the connector

Cool, we created the AD connector and we can move to create the RADIUS server and OTP server.

RADIUS server and OTP server setup

We refer to this: https://github.com/johnalvero/ADConnector-MFA to setup the RADIUS server and OTP server using Free RADIUS and LinOTP. I have made some changes on it to enable high availability:

Install LinOTP

1. Create MariaDB RDS instance and enable multi-AZ (I use t3.small, you can adjust based on your usage. Also need to use version 10.2 or before due to this issue: https://jira.mariadb.org/browse/MDEV-18884 or you can adjust the grant permission script in linotp-create-mariadb-rds)

2. Create a EC2 with CentOS 7 AMI (I use t3.small, you can adjust based on your usage). Configure the security group that allows communicate between the RDS and EC2

3. SSH to the EC2 instance, switch to root account and execute

sudo su
yum update -y

4. Install, configure and start NTP service

yum install -y ntp
cat <<'EOF'> /etc/ntp.conf
# by default act only as a basic NTP clientrestrict -4 default nomodify nopeer noquery notraprestrict -6 default nomodify nopeer noquery notrap# allow NTP messages from the loopback address, useful for debuggingrestrict 127.0.0.1restrict ::1# server(s) we time sync toserver 0.asia.pool.ntp.orgserver 1.asia.pool.ntp.orgserver 2.asia.pool.ntp.orgserver 3.asia.pool.ntp.orgEOFsystemctl start ntpd

5. Configure SELinux since LinOTP can support SELinux

yum install policycoreutils-python -ysemanage fcontext -a -t httpd_sys_content_t "/etc/linotp2(/.*)?"semanage fcontext -a -t httpd_sys_rw_content_t "/etc/linotp2/data(/.*)?"semanage fcontext -a -t httpd_sys_rw_content_t "/var/log/linotp(/.*)?"

6. Preparation for installing LinOTP

yum install git epel-release -yyum localinstall http://linotp.org/rpm/el7/linotp/x86_64/Packages/LinOTP_repos-1.1-1.el7.x86_64.rpm -ygit clone https://github.com/johnalvero/ADConnector-MFA.git /usr/local/ADConnector-MFA

7. Install LinOTP and MariaDB module

yum install -y LinOTP LinOTP_mariadbrestorecon -Rv /etc/linotp2/restorecon -Rv /var/log/linotp

8. Download the file from https://bitbucket.org/snippets/zenliu/XL9ogL . Execute the command with the parameters <RDS host> <RDS admin> <RDS admin password> to configure the LinOTP with MariaDB RDS

chmod u+x linotp-create-mariadb-rds
./linotp-create-mariadb-rds <RDS host> <RDS admin> <RDS admin password>

9. Lock python-repoze-who version, install apache, vhost config and start apache

# Lock python-repoze-who versionyum install yum-plugin-versionlock -yyum versionlock python-repoze-who -y# install apache and vhost configyum install LinOTP_apache -ysetsebool -P httpd_can_network_connect_db onsetsebool -P httpd_can_connect_ldap onmv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.backmv /etc/httpd/conf.d/ssl_linotp.conf.template /etc/httpd/conf.d/ssl_linotp.confsystemctl enable httpdsystemctl start httpd

10. Change the admin password of LinOTP

htdigest /etc/linotp2/admins "LinOTP2 admin area" admin

Create AWS Application Load Balancer

So far so good, LinOTP setup is completed. The next step is to create AWS Application Load Balancer (ALB):

  1. Go to AWS EC2 section > Load Balancers > Create Load Balancer
  2. Select Application Load Balancer, enter the name of the load balancer, select Internet-facing as the Schema and ipv4 as the IP address type
  3. You can keep the HTTP listener if you don’t have custom domain (the setup will be Browser -> HTTP -> ALB -> HTTPS -> LinOTP). On the other hand, you can add HTTPS listener if you have a custom domain (Browser -> HTTPS -> ALB -> HTTPS -> LinOTP) and create a SSL in ACM for your domain by following this: https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html#request-public-console)
  4. Select the VPC which is same as the EC2 and enable the AZs
  5. Create a security group that allow public access for HTTP (and HTTPS if necessary) and access to the EC2 (either by IP or a security group like the default group)
  6. Create a new target group with Instance as Target type, HTTPS as Protocol and 443 as the Port
  7. Configure Heath checks using HTTPS as Protocol and /selfservice/login as Path. Advanced health check settings can keep as default
  8. Register the EC2 as the target and confirm to create the load balancer

Configure LinOTP

After setting up the ALB, we go into the LinOTP web portal and configure the LinOTP to get the AD users:

  1. Visit the LinOTP web portal by http://<loadbalancer DNS name>/manage and login with the admin account (password was setup in step 10 of Install LinOTP section)
  2. Click the LinOTP Config in the top bar > UserIdResolver
  3. Create a new Resolver using LDAP
  4. Enter the information of your AD server
    *DN can be found by the command dsquery:(https://knowledge.broadcom.com/external/article/166122/find-the-ldap-user-and-group-base-dn-for.html)
  5. Click Test LDAP Server connection to test the connection. If there is any connection error, please make sure the EC2 has opened related ports for LDAP (default port 389) and the EC2 can actually reach the AD server
  6. The previous step will automatically prompt you to create the default realm (the realm will be used in FreeRADUIS settings). After creating the realm, you should now be able to see your users from the User View.
  7. Download the policy file from https://bitbucket.org/snippets/zenliu/bLpoE5 . Go to Policies tab near the User View, import the policy.txt file. After import the files, you can see there are four policies.
  8. Enroll Token for each user who need to use the Workspaces (https://www.linotp.org/doc/latest/part-management/managingtokens/enroll.html) or ask users to visit the self-service portal by http://<loadbalancer DNS name>/selfservice/login/
    *If you choose to use custom domain with HTTPS, you should access the portal by https://<your custom domain>

Install and configure FreeRADIUS

We are almost done and we need to install the last component: FreeRADIUS.

1. SSH to the EC2 which installed LinOTP, switch to root and install FreeRADIUS

sudo suyum  install -y yum install freeradius freeradius-perl freeradius-utils perl-App-cpanminus perl-LWP-Protocol-https perl-Try-Tinycpanm Config::File

2. Configure FreeRADIUS, replace the ip-range-of-ad-connector of AD connector, netmask-bit (subnet mask bits) and the SECRET (the secret will be used in the MFA configuration of AD connector) with your settings

mv /etc/raddb/clients.conf /etc/raddb/clients.conf.backmv /etc/raddb/users /etc/raddb/users.backcat << 'EOF' > /etc/raddb/clients.confclient localhost {ipaddr  = 127.0.0.1netmask = 32secret  = <SECRET>}client adconnector {ipaddr  = <ip-range-of-ad-connector>netmask = <netmask-bit>secret  = <SECRET>}EOF

3. Download and setup LinOTP perl module

# Download the freeradius linotp perl modulegit clone https://github.com/LinOTP/linotp-auth-freeradius-perl.git /usr/share/linotp/linotp-auth-freeradius-perl# Setup the linotp perl modulecat << 'EOF' > /etc/raddb/mods-available/perlperl {filename = /usr/share/linotp/linotp-auth-freeradius-perl/radius_linotp.pm}EOF# Activate itln -s /etc/raddb/mods-available/perl /etc/raddb/mods-enabled/perl

4. Configure perl, replace the your-realm with the value which you configured in previous section (LinOTP LDAP connection)

# freeradius linotp perl configcat << 'EOF' > /etc/linotp2/rlm_perl.iniURL=https://localhost/validate/simplecheckREALM=<your-realm>Debug=TrueSSL_CHECK=FalseEOF# Remove unnecessary configrm -f /etc/raddb/sites-enabled/inner-tunnelrm -f /etc/raddb/sites-enabled/defaultrm -f /etc/raddb/mods-enabled/eap

5. Activate the FreeRADIUS Linotp virtual host

# Activate the freeradius linotp virtual hostcp /usr/local/ADConnector-MFA/linotp /etc/raddb/sites-available/ln -s /etc/raddb/sites-available/linotp /etc/raddb/sites-enabled/linotp

6. Start FreeRADIUS as a service

systemctl enable radiusdsystemctl start radiusd

7. You can test Radius Authentication (OTP) using the account created in LinOTP by the below command: (SECRET is configured in step 2)

radtest <username> <token-from-google-authenticator> localhost 0 <SECRET>

And the success result should be similar to the following:

# Success resultSent Access-Request Id 19 from 0.0.0.0:50410 to 127.0.0.1:1812 length 81User-Name = "<username>"User-Password = "375937"NAS-IP-Address = 127.0.0.1NAS-Port = 0Message-Authenticator = 0x00Cleartext-Password = "375937"Received Access-Accept Id 19 from 127.0.0.1:1812 to 0.0.0.0:0 length 43Reply-Message = "LinOTP access granted"

Awesome! We just finish the OTP and RADIUS settings. If you cannot see the success message of the test, you can double check the SECRET setting in step 2. Now you can clone the EC2 by taking a snapshot and create EC2 from the AMI. After that, add the EC2 to the ALB target group that we created before. Then we can go back to the AD connector and enable the MFA.

Enable MFA of AD connector

  1. Go to Directory Service section > Directories > click the Directory ID of the AD connector
  2. Click Networking & security tab and scroll down to Multi-factor authentication section, click the Actions > Enable
  3. Enter the private IPs of EC2 with comma, the secret we created in FreeRADIUS as Shared secret code, PAP as the Protocol, 10 seconds as the Server timeout and keep Max RADIUS request retries as 4
  4. Click Enable

Wait for few minutes and you can see the status of MFA changes to Completed if all settings are correct. Otherwise, please double check with the network security group and the secret, AD connector IPs and subnet mask in FreeRADIUS settings.

Final Step: Create workspaces

Now we can go back to Amazon Workspaces to create the actual workspaces. Create workspaces using the AD connector that we created in previous sections. Then select the users and create workspaces instance for them. Beware that user and workspaces instance is 1 to 1 relationship. It’s different to other VDI solution like Citrix, a workspace instance cannot share to multiple users.

Extra: Some tips or findings during our setup

Our team had setup several workspaces for clients recently. Here are some tips and finding during the process, hope they can help you to save time when having troubles:

  1. Ensure RADIUS server security group allow traffic from AD connector (port 1812) and the secret configured in client.conf is matched with the setting in AWS console.
  2. The permission of Service account in AD connector, make sure it has enough permission
  3. Web access of workspaces need to enable in console (Directories > Update Directory Detail > Access Control Options). Also it requires to rebuild the workspace afterwards
    https://aws.amazon.com/blogs/aws/new-web-access-for-amazon-workspaces/
  4. WAM (Web Application Manager) need to install manually, the setup file is in C:\Program Files\Amazon\WorkspaceApplicationManager.exe
  5. Monthly cost in hourly billing option is pro rata basic. But if you create at the beginning of the month, it will charge it as a full month LOL
  6. AD Connector same price as Simple AD
  7. If you created workspaces with the directory (either AD connector, managed AD or simple AD), you need to remove all application assignment before deleting the directory. Otherwise it will display an error: https://docs.aws.amazon.com/wam/latest/adminguide/remove_all_assignments.html
  8. WorkSpaces may take up to 20 minutes to become available, most likely need around 15 mins

I hope this post can help you when you want to setup Amazon Workspaces with MFA. Please feel free to leave a comment if you have any further question. I also hope COVID-19 could end soon and we can back to our normal life [finger-cross]!

--

--