Markdown Preview
Ubuntu 22.04·24.04에서 TigerVNC 설치와 SSH 터널로 안전하게 접속하기
Frontmatter
Ubuntu 22.04·24.04에서 TigerVNC와 Xfce를 설치하고, VNC를 loopback에만 바인딩해 SSH 터널로 안전하게 접속하며 systemd 설정과 문제 해결 방법을 안내한다.
서버에 직접 모니터를 연결하지 않고 그래픽 데스크톱을 사용해야 할 때 VNC를 이용할 수 있다. 다만 VNC 포트를 외부에 그대로 열기보다는 서버의 loopback에만 바인딩하고 SSH 터널을 통해 접속하는 편이 안전하다.
이 글은 DigitalOcean의 원문을 한국어로 옮기고, Ubuntu 패키지의 동작에 맞춰 일부 명령과 주의사항을 보완한 보관용 문서다. 실제 운영 환경에 적용하기 전에 설치된 패키지와 설정을 확인하자.
원문과 라이선스
- 원저자: Mark Drake, Jamon Camisso · 편집: Vinayak Baranwal · 발행: DigitalOcean Community
- 원문에 표시된 라이선스: CC BY-NC-SA 4.0. 이 번역·수정본도 같은 라이선스로 제공한다. 이용 시 저작자 표시, 비상업적 이용, 동일 조건 변경 허락이 필요하다.
- 변경 사항: 한국어 번역과 구조 정리, Wayland 설명 및 Xfce 시작 스크립트·systemd 예시 보완, SSH 터널 안내와 점검 항목 추가. 원문의 댓글과 사이트 메뉴는 포함하지 않았다.
이 글에서 다루는 내용
- TigerVNC, Xfce, VNC display와 SSH 터널의 관계
- Ubuntu 22.04·24.04에서 설치와 VNC 비밀번호 설정
- VNC 세션 수동 실행, loopback 바인딩 확인, systemd 자동 시작
- 검은 화면, 인증 실패, 포트 충돌 등 자주 발생하는 문제의 확인 순서
전제 환경
- Ubuntu Server 22.04 또는 24.04와 sudo 권한이 있는 일반 사용자
- 서버로 SSH 접속 가능, 클라이언트에 VNC Viewer 설치
- 예시 사용자
sammy, 서버 주소your_server_ip, 홈 디렉터리/home/sammy는 환경에 맞게 교체
- 본문 명령은 별도 표시가 없으면 서버의 VNC 사용자로 실행한다. SSH 터널 명령은 로컬 PC에서 실행한다.
- 설정은 Ubuntu 패키지 문서와 원문을 바탕으로 정리했으며, 여기서 두 버전의 실제 서버 실행 테스트는 수행하지 않았다.
VNC는 어떻게 동작할까?
VNC는 서버의 화면을 클라이언트에 전달하고, 클라이언트의 키보드와 마우스 입력을 서버로 보낸다. 이 글의 TigerVNC는 기존 물리 화면을 공유하기보다 별도의 가상 X 데스크톱 세션을 만든다. Viewer 연결을 끊어도 서버 세션이 유지되면 실행 중인 창에 다시 접속할 수 있다.
[로컬 PC] VNC Viewer → localhost:59000
│ SSH 암호화 터널
[서버] └→ localhost:5901 → TigerVNC display :1 → XfceVNC Viewer에서 서버의 가상 Xfce 세션까지 이어지는 접속 경로:
기본적으로 display 번호에 5900을 더한 포트를 사용한다. 예를 들어
:1은 5901, :2는 5902다. 포트를 별도로 지정했다면 달라질 수 있다.SSH X forwarding은 보통 개별 X11 애플리케이션을 전달하고, VNC는 데스크톱 전체 세션을 제공한다. VNC 인증 방식에 따라 암호화 여부가 다르므로, 이 글에서는 SSH 터널을 암호화 경로로 사용하고 VNC는 loopback에만 바인딩한다.
VNC 서버 선택
서버 | 주요 용도 | 특징 |
TigerVNC | 별도의 가상 데스크톱 | Ubuntu 저장소에서 설치 가능. 이 글의 기준 |
TightVNC | 기존 가이드·레거시 구성 | 오래된 예제가 많으므로 유지보수 상태와 호환성 확인 필요 |
x11vnc | 기존 X11 화면 공유 | 별도 가상 세션보다 현재 Xorg 화면을 공유할 때 적합 |
RealVNC | 벤더 관리형 접속 | 별도 설치와 라이선스·기능 조건 확인 필요 |
1. Xfce 데스크톱 설치
서버에서 실행한다. 먼저 패키지 인덱스를 갱신하고 Xfce와 유틸리티를 설치한다.
sudo apt update
sudo apt install xfce4 xfce4-goodiesUbuntu 22.04의 저장소 코드명은
jammy, 24.04는 noble이다. 설치 과정에서 display manager 선택 화면이 나올 수 있다. VNC로 별도 Xfce 세션만 사용할 계획이라면 로컬 로그인 화면의 선택과 VNC 세션은 구분해서 판단한다.GNOME도 별도 선택지지만 Xfce보다 많은 자원을 사용할 수 있고 환경에 따라 세션 설정이 더 복잡하다. 이 글의 기본 경로는 Xfce다.
2. Wayland와 기존 데스크톱 확인
TigerVNC의 가상 Xvnc 세션은 X11 기반이지만, 별도 가상 세션을 만들기 위해 기존 GDM의 Wayland를 무조건 끌 필요는 없다. 서버에 GDM이 없거나 기존 로컬 세션을 건드리지 않는다면 이 단계는 건너뛴다.
반면 기존 GNOME 콘솔을 Xorg로 사용해야 하는 별도 요구가 있다면, 현재 상태와 설정을 확인한 뒤 변경한다.
systemctl is-active gdm3
sudo cp -a /etc/gdm3/custom.conf /etc/gdm3/custom.conf.bak
sudo nano /etc/gdm3/custom.confGDM3가 설치되어 있고 기존 설정을 백업한 경우에만
[daemon] 아래에 다음을 설정한다.[daemon]
WaylandEnable=false적용 시 로컬 로그인 세션에 영향이 있다. 유지보수 시간을 확보하고 콘솔 접근 경로를 확인한 뒤 재부팅한다. 이후 실제 그래픽 콘솔 세션 안에서
echo "$XDG_SESSION_TYPE"으로 x11 여부를 확인한다. SSH 셸의 결과는 해당 콘솔 세션의 상태를 보장하지 않는다.롤백하려면 백업한 설정을 복원하고 재부팅한다.
sudo cp -a /etc/gdm3/custom.conf.bak /etc/gdm3/custom.conf
sudo reboot3. TigerVNC 설치
sudo apt install tigervnc-standalone-server tigervnc-common설치된 실제 패키지 버전과 실행 파일을 확인한다. 업데이트에 따라 버전 문자열은 달라질 수 있다.
apt-cache policy tigervnc-standalone-server tigervnc-common
command -v tigervncserver
man tigervncserver4. VNC 비밀번호와 Xfce 시작 스크립트
4-1. 비밀번호 설정
VNC 세션을 실행할 일반 사용자로 다음 명령을 실행한다.
vncpasswd비밀번호를 두 번 입력하고 읽기 전용 접속이 필요하지 않으면 view-only password 질문에
n을 선택한다. 비밀번호 파일은 일반적으로 ~/.vnc/passwd에 저장된다.전통적인 VNC 비밀번호 인증은 유효 길이가 최대 8자로 제한되고 저장 방식도 강력한 암호화가 아니다. 시스템 비밀번호와 재사용하지 말고, VNC 포트를 외부에 노출하지 않으며 SSH 키 인증 등과 함께 사용한다.
4-2. 시작 스크립트 작성
기존 파일이 있다면 덮어쓰기 전에 백업한다.
:1에 이미 중요한 세션이 있다면 종료하지 말고 다른 display를 선택하자.mkdir -p ~/.vnc
[ ! -e ~/.vnc/xstartup ] || cp -a ~/.vnc/xstartup ~/.vnc/xstartup.bak
nano ~/.vnc/xstartup다음을 작성한다.
#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
[ ! -r "$HOME/.Xresources" ] || xrdb "$HOME/.Xresources"
exec dbus-run-session -- startxfce4실행 권한을 부여하고 확인한다.
chmod +x ~/.vnc/xstartup
ls -l ~/.vnc/xstartup
command -v dbus-run-session원문은
startxfce4 &를 사용하지만, Ubuntu의 TigerVNC는 기본적으로 시작 스크립트가 종료되면 서버를 종료할 수 있다. 여기서는 exec로 세션을 전면 실행하고 아래 실행 명령에서 -xstartup을 명시해 해당 스크립트를 사용한다. 패키지에 따라 기본 시작 파일이 ~/.vnc/Xtigervnc-session일 수 있으므로 이름을 자동으로 찾는다고 가정하지 않는다.GNOME이 꼭 필요하다면 Xorg 기반 GNOME 세션 및 D-Bus 의존성을 별도로 확인해야 한다. 원문은
exec dbus-run-session -- gnome-session을 대안으로 제시하지만 환경별 차이가 크므로 먼저 Xfce 경로를 검증하는 편이 쉽다.5. VNC 서버 수동 실행과 확인
먼저 사용 중인 display를 확인한다. 다른 세션과 충돌하지 않는 번호를 선택한다.
tigervncserver -list
ss -ltn | grep ':5901'아래는 display
:1을 사용하는 예시다. 필요하면 번호와 포트를 함께 바꾼다.tigervncserver :1 -geometry 1920x1080 -depth 24 -localhost yes -xstartup "$HOME/.vnc/xstartup"
tigervncserver -list
ss -ltnp | grep ':5901'127.0.0.1:5901 또는 ::1:5901 같은 loopback 주소만 보여야 한다. 0.0.0.0:5901이나 [::]:5901로 리스닝한다면 외부 인터페이스에도 열려 있을 수 있으므로 설정을 다시 확인한다.시작에 실패했거나 포트가 보이지 않으면 로그를 확인한다.
ls -lt ~/.vnc/*.log
# 해당 display의 실제 로그 파일을 지정한다.
tail -n 100 ~/.vnc/<호스트명>:<포트또는display>.log로그 파일명은 패키지 버전과 호스트명에 따라 다를 수 있다. 위의
<...>는 그대로 입력하는 문자가 아니라 실제 파일명으로 교체할 자리다.6. systemd 서비스로 자동 시작
수동 테스트가 끝나면 해당 VNC 사용자의
:1 세션만 종료하고 systemd에 넘긴다. 세션 안의 프로그램도 종료되므로 먼저 작업을 저장한다.tigervncserver -kill :1기존 unit이 있는지 확인하고, 있다면 덮어쓰기 전에 백업한다.
sudo systemctl cat vncserver@.service
# 파일이 존재하면 백업
sudo cp -a /etc/systemd/system/vncserver@.service /etc/systemd/system/vncserver@.service.bak기존 파일이 없다면
cat 또는 cp가 실패할 수 있으며, 이 경우 새 unit을 만든다.sudo nano /etc/systemd/system/vncserver@.service다음 예시의
sammy와 홈 디렉터리를 실제 VNC 사용자에 맞게 모두 변경한다. 사용자와 그룹 이름이 다르면 Group도 실제 기본 그룹으로 수정한다. id sammy로 확인할 수 있다.[Unit]
Description=TigerVNC for display %i
After=network.target
[Service]
Type=simple
User=sammy
Group=sammy
WorkingDirectory=/home/sammy
ExecStart=/usr/bin/tigervncserver :%i -fg -geometry 1920x1080 -depth 24 -localhost yes -xstartup /home/sammy/.vnc/xstartup
[Install]
WantedBy=multi-user.target원문의
Type=forking과 PID 파일 대신 Ubuntu TigerVNC의 -fg를 사용하는 예시다. display를 자동으로 강제 종료하지 않으므로 충돌이 나면 이미 실행 중인 세션을 먼저 확인한다. 설치 환경의 바이너리 경로는 command -v tigervncserver로 검증한다.sudo systemctl daemon-reload
sudo systemctl enable --now vncserver@1.service
sudo systemctl status vncserver@1.service --no-pager
ss -ltnp | grep ':5901'@1의 숫자는 사용자명이 아니라 display 번호다. 시작이 실패하면 sudo journalctl -u vncserver@1.service -n 100 --no-pager와 VNC 로그를 함께 확인한다.서비스를 중지하고 자동 시작을 해제하려면 다음을 실행한다. 기존 unit을 수정한 경우 백업 파일을 복원한 뒤
daemon-reload한다.sudo systemctl disable --now vncserver@1.service7. SSH 터널로 안전하게 접속
서버의
5901을 UFW나 클라우드 방화벽에서 외부에 열지 않는다. SSH 접근 경로는 기존 정책에 맞게 유지한다.로컬 PC에서 실행한다. 예시의 사용자와 주소를 교체한다.
ssh -L 127.0.0.1:59000:localhost:5901 -N -o ExitOnForwardFailure=yes sammy@your_server_ip127.0.0.1:59000: 로컬 PC에서만 접근할 터널 입구
localhost:5901: SSH 서버 측에서 접근할 VNC 포트
-N: 원격 셸을 실행하지 않고 포워딩만 유지
ExitOnForwardFailure=yes: 로컬 포트 바인딩에 실패하면 오류로 종료
처음 접속할 때 SSH가 호스트 키 확인을 요청할 수 있다. 신뢰할 수 있는 경로로 서버의 fingerprint를 확인한 후 수락한다. 터널이 실행 중인 상태에서 VNC Viewer로 **
localhost:59000**에 접속하고 4단계에서 설정한 VNC 비밀번호를 입력한다. Viewer마다 포트 입력 표기법이 다를 수 있으므로 해당 클라이언트의 안내를 확인한다.Windows의 OpenSSH도 PowerShell에서 같은 방식으로 사용할 수 있다. PuTTY에서는 SSH → Tunnels에서 Source port
59000, Destination localhost:5901을 설정한 뒤 연결한다.원문은
-C 압축과 -f 백그라운드 실행을 사용한다. 압축은 네트워크와 데이터에 따라 효과가 다를 수 있다. 위 예시는 관리하기 쉽게 전면에서 실행하며, 터널을 종료할 때 해당 터미널에서 Ctrl+C를 누른다. 터널이나 Viewer를 닫는 것만으로 서버의 데스크톱 세션이 종료되지는 않는다.문제 해결: 어디부터 확인할까?
우선 서비스 상태 → VNC 로그 → 리스닝 주소 → SSH 터널 → Viewer 설정 순서로 확인한다. 방화벽부터 변경하기보다 서버 프로세스가 정상적으로 떠 있는지 먼저 보는 편이 안전하다.
아래 점검 도구에서 각 단계를 선택하면 확인 위치와 예시 명령을 볼 수 있다. HTML이 표시되지 않아도 바로 아래 명령과 설명을 따라가면 된다.
# 서버
sudo systemctl status vncserver@1.service --no-pager
sudo journalctl -u vncserver@1.service -n 100 --no-pager
tigervncserver -list
ss -ltnp | grep ':5901'
ls -lt ~/.vnc/*.log서버가 시작되지 않음
:1또는5901을 다른 프로세스가 쓰는지 확인한다. 중요한 세션을 강제 종료하지 말고 다른 display를 선택할 수 있다.
- unit의
User,Group, 홈 경로,tigervncserver경로와-xstartup경로가 실제 환경과 맞는지 확인한다.
- VNC 비밀번호와 시작 스크립트가 서비스 사용자 계정에 만들어졌는지 확인한다.
검은 화면 또는 시작 직후 종료
~/.vnc/xstartup의 실행 권한과exec dbus-run-session -- startxfce4를 확인한다.
- VNC 로그에서 세션 스크립트가 너무 빨리 종료되는지, Xfce 또는 D-Bus 관련 오류가 있는지 확인한다.
- 댓글에서는 Ubuntu 24.04에서
dbus-x11설치가 필요했던 사례가 있지만 모든 환경에 필수라는 뜻은 아니다. 로그와 설치 상태를 먼저 확인한 뒤 필요한 경우 설치한다.
dpkg -l dbus-x11
# 관련 오류가 있고 패키지가 필요한 경우
sudo apt install dbus-x11
sudo systemctl restart vncserver@1.service인증 실패
서비스를 실행하는 사용자로
vncpasswd를 다시 설정하고 접속한다. 서비스 재시작이 필요할 때는 실행 중인 데스크톱과 프로그램이 종료될 수 있으므로 먼저 저장한다. SSH 계정 비밀번호와 VNC 비밀번호는 별개다.연결 거부 또는 시간 초과
- 서버에서
5901이 loopback에 떠 있는지 확인한다.
- 로컬에서 SSH 터널이 살아 있는지,
59000이 다른 프로그램에 사용 중이지 않은지 확인한다.
- Viewer는 서버 공인 IP의
5901이 아니라 **로컬localhost:59000**에 연결한다.
- 원격 SSH 서버의 포트 포워딩 정책과 SSH 접속 자체도 확인한다.
기존 GNOME 화면이 기대와 다름
이 구성은 기존 콘솔을 복제하지 않고 별도의 가상 세션을 만든다. 기존 Xorg 화면을 공유하려는 요구라면 x11vnc 등 다른 방식을 검토한다. Wayland 오류가 의심되더라도 먼저 실제로 문제가 생긴 세션이 로컬 콘솔인지 VNC 가상 세션인지 구분한다.
자주 묻는 질문
Ubuntu 24.04에서도 같은 방법을 사용할 수 있나?
TigerVNC 패키지를 설치하고 Xfce와 SSH 터널을 구성하는 흐름은 같다. 다만 패키지 버전과 기본 파일 경로는 설치된 환경에서 확인해야 한다.
세션이 실행 중인지 어떻게 확인하나?
tigervncserver -list, ss -ltnp, systemctl status vncserver@1.service를 함께 본다. systemd를 사용하지 않는 수동 세션은 해당 서비스 상태에 표시되지 않을 수 있다.세션은 어떻게 종료하나?
systemd가 관리하면
sudo systemctl stop vncserver@1.service, 수동 실행 세션이면 실행한 사용자로 tigervncserver -kill :1을 사용한다. 종료 시 세션 안의 작업이 사라질 수 있다.Viewer가 암호화되지 않았다고 경고한다면?
Viewer와 로컬 터널 입구 사이의 VNC 구간을 기준으로 경고할 수 있다. 실제 SSH 터널에 연결되어 있고 서버의 VNC가 loopback에만 바인딩된 경우 SSH 구간은 암호화된다. 경고만으로 전체 경로의 안전성을 단정하지 말고 접속 대상과 리스닝 주소를 확인한다.
핵심 정리와 체크리스트
VNC 전용 일반 사용자로 비밀번호와 시작 스크립트를 만들었다.
사용 중인 display와 포트가 충돌하지 않는다.
ss에서 VNC가 loopback에만 리스닝한다.서비스 사용자, 홈 디렉터리와 스크립트 경로를 확인했다.
Viewer가 공인 IP가 아닌 SSH 터널의 로컬 포트에 연결한다.
systemd 재시작 전 세션 내 작업을 저장했다.
기존 GNOME·Wayland 설정은 실제 필요가 있을 때만 변경했다.