La mejor manera de dar soporte a un usuario remoto es a través de VNC, podrÃamos optar por soluciones como teamviewer pero estarÃamos confiando completamente en que la gente de teamviewer no nos esté robando datos o registrando sesiones, ya sabéis que la paranoia nunca está de mas.
Este manual se divide en varias partes:
VNC Cliente
Instalamos el servidor VNC:
Desde la sesión del usuario que recibirá soporte remoto generamos un password de acceso:
Cada vez que el usuario necesite soporte deberá ejecutar el siguiente comando, de este modo arrancará el servidor de VNC para que accedan de forma remota:
NOTA: La opción loop hará que el servidor VNC se reinicie en caso de desconexión por parte del cliente, si no ponemos esta opción y el cliente se desconecta, el equipo quedará inaccesible hasta que el usuario vuelva a ejecutar el comando.
Por otro lado el técnico tendrá que acceder mediante un cliente VNC:
La conexión se realizará indicando los siguientes parámetros:
vncviewer IP:5900
VNC Jail
Si se trata de un servidor headless al que queremos acceder vÃa VNC debemos arrancar primero un servidor Xorg falso que será mostrado por VNC y donde arrancaremos nuestro WM.
Instalamos todo lo necesario:
Arrancamos dbus:
service dbus start
Añadimos el usuario al grupo video:
Generamos desde el usuario un password de acceso:
x11vnc -storepasswd
Desde el usuario kr0m arrancamos el servidor gráfico falso:
Le indicamos al servidor VNC que muestre vÃa red el display :0
Arrancamos el WM en el display :0
Ya podemos acceder al servidor VNC:
En ambos casos ya sea la conexión al cliente o a la jail con xvfb veremos que nos pide password y una vez autenticados accederemos al sistema:
 
  
  
  
 
  
  
  
VNC SSL
El servidor VNC soporta SSL de forma nativa pero en muchos casos da problemas de compatibilidad por algoritmos de cifrado incompatibles entre el cliente y el servidor, para evitar este tipo de problemas utilizaremos noVNC , de este modo tan solo nos preocuparemos de que la conexión del navegador al servidor noVNC vaya cifrada con un certificado SSL y del servidor noVNC en claro hasta el servidor final, además el acceso será mas universal ya que se hará a través de un navegador con HTML5 sin necesidad de un cliente VNC.
A fecha de 28/05/2022 si habilitamos el SSL está dando este problema:
28/05/2022 21:03:15 SSL: error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher
Debido a este bug .
Los pasos son iguales que en el anterior escenario pero además arrancaremos en servidor noVNC.
Arrancamos el servidor gráfico:
Arrancamos el servidor VNC:
Arrancamos el WM:
Instalamos git y noVNC:
El servidor noVNC precisa de numpy:
Asignamos los permisos necesarios
Consultamos los parámetros permitidos por el servidor:
./utils/novnc_proxy -h
Usage: novnc_proxy [--listen PORT] [--vnc VNC_HOST:PORT] [--cert CERT] [--ssl-only]
Starts the WebSockets proxy and a mini-webserver and 
provides a cut-and-paste URL to go to.
    --listen PORT         Port for proxy/webserver to listen on
                          Default: 6080
    --vnc VNC_HOST:PORT   VNC server host:port proxy target
                          Default: localhost:5900
    --cert CERT           Path to combined cert/key file, or just
                          the cert file if used with --key
                          Default: self.pem
    --key KEY             Path to key file, when not combined with cert
    --web WEB             Path to web files (e.g. vnc.html)
                          Default: ./
    --ssl-only            Disable non-https connections.
                                    
    --record FILE         Record traffic to FILE.session.js
                                    
    --syslog SERVER       Can be local socket such as /dev/log, or a UDP host:port pair.
                                    
    --heartbeat SEC       send a ping to the client every SEC seconds
    --timeout SEC         after SEC seconds exit when not connected
    --idle-timeout SEC    server exits after SEC seconds if there are no
                          active connections
Probemos primero el acceso sin SSL, en el siguiente comando estamos enlazando el puerto 5900 con el servidor VNC arrancado en la jail 192.168.69.56:5901
Nos dará una URL como esta:
http://test.alfaexploit.com:5900/vnc.html?host=test.alfaexploit.com&port=5900
Si accedemos a esta veremos una ventana de autenticación que corresponde con el password asignado al servidor VNC:
 
  
  
  
 
  
  
  
 
  
  
  
Siguiente paso configurar el certificado SSL ya que hay un login y el password podrÃa ser interceptado.
Emitimos la solicitud de certificado mediante 
    
        acme.sh
    
:
curl https://get.acme.sh | sh -s email=kr0m@alfaexploit.com
acme.sh --issue --standalone -d test.alfaexploit.com
[Sat May 28 18:56:17 CEST 2022] Your cert is in: /root/.acme.sh/test.alfaexploit.com/test.alfaexploit.com.cer
[Sat May 28 18:56:17 CEST 2022] Your cert key is in: /root/.acme.sh/test.alfaexploit.com/test.alfaexploit.com.key
[Sat May 28 18:56:17 CEST 2022] The intermediate CA cert is in: /root/.acme.sh/test.alfaexploit.com/ca.cer
[Sat May 28 18:56:17 CEST 2022] And the full chain certs is there: /root/.acme.sh/test.alfaexploit.com/fullchain.cer
Arrancamos el servidor noVNC con los parámetros SSL:
./utils/novnc_proxy --vnc 192.168.69.56:5901 --cert /root/.acme.sh/test.alfaexploit.com/fullchain.cer --key /root/.acme.sh/test.alfaexploit.com/test.alfaexploit.com.key --listen 5900 --ssl-only
Nos dará una URL como esta:
https://test.alfaexploit.com:5900/vnc.html?host=test.alfaexploit.com&port=5900
El contenido de la web será el mismo pero esta vez el tráfico irá cifrado:
 
  
  
  
VNC SSL Daemon
Para que todo esto arranque de forma automática vamos a crear un script RC:
#! /bin/sh
#
# $FreeBSD$
#
# PROVIDE: vnc
# REQUIRE: DAEMON
# KEYWORD: shutdown 
. /etc/rc.subr
name="vnc"
extra_commands="status"
username="kr0m"
start_cmd="${name}_start"
stop_cmd="${name}_stop"
status_cmd="${name}_status"
vnc_start(){
    PID=$(ps -U ${username}|grep Xvfb|grep -v grep|awk '{print$1}')
    if [ -z $PID ]; then
        echo "Starting service: Xvfb"
        /bin/rm /tmp/.X*-lock 2>/dev/null
        /usr/bin/su -l ${username} -c '/usr/bin/nohup /usr/local/bin/Xvfb :0 > /dev/null 2>&1 &' 1>/dev/null
    else
        echo "Service: Xvfb already started"
    fi
    PID=$(ps -U ${username}|grep x11vnc|grep -v grep|awk '{print$1}')
    if [ -z $PID ]; then
        echo "Starting service: X11vnc"
        /usr/bin/su -l ${username} -c '/usr/bin/nohup /usr/local/bin/x11vnc -usepw -rfbport 5901 -display :0 -noshm -forever -shared > /dev/null 2>&1 &' 1>/dev/null
    else
        echo "Service: x11vnc already started"
    fi
    PID=$(ps -U ${username}|grep xfce4-session|grep -v grep|awk '{print$1}'|sort|head -n 1)
    if [ -z $PID ]; then
        echo "Starting service: XFCE"
        /usr/bin/su -l ${username} -c 'export DISPLAY=:0 && /usr/bin/nohup /usr/local/bin/startxfce4 > /dev/null 2>&1 &' 1>/dev/null
    else
        echo "Service: x11vnc already started"
    fi
    # WEBSOCKIFY launches more than one thread in that way we have to check the number of running threads
    WEBSOCKIFY_N=$(ps -U root|grep websockify|grep -v grep|wc -l|awk '{print$1}')
    if [ $WEBSOCKIFY_N -eq 0 ]; then
        echo "Starting service: Websockify"
        PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin
        /usr/bin/nohup /usr/local/bin/bash /usr/local/libexec/novnc/utils/novnc_proxy --vnc 192.168.69.56:5901 --cert /root/.acme.sh/test.alfaexploit.com/fullchain.cer --key /root/.acme.sh/test.alfaexploit.com/test.alfaexploit.com.key --listen 5900 --ssl-only > /dev/null 2>&1 & 1>/dev/null
    else
        echo "Service: Websockify already started"
    fi
    
    /bin/rm /home/${username}/nohup.out 2>/dev/null
    /bin/rm /root/nohup.out 2>/dev/null
}
vnc_stop(){
    PID=$(ps -U ${username}|grep Xvfb|grep -v grep|awk '{print$1}')
    if [ -z $PID ]; then
        echo "It appears Xvfb is not running."
    else
        echo "Stopping service: Xvfb/X11vnc/XFCE"
        kill -s INT $PID
        sleep 3
    fi
    # WEBSOCKIFY launches more than one thread in that way we have to check the number of running threads
    WEBSOCKIFY_N=$(ps -U root|grep websockify|grep -v grep|wc -l|awk '{print$1}')
    if [ $WEBSOCKIFY_N -eq 0 ]; then
        echo "It appears Websockify is not running."
    else
        echo "Stopping service: Websockify"
        for PID in $(ps -U root|grep websockify|grep -v grep|awk '{print$1}'); do
                kill -s INT $PID
        done
        sleep 3
    fi
}
vnc_status(){
    PID=$(ps -U ${username}|grep Xvfb|grep -v grep|awk '{print$1}')
    if [ -z $PID ]; then
        echo "Xvfb is not running."
    else
        echo "Xvfb running with PID: $PID"
    fi
    PID=$(ps -U ${username}|grep x11vnc|grep -v grep|awk '{print$1}')
    if [ -z $PID ]; then
        echo "x11vnc is not running."
    else
        echo "X11vnc running with PID: $PID"
    fi
    PID=$(ps -U ${username}|grep xfce4-session|grep -v grep|awk '{print$1}'|sort|head -n 1)
    if [ -z $PID ]; then
        echo "XFCE is not running."
    else
        echo "XFCE running with PID: $PID"
    fi
    # WEBSOCKIFY launches more than one thread in that way we have to check the number of running threads
    WEBSOCKIFY_N=$(ps -U root|grep websockify|grep -v grep|wc -l|awk '{print$1}')
    if [ $WEBSOCKIFY_N -eq 0 ]; then
        echo "Websockify is not running."
    else
        echo "Websockify running with PIDS:"
        for PID in $(ps -U root|grep websockify|grep -v grep|awk '{print$1}'); do
                echo "PID: $PID"
        done
        sleep 3
    fi
}
load_rc_config ${name}
run_rc_command "$1"
Asignamos los permisos necesarios:
chown root:wheel /usr/local/etc/rc.d/vnc
Habilitamos y arrancamos el servicio:
service vnc start
Con este script todos los procesos arrancarán de forma automática en cada reinicio.