Secure VNC configuration for RHEL7
Hello
I want to deploy a secure vnc configuration on my RHEL7 servers.
We use Windows clients with Putty and VNC Viewer from RealVNC Ltd.
I don't really like the standard configuration for tigervnc as it is documented here:
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/ch-TigerVNC.html
Shortcomings:
- VNC password is not encrypted (but it's not plain text)
- No system authentication (session is started upon service start)
eg. start service for given user, lock account of user, connect with vnc client, guess what happens.
- Configuration is not user independent, one config for each user.
- Transport not encrypted (at least with Windows vnc viewer from realvnc)
- Logout does not work (at least on my test server)
Goals:
- User authentication upon connection
- Encrypted traffic using ssh port forwarding
- User independent configuration
In RHEL6, I used a configuration based on xinetd.
Now that I'm starting to use RHEL7 it's time to get familiar with systemd.
This is what I got so far:
Create systemd service:
The configuration uses a systermd socket instead of inetd, as described here:
http://0pointer.de/blog/projects/inetd.html
/etc/systemd/system/vncserver-gdm-local.socket
[Unit]
Description=vncserver socket with gdm listening on localhost
[Socket]
ListenStream=127.0.0.1:5900
Accept=yes
[Install]
WantedBy=sockets.target
Second is the service definition.
Because I did not find how to bind the xdmcp and X service only to localhost I made a dependency to firewalld
If firewlld is stopped it will be started - if firewalld is stopped, vncserver will be killed.
Uncomment one of the ExecStart lines, depending if you want a pre-authentication with vnc (-securitytypes=VncAuth -rfbauth=/etc/vncpasswd) or not.
/etc/systemd/system/vncserver-gdm-local@.service
[Unit]
Description=vncserver with gdm and firewalld dependency
Requires=firewalld.service
Requires=gdm.service
[Service]
#ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1024x768 -depth 16 -once -securitytypes=VncAuth -rfbauth=/etc/vncpasswd
#ExecStart=-/usr/bin/Xvnc -inetd -query localhost -geometry 1024x768 -depth 16 -once -securitytypes=none
User=nobody
Group=tty
StandardInput=socket
For pre-authentication create the password file
# vncpasswd /etc/vncpasswd
# chown nobody /etc/vncpasswd
Make gdm ready for network connection.
/etc/gdm/custom.conf
[xdmcp]
Enable=true
[security]
DisallowTCP=false
Start service
# systemctl daemon-reload
# systemctl restart gdm.service
# systemctl enable vncserver-gdm-local.socket
# systemctl start vncserver-gdm-local.socket
Connect with vnc viewer.
On Windows, I use a wrapper scrip to connect, see below.
Check:
# systemctl status vncserver-gdm-local.socket
vncserver-gdm-local.socket - vncserver socket with gdm listening on localhost
Loaded: loaded (/etc/systemd/system/vncserver-gdm-local.socket; enabled)
Active: active (listening) since Wed 2015-05-13 14:52:40 CEST; 5min ago
Listen: 127.0.0.1:5900 (Stream)
Accepted: 3; Connected: 1
May 13 14:52:40 example.com systemd[1]: Listening on vncserver socket with gdm listening on localhost.
Things that do not work:
- Screen resolution, same as:
https://access.redhat.com/discussions/1261403
- Copy/paste in gdm:
I want to use vncconfig to enable copy/paste for the login screen, but I had no luck with the gdm configuration.
Open points:
- Is it really secure?
- Is there another way to run gdm in vncserver (without using xdmcp)?
- Is there a way to configure gdm and Xvnc to listen only on localhost?
Regards
Kolja
Windows wrapper:
@echo off
mode con: cols=40 lines=10
set server=%1
if "%server%" == "" (
set /p server= "Enter Servername: "
)
set remote_user=adm_%username%
set port=5901
goto :check_portfree
:inc
set /a port=(%port% + 1)
:check_portfree
netstat -tnoa|findstr "127.0.0.1:%port%"|findstr LISTEN
if ERRORLEVEL 1 (
echo port %port% free
goto :run_wrapper
) else (
echo port %port% used
goto :inc
)
goto :eof
:run_wrapper
set prog=start /MIN "vnc tunnel: %server%@%port%" "C:\Program Files\PuTTY\plink" -4 -L %port%:127.0.0.1:5900 %remote_user%@%server% -N
%prog%
rem wait until port is used
:check_portused
netstat -tnoa|findstr "127.0.0.1:%port%"|findstr LISTEN
if ERRORLEVEL 1 (
echo Waiting for plink
ping -n 2 localhost > nul
goto :check_portused
)
for /F "tokens=5" %%c in ('netstat -tnoa^|findstr "127.0.0.1:%port%"^|findstr LISTEN') do set plink_pid=%%c
"C:\Program Files\RealVNC\VNC Viewer\vncviewer.exe" -SecurityNotificationTimeout=0 WarnUnencrypted=0 127.0.0.1:%port%
taskkill /PID %plink_pid%
Responses
Hello
>Shortcomings:
- VNC password is not encrypted (but it's not plain text)
A shortcoming of VNC rather than the description I think. and hence the section on using SSH.
- No system authentication (session is started upon service start)
eg. start service for given user, lock account of user, connect with vnc client, guess what happens.
I will mention this point to the software maintainers.
- Configuration is not user independent, one config for each user.
I'll mention this, but I think this is a systemd issue rather than a VNC issue.
- Transport not encrypted (at least with Windows vnc viewer from realvnc)
Hence the section on using SSH. Is there no SSH for Windows?
- Logout does not work (at least on my test server)
I did not notice this when I tested the procedures. Is there something I should add?
Goals:
- User authentication upon connection
- Encrypted traffic using ssh port forwarding
Would using SSH cover the above two goals?
- User independent configuration
I will mention this, see response above.
Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.
