이 기사는 다음 기사에 이어집니다.
지금까지의 구축 방법은 아래를 참고해 주세요.
과제
저희 회사에서는 직원들에게 작업용 단말기로 iPad(10세대)를 배포하고 있습니다.
평소 재택근무에서는 직원들이 각자의 컴퓨터에서 WorkSpaces에 접속하여 작업을 수행하고 있습니다.
iPad에서도 WorkSpaces 클라이언트 애플리케이션 설치가 가능하기 때문에, 외근 시에는 iPad를 사용해 WorkSpaces에 접속하여 업무를 진행하게 하려고 했습니다.
iPad용 Magic Keyboard로 조작할 것을 가정했지만, WorkSpaces에 로그인은 가능하나 방향키가 작동하지 않는 현상이 발생했습니다.
원인
조사해 보았지만, 원인이나 유사한 현상은 확인할 수 없었고, 정확한 원인은 불명입니다.
여러 장치에서 발생하는 문제이므로 장치 자체의 결함은 아닌 것 같지만, 유사한 문제 보고는 인터넷에서도 확인되지 않았습니다.
다만, 아래와 같은 방법으로 우회하여 일단 방향키 조작이 가능하게 되었기에 이를 일단락 지었습니다.
방법
결론적으로, 우리는 RDP로 WorkSpaces에 연결하고 있습니다.
PCoIP로 연결 시 문제가 발생하는 것 같아, RDP로 WorkSpaces에 접속함으로써 방향키가 작동하게 되었습니다.
다음 정보를 참고했습니다.
RDP를 사용하여 WorkSpaces에 연결하려면 어떻게 해야 하나요?
https://repost.aws/ko/knowledge-center/connect-workspace-rdp
다만, WorkSpaces가 위치한 서브넷은 사설 서브넷으로 유지하고자 하는 요구 사항이 있어, AWS Client VPN도 함께 사용하기로 했습니다.
WorkSpaces에서 이미 Directory Service를 사용하고 있기 때문에, 이를 AWS Client VPN 인증에 그대로 사용할 수 있습니다.
이는 꽤 편리하며, 직원들은 평소 사용하는 비밀번호로 AWS Client VPN에 접속할 수 있습니다.
구성은 다음과 같은 느낌입니다.
관리자 단계
구성을 준비하기 위해 제가 수행한 단계는 다음과 같습니다.
Route 53 호스트 존 생성
직원들이 RDP를 통해 WorkSpaces에 연결할 때, WorkSpaces의 IP 주소를 입력해야 합니다.
관리자(저)만 IP 주소를 확인할 수 있기 때문에, 직원들에게 개별적으로 알리는 것은 번거롭습니다.
따라서 사용자 ID에 기반하여 자동으로 도메인 이름을 할당하기로 했습니다.
- 다음 URL에서 Route 53 호스트 존을 생성하세요:
https://us-east-1.console.aws.amazon.com/route53/v2/hostedzones#CreateHostedZone - 다음 설정으로 구성합니다.
- 도메인 이름: user.workspaces
- 유형: ⦿ 프라이빗 호스팅 영역
- 호스팅 영역과 연결할 VPC
- 리전: 미국 동부(버지니아 북부)
- VPC ID: WorkSpaces가 위치한 VPC
이미지
Lambda 핸들러 생성
Client VPN에 연결할 때 동시에 실행하고자 하는 프로그램이나 작업을 Lambda 핸들러에 설정할 수 있습니다.
WorkSpaces는 활성화 상태일 때 비용이 많이 들기 때문에 AutoStop 모드로 설정되어 있습니다.
따라서 Lambda 핸들러에서 매번 WorkSpaces를 시작하도록 할 것입니다.
또한 Lambda 핸들러가 WorkSpaces의 IP 주소를 Route 53 호스트 존에 등록합니다.
- Lambda 함수용 IAM 역할을 생성하기 위해 다음 AWS CLI 명령을 실행하세요:
AWS CLI 명령
# Create IAM role
aws iam create-role \
--role-name LambdaCustomRole \
--assume-role-policy-document '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}'
# Attach the IAM policy required for updating Route 53
aws iam attach-role-policy \
--role-name LambdaCustomRole \
--policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess
# Attach the IAM policy required for updating WorkSpaces
aws iam attach-role-policy \
--role-name LambdaCustomRole \
--policy-arn arn:aws:iam::aws:policy/AmazonWorkSpacesAdmin
# Attach the IAM policy required for logging
aws iam attach-role-policy \
--role-name LambdaCustomRole \
--policy-arn arn:aws:iam::aws:policy/CloudWatchLogsFullAccess
- 以下の URL から Lambda 関数を作成します。
https://us-east-1.console.aws.amazon.com/lambda/home?region=us-east-1#/create/function - 다음 설정으로 구성합니다.
- 함수 이름: AWSClientVPN-ReadyWorkSpaces
* 반드시 “AWSClientVPN-“로 시작해야 합니다.† - 런타임: Python 3.12
- 실행 역할: LambdaCustomRole
- 함수 이름: AWSClientVPN-ReadyWorkSpaces
이미지
- [구성] 탭 > [일반 구성]으로 이동하여 시간 제한을 1분으로 변경합니다.
이미지
- Lambda 함수의 코드를 입력합니다.
대부분 ChatGPT가 작성했으며 코드는 다음과 같습니다.
AWSClientVPN-ReadyWorkSpaces 코드
import boto3
def lambda_handler(event, context):
# 리소스 정보
directory = '<디렉터리 ID>'
hostedzone = '<호스트존 ID>'
domain = 'user.workspaces'
# 이벤트에서 사용자 이름 가져오기
username = event.get('username')
if not username:
return {
"allow": True,
"error-msg-on-failed-posture-compliance": "Username not provided",
"posture-compliance-statuses": [],
"schema-version": "v2"
}
# WorkSpaces 클라이언트 생성
workspaces_client = boto3.client('workspaces')
# 사용자의 WorkSpaces 가져오기
response = workspaces_client.describe_workspaces(
DirectoryId=directory,
UserName=username
)
workspaces = response.get('Workspaces', [])
if not workspaces:
return {
"allow": True,
"error-msg-on-failed-posture-compliance": f'No WorkSpaces found for user {username}',
"posture-compliance-statuses": [],
"schema-version": "v2"
}
# WorkSpaces 실행
workspace_id = workspaces[0]['WorkspaceId']
workspaces_client.start_workspaces(
StartWorkspaceRequests=[
{'WorkspaceId': workspace_id}
]
)
# WorkSpaces의 IP 주소 가져오기
workspace_ip = workspaces[0]['IpAddress']
# Route 53 클라이언트 생성
route53_client = boto3.client('route53')
# 서브도메인 이름 생성
subdomain = f"{username}.{domain}"
# 레코드 생성
try:
route53_client.change_resource_record_sets(
HostedZoneId=hostedzone,
ChangeBatch={
'Changes': [
{
'Action': 'CREATE',
'ResourceRecordSet': {
'Name': subdomain,
'Type': 'A',
'TTL': 300,
'ResourceRecords': [{'Value': workspace_ip}]
}
}
]
}
)
except Exception as ex:
route53_client.change_resource_record_sets(
HostedZoneId=hostedzone,
ChangeBatch={
'Changes': [
{
'Action': 'UPSERT',
'ResourceRecordSet': {
'Name': subdomain,
'Type': 'A',
'TTL': 300,
'ResourceRecords': [{'Value': workspace_ip}]
}
}
]
}
)
return {
"allow": True,
"error-msg-on-failed-posture-compliance": f'Successfully started WorkSpaces for user {username}',
"posture-compliance-statuses": [],
"schema-version": "v2"
}
ACM에서 인증서 발급
Client VPN 엔드포인트를 생성하려면 ACM 인증서가 필요합니다.
도메인이 있으면 인증서를 즉시 발급할 수 있지만, 도메인이 없는 경우에는 직접 인증서를 발급하여 ACM에 가져와야 합니다.
제 경우에는 CloudShell을 사용해 인증서를 생성하고 ACM에 가져왔습니다.
- 아래 URL의 단계 “a”를 따라 CloudShell을 시작합니다.
https://docs.aws.amazon.com/ko_kr/cloudshell/latest/userguide/getting-started.html#launch-region-shell
- 탐색 모음에서 CloudShell 아이콘을 선택합니다.
- 아래 URL에 제공된 명령을 실행하여 인증서를 발급하고 가져오세요.
https://docs.aws.amazon.com/ko_kr/vpn/latest/clientvpn-admin/client-auth-mutual-enable.html
$
git clone https://github.com/OpenVPN/easy-rsa.git$
cd easy-rsa/easyrsa3$
./easyrsa init-pki$
./easyrsa build-ca nopass$
./easyrsa –san=DNS:server build-server-full server nopass$
mkdir ~/custom_folder
/$
cp pki/ca.crt ~/custom_folder
/$
cp pki/issued/server.crt ~/custom_folder
/$
cp pki/private/server.key ~/custom_folder
/$
cd ~/custom_folder
/$
aws acm import-certificate –certificate fileb://server.crt –private-key fileb://server.key –certificate-chain fileb://ca.crt
Client VPN 엔드포인트 생성 및 설정
- 다음 URL을 사용하여 Client VPN 엔드포인트를 생성합니다:
https://us-east-1.console.aws.amazon.com/vpcconsole/home?region=us-east-1#CreateClientVpnEndpoint: - 다음 설정으로 구성합니다:
- 이름 태그 – 선택 사항: client-vpn-for-remotework
- 클라이언트 IPv4 CIDR: 192.168.252.0/22
* VPC CIDR과 중복되지 않도록 합니다.† - 서버 인증서 ARN: ACM에서 인증서를 발급에서 가져온 인증서
- 인증 옵션: ☑ 사용자 기반 인증 사용
- 사용자 기반 인증 옵션: ⦿ Active Directory 인증
- 디렉토리 ID: WorkSpaces에서 사용 중인 디렉토리
- 기타 파라미터 – 선택 사항
- DNS 서버 1 IP 주소: VPC CIDR +2 IP 주소
- VPC CIDR이 10.0.0.0/16인 경우 10.0.0.2.
- 프라이빗 호스트 존을 사용할 때 VPC CIDR +2를 지정해야 합니다.
- 분할 터널 활성화: 활성화
- 비활성화하면 iPad의 모든 트래픽이 AWS를 통해 라우팅됩니다.
- WorkSpaces 트래픽만 필요하므로 이 옵션을 활성화합니다.
- 셀프 서비스 포털 활성화: 활성화
- 직원들이 설정 파일을 직접 다운로드할 수 있습니다.
- DNS 서버 1 IP 주소: VPC CIDR +2 IP 주소
이미지
- [대상 네트워크 연결] 탭에서 대상 네트워크를 연결합니다.
- VPC: WorkSpaces가 위치한 VPC
- 연결할 서브넷 선택: 프라이빗 서브넷 중 하나
이미지
- [권한 부여 규칙] 탭에서 인증 규칙을 추가합니다.
- 액세스를 활성화할 대상 네트워크: 0.0.0.0/0
- 액세스 권한 부여 대상: ⦿ 모든 사용자에게 액세스 허용
이미지
- Client VPN 엔드포인트의 상태가 Available로 변경될 때까지 기다립니다.
이미지
사용자 측 절차
이 구성을 통해, 직원들에게 다음 작업을 요청했습니다:
- iPad에 OpenVPN 클라이언트 설치
- 셀프 서비스 포털에서 설정 파일 다운로드
- URL: https://self-service.clientvpn.amazonaws.com/endpoints/<endpoint-id>
- OpenVPN 클라이언트에 설정 파일 가져오기
- iPad에 RD 클라이언트 설치
- RD 클라이언트에 PC 추가
- 호스트명:
<user-id>.user.workspaces
- 호스트명:
연결 시 직원들은 OpenVPN으로 Client VPN에 연결한 후, RD 클라이언트를 통해 WorkSpaces에 RDP로 접속합니다.
예상보다 어려움을 겪는 직원이 적어, 전개는 순조롭게 이루어졌습니다.
현재 이 구성이 잘 작동하는 것 같아, 계속 모니터링하려고 합니다.
이 정보가 누군가에게 참고가 되길 바랍니다.