> For the complete documentation index, see [llms.txt](https://doc.velneo.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.velneo.com/38/aplicacion-vlanzadera-y-login-social/configuracion-de-vlanzadera-en-servidores-propietarios-windows.md).

# Configuración de vLanzadera en servidores propietarios Windows

A continuación indicamos los pasos para publicar vLanzadera en un servidor propietario Windows, sirviéndola **desde el propio Velneo vServer**. Toda la configuración se hace desde Velneo vAdmin y el registro de Windows.

A lo largo de la guía, **mi-dominio** es tu dominio.

Hace falta tener activada la **licencia de servicio HTTP**: sin ella el servidor responde con un error de acceso denegado al pedir la lanzadera.

{% hint style="info" %}
La lanzadera también puede servirse con Velneo vModApache, que es como se montaba antes de la versión 38. Funciona y tiene soporte, pero necesita Apache instalado y configurado a mano: si aun así es lo que prefieres, está en el [anexo A](#anexo-a-publicarla-con-velneo-vmodapache).
{% endhint %}

## Resumen, si ya lo has hecho antes

Los datos que hay que acertar, para no releer la guía entera. Si es tu primera vez, sáltate esta sección y empieza por el paso 1.

Cada bloque acaba en lo que tiene que funcionar antes de pasar al siguiente. Si eso no funciona, el problema está en ese bloque.

### El certificado — paso 2

* `C:\Windows\System32\config\systemprofile\Velneo\ssl\`: tu certificado y tu clave. El `.crt` con la cadena completa y en base64.
* Registro, `HKEY_USERS\.DEFAULT\Software\Velneo\vServer`: `CertificateKey` y `PrivateKey` (`REG_SZ`) con la ruta de cada uno.

**Comprobar:** en Velneo vAdmin aparece `Cifrado de VATPS activado, certificado ssl: [...]`.

### La lanzadera — paso 3

* Registro, misma clave: `jwtKey` (`REG_SZ`), 32 caracteres como mínimo.

### El virtual host y la ruta — paso 4

* vAdmin › **Web**, virtual host **Principal**: activo, tu dominio, **SSL marcado** y un puerto libre —el `443` si no hay otro servidor web en la máquina—.
* Pestaña **Rutas**: ruta `/auth`, tipo **App**, la instancia de la lanzadera y el usuario con el que se ejecuta.
* Reiniciar el servidor HTTP.

**Comprobar:** **<https://mi-dominio/auth>** carga la lanzadera, y desde ella arranca una aplicación.

### El cortafuegos — paso 5

* Abrir el puerto del virtual host, el de vatp y el de websockets.

Si alguna comprobación falla, la tabla de síntomas del final dice dónde mirar.

## Paso 1 - Instalar Velneo vServer

Sigue la documentación para instalar Velneo vServer en Windows.

En los mensajes de arranque de Velneo vAdmin, apunta los dos puertos que hacen falta en el paso 5:

* El **puerto vatp**, del mensaje `Servidor vatp de 64 bits iniciado con licencia [...] Puerto: 690 [...]`.
* El **puerto de websockets**, del mensaje `Servidor websockets iniciado en puerto xxx`.

## Paso 2 - Copiar el certificado para Velneo vServer

Con este certificado Velneo vServer cifra las dos cosas: las conexiones VATPS de las aplicaciones y la propia lanzadera.

1. Copia tu certificado y tu clave a `<directorio del usuario que ejecuta el servicio>\Velneo\ssl\`. Con la cuenta del sistema, que es lo habitual, es `C:\Windows\System32\config\systemprofile\Velneo\ssl\`.
2. En el registro, en `HKEY_USERS\.DEFAULT\Software\Velneo\vServer`, añade dos **valores de cadena**:

| Nombre           | Tipo     | Datos                                                            |
| ---------------- | -------- | ---------------------------------------------------------------- |
| `CertificateKey` | `REG_SZ` | `C:/Windows/System32/config/systemprofile/Velneo/ssl/server.crt` |
| `PrivateKey`     | `REG_SZ` | `C:/Windows/System32/config/systemprofile/Velneo/ssl/server.key` |

3. Reinicia Velneo vServer.

**Comprobar:** en Velneo vAdmin aparece `Cifrado de VATPS activado, certificado ssl: [...]`. Si aparece `Se usará el certificado por defecto`, no ha podido cargarlo.

{% hint style="warning" %}
Usa un certificado de una autoridad reconocida. Para un **entorno de pruebas**, en el anexo B hay una alternativa.
{% endhint %}

* El `.crt` tiene que estar en base64 y llevar la **cadena completa**: tu certificado, los intermedios y la raíz. Con Let's Encrypt es `fullchain.pem`, no `cert.pem`.
* Reconocerás la clave del registro porque ya tiene valores del servidor, como `Licencia` o `PasswordsDays`. Si el servicio usa otra cuenta, la clave estará bajo el identificador de ese usuario.
* **Al renovar el certificado** hay que volver a copiarlo aquí y reiniciar el servidor. Con Let's Encrypt toca cada pocas semanas, y si esta copia caduca las aplicaciones dejan de funcionar aunque el navegador siga viendo bien el sitio.

## Paso 3 - Instalar la vLanzadera y su clave JWT

1. Sigue la sección de instalación de vLanzadera.
2. En el registro, en la misma clave del paso 2, añade la clave JWT:

| Nombre   | Tipo     | Datos                                      |
| -------- | -------- | ------------------------------------------ |
| `jwtKey` | `REG_SZ` | Tu clave, de **32 caracteres como mínimo** |

3. Reinicia Velneo vServer.

Opcionalmente puedes limitar la validez del token con `jwtExpiredSeconds` (`REG_DWORD`, en segundos). El servidor acepta el token durante ese tiempo más 60 segundos de cortesía, por si hay desviación de hora entre cliente y servidor. Por defecto, 60 segundos.

{% hint style="danger" %}
La clave JWT solo debe conocerla el administrador.
{% endhint %}

## Paso 4 - Publicar la lanzadera

En Velneo vAdmin, sección **Web** del menú lateral.

### 4.1 Configurar el virtual host

Haz doble clic sobre el virtual host marcado como **Principal** —o créalo con el botón de añadir— y configúralo así:

* **Activo**: marcado
* **Puerto de escucha**: el puerto por el que publicar la lanzadera, por ejemplo `443`
* **Dominio de escucha**: tu dominio
* **SSL**: **marcado**
* **Máximas conexiones concurrentes**: el valor por defecto

{% hint style="danger" %}
**SSL va marcado.** Es el propio servidor el que cifra, con el certificado del paso 2, y sin cifrado las aplicaciones WebAssembly no funcionan: los navegadores solo habilitan lo que necesitan en un contexto seguro.
{% endhint %}

* Elige un **puerto libre**: si hay un Apache u otro servidor web escuchando en el mismo, uno de los dos no podrá abrirlo y el fallo no siempre queda claro en los mensajes del servidor.
* Si pones un proxy delante y **termina el TLS**, esta conexión puede ir en claro y SSL va sin marcar; las condiciones están en antes de exponerlo a internet.

### 4.2 Publicar la lanzadera en una ruta

En el mismo diálogo, pestaña **Rutas**, añade una:

| Campo         | Valor                            | Ejemplo          |
| ------------- | -------------------------------- | ---------------- |
| **Ruta**      | `/auth`                          | `/auth`          |
| **Instancia** | La instancia de la vLanzadera    | `VLANZADERA_APP` |
| **Usuario**   | El usuario con el que se ejecuta | `velneo`         |
| **Tipo**      | App                              | App              |

Acepta y **reinicia el servidor HTTP** desde la barra de herramientas de la sección **Web**.

**Comprobar:** **<https://mi-dominio/auth>** carga la lanzadera. Esa es la dirección que hay que repartir a los usuarios.

{% hint style="danger" %}
**La ruta tiene que ser `/auth`.** La página de la lanzadera pide el token de acceso a `/auth/get_tok`, con la ruta escrita tal cual, así que en cualquier otra la lanzadera carga y se ve bien, pero al pulsar una aplicación falla con un error de comunicación. Los favoritos, igual.
{% endhint %}

* En el mismo virtual host puedes publicar otras aplicaciones añadiendo más rutas, esas sí con el nombre que quieras.
* **La raíz del dominio no sirve la lanzadera**: se entra por `/auth`. Si la necesitas en la raíz, hace falta algo delante que reescriba la petición, como el Apache del anexo A.
* Los cambios no se aplican hasta reiniciar el servidor HTTP.

## Paso 5 - Abrir los puertos

Con el cortafuegos de Windows activo, abre en la máquina del servidor:

* El **puerto del virtual host** del paso 4.1.
* El **puerto vatp** y el **de websockets** que apuntaste en el paso 1.

## Comprobación final

1. **<https://mi-dominio/auth>** carga la lanzadera.
2. Entras con un usuario y una aplicación arranca en el navegador.

No hay que configurar nada para las aplicaciones de escritorio web: vienen con la instalación de Velneo vServer y las sirve él mismo. Si importas un paquete desde los parámetros de la lanzadera, se sirve por la misma vía.

**Si algo falla:**

| Síntoma                                                                                             | Dónde mirar                                                                                                                         |
| --------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Error de acceso denegado al pedir la lanzadera                                                      | La licencia de servicio HTTP                                                                                                        |
| **404** al pedir `/auth`                                                                            | La ruta del paso 4.2, o el servidor HTTP sin reiniciar después de crearla                                                           |
| **404** en la raíz del dominio                                                                      | Es lo normal en este modo: se entra por `/auth`                                                                                     |
| Carga, pero las aplicaciones no arrancan                                                            | Que entras por `https`: sin contexto seguro no arrancan, y eso exige **SSL marcado** en el virtual host (paso 4.1)                  |
| Entras, pero la aplicación se queda sin abrir y la consola del navegador da un error de `WebSocket` | El puerto de websockets (paso 5): cerrado en el cortafuegos, o con un proxy delante que no lo reenvía ni lo declara en «Puerto WSS» |
| Ninguna aplicación abre, y en el arranque no aparece `Servidor websockets iniciado en puerto`       | La licencia de ejecución web: sin ella Velneo vServer no levanta ese servicio, así que no hay ningún puerto al que conectarse       |
| La lanzadera carga pero no deja entrar                                                              | La clave JWT, en el registro (paso 3)                                                                                               |
| El servidor HTTP no levanta el puerto                                                               | Otro servidor web escuchando en el mismo puerto (paso 4.1). Compruébalo con `netstat -ano` filtrando por el puerto                  |
| Las aplicaciones dejan de funcionar de golpe, semanas después                                       | El certificado, caducado tras una renovación (paso 2)                                                                               |

## Antes de exponerlo a internet

Con lo anterior la lanzadera funciona y se puede probar. Para publicarla hacia fuera **recomendamos poner un proxy delante** del servidor HTTP: le faltan funcionalidades de seguridad que un proxy sí aporta. Vale cualquiera —Apache, Nginx u otro—, y su configuración es parte del despliegue de cada uno.

Lo que el proxy tiene que hacer:

* **Reenviar el virtual host completo** al puerto del servidor HTTP, no rutas concretas: por esa misma vía van la lanzadera, las aplicaciones de escritorio web y cualquier otra ruta que publiques.
* **Dejar pasar el tráfico tal cual**, sin añadir ni reescribir cabeceras. Las emiten ya la propia lanzadera en su página —incluidas `Cross-Origin-Embedder-Policy` y `Cross-Origin-Opener-Policy`— y el servidor HTTP en las aplicaciones. Duplicadas, el navegador las descarta y las aplicaciones no arrancan.

Con el proxy delante, el **puerto del servidor HTTP deja de publicarse**: en el cortafuegos se abre el del proxy, y el otro queda accesible solo desde él.

El **puerto de websockets no es ninguno de esos dos**. Por él entra el navegador para ejecutar las aplicaciones, y va directo a Velneo vServer: el proxy no lo toca salvo que lo configures para ello, así que si lo cierras al abrir el del proxy, la lanzadera seguirá cargando y las aplicaciones dejarán de arrancar. Hay dos salidas, y las dos valen:

* **Dejarlo abierto**, como en el paso 5. No hay nada que configurar: la lanzadera anuncia el puerto en el que escucha el servidor y el navegador llega hasta él.
* **Reenviarlo también por el proxy**, si prefieres que hacia fuera solo haya un puerto abierto. Puedes llevarlo al puerto de websockets del servidor, o dejar que entre por la misma vía que todo lo demás: el servidor HTTP atiende el websocket en la ruta `/ws` del virtual host que ya estás reenviando. Por ese segundo camino el servidor **comprueba que el `Origin` de la petición coincide con el `Host`**, así que el proxy tiene que reenviar el `Host` original; si lo reescribe, el navegador recibe un 403 y no dice por qué.

Reenviándolo, el navegador ya no llega al puerto del servidor sino al del proxy, y entonces hay que **declararlo en el parámetro «Puerto WSS»** de la lanzadera: Velneo vServer no tiene forma de saber que hay un proxy delante, así que seguiría anunciando el suyo.

Si el proxy **termina el TLS**, el cifrado de cara al navegador lo pone él y la conexión con el servidor HTTP puede ir en claro, con SSL sin marcar en el paso 4.1. Lo que sí hace falta es que **ese tramo no sea observable por terceros**: lo habitual es que el proxy y el servidor estén en la misma máquina, y entonces el reenvío va a `localhost` y no sale de ella. Si el tráfico atraviesa una red que no controlas por completo, tiene que ir cifrado — por ahí pasan las credenciales del formulario de login y el token JWT.

Cómo se configura cada proxy queda fuera de esta documentación: depende del que elijas.

***

## Anexo A: publicarla con Velneo vModApache

Así se montaba la lanzadera antes de la versión 38: la página la sirve Apache con el módulo de Velneo, y las aplicaciones de escritorio web se reenvían al servidor HTTP. Sigue funcionando y tiene soporte, pero es bastante más trabajo que el modo del cuerpo de esta guía, así que se mantiene para quien ya lo tenga montado o prefiera seguir con él.

Los **pasos 1 a 3** son los mismos: Velneo vServer, su certificado y la lanzadera con su clave JWT. Cambia todo lo que viene después, y el virtual host se configura al revés que en el paso 4.1: en un puerto interno, sin dominio y **sin SSL**, porque aquí quien cifra de cara al navegador es Apache.

En este anexo, **PUERTO\_HTTP** es el puerto que configurarás en el paso A.3.

{% hint style="warning" %}
Apache y Velneo vServer tienen que estar **en la misma máquina**. En máquinas separadas hay que resolver el acceso entre ellas y su cifrado, y eso queda fuera de esta documentación.
{% endhint %}

Se usa la distribución de [Apache Lounge](https://www.apachelounge.com/download/). Con otra distribución hay que adaptar las rutas.

### A.1 Instalar Apache

1. Instala el [Visual C++ Redistributable 2017-2026](https://aka.ms/vc14/vc_redist.x64.exe).
2. Descarga la versión **Win64** de [Apache Lounge](https://www.apachelounge.com/download/) y descomprime la carpeta `Apache24` en la raíz de `C:`, de forma que quede `C:\Apache24`.
3. Abre una terminal **como administrador** y ejecuta:

```
cd C:\Apache24\bin
.\httpd.exe -k install
.\httpd.exe -k start
```

**Comprobar:** **<http://localhost>** muestra la página de bienvenida de Apache.

* Sin el Visual C++ Redistributable, Apache no arranca y el error no dice que falte eso.
* Si instalas Apache en otra ruta, cambia `Define SRVROOT "C:/Apache24"` en `C:\Apache24\conf\httpd.conf`, con barras normales.

### A.2 Activar SSL en Apache

En `C:\Apache24\conf\httpd.conf`, quita la almohadilla de estas cinco líneas, que están juntas en la zona de `LoadModule`:

```apacheconf
#LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
#LoadModule rewrite_module modules/mod_rewrite.so
#LoadModule proxy_module modules/mod_proxy.so
#LoadModule proxy_http_module modules/mod_proxy_http.so
#LoadModule ssl_module modules/mod_ssl.so
```

Y de esta, que está casi al final del fichero entre otras muchas `Include`:

```apacheconf
#Include conf/extra/httpd-ssl.conf
```

{% hint style="danger" %}
Las dos que más se escapan: **`socache_shmcb`**, porque no parece "de SSL" y sin él Apache no arranca con SSL activado; y el **`Include`**, porque sin él Apache arranca con normalidad y sigue sirviendo HTTP, pero **https no responde y no hay ningún error que lo explique**.
{% endhint %}

Después, coloca el certificado y el dominio:

1. Copia tu certificado y tu clave privada a `C:\Apache24\conf\` y renómbralos a `server.crt` y `server.key`, que son los nombres que la configuración espera. Es la **misma pareja** del paso 2: Apache necesita su propia copia porque se ejecuta con otra cuenta y no tiene por qué poder leer la del servicio.
2. En `C:\Apache24\conf\extra\httpd-ssl.conf`, dentro de `<VirtualHost _default_:443>`, cambia `ServerName www.example.com:443` por `ServerName mi-dominio:443`.
3. Reinicia, desde una terminal como administrador:

```
cd C:\Apache24\bin
.\httpd.exe -k restart
.\httpd.exe -t
netstat -ano | findstr :443
```

**Comprobar:** `httpd -t` responde `Syntax OK`, `netstat` devuelve alguna línea, y **<https://mi-dominio>** carga la página de Apache con el candado y sin avisos de certificado.

* Si prefieres conservar los nombres de tus ficheros, cambia `SSLCertificateFile` y `SSLCertificateKeyFile` en `httpd-ssl.conf`.
* Si `netstat` no devuelve nada, casi siempre es el `Include` de `httpd-ssl.conf` sin descomentar.
* No sigas sin esto: los pasos siguientes tampoco funcionarán.

### A.3 Configurar el virtual host del servidor HTTP

En Velneo vAdmin, sección **Web** del menú lateral:

1. **Desactiva el virtual host del 443** que Velneo vServer ha creado al arrancar: doble clic, **desmarca Activo**, acepta. Si vienes del modo del cuerpo de esta guía, es el que configuraste en el paso 4.1.
2. Añade el virtual host de trabajo con estos valores:
   * **Activo**: marcado
   * **Puerto de escucha**: uno libre, por ejemplo `8080`
   * **Dominio de escucha**: **vacío**
   * **SSL**: **sin marcar**
3. Reinicia el servidor HTTP desde la barra de herramientas de esa pantalla.
4. Apunta el puerto: es **PUERTO\_HTTP** del paso A.5.

**Comprobar:** en el navegador de la propia máquina, `http://localhost:8080/login/38.0.0/wasm-bridge.js` descarga o muestra un fichero. Cambia `38.0.0` por la versión de tu Velneo vServer, la del mensaje de arranque: los ficheros cuelgan de un directorio con el número de versión, así que sin él responde 404.

{% hint style="danger" %}
**Desactiva el virtual host del 443, no lo borres**: si lo borras, el servidor lo vuelve a crear en el siguiente arranque.

Y hazlo antes de seguir, porque si un virtual host no consigue abrir su puerto **el servidor HTTP no arranca ninguno**. El síntoma engaña: Apache responde **503** a todas las aplicaciones con la configuración correcta, y en vAdmin sale `Error al iniciar servidor HTTP`.
{% endhint %}

{% hint style="danger" %}
**Aquí SSL va sin marcar**, al contrario que en el paso 4.1. El cifrado de cara al navegador lo pone Apache; esta conexión es interna y va sin cifrar. Si marcas SSL, el servidor responde cifrado, Apache reenvía en claro y todas las aplicaciones dan **502**.
{% endhint %}

* **Dominio de escucha vacío** hace que atienda cualquier dominio, que es lo que quieres para una conexión interna. Si le pones uno, el reenvío del paso A.5 tendrá que usarlo en lugar de `localhost`.
* El puerto del servidor HTTP **no hay que abrirlo** en el cortafuegos: solo lo usa Apache dentro de la misma máquina. Los que sí se abren son el 443, el de vatp y el de websockets — este último solo si no lo reenvías por Apache (paso A.6).
* Si no responde, comprueba que está escuchando con `netstat -ano | findstr :8080`.

### A.4 Instalar Velneo vModApache

Sigue los pasos de la documentación de vModApache.

### A.5 Configurar Apache para la vLanzadera

1. Abre `C:\Apache24\conf\extra\httpd-ssl.conf`.
2. Pega este bloque **dentro** de `<VirtualHost _default_:443>`, justo antes de `</VirtualHost>`:

```apacheconf
# --- vLanzadera ------------------------------------------------------------

# La raíz responde con la lanzadera. El flag PT es imprescindible: sin él
# Apache busca un fichero llamado "auth" y la raíz responde 404.
RewriteEngine On
RewriteRule ^/?$ /auth?%{QUERY_STRING} [NC,PT,L]

# La página de la lanzadera, servida por Velneo vModApache
<Location /auth>
	SetHandler velneo
	#VelneoMode SERVER
	Vrl vatps://usuario:contraseña@servidor[:num_puerto]/id_instancia
</Location>

# Las aplicaciones WebAssembly: /login las de la instalación de Velneo vServer,
# /velneoWASM las de un paquete importado. Las dos son necesarias.
<Location /login>
	ProxyPass        http://localhost:PUERTO_HTTP/login
	ProxyPassReverse http://localhost:PUERTO_HTTP/login
	SetEnv no-gzip 1
</Location>

<Location /velneoWASM>
	ProxyPass        http://localhost:PUERTO_HTTP/velneoWASM
	ProxyPassReverse http://localhost:PUERTO_HTTP/velneoWASM
	SetEnv no-gzip 1
</Location>
```

3. Sustituye la `Vrl` por los datos de tu instancia de la vLanzadera y **PUERTO\_HTTP** por el puerto del paso A.3.
4. Reinicia Apache:

```
cd C:\Apache24\bin
.\httpd.exe -k restart
```

{% hint style="danger" %}
**No añadas ninguna cabecera para la vLanzadera.** Las emiten ya la propia lanzadera en su página —incluidas `Cross-Origin-Embedder-Policy` y `Cross-Origin-Opener-Policy`— y el servidor HTTP de Velneo vServer en las aplicaciones. Duplicadas, el navegador las descarta y las aplicaciones no arrancan.

Si vienes de una configuración anterior de la vLanzadera, quita antes:

* los `Include` de `vLanzadera.conf`, `vLanzadera-headers.conf`, `vLanzadera-assets.conf` y `vLanzadera-rewrites.conf`, y los propios ficheros,
* cualquier `Header` con `Cross-Origin-Embedder-Policy`, `Cross-Origin-Opener-Policy` o `Cache-Control` en el camino de la vLanzadera,
* el `RewriteRule` de la raíz hacia `/auth` que tuvieras dentro de un `<Directory>`,
* y el `<LocationMatch>` de los assets de la vLanzadera.

Tampoco hace falta ya cambiar el `DocumentRoot` ni crear directorios para los assets: Apache no sirve ninguno.
{% endhint %}

### A.6 El websocket, si no quieres abrir su puerto

Por defecto el navegador abre el websocket **directamente contra Velneo vServer**, en el puerto de websockets del paso 1, así que ese puerto tiene que estar abierto. Si prefieres que hacia fuera solo esté abierto el 443, Apache también puede reenviarlo, y entonces no hay que abrirlo.

Hace falta el módulo de túnel de websockets, que no está entre los del paso A.2. En `C:\Apache24\conf\httpd.conf`, quita la almohadilla de esta línea:

```apacheconf
#LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
```

Elige **una** de las dos formas y añade su bloque dentro del mismo `<VirtualHost>` del paso A.5, en `C:\Apache24\conf\extra\httpd-ssl.conf`. La ruta es `/ws` en los dos casos: es la que pide el navegador, y no se configura en ninguna parte.

**Al puerto de websockets de Velneo vServer**, que es el mismo destino al que iba el navegador:

```apacheconf
SSLProxyEngine On

<Location /ws>
	ProxyPass        wss://mi-dominio:PUERTO_WS/
	ProxyPassReverse wss://mi-dominio:PUERTO_WS/
</Location>
```

Sustituye **PUERTO\_WS** por el puerto de websockets del paso 1, y **mi-dominio** por el tuyo. Ese puerto va cifrado, con el mismo certificado del paso 2, y por eso hace falta `SSLProxyEngine On`: sin él Apache reenvía en claro y responde **500** sin reclamar la directiva que falta.

Y va el **dominio**, no `localhost`: Apache comprueba que el nombre del certificado del otro extremo coincida con el del destino, así que por `localhost` responde también **500** y deja en el log `SSL Proxy: Peer certificate does not match for hostname localhost`. Eso sí, el dominio tiene que resolver desde la propia máquina; si tu DNS interno no lo hace, basta una línea en el fichero de `hosts` apuntándolo a `127.0.0.1`.

**Al servidor HTTP, por la misma vía que todo lo demás.** El servidor HTTP atiende el websocket en el `/ws` del virtual host que ya estás reenviando, así que va sin cifrar al mismo **PUERTO\_HTTP** del paso A.3:

```apacheconf
ProxyPreserveHost On

<Location /ws>
	ProxyPass        ws://localhost:PUERTO_HTTP/ws
	ProxyPassReverse ws://localhost:PUERTO_HTTP/ws
</Location>
```

`ProxyPreserveHost On` **no es opcional aquí**: por este camino el servidor comprueba que el `Origin` de la petición coincide con el `Host`, y si Apache reescribe el `Host` a `localhost` el navegador recibe un **403** sin más explicación.

Sea cual sea la que elijas, el navegador deja de llegar al puerto del servidor y llega al de Apache, así que hay que **declarar el 443 en el parámetro «Puerto WSS»** de la lanzadera. Velneo vServer no tiene forma de saber que hay un Apache delante: si no se lo dices, sigue anunciando su propio puerto y el navegador vuelve a intentar el que acabas de cerrar.

Reinicia Apache al terminar, desde una terminal como administrador:

```
cd C:\Apache24\bin
.\httpd.exe -k restart
```

### Comprobación del anexo

1. **<https://mi-dominio/auth>** carga la lanzadera.
2. **<https://mi-dominio>** devuelve lo mismo: aquí la raíz sí sirve la lanzadera, por el `RewriteRule` del bloque.
3. Entras con un usuario y una aplicación arranca en el navegador.

**Si algo falla:**

| Síntoma                                                                                | Dónde mirar                                                                                                                                                                                               |
| -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **503** en todas las aplicaciones                                                      | El virtual host del 443 sin desactivar (paso A.3)                                                                                                                                                         |
| **502** al cargar la aplicación                                                        | SSL marcado en el virtual host, o `PUERTO_HTTP` distinto del configurado en vAdmin                                                                                                                        |
| **500** al abrir el websocket, con `Peer certificate does not match` en el `error_log` | El destino del reenvío puesto como `localhost`: tiene que ser el dominio del certificado (paso A.6)                                                                                                       |
| **403** `Origin no permitido` al abrir el websocket                                    | Falta `ProxyPreserveHost On` en el reenvío al `/ws` del servidor HTTP (paso A.6)                                                                                                                          |
| **404** en la raíz, pero `/auth` funciona                                              | Falta el flag `PT` en el `RewriteRule`                                                                                                                                                                    |
| Error de `SharedArrayBuffer` o `crossOriginIsolated`                                   | Cabeceras duplicadas. Escribe `self.crossOriginIsolated` en la consola; si da `false`, mira en la pestaña **Network** si `cross-origin-embedder-policy` o `cross-origin-opener-policy` aparecen dos veces |
| Entras, pero la aplicación se queda sin abrir y la consola da un error de `WebSocket`  | El websocket: si no lo reenvías por Apache, su puerto tiene que estar abierto en el cortafuegos; si lo reenvías (paso A.6), falta declarar el 443 en «Puerto WSS»                                         |

***

## Anexo B: certificado para un entorno de pruebas

{% hint style="danger" %}
**Solo para entornos de pruebas.** Un certificado de desarrollo lo firma una autoridad que solo existe en tu máquina: para cualquier otro usuario el sitio aparecerá como no seguro y las aplicaciones no funcionarán en su navegador.
{% endhint %}

1. Genera el certificado con [mkcert](https://github.com/FiloSottile/mkcert):

```
mkcert -install
mkcert mi-dominio
```

2. Usa `mi-dominio.pem` (certificado) y `mi-dominio-key.pem` (clave) donde la guía pide el certificado: el paso 2 y, si montas el anexo A, también su paso A.2.
3. Si el dominio no existe en el DNS, añádelo a `C:\Windows\System32\drivers\etc\hosts` apuntando a la IP de la máquina.

### Dos cosas que se comportan distinto

**Al arrancar verás en Velneo vAdmin dos errores de certificado:**

```
Error de certificado TLS/SSL: The issuer certificate of a locally looked up certificate could not be found
Error de certificado TLS/SSL: No certificates could be verified
```

Son **avisos**: el certificado se carga igual, y lo confirma el mensaje siguiente, `Cifrado de VATPS activado, certificado ssl: mkcert development certificate [...]`. Salen porque el fichero no incluye quién emitió el certificado. Para que no aparezcan, monta el fichero con la cadena completa (`mkcert -CAROOT` dice dónde está la raíz):

```cmd
copy /b mi-dominio.pem + "<CAROOT>\rootCA.pem" server.crt
```

El `server.crt` resultante debe tener dos bloques `-----BEGIN CERTIFICATE-----`.

**Si importas un paquete de aplicaciones, el log avisará de que no se ha podido comprobar que el servidor lo sirva.** Velneo vServer no da por válido su propio certificado local al hacerse peticiones a sí mismo —en Windows es habitual, por la comprobación de revocación—. **No impide usar el paquete**: la lanzadera comprueba que los ficheros están en disco y sigue. Con un certificado de una autoridad reconocida el aviso no aparece.
