Creación e instalación de un perfil OpenVPN en iOS

Hace tiempo la cosa era más complicada, pero hoy en día crear y activar un perfil OpenVPN para iOS es bastante trivial.

Creación de un fichero de configuración OpenVPN

  1. Creamos un par de claves públicas y privadas para el usuario. Esas claves deben ir firmadas por la entidad de certificación asociada al servidor OpenVPN y tienen una caducidad determinada (por defecto, un año).

    Si usamos easy-rsa, los comandos a ejecutar son:

    jcea@OpenVPN_Server:~$ cd /etc/openvpn/easy-rsa/2.2.2/
    jcea@OpenVPN_Server:/etc/openvpn/easy-rsa/2.2.2$ source vars
    NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/2.2.2/keys
    jcea@OpenVPN_Server:/etc/openvpn/easy-rsa/2.2.2$ echo $KEY_EXPIRE
    365
    

    Lo anterior inicializa easy-rsa. Podemos ver que la expiración por defecto es de 365 días. Podemos modificarla si así lo deseamos.

    Lo normal ahora sería generar el certificado OpenVPN para el usuario, sin más. Sin embargo la versión 2.2.2 de easy-rsa no permite crear una clave nueva para un usuario ya existente, AUNQUE LA CLAVE ANTIGUA HAYA CADUCADO. En mi opinión, esto es un bug.

    El siguiente paso, por tanto, es revocar el certificado actual del usuario:

    jcea@OpenVPN_Server:/etc/openvpn/easy-rsa/2.2.2$ ./revoke-full NOMBRE
    [...]
    error 23 at 0 depth lookup: certificate revoked
    error NOMBRE.crt: verification failed
    

    Aquí se crea una CRL nueva y se comprueba que, efectivamente, revoca el certificado actual.

    A continuación generamos el nuevo certificado a enviar al usuario:

    jcea@OpenVPN_Server:/etc/openvpn/easy-rsa/2.2.2$ ./build-key NOMBRE
    [...]
    1 out of 1 certificate requests certified, commit? [y/n] y
    Write out database with 1 new entries
    Data Base Updated
    

    Esto generará tres ficheros en el directorio keys: la clave privada, el certificado público firmado con la entidad de certificación del servidor OpenVPN y el fichero de petición del certificado (que ya no se necesita para nada).

  2. Ahora cogemos la plantilla siguiente, un fichero de texto, y completamos las partes marcadas del final:

    ##############################################
    # Sample client-side OpenVPN 2.0 config file #
    # for connecting to multi-client server.     #
    #                                            #
    # This configuration can be used by multiple #
    # clients, however each client should have   #
    # its own cert and key files.                #
    #                                            #
    # On Windows, you might want to rename this  #
    # file so it has a .ovpn extension           #
    ##############################################
    
    # Specify that we are a client and that we
    # will be pulling certain config file directives
    # from the server.
    client
    
    # Use the same setting as you are using on
    # the server.
    # On most systems, the VPN will not function
    # unless you partially or fully disable
    # the firewall for the TUN/TAP interface.
    ;dev tap
    dev tun
    
    # Windows needs the TAP-Win32 adapter name
    # from the Network Connections panel
    # if you have more than one.  On XP SP2,
    # you may need to disable the firewall
    # for the TAP adapter.
    ;dev-node MyTap
    
    # Are we connecting to a TCP or
    # UDP server?  Use the same setting as
    # on the server.
    ;proto tcp
    proto udp
    
    # The hostname/IP and port of the server.
    # You can have multiple remote entries
    # to load balance between the servers.
    remote SERVIDOR 1194
    ;remote my-server-2 1194
    
    # Choose a random host from the remote
    # list for load-balancing.  Otherwise
    # try hosts in the order specified.
    ;remote-random
    
    # Keep trying indefinitely to resolve the
    # host name of the OpenVPN server.  Very useful
    # on machines which are not permanently connected
    # to the internet such as laptops.
    resolv-retry infinite
    
    # Most clients don't need to bind to
    # a specific local port number.
    nobind
    
    # Downgrade privileges after initialization (non-Windows only)
    user nobody
    group nogroup
    
    # Try to preserve some state across restarts.
    persist-key
    persist-tun
    
    # If you are connecting through an
    # HTTP proxy to reach the actual OpenVPN
    # server, put the proxy server/IP and
    # port number here.  See the man page
    # if your proxy server requires
    # authentication.
    ;http-proxy-retry # retry on connection failures
    ;http-proxy [proxy server] [proxy port #]
    
    # Wireless networks often produce a lot
    # of duplicate packets.  Set this flag
    # to silence duplicate packet warnings.
    ;mute-replay-warnings
    
    # SSL/TLS parms.
    # See the server config file for more
    # description.  It's best to use
    # a separate .crt/.key file pair
    # for each client.  A single ca
    # file can be used for all clients.
    ;ca [inline]
    ;cert [inline]
    ;key [inline]
    
    # Verify server certificate by checking
    # that the certicate has the nsCertType
    # field set to "server".  This is an
    # important precaution to protect against
    # a potential attack discussed here:
    #  http://openvpn.net/howto.html#mitm
    #
    # To use this feature, you will need to generate
    # your server certificates with the nsCertType
    # field set to "server".  The build-key-server
    # script in the easy-rsa folder will do this.
    ns-cert-type server
    
    # If a tls-auth key is used on the server
    # then every client must also have the key.
    ;tls-auth ta.key 1
    
    # Select a cryptographic cipher.
    # If the cipher option is used on the server
    # then you must also specify it here.
    ;cipher x
    
    # Enable compression on the VPN link.
    # Don't enable this unless it is also
    # enabled in the server config file.
    comp-lzo
    
    # Set log file verbosity.
    verb 3
    
    # Silence repeating messages
    ;mute 20
    
    <ca>
    -----BEGIN CERTIFICATE-----
    [...]
    -----END CERTIFICATE-----
    </ca>
    
    <cert>
    -----BEGIN CERTIFICATE-----
    [...]
    -----END CERTIFICATE-----
    </cert>
    
    <key>
    -----BEGIN PRIVATE KEY-----
    [...]
    -----END PRIVATE KEY-----
    </key>
    

    En la sección <ca> debe incluirse el certificado público X.509 del servidor OpenVPN. Hasta aquí esta plantilla puede ser común para todos los usuarios del sistema.

    En las secciones <cert> y <key> se pone la clave pública X.509 y la clave privada del usuario.

Instalación del perfil OpenVPN en un dispositivo iOS

  1. La forma más simple de proceder ahora es enviar por correo electrónico ese fichero como adjunto, que debe tener la extensión ovpn, al dispositivo iOS en el que queremos instalarlo.

    Podemos llamarlo, por ejemplo, NOMBRE.ovpn.

  2. Recibimos ese email en el dispositivo iOS que nos interesa. Veremos un fichero adjunto. Si tenemos OpenVPN instalado en el dispositivo iOS, podemos pulsar sobre ese fichero adjunto.

    Al hacerlo nos aparecerá la hoja de compartir habitual de iOS y uno de los destinos posibles será OpenVPN.

  3. Seleccionamos compartir con OpenVPN. Se abrirá el programa, que nos mostrará el nombre del perfil y el servidor OpenVPN al que se va a conectar. Se nos ofrece la opción de añadir ese perfil a nuestra configuración, o bien borrarlo.

  4. Si seleccionamos "add", podremos editar el nombre del perfil para ponerle el nombre que queramos (por defecto será SERVIDOR [NOMBRE]). Esto se podrá editar con posterioridad, no hay que preocuparse por ello.

  5. Seguidamente pulsamos "connect" para conectarnos. Si todo va bien, el dispositivo iOS se conectará sin más historia.

  6. En caso necesario, dependiendo de la red en la que estemos, podemos editar el perfil una vez añadido al programa OpenVPN para activar el Kill Switch, cambiar el nombre del perfil, modificar el servidor al que nos conectamos e, incluso, añadir un proxy.

    Por supuesto, también podemos borrar este perfil y, naturalmente, podemos tener varios perfiles diferentes.