레거시 프로그램을 위한 가상 PC Pool 구성기
Guacamole + VMware ESXi로 Windows VM Pool 구축하기
지원이 종료된 레거시 프로그램을 격리하고, 웹에서 동적으로 할당할 수 있을까?
오래된 시스템을 유지하다 보면 프로그램 자체는 아직 사용할 수 있지만 운영체제나 브라우저의 변화로 정상적인 실행이 어려워지는 경우가 있다.
특히 ActiveX, 구형 Runtime, 특정 Windows 버전 등에 의존하는 프로그램은 개발이나 지원이 종료된 이후에도 기존 시스템과의 연동 때문에 계속 사용해야 하는 경우가 있다.
이번에 다룬 프로그램도 비슷한 경우였다.
정확한 제품명은 생략하고, 이 글에서는 단순히 ActiveX 기반 레거시 문서뷰어라고 부르려고 한다.
해당 프로그램은 특정 Windows 환경과 브라우저 구성, 오래된 Runtime 등에 의존하고 있었고 최신 Windows에서는 PC 환경에 따라 실행되지 않거나 동작이 불안정한 문제가 있었다.
이미 개발사 차원의 적극적인 호환성 개선을 기대하기 어려운 프로그램이라면 최신 PC마다 환경을 억지로 맞추는 것보다 정상적으로 동작하는 실행환경 자체를 별도로 유지하는 방법도 생각해볼 수 있다.
기존 방식은 대략 다음과 같았다.
사용자 PC
↓
레거시 프로그램 실행
↓
실행 실패
↓
호환성 설정 확인
↓
관리자 권한 확인
↓
브라우저 설정 확인
↓
Runtime 재설치
↓
보안 설정 확인
↓
별도 VM으로 우회PC 한두 대라면 이런 식으로 대응할 수도 있다.
하지만 사용하는 PC가 늘어나거나 Windows가 업데이트될 때마다 동일한 문제를 반복해서 확인해야 한다면 관리 포인트가 계속 늘어난다.
각 PC에 Local VM을 배포하는 방법 역시 VM 이미지 손상, VMware 버전 차이, 비정상 종료 등 또 다른 문제가 생긴다.
그래서 이번에는 접근 방법을 조금 다르게 잡아봤다.
지원이 종료되었거나 최신 Windows와 호환되지 않는 레거시 프로그램을 사용자 PC에서 직접 실행하지 않고, 정상 동작하는 Windows 환경을 중앙에 유지한 뒤 사용자는 웹 브라우저를 통해 해당 환경을 빌려 쓰게 만들 수 있을까?
그리고 여기에는 한 가지 목적이 더 있었다.
이 구조가 이론적으로만 가능한지, 실제로 구성했을 때도 제대로 동작하는지 직접 실험해보고 싶었다.
이번 구성에서 확인해보고 싶었던 것
단순히 VM 한 대에 Guacamole로 접속하는 것이라면 이미 흔한 구성이다.
이번에는 그보다 조금 더 나아가 다음과 같은 구조가 실제로 가능한지 확인해보고 싶었다.

여기에 지원이 종료된 Windows 환경을 그대로 내부망에 노출하지 않고,
Legacy VM
↓
Linux Gateway
↓
필요한 목적지만 허용하는 격리 구조까지 함께 만들어보기로 했다.
즉 실험의 핵심은 크게 네 가지였다.
1. 레거시 Windows 환경을 중앙에서 표준화할 수 있는가?
2. Guacamole을 이용해 여러 Windows VM을
하나의 Pool처럼 제공할 수 있는가?
3. 사용자가 특정 VM을 고르지 않아도
가용 VM을 자동으로 배정할 수 있는가?
4. 지원이 종료된 환경을 별도 네트워크에 격리하면서
필요한 통신만 허용할 수 있는가?결과적으로 구성한 것이
Guacamole + VMware ESXi + Linux Gateway 기반 Windows VM Pool
이다.
전체 구조
논리적인 흐름은 다음과 같다.

Legacy VM Network는 ESXi의 vSwitch나 Port Group 등을 이용해 별도의 논리 네트워크로 구성할 수 있다.
Linux Gateway 역시 반드시 별도 물리 서버일 필요는 없다.
ESXi 위에 Linux VM을 하나 구성하고 두 개 이상의 가상 NIC를 연결해 Gateway 역할을 맡길 수도 있다.
VMware ESXi
│
├─ Linux Gateway VM
│ ├─ 내부망 NIC
│ └─ Legacy VM Network NIC
│
├─ LEGACY-01
├─ LEGACY-02
└─ LEGACY-03사용자 PC에는 레거시 프로그램을 설치하지 않는다.
Chrome이나 Edge 같은 일반적인 웹 브라우저만 있으면 된다.

Linux Gateway가 중요한 이유
이번 구성에서 Linux 서버는 단순히 Guacamole Docker를 실행하는 서버가 아니다.
다음 역할을 동시에 담당한다.
웹 접속 Gateway
Reverse Proxy
Guacamole Server
VM 전용망 Gateway
DHCP Server
Router
Firewall / ACL
필요 시 제한적 NAT특히 중요한 부분은 레거시 Windows VM을 일반 내부망에 직접 연결하지 않는 것이다.
가장 단순하게 구성한다면 다음과 같이 동일한 내부망에 VM을 연결할 수도 있다.
내부망
├─ 사용자 PC
├─ 일반 서버
├─ Windows VM-01
├─ Windows VM-02
└─ Windows VM-03하지만 이렇게 구성하면 지원이 종료된 Windows나 오래된 Runtime을 사용하는 VM 역시 다른 장비와 비슷한 수준으로 내부망에 노출된다.
평상시에는 문제가 없어 보이더라도 내부망의 다른 장비가 침해될 경우, 보안 업데이트가 중단된 레거시 VM이 추가 공격이나 횡적 이동(Lateral Movement)의 대상이 될 수 있다.
그래서 이번 구성에서는 네트워크를 한 단계 더 분리했다.

Legacy VM Network의 기본 Gateway는 Linux 서버가 담당하며, 다른 네트워크로 이동하는 트래픽은 Linux Gateway를 통과하도록 구성했다.
여기서 단순히 Subnet만 분리한 것이 아니라 Firewall 정책을 통해 Legacy VM이 접근할 수 있는 네트워크 범위도 제한했다.
개념적으로는 다음과 같다.
내부망 → Legacy VM
필요한 관리 접근 허용
Legacy VM → 일반 내부망
기본 차단
Legacy VM → Internet
기본 차단
Legacy VM → 필요한 특정 서버
예외 허용즉 Linux Gateway는 단순한 Router가 아니라,
레거시 실행환경과 나머지 네트워크 사이의 보안 경계
역할도 담당한다.
실제 IP Forwarding, Firewall Rule, NAT 구성 방법은 뒤에서 별도로 다룬다.
완전한 VDI를 만들려는 것은 아니다
이 구성은 VMware Horizon이나 Citrix Virtual Apps and Desktops 같은 완성형 VDI 솔루션을 대체하기 위해 만든 것은 아니다.
완성형 VDI에는 일반적으로 다음과 같은 기능이 포함된다.
자동 VM Provisioning
고가용성
User Profile 관리
대규모 Session Broker
Desktop Lifecycle 관리
정교한 사용자 인증 및 권한 관리
GPU 가상화이번 구성은 훨씬 단순하다.
VMware ESXi
+
Windows VM
+
Linux Gateway
+
RDP
+
Apache Guacamole
+
Nginx
+
PostgreSQL따라서 일반적인 VDI라기보다는
레거시 애플리케이션 전용 경량 가상 데스크톱 환경
정도로 보는 것이 적절하다.
특히 이번 실험에서 확인하려는 것도 VDI 전체를 구현하는 것이 아니라,
이미 생성되어 있는 여러 Windows VM 중 사용할 수 있는 VM을 사용자에게 자동으로 연결하는 것
이었다.
1. 정상 동작하는 Windows Golden Image를 만든다
가장 먼저 레거시 프로그램이 정상적으로 동작하는 Windows VM 하나를 만든다.
이 VM이 이후 모든 VM의 기준이 된다.
Windows 설치
↓
Windows 기본 설정
↓
필요 Runtime 설치
↓
브라우저 / ActiveX 구성
↓
레거시 프로그램 설치
↓
실제 기능 테스트
↓
Golden Image 완성이 VM은 일반 PC로 사용할 목적이 아니다.
레거시 프로그램 하나를 안정적으로 실행하기 위한 전용 환경이다.
따라서 불필요한 프로그램은 최대한 설치하지 않는다.
특히 보안 지원이 종료된 Windows가 필요한 경우라면 인터넷이나 다른 네트워크로의 접근을 최소화하는 것이 중요하다.
2. 관리자 계정과 사용자 계정을 분리한다
Windows VM에는 최소 두 종류의 계정을 구성한다.
| 계정 | 용도 |
|---|---|
| 관리자 계정 | 프로그램 설치, 정책 수정, 장애 조치 |
| 사용자 계정 | Guacamole을 통한 레거시 프로그램 사용 |
사용자 계정은 Remote Desktop Users 정도의 권한만 부여한다.
net user legacyuser <PASSWORD> /add
net localgroup users legacyuser /add
net localgroup "Remote Desktop Users" legacyuser /add관리자 계정은 별도로 만든다.
net user legacyadmin <PASSWORD> /add
net localgroup administrators legacyadmin /add실제 비밀번호는 스크립트나 공개 문서에 기록하지 않는다.
3. Windows RDP를 활성화한다
Guacamole은 Windows 프로그램을 직접 실행하는 것이 아니다.
Windows RDP 세션에 연결한 뒤 해당 화면을 HTML5 기반 웹 화면으로 전달한다.
따라서 Windows VM에서 RDP를 활성화한다.
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" ^
/v fDenyTSConnections /t REG_DWORD /d 0 /fWindows Firewall에서도 RDP를 허용한다.
netsh advfirewall firewall set rule group="Remote Desktop" new enable=Yes서비스 확인:
sc query TermService다만 사용자 네트워크에서 VM의 TCP/3389에 직접 접근하도록 만들지는 않는다.
사용자 PC
X
└── Windows VM 직접 RDP
Guacamole
│
└── RDP → Windows VM4. 로그인하면 레거시 프로그램만 실행되도록 만든다
일반적인 RDP Desktop을 사용자에게 제공하는 것이 목적이 아니다.
원하는 흐름은 다음과 같다.
로그인
↓
레거시 프로그램 실행
↓
사용
↓
종료사용자 계정의 Windows Shell을 특정 프로그램으로 지정한다.
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" ^
/v Shell /t REG_SZ ^
/d "C:\LegacyViewer\Viewer.exe" /fHKCU이므로 사용자 계정 컨텍스트에서 적용해야 한다.
로그인하면 일반적인 explorer.exe Desktop 대신 지정한 프로그램이 실행된다.
브라우저 접속
↓
Windows 로그인
↓
Viewer.exe 실행정확히는 RemoteApp이 아니라 일반 RDP Session의 Shell을 특정 프로그램으로 제한하는 방식이다.
5. 사용자 환경을 일부 제한한다
전용 실행환경이므로 사용자가 Windows 환경을 임의로 변경하지 못하도록 일부 기능을 제한한다.
실행창:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ^
/v NoRun /t REG_DWORD /d 1 /f제어판:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer" ^
/v NoControlPanel /t REG_DWORD /d 1 /fCMD:
reg add "HKCU\Software\Policies\Microsoft\Windows\System" ^
/v DisableCMD /t REG_DWORD /d 2 /fRegistry Editor:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" ^
/v DisableRegistryTools /t REG_DWORD /d 1 /fTask Manager:
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System" ^
/v DisableTaskMgr /t REG_DWORD /d 1 /f다만 이러한 설정 자체를 보안 경계로 보면 안 된다.
목적은 사용자가 실수로 실행환경을 변경하는 것을 줄이는 것이다.
실제 보안 경계는 계정 권한과 네트워크 ACL에서 만든다.
6. 사용이 끝난 Session을 정리한다
VM Pool에서 중요한 것은 VM 재사용이다.
사용자 A가 사용한 Session이 남아 있으면 다음 사용자가 같은 VM을 할당받았을 때 이전 상태가 남을 수 있다.
사용자 A
↓
Viewer 실행
↓
연결 종료
↓
Session 유지
↓
사용자 B 접속
↓
이전 상태 잔존이를 방지하기 위해 Idle Session과 Disconnect Session을 일정 시간 후 정리하도록 설정한다.
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ^
/v MaxIdleTime /t REG_DWORD /d 600000 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ^
/v MaxDisconnectionTime /t REG_DWORD /d 60000 /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" ^
/v fResetBroken /t REG_DWORD /d 1 /f600000ms는 10분, 60000ms는 1분이다.
적용:
gpupdate /force핵심은 시간 값 자체보다 다음 흐름이다.
사용 종료
↓
Session 정리
↓
다음 사용자 접속
↓
새로운 Session 시작7. Golden Image를 복제해 VM Pool을 만든다
Golden Image가 완성되면 ESXi에서 여러 VM으로 복제한다.
Golden Image
├─ LEGACY-01
├─ LEGACY-02
└─ LEGACY-03복제 후 다음 항목은 개별화한다.
VM 이름
Windows Hostname
MAC Address
IP Address예:
LEGACY-01 → 10.20.30.11
LEGACY-02 → 10.20.30.12
LEGACY-03 → 10.20.30.13IP는 DHCP Reservation으로 관리한다.
8. Linux Gateway에 전용 네트워크를 만든다
예:
Legacy VM Network
10.20.30.0/24Gateway:
10.20.30.1구조:

IP Forwarding:
sudo sysctl -w net.ipv4.ip_forward=1영구 적용:
echo "net.ipv4.ip_forward=1" \
| sudo tee /etc/sysctl.d/99-legacy-forward.conf
sudo sysctl --system9. DHCP도 Linux Gateway가 담당한다
dnsmasq 등을 이용해 VM 전용망에 DHCP를 제공할 수 있다.
VM-01
MAC AA:BB:CC:DD:EE:01
→ 10.20.30.11
VM-02
MAC AA:BB:CC:DD:EE:02
→ 10.20.30.12
VM-03
MAC AA:BB:CC:DD:EE:03
→ 10.20.30.13VM 추가 과정도 단순해진다.
VM 복제
↓
MAC 확인
↓
DHCP Reservation 추가
↓
Guacamole Connection 추가10. Firewall은 Default Deny로 구성한다
레거시 VM은 일반 인터넷 PC가 아니다.
VM → Internet
차단
VM → 일반 내부망
차단
VM → 필요한 내부 서버
허용
Guacamole → VM RDP
허용예를 들어:
Legacy VM Network
10.20.30.0/24
필요한 서버
192.0.2.100 TCP/80기본 정책:
sudo iptables -P FORWARD DROP정상 Session 허용:
sudo iptables -A FORWARD \
-m conntrack \
--ctstate ESTABLISHED,RELATED \
-j ACCEPT필요한 목적지만 허용:
sudo iptables -A FORWARD \
-s 10.20.30.0/24 \
-d 192.0.2.100 \
-p tcp \
--dport 80 \
-j ACCEPT결국:
Legacy VM
│
├── X → Internet
├── X → 일반 내부망
└── O → 필요한 서버구조다.
VM으로 만들었다는 사실 자체가 보안을 보장하지 않는다.
지원이 종료된 OS를 유지해야 한다면 접근 가능한 네트워크 범위를 줄이는 것이 중요하다.
11. NAT도 필요한 경우에만 사용한다
VM Network 전체에 NAT를 걸어버리는 방법도 있다.
iptables -t nat -A POSTROUTING \
-s 10.20.30.0/24 \
-o eth0 \
-j MASQUERADE하지만 이렇게 하면 레거시 VM이 일반 인터넷 PC처럼 동작하게 될 가능성이 있다.
필요하다면 특정 목적지만 제한적으로 NAT한다.
iptables -t nat -A POSTROUTING \
-s 10.20.30.0/24 \
-d 192.0.2.100 \
-o eth0 \
-j MASQUERADE라우팅만으로 통신할 수 있다면 NAT를 사용하지 않는 편이 더 단순하다.
12. Apache Guacamole 설치
Apache Guacamole은 웹 브라우저에서 RDP, VNC, SSH 등을 사용할 수 있도록 해주는 HTML5 기반 Remote Access Gateway다.
이번 구성에서는 Docker를 사용했다.
guacamole
guacd
PostgreSQL역할:
guacamole
→ Web Application
guacd
→ RDP/VNC/SSH 중계
PostgreSQL
→ 사용자, 권한, Connection 설정Docker Compose 예:
services:
guacd:
image: guacamole/guacd:1.6.0
container_name: guacd
restart: unless-stopped
postgres:
image: postgres:16-alpine
container_name: guac-postgres
restart: unless-stopped
environment:
POSTGRES_DB: guacamole_db
POSTGRES_USER: guacamole_user
POSTGRES_PASSWORD: "CHANGE_ME"
volumes:
- ./postgres_data:/var/lib/postgresql/data
guacamole:
image: guacamole/guacamole:1.6.0
container_name: guacamole
restart: unless-stopped
depends_on:
- guacd
- postgres
environment:
GUACD_HOSTNAME: guacd
POSTGRESQL_ENABLED: "true"
POSTGRESQL_HOSTNAME: postgres
POSTGRESQL_DATABASE: guacamole_db
POSTGRESQL_USERNAME: guacamole_user
POSTGRESQL_PASSWORD: "CHANGE_ME"
ports:
- "127.0.0.1:8080:8080"Guacamole을 네트워크 전체에 직접 노출하지 않고 localhost에만 Bind한다.
127.0.0.1:8080접속은 Nginx를 통해서만 받는다.
13. PostgreSQL Schema 초기화
Guacamole용 Database Schema를 생성한다.
docker run --rm guacamole/guacamole:1.6.0 \
/opt/guacamole/bin/initdb.sh --postgresql \
> initdb.sqlDB 적용:
cat initdb.sql | docker exec -i guac-postgres \
psql -U guacamole_user -d guacamole_db실행:
docker compose up -d확인:
docker compose ps
docker logs guacamole
docker logs guacd
docker logs guac-postgres14. Nginx Reverse Proxy 구성
접속 구조:
Browser
│ HTTPS
▼
Nginx :443
│
▼
127.0.0.1:8080
│
▼
Guacamole예:
server {
listen 443 ssl;
server_name legacy.example.internal;
ssl_certificate /etc/nginx/ssl/legacy.crt;
ssl_certificate_key /etc/nginx/ssl/legacy.key;
location / {
return 302 /guacamole/;
}
location /guacamole/ {
proxy_pass http://127.0.0.1:8080/guacamole/;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /guacamole/websocket-tunnel {
proxy_pass http://127.0.0.1:8080/guacamole/websocket-tunnel;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}검사:
sudo nginx -t적용:
sudo systemctl reload nginx15. Docker Network와 VM Network 사이의 RDP 경로
Guacamole은 Docker 안에서 동작하므로 실제 통신 경로는 다음과 같다.
Browser
↓
Nginx
↓
Guacamole Container
↓
guacd Container
↓
Docker Network
↓
Linux Host
↓
Legacy VM Network
↓
Windows RDP따라서 Linux Firewall이나 DOCKER-USER Chain에서 Docker → VM Network 통신이 차단되지 않는지 확인해야 한다.
16. Guacamole에 Windows VM을 등록한다
| Connection | Protocol | Host |
|---|---|---|
| LEGACY-01 | RDP | 10.20.30.11 |
| LEGACY-02 | RDP | 10.20.30.12 |
| LEGACY-03 | RDP | 10.20.30.13 |
Port:
3389접속 계정:
Username: legacyuser
Password: ********각 VM의 최대 동시 Connection은 1로 제한한다.
LEGACY-01 → 최대 1
LEGACY-02 → 최대 1
LEGACY-03 → 최대 117. VM을 Balancing Group으로 묶는다
여기서 이번 실험의 핵심이었던 VM Pool이 만들어진다.
LEGACY_POOL
├─ LEGACY-01
├─ LEGACY-02
└─ LEGACY-03사용자에게는 개별 VM을 보여주지 않는다.
LEGACY_POOL만 보여준다.
사용자가 Pool에 접속하면 Guacamole이 사용 가능한 Connection을 선택한다.
사용자 A
↓
LEGACY_POOL
↓
LEGACY-02
사용자 B
↓
LEGACY_POOL
↓
LEGACY-01사용자는 실제 어떤 VM을 배정받았는지 알 필요가 없다.
여기서 말하는 '동적 할당'
이 부분은 정확히 구분할 필요가 있다.
이번 실험에서 구현한 것은 Dynamic Provisioning이 아니다.
즉 접속할 때마다 새로운 VM을 자동 생성하는 구조는 아니다.
이미 만들어져 있는 VM들 가운데 현재 사용할 수 있는 Connection을 자동으로 선택한다.
사용자 접속
↓
LEGACY_POOL
↓
가용 Connection 확인
↓
가용 Windows VM 선택
↓
RDP 연결따라서 정확하게 표현하면
VM Pool 내 가용 VM 동적 할당
또는
가용 RDP Connection 자동 배정
정도가 적절하다.
이번 실험에서 확인하고 싶었던 핵심 중 하나도 바로 이것이었다.
전용 VDI 솔루션 없이 Guacamole의 Balancing Group만으로 간단한 VM Pool 배정 구조를 만들 수 있을까?
결과적으로 제한적인 형태이기는 하지만 가능했다.
18. 사용자 입장에서는 상당히 단순해진다
기존 Local VM:
VMware 실행
↓
VM 선택
↓
Windows 부팅
↓
로그인
↓
레거시 프로그램 실행변경 후:
Browser 실행
↓
접속 주소 접속
↓
LEGACY_POOL 선택
↓
레거시 프로그램 사용실제로 뒤에서는:
Browser
↓
Nginx
↓
Guacamole
↓
LEGACY_POOL
↓
가용 Windows VM 선택
↓
RDP
↓
Windows 로그인
↓
Viewer.exe 실행이 이루어진다.
19. 자동 로그인은 별도의 문제
Guacamole은 HTTP Header Authentication도 지원한다.
하지만 단순히 Header 하나를 넣는 것으로 끝낼 문제는 아니다.
proxy_set_header X-Guac-User someuser;사용자가 해당 Header를 직접 조작할 수 없도록 신뢰 가능한 인증 계층이 필요하다.
사용자
↓
인증 시스템
↓
Reverse Proxy
↓
외부 인증 Header 제거
↓
검증된 사용자 Header 생성
↓
Guacamole따라서 테스트 수준에서는 여러 방식을 실험할 수 있지만 실제 운영 환경에서는 일반 로그인이나 기존 SSO 연동을 사용하는 편이 안전하다.
20. 테스트에서 중요했던 부분
단순히 한 번 접속되는지만 확인해서는 VM Pool을 검증했다고 보기 어렵다.
| 테스트 | 정상 기준 |
|---|---|
| Browser → Nginx | 정상 |
| Browser → Guacamole | 정상 |
| Guacamole → VM | RDP 정상 |
| 사용자 로그인 | 정상 |
| Viewer 실행 | 정상 |
| 프로그램 기능 | 정상 |
| 연결 종료 | Session 정리 |
| 재접속 | 깨끗한 상태 |
| 기존 VM 사용 중 추가 접속 | 다른 VM 배정 |
| 필요한 내부 서버 | 통신 가능 |
| Internet | 차단 |
| 불필요한 내부 서버 | 차단 |
특히 반복적으로:
접속
→ 사용
→ 종료
→ Session 정리
→ 재접속
→ VM 재할당과정을 확인했다.
이번 실험에서는 최초 연결보다 VM을 반복해서 재사용할 수 있는가가 더 중요한 검증 대상이었다.
어디에 활용할 수 있을까?
| 대상 | 적합성 |
|---|---|
| ActiveX / 구형 IE 프로그램 | 높음 |
| 특정 Java Runtime 의존 프로그램 | 높음 |
| 특정 .NET Framework 프로그램 | 높음 |
| 구형 Oracle Client / ODBC 프로그램 | 높음 |
| 특정 Office Add-in | 조건부 |
| 오래된 장비 관리 프로그램 | 높음 |
| 테스트 / 호환성 검증 환경 | 높음 |
| 일반 Desktop | 낮음 |
| 영상편집 / CAD / GPU 프로그램 | 낮음 |
| USB 직접 제어 프로그램 | 낮음 |
핵심은:
프로그램의 실행환경을 사용자 PC와 분리했을 때 얻는 이득이 큰가?
이다.
프로그램별 Pool로 확장하는 것도 가능하다
Guacamole
├─ DOCUMENT_POOL
│ ├─ DOC-01
│ ├─ DOC-02
│ └─ DOC-03
│
├─ LEGACY_WEB_POOL
│ ├─ WEB-01
│ └─ WEB-02
│
├─ OLD_APP_POOL
│ ├─ APP-01
│ └─ APP-02
│
└─ DEVICE_TOOL_POOL
└─ TOOL-01Firewall 정책도 Pool별로 나눌 수 있다.
DOCUMENT_POOL
→ Document Server만 허용
OLD_APP_POOL
→ 필요한 서버만 허용
DEVICE_TOOL_POOL
→ 관리 대상 장비만 허용결국 프로그램마다 필요한 호환환경을 독립된 서비스처럼 분리할 수 있다.
Golden Image 관리
VM 각각을 개별 관리하기 시작하면 Pool을 만든 의미가 줄어든다.
가능하면 기준 이미지를 관리한다.
Golden Image
↓
TEST VM Clone
↓
Update
↓
호환성 테스트
↓
정상 확인
↓
운영 Pool 반영레거시 환경에서는 항상 최신 상태보다 검증된 동일 상태를 유지하는 것이 더 중요할 수도 있다.
물론 실험에서 끝나는 부분도 있다
이번 구성은 어디까지나 기술적 가능성을 검증하기 위한 목적도 포함된 환경이다.
따라서 실제 Production 환경에서 요구되는 모든 요소를 갖춘 것은 아니다.
예를 들어:
Hypervisor HA
Gateway 이중화
Storage 이중화
자동 VM Provisioning
사용자 Profile 관리
대규모 인증 시스템
중앙 로그 관리
자동 장애 복구등은 별도의 영역이다.
즉 이번 실험의 의미는
전용 VDI 제품 없이도 오픈소스 소프트웨어와 일반적인 가상화 환경을 조합해, 레거시 애플리케이션 전용 VM Pool과 사용자 자동 할당 구조를 어느 정도까지 구현할 수 있는가?
를 확인해본 데 있다.
중앙화하면서 생기는 새로운 위험
Local VM에서는:
한 VM 장애
→ 해당 사용자만 영향정도였던 문제가 중앙화 이후에는:
ESXi 장애
Storage 장애
Linux Gateway 장애
Guacamole 장애
→ 전체 Pool 영향으로 확대될 수 있다.
따라서 실제 운영으로 확장하려면 백업, 복구, 이중화 설계를 별도로 고민해야 한다.
Windows와 프로그램 라이선스는 별도로 확인해야 한다
기술적으로 동작한다고 해서 사용권까지 자동으로 해결되는 것은 아니다.
특히 Windows Client VM을 ESXi 같은 Hypervisor에 여러 대 구성하고 여러 사용자가 원격으로 사용하는 경우에는 일반적인 Windows Pro PC 한 대를 사용하는 것과 라이선스 조건이 다를 수 있다.
Windows Pro가 설치되어 있다는 사실만으로 온프레미스 가상 Desktop 환경에 필요한 권리가 자동으로 충족된다고 볼 수는 없다.
실제 운영 시에는 Microsoft의 현재 라이선스 조건을 기준으로 Enterprise, VDA, Microsoft 365 등에 포함된 가상화 접근 권리를 확인할 필요가 있다.
레거시 프로그램 역시 마찬가지다.
설치 수
Device
Named User
Concurrent User
Server
Site등 제품마다 라이선스 기준이 다를 수 있다.
Golden Image 하나를 여러 VM으로 복제하는 행위가 별도 설치로 계산되는 제품도 있을 수 있다.
따라서 이 글은 기술적인 구현과 실험 결과를 설명하는 것이며, 실제 운영 시에는 Windows와 각 프로그램의 라이선스를 별도로 확인해야 한다.
결국 이번 실험에서 확인한 것
처음에는 단순히 오래된 프로그램을 실행하기 위한 방법에서 시작했다.
하지만 구조를 확장하면서 다음을 실제로 확인할 수 있었다.
레거시 실행환경을 Golden Image로 표준화
+
여러 Windows VM을 Pool로 구성
+
Guacamole으로 가용 VM 자동 배정
+
Session 종료 후 VM 재사용
+
Linux Gateway로 네트워크 격리즉 최소한 기술적인 관점에서는:
특정 Windows 환경에 종속된 레거시 프로그램을 중앙 VM Pool로 분리하고, 사용자는 웹을 통해 가용 환경을 자동으로 할당받아 사용하는 구조
를 만들 수 있었다.
마무리
이 구성은 ActiveX를 현대화하는 방법은 아니다.
레거시 프로그램이 최신 기술로 바뀐 것도 아니다.
오히려 오래된 실행환경을 그대로 유지하되 사용자 PC와 분리하고 제한된 공간에 격리하는 방법에 가깝다.
기존에는:
최신 사용자 PC
+
레거시 프로그램
+
구형 Runtime
+
ActiveX
+
각종 호환성 설정이었다면,
이제는:
사용자 PC
│
│ Browser
▼
Linux Gateway
│
├─ Nginx
├─ Guacamole
├─ Firewall
├─ Routing
└─ DHCP
│
▼
Windows VM Pool
│
├─ 구형 Runtime
├─ ActiveX
└─ 레거시 프로그램로 분리한다.
처음에는 단순히 오래된 프로그램 하나를 살리기 위한 우회 방법을 생각했다.
그리고 동시에
“Guacamole과 일반 Hypervisor만으로 어디까지 구현할 수 있을까?”
라는 실험적인 목적도 있었다.
구성하고 나니 단순한 원격 VM 한 대가 아니라,
Golden Image → VM Pool → 사용자 동적 배정 → Session 재사용 → 네트워크 격리
까지 이어지는 작은 애플리케이션 제공 환경이 만들어졌다.
완성형 VDI와 비교할 수준은 아니지만, 특정 Windows 환경에서만 동작하는 프로그램을 별도 실행환경으로 분리한다는 목적에는 충분히 활용할 수 있었다.
다른 레거시 프로그램까지 확장한다면 결국 형태는 다음에 가까워질 수 있다.
Legacy Application Access Platform사용자 PC를 프로그램에 맞추는 대신,
프로그램이 요구하는 실행환경을 중앙에 고정하고 사용자는 필요할 때 그 환경을 빌려 쓰는 방식.
지원이 종료되었거나 당장 현대화하기 어려운 레거시 프로그램을 계속 사용해야 하는 상황이라면 기술적으로 한번 실험해볼 만한 접근 방법이라고 생각한다.
참고자료
작성 기준: 2026년 9월
- Apache Guacamole Documentation
- Apache Guacamole Docker Deployment
- Apache Guacamole PostgreSQL Authentication
- Apache Guacamole HTTP Header Authentication
- Apache Guacamole JDBC Authentication / Balancing Connection Group
- Microsoft Windows Virtual Desktop Licensing Guidance
- Microsoft Windows Desktop Operating System Product Terms
※ 제품 버전, 지원 정책 및 라이선스 조건은 변경될 수 있으므로 실제 운영 시점의 공식 문서를 다시 확인하는 것이 좋다.