VNC의 정의와 역사

VNC(Virtual Network Computing)는 원격 접속 기술 중 하나로그래픽 기반 원격 제어를 제공하는 프로토콜이다.
VNC
 1994년 영국의 영국 컴퓨터 암호학 연구소인 AT&T의 개발자들이 개발하였으며, 초기에는 Virtual Network Computing이라는 이름으로 개발되었고초기 버전인 VNC 1.0은 퍼블릭 도메인 소프트웨어로 공개되었다.
이후 VNC는 많은 개발자들에 의해 발전되어 왔으며현재는 오픈 소스 프로젝트로 유지되고 있다.

VNC의 핵심 구성 요소

VNC는 크게 VNC 클라이언트, VNC 서버, VNC 프로토콜로 구성되며 구성별 설명은 아래와 같다.

 

VNC 클라이언트

VNC 클라이언트는 원격으로 접속하여 원격 장치의 화면을 표시하고 사용자 입력을 전송하는 역할을 한다.
클라이언트는 다양한 플랫폼에서 실행될 수 있으며원격 장치의 화면 정보를 받아 사용자에게 시각적으로 전달한다.

 

VNC 서버

VNC 서버는 원격으로 제어하고자 하는 컴퓨터 또는 장치에 설치되어 실행된다.
서버는 원격 장치의 화면 정보를 수집하고 클라이언트로 전송하며클라이언트로부터의 사용자 입력을 받아 처리한다.

 

VNC 프로토콜

VNC 프로토콜은 클라이언트와 서버 간의 통신을 관리하는 규약이다. VNC 클라이언트와 서버는 VNC 프로토콜을 사용하여 화면 데이터마우스 및 키보드 입력 등을 주고받는다. 프로토콜은 데이터 압축암호화클립보드 공유 등 다양한 기능을 제공하여 원격 접속의 안전성과 편의성을 보장한다.

 

VNC의 동작 원리 및 프로토콜

VNC는 클라이언트서버 아키텍처를 기반으로 동작하고 동작원리는 아래에서 설명한다.

VNC의 동작 원리

  1. 클라이언트가 원격으로 접속하고자 하는 VNC 서버의 IP 주소나 호스트 이름을 입력한다.
  2. 클라이언트와 서버 간의 연결이 수립되면, 클라이언트는 VNC 프로토콜을 사용하여 서버에 연결한다.
  3. 연결이 확립되면, 서버는 화면 정보를 클라이언트로 전송하며, 이는 그래픽 프레임 버퍼의 변경 내용을 클라이언트에게 전송하는 방식으로 이루어진다.
  4. 클라이언트는 서버로부터 받은 화면 정보를 해석하여 로컬 디스플레이에 표시하고 이로써 클라이언트는 원격 서버의 화면을 실시간으로 볼 수 있게 된다.
  5. 클라이언트는 마우스 및 키보드 입력을 서버로 전송한다. 이 입력은 VNC 프로토콜을 통해 서버로 전달되고, 서버는 이를 수신하여 원격 장치에 적용한다.
  6. 이러한 과정이 지속되면서 클라이언트와 서버 간에 양방향 통신이 이루어지며, 클라이언트는 서버의 화면을 실시간으로 업데이트하고, 서버는 클라이언트로부터의 입력을 처리한다.
  7. VNC 프로토콜은 TCP/IP 프로토콜을 기반으로 동작하며, 화면 데이터 전송, 마우스 및 키보드 입력, 압축, 암호화, 클립보드 공유 등을 위한 다양한 명령과 메시지를 정의한다. 프로토콜은 클라이언트와 서버 간의 상호작용을 원활하게 하며, 안전한 원격 접속을 제공하기 위해 보안 기능을 포함할 수도 있다.
1~3번까지의 VNC 동작원리
4번 VNC 동작원리
5번 VNC 동작원리
6번 VNC 동작원리

VNC 서버 구현

VNC 서버 소프트웨어 선택 기준

VNC 서버를 구현하기 위해서는 다양한 소프트웨어 옵션이 존재한다. VNC 서버 소프트웨어를 선택할 때 고려해야 할 주요 기준은 아래와 같다.

  • 플랫폼 호환성
    • VNC 서버는 다양한 운영 체제에서 실행될 수 있어야 하고, 선택한 VNC 서버 소프트웨어가 목표로 하는 플랫폼과 호환되는지 확인한다.
  • 보안 기능
    • 원격 접속은 보안이 매우 중요한 요소이므로 VNC 서버 소프트웨어는 데이터 암호화, 인증 메커니즘, 접속 제한 등과 같은 보안 기능을 제공하는지 확인한다.
  • 성능
    • 원격으로 제어하는 장치의 화면 정보를 실시간으로 전송해야 하므로, VNC 서버의 성능도 중요한 요소이다.
      빠른 전송 속도와 낮은 지연 시간을 제공하는 VNC 서버를 선택해야 한다.
  • 추가 기능
    • 일부 VNC 서버 소프트웨어는 화면 공유, 파일 전송, 클립보드 공유 등과 같은 추가 기능을 제공할 수 있다.
      프로젝트 요구사항에 맞춰 필요한 기능을 고려하여 선택한다.

VNC 프로그램 종류와 차이점

VNC 플랫폼 기능 및 성능 운영체제 지원 여부 사용 편의성 라이센스
RealVNC 다양한 기능 제공
(화면 공유, 파일 전송 등)
Windows, macOS,
Linux 등 다양한 운영 체제 지원
사용하기
쉬운 인터페이스
무료
상용 버전 존재
TightVNC 압축 기술을 통한
효율적인 원격 제어
Windows, Unix 기반 시스템 지원 간단한 설정과 사용 무료
UltraVNC 암호화 및 파일 전송 기능 제공 Windows 운영 체제 지원 사용자 친화적인
인터페이스
무료
TigerVNC 고성능 원격 제어 및
암호화 기능
Linux, Unix 기반 시스템 지원 다양한 설정 옵션 무료
VNC Connect 클라우드 연결
강화된 암호화 기능
Windows, macOS,
Linux, Raspberry Pi 등 지원
웹 기반
인터페이스 제공
상용 버전 유료

VNC 서버의 아키텍처와 기능 설계

VNC 서버를 구현하기 위해서는 아키텍처와 기능을 설계해야 한다.

VNC 아키텍처

VNC 아키텍처

VNC 서버의 아키텍처와 기능 설계 요소

  •  화면 캡처
    • VNC 서버는 원격 장치의 화면 정보를 실시간으로 캡처하여 전송해야 하고, 이를 위해 화면 캡처 및 그래픽 처리 기능을 구현해야 한다.
  • 입력 수신
    • VNC 서버는 클라이언트로부터의 마우스 및 키보드 입력을 수신하고 처리해야 하고, 클라이언트의 입력을 서버의 로컬 입력으로 변환하고, 장치에 적용하는 기능을 구현한다.
  • 데이터 압축
    • VNC 서버는 전송할 화면 데이터를 압축하여 효율적인 데이터 전송을 가능하게 해야 하며,
      데이터 압축 알고리즘을 구현하고, 압축된 데이터를 클라이언트에게 전송하는 기능을 구현한다.
  • 데이터 전송
    • VNC 서버는 TCP/IP 프로토콜을 사용하여 클라이언트와 데이터를 주고받아야 하는데, 클라이언트로부터 받은 입력을 처리하고, 화면 데이터를 전송하는 기능을 구현한다.
  • 보안 기능
    • VNC 서버는 보안을 위해 암호화, 인증 메커니즘, 접속 제한 등과 같은 보안 기능을 제공해야 한다.
      SSL/TLS 프로토콜을 사용하여 데이터를 암호화하거나, 사용자 인증을 구현하는 등의 기능을 추가해서 사용한다.
  • 확장성
    • VNC 서버는 여러 클라이언트의 동시 접속을 처리할 수 있어야 하고, 멀티스레드 또는 멀티프로세스 기술을 활용하여 동시성을 지원하는 구조를 설계한다.

 

VNC 서버 구축 방법

VNC 서버 구축 환경

#OS 버전 확인 명령어
cat /etc/redhat-release
 
#출력 결과
CentOS Linux release 7.9.2009 (Core)
 
#SELinux OFF [임시 OFF]
setenforce 0
 
#SELinux OFF [영구적 OFF / 반드시 재부팅 필요] 
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/sysconfig/selinux

VNC 서버 구축을 위한 패키지 설치

#Linux update
yum -y update

#EPEL은 Extra Packages of Enterprise Linux 의 준말이며, 리눅스의 추가 패키지다.
yum -y install epel-release

#Linux 운영체제를 최소 설치하여 그래픽 환경이 존재하지 않을 시 설치
yum -y groupinstall "GNOME Desktop"

#VNC Server Packages Install
yum install -y tigervnc-server

#시스템 반영
systemctl daemon-reload

#VNC에 접속하기 위한 패키지 설치
yum -y install tigervnc
 

VNC 서버 방화벽 설정

#VNC Firewall 방화벽 허용
#예시에서는 5901 port open
firewall-cmd --permanent --add-port=5901/tcp

#firewall 재실행
firewall-cmd --reload


#VNC Iptable 방화벽 허용
#사용할 port 수만큼 Open 예시에서 5900 ~ 6000 Open 설정
iptables -I INPUT -p tcp -m multiport --dport 5900:6000 -j ACCEPT

#iptable 방화벽 정책 저장
service iptables save

#서비스 재시작
systemctl restart iptables
 

VNC 사용자 생성

#사용자 testuser1 생성
[root@localhost ~]#useradd testuser1

#EX vncserver :[port number] -geometry [해상도] -depth [number(기본값 24)]
[testuser1@localhost ~]$ vncserver :1 -geometry 3840x1080 -depth 24

You will require a password to access your desktops.

Password:
Verify:
Would you like to enter a view-only password (y/n)? n
A view-only password is not used

New 'vncserver:1 (testuser1)' desktop is vncserver:1

Starting applications specified in /home/testuser1/.vnc/xstartup
Log file is /home/testuser1/.vnc/vncserver:1.log
[testuser1@localhost ~]$
실행 명령어 및 옵션 설명
vncserver VNC 서버를 실행하는 명령어이다.
1 VNC 디스플레이 번호를 나타내며 디스플레이 번호 + 5901이 포트 번호이다.
geometry 원격 데스크탑의 해상도를 지정한다.
depth 24 원격 데스크탑의 색상 깊이를 지정한다.

VNC 파일 설명

경로 및 File name 설명
$HOME/.vnc/xstartup VNC 데스크탑이 시작될 때 실행할 X 응용 프로그램을 지정하는 셸 스크립트이며,
이 파일이 없으면 vncserver는 선택한 창 관리자를 시작하려고
시도하는 기본 xstartup 스크립트를 만든다.
$HOME/.vnc/passwd VNC 암호 파일이다.
$HOME/.vnc/ 호스트 : 디스플레이# .log Xvnc 및 응용 프로그램에 대한 로그 파일이다.
$HOME/.vnc/ 호스트 : 디스플레이# .pid -kill 옵션 에서 사용하는 Xvnc 프로세스 ID를 식별하기 위한 파일이다.

VNC서버 실행 명령어

#VNC 실행 명령어 옵션별 설명
vncserver :[port number] -geometry [해상도] -depth [number(기본값 24)]

#VNC 실행 명령어 예시
vncserver :1 -geometry 3840x1080 -depth 24

VNC 프로세스 확인 명령어

ps aux | grep vnc

VNC 자동실행 스크립트(Auto Script)

  1. 아래 스크립트는 사용자의 UID를 식별하여 해당 번호의 VNC를 실행시켜 준다. 예를 들어 사용자의 UID가 2001번이라면 5901번의 VNC 포트로 하여금 실행된다.
  2. GEOMETRY의 경우 해상도가 달라질 수 있기에 변수처리 하였다.
  3. xstartup 없는 경우라는 사용자의 홈 디렉토리에 만들지만 일관된 설정을 하기 위에 하나의 xstartup을 만들어 놓고 모든 사용자에게 같은 환경을 제공하기 위해 하나의 xstartup 파일을 만들어서 참조한다.
  4. 태초에 vnc passwd가 없다면 초기 비밀번호를 “p@ssw0rd”라는 임시 비밀번호로 설정한다.

아래의 스크립트를 사용자의 crontab에 * * * * * /bin/bash /VNC_Auto_Script.sh를 등록하면 일정시간 간격으로 실행하며 VNC가 실행되고 있지 않을 경우 자동으로 실행된다.

bash Shell을 사용하지 않고 타 쉘을 사용하고 있다면 반드시 crontab에 사용 Shell을 정의해주어야 한다.

아래는 crontab에 등록되어 있을 경우의 예시이다.

쉘=/bin/tcsh

* * * * * /bin/bash /VNC_Auto_Script.sh

#!/bin/bash
# Set the display number and geometry
DISPLAY_NUM=`id -u $USER | tail -c 4 | head -c 3 | awk '{print int($0)}'`
GEOMETRY="3840x1080"

# Set the location of the xstartup file
XSTARTUP_FILE="/ServerConfigFile/xstartup"

# Set the VNC password
VNC_PASSWORD="p@ssw0rd"

# Check if the VNC process is running
if pgrep -u $USER -x "Xvnc" > /dev/null; then
  echo "VNC is already running for user $USER."
else
  # If the VNC process is not running, start it
  echo "Starting VNC server..."

  # Check if a password has been set
  if ! [ -f "$HOME/.vnc/passwd" ]; then
    # If a password has not been set, set one automatically
    echo "Setting VNC password..."
    expect -c "
      set timeout 10
      spawn vncpasswd
      expect \"Password:\"
      send \"$VNC_PASSWORD\n\"
      expect \"Verify:\"
      send \"$VNC_PASSWORD\n\"
      expect \"Would you like to enter a view-only password (y/n)?\"
      send \"n\n\"
      expect eof
    "
  fi

  # Start the VNC server
  vncserver :$DISPLAY_NUM -depth 24 -geometry $GEOMETRY -xstartup $XSTARTUP_FILE
 
#!/bin/bash
# Set the display number and geometry
DISPLAY_NUM=`id -u $USER | tail -c 4 | head -c 3 | awk '{print int($0)}'`
GEOMETRY="3840x1080"

# Set the location of the xstartup file
XSTARTUP_FILE="/ServerConfigFile/xstartup"

# Set the VNC password
VNC_PASSWORD="p@ssw0rd"

# Check if the VNC process is running
if pgrep -u $USER -x "Xvnc" > /dev/null; then
  echo "VNC is already running for user $USER."
else
  # If the VNC process is not running, start it
  echo "Starting VNC server..."

  # Check if a password has been set
  if ! [ -f "$HOME/.vnc/passwd" ]; then
    # If a password has not been set, set one automatically
    echo "Setting VNC password..."
    expect -c "
      set timeout 10
      spawn vncpasswd
      expect \"Password:\"
      send \"$VNC_PASSWORD\n\"
      expect \"Verify:\"
      send \"$VNC_PASSWORD\n\"
      expect \"Would you like to enter a view-only password (y/n)?\"
      send \"n\n\"
      expect eof
    "
  fi

  # Start the VNC server
  vncserver :$DISPLAY_NUM -depth 24 -geometry $GEOMETRY -xstartup $XSTARTUP_FILE
 

VNC xstartup 파일 튜닝 방법

데스크톱 그래픽 환경 변경 방법

#xstartup xstartup 파일 편집기 접속
vi ~/.vnc/xstartup

#파일의 맨 하단에 사용하고자 하는 데스크톱 환경 선택하여 기재한다.

#GNOME 데스크탑
exec gnome-session &

#MATE 데스크탑
exec mate-session &

#KDE Plasma 데스크탑
startkde &

#Xfce 데스크탑
startxfce4 &

MATE 데스크톱 적용 예시

MATE 데스크톱 적용 예시

gsettings set 설정 방법

#xstartup xstartup 파일 편집기 접속
vi ~/.vnc/xstartup

#MATE 데스크탑 환경의 스크린세이버에서 잠금 기능(lock)을 비활성화한다.
gsettings set org.mate.screensaver lock-enabled false

#MATE 데스크탑 환경의 스크린세이버에서 활동이 없을 때 자동으로 활성화되는 기능을 비활성화한다.
gsettings set org.mate.screensaver idle-activation-enabled false

#MATE 데스크탑 환경의 윈도우 매니저인 Marco에서 합성(compositing) 관리자 기능을 비활성화하고, 이로써 그래픽 효과를 사용하지 않는 단순한 윈도우 매니저로 전환된다.
gsettings set org.mate.Marco.general compositing-manager false

#MATE 데스크탑 환경의 배경화면 설정에서 색상 그라데이션(color shading) 유형을 '단색(solid)'으로 설정한다.
gsettings set org.mate.background color-shading-type 'solid'

MATE 데스크탑 환경의 배경화면 설정에서 사용할 이미지 파일의 경로를 '/usr/share/backgrounds/cosmos/background-1.xml'로 설정한다.
gsettings set org.mate.background picture-filename '/usr/share/backgrounds/cosmos/background-1.xml'

#MATE 데스크탑 환경의 배경화면 설정에서 이미지 표시 옵션을 '확대(zoom)'으로 설정한다.
gsettings set org.mate.background picture-options 'zoom'

#MATE 데스크탑 환경의 기본 색상(primary color)을 '#334D60'으로 설정한다.
gsettings set org.mate.background primary-color '#334D60'

#MATE 데스크탑 환경에서 화면 잠금(lock screen) 기능을 비활성화 한다.
gsettings set org.mate.lockdown disable-lock-screen true

#MATE 데스크탑 환경에서 로그아웃 기능을 비활성화 한다.
gsettings set org.mate.lockdown disable-log-out true

#MATE 데스크탑 환경에서 사용자 전환(user switching) 기능을 비활성화 한다.
gsettings set org.mate.lockdown disable-user-switching true

VNC 해상도 추가

#xstartup xstartup 파일 편집기 접속
vi ~/.vnc/xstartup

#EX) cvt 1920 1080 60
xrandr --newmode "1920x1080"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
xrandr --addmode VNC-0 "1920x1080"

#EX) cvt 3840 1080 60
xrandr --newmode "3840x1080"  346.00  3840 4088 4496 5152  1080 1083 1093 1120 -hsync +vsync
xrandr --addmode VNC-0 "3840x1080"

VNC 다국어 입력 및 입력 오류처리 방법

  • GTK_IM_MODULE=”ibus” 내보내기
    • GTK_IM_MODULE 환경 변수는 GTK 기반 응용 프로그램에서 사용하는 입력 방법 (input method) 모듈을 지정한다. 여기서 “ibus”는 Intelligent Input Bus의 약자로, 다양한 입력 방법을 관리하는 프레임워크이며, 이 환경 변수를 설정함으로써 MATE 데스크탑 환경에서 GTK 애플리케이션에서 ibus를 사용할 수 있게 된다.
  • XMODIFIERS=”@im=ibus” 내보내기
    • XMODIFIERS 환경 변수는 X Window 시스템에서 입력 방법을 조정하는 데 사용된다.
      여기서 “@im=ibus”는 XMODIFIERS에 ibus 입력 방법을 설정한다는 것을 의미하고 이렇게 설정하면 MATE 데스크탑 환경에서 ibus를 통해 입력한 문자가 올바르게 처리되고 응용 프로그램에 전달된다.
  • QT_IM_MODULE=”ibus” 내보내기
    • QT_IM_MODULE 환경 변수는 QT 기반 응용 프로그램에서 사용하는 입력 방법 모듈을 설정하고, “ibus”를 설정함으로써 MATE 데스크탑 환경에서 QT 애플리케이션에서 ibus를 사용할 수 있게 된다.
#xstartup xstartup 파일 편집기 접속
vi ~/.vnc/xstartup

export GTK_IM_MODULE="ibus"
export XMODIFIERS="@im=ibus"
export QT_IM_MODULE="ibus"

  • ibus-데몬 -xd
    • IBus (Intelligent Input Bus)를 백그라운드에서 실행하는 명령어이다.
  • -엑스
    • IBus를 X Window 시스템과 연결하고, 이 옵션을 사용하면 IBus가 X Window 시스템과 상호작용하고 입력을 처리할 수 있다.
  • -디
    • IBus를 백그라운드에서 실행한다. 이 옵션을 사용하면 IBus가 실행된 후 프롬프트를 반환하여 사용자의 작업을 방해하지 않고 실행된다.
#xstartup xstartup 파일 편집기 접속
vi ~/.vnc/xstartup

ibus-daemon -xd

xstartup 파일 커스텀 완성본

#!/bin/sh
export GTK_IM_MODULE="ibus"
export XMODIFIERS="@im=ibus"
export QT_IM_MODULE="ibus"
ibus-daemon -xd

# cvt 1920 1080 60
xrandr --newmode "1920x1080"  173.00  1920 2048 2248 2576  1080 1083 1088 1120 -hsync +vsync
xrandr --addmode VNC-0 "1920x1080"

# cvt 3840 1080 60
xrandr --newmode "3840x1080"  346.00  3840 4088 4496 5152  1080 1083 1093 1120 -hsync +vsync
xrandr --addmode VNC-0 "3840x1080"

gsettings set org.mate.screensaver lock-enabled false
gsettings set org.mate.screensaver idle-activation-enabled false
gsettings set org.mate.Marco.general compositing-manager false
gsettings set org.mate.background color-shading-type 'solid'
gsettings set org.mate.background picture-filename '/usr/share/backgrounds/cosmos/background-1.xml'
gsettings set org.mate.background picture-options 'zoom'
gsettings set org.mate.background primary-color '#334D60'
gsettings set org.mate.lockdown disable-lock-screen true
gsettigns set org.mate.lockdown disable-log-out true
gsettigns set org.mate.lockdown disable-user-switching true

exec mate-session &
 

VNC 클라이언트 구현

VNC 클라이언트 소프트웨어 선택 기준

VNC 클라이언트를 구현하기 위해서도 다양한 소프트웨어 옵션이 있으며, VNC 클라이언트 소프트웨어를 선택할 때 고려해야 할 주요 기준은 다음과 같다.

 

  • 플랫폼 호환성
    • 선택한 VNC 클라이언트 소프트웨어가 사용할 플랫폼과 호환되는지 확인해야 합니다. 대부분의 VNC 클라이언트는 다양한 운영 체제에서 실행될 수 있다.
  • 기능
    • VNC 클라이언트는 VNC 서버와의 상호작용을 위한 다양한 기능을 제공해야 합니다. 화면 표시, 마우스 및 키보드 입력 전송, 클립보드 공유, 파일 전송 등의 기능을 제공하는지 확인해야 한다.
  • 사용자 경험
    • 사용자 인터페이스의 직관성과 사용 편의성은 VNC 클라이언트의 선택에 중요한 요소이다. 사용자 경험을 고려하여 직관적이고 간결한 인터페이스를 제공하는 소프트웨어를 선택해야 한다.
  • 보안 기능
    • 원격 접속은 보안이 매우 중요한 요소이다. VNC 클라이언트 소프트웨어가 데이터 암호화, 인증 기능 등을 제공하는지 확인해야 한다.

VNC 클라이언트의 사용자 인터페이스 설계

VNC 클라이언트의 사용자 인터페이스는 사용자가 원격 서버와 상호작용할 수 있도록 한다.
사용자 인터페이스를 설계할 때 고려해야 할 사항은 다음과 같다

 

  • 연결 설정
    • 사용자는 원격 접속할 서버의 IP 주소나 호스트 이름, 포트 번호 등을 입력할 수 있어야 한다.
      연결 설정 화면에서 이러한 정보를 입력할 수 있도록 UI를 설계한다.
  • 화면 표시
    • 원격 서버의 화면은 사용자에게 표시되어야 합니다. 사용자 인터페이스는 화면을 표시하는 영역을 제공하고, 받은 화면 데이터를 효율적으로 표시할 수 있도록 설계한다.
  • 입력 전송
    • 사용자는 마우스 클릭, 키보드 입력 등을 원격 서버로 전송할 수 있어야 하며, 인터페이스는 이러한 입력을 받을 수 있는 버튼, 키보드 에뮬레이션 등의 요소를 제공해야 한다.
  • 기타 기능
    • VNC 클라이언트는 클립보드 공유, 파일 전송 등의 추가 기능을 제공할 수 있으며, 사용자 인터페이스는 이러한 기능에 대한 요소를 포함해야 한다.
  • 사용자 경험
    • 사용자 인터페이스는 직관적이고 사용하기 쉬워야 하고 사용자 경험을 고려하여 UI 요소의 배치, 디자인, 피드백 등을 설계해야 한다.