Usar un Proxy en Linux

Linux Nivel Medio 27 de sep. de 2023

El proxy para los Linuxeros

Muchas veces los usuarios de GNU/Linux tenemos que subsistir en redes y dominios Windows, siendo los bichos raros de la red.

Uno de los mayores problemas que nos encontramos es el poder usar el proxy de la red que generalmente está configurada y pensada solo para los equipos que están dentro del dominio Windows.

Hace más 20 años que mi ordenador de trabajo usa unicamente GNU/Linux y sigue superviviendo y viendo pasar a su lado todas las diferentes versiones de clientes windows, servidores de dominio (Samba, NT, AD, etc), además de diferentes versiones de proxys que se instalan y configuran desde los departamentos de seguridad, todos esos cambios hacen que haya pasado por varios métodos para poder navegar y mantener totalmente actualizado mi equipo.

Vamos a ver algunos de los tipos de Proxy que podemos encontrarnos y como configurar correctamente nuestro equipo con Linux para que funcione correctamente.

PROXY POR FICHERO .PAC

Los ficheros PAC (Proxy Automatic Configuration) son un tipo de ficheros diseñados para la configuración automática del Proxy.

El administrador de la red nos proporcionará la URL a la que apuntar para acceder a este fichero. También podemos encontrarlo en la configuración de cualquier otro sistema operativo de un compañero que tenga configurado el proxy.

En nuestro equipo Linux, tendremos que ir hasta Centro de Control, si accedemos al Proxy de la red, solo tenemos que indicarselo allí.

Ejemplo: http://proxyconfig.dominiointerno.com/proxy.pac

PROXY POR URL/PUERTO

Este es otro de los tipos de proxy sencillos de configurar.

Tan solo hay que indicar la URL del Proxy y el Puerto por el que podemos salir.

Se puede indicar uno generico para todo o separarlo por tipo de conexiones: http, https, ftp y socks.

Ejemplo:
URL --> http://proxy.dominiointerno.com
PUERTO --> 8181

Este tipo de proxy y el anterior se pueden configurar facilmente desde el propio "Centro de Control" de nuestro entorno gráfico en Linux.

Esta configuración aplicada desde el entorno gráfico permite que casi todo lo relacionado con la navegación funcione.

Tanto para el tipo de proxy por url/puerto, como el de fichero .pac, desde el departamento de seguridad pueden haber configurado que sea necesario el uso de usuario y contraseña para el acceso, en ese caso habrá que indicarselo para que funcione.

EL PROXY Y LA SHELL

Sin embargo desde la terminal/consola, esto no es así, para que nos funcione desde la shell de forma transparente el proxy hay que realizar varios pasos o configuraciones.

Indicar el proxy como variables de entorno
Los ajustes de proxy para la shell se pueden realizar incluyendo las variables necesarias en cualquiera de estos dos ficheros:
/etc/profile
/etc/environment

Personalmente recomiendo usar este último /etc/environment pues es el que está específicamente preparado para trabajar con variables de entorno, aunque realizar los cambios en el otro también funcionaría.

Si disponemos de acceso como usuario root en nuestra maquina, incluiremos estas líneas en el fichero indicado y se aplicarán a cualquier usuario en cuanto inicialice una consola.

En caso de que no puedas acceder a este fichero, puedes incluir las lineas necesarial al final de tu fichero .bashrc en la raíz de tu carpeta de usuario.

Lineas a incluir para el Proxy en la bash:

# Variables Proxy --Todo sale por http aunque pidamos https o ftp --
export http_proxy="http://proxyconfig.dominiointerno.com:8181"
export https_proxy="http://proxyconfig.dominiointerno.com:8181"
export ftp_proxy="http://proxyconfig.dominiointerno.com:8181"

Proxy para Java en la shell
Si trabajamos con JAVA podemos indicar que debe de usar un proxy para las conexiones necesarias, en ese caso debemos incluir la siguientes líneas en el fichero /etc/profile (para todos los usuarios) o en .bashrc:

# Variables Proxy para JAVA
export JAVA_FLAGS="-Dhttp.proxyHost=proxyconfig.dominiointerno.com -Dhttp.proxyPort=8181 -Dhttps.proxyHost=proxyconfig.dominiointerno.com -Dhttp.proxyPort=8181"

Proxy para PHP/Composer en la shell
Para los programadores de PHP que utilicen Composer, debemos indicarle que use peticiones HTTP y evite la conexión por HTTPS:

# Variables Proxy para COMPOSER --HTTP si, HTTPS no y conectara por http--
export HTTP_PROXY_REQUEST_FULLURI=true
export HTTPS_PROXY_REQUEST_FULLURI=false

Proxy en la configuracion de APT
Con las variables de http_proxy exportadas, puedes realizar la descarga de paquetes mediante apt. Pero si usas el instalador de paquetes apt desde la consola, no es necesario tenerlo definido así.
Puedes indicar una configuración personalizada para este gestor de paquetes, tan solo tienes que editar o crear si no existe, el fichero /etc/apt/apt.conf e incluir en el las siguientes líneas:

Acquire::http::proxy "http://proxyconfig.dominiointerno.com:8080";
Acquire::https::proxy "http://proxyconfig.dominiointerno.com:8080";
Acquire::ftp::proxy "http://proxyconfig.dominiointerno.com:8080";
configuracion personalizada del proxy para apt

SOLVENTANDO PROBLEMAS DE USUARIO / CLAVE

Algunas veces el proxy no nos solicita automaticamente el usuario/clave para su correcta utilización.
Otra veces no es sencillo el pasar estos datos mediante ficheros de configuracion, variables, etc. Para solventar esto disponemos de varias opciones.

Proxy con usuario de dominio mediante NTLM / CNTLM
Muchas veces no nos vale con disponer de la URL y el puerto del Proxy para el acceso a recursos externos de nuestra red.

Es necesario el realizar una autenticación con usuario/clave de un Dominio para conectarnos al proxy.

Una solución sencilla es el crearnos una conexión de proxy propia mediante CNTLM. Un esquema de este tipo de solución es:

Proxy CNTLM

Los pasos simplificados son:

  1. En mi equipo local instalo y configuro un "Proxy CNTLM" que contiene los datos de Usuario/Clave, Dominio y Proxy a utilizar.
  2. Despues en mi equipo apunto todas las salidas a internet a mi propio servicio de 'Proxy CNTLM'

Para la instalación de un proxy CNTLM podemos usar el paquete:
cntlm - Fast NTLM authentication proxy with tunneling

En Debian es tan sencillo como ejecutar:

sudo apt -y install cntlm

Ahora debemos crear una configuración mínima para CNTLM. Como root creamos el fichero /etc/cntlm.conf, debemos escribir las siguientes líneas en él:

Username <usuario>
Domain <dominio>
Auth NTLMv2
PassNTLMv2 <Clave-Hash>
Proxy <Ip_del_Proxy:Puerto>
NoProxy localhost,127.0.0.1, *.dominiointerno.com
Listen 3128
Gateway no
Allow 127.0.0.1

NOTA: Todo lo contenido entre los simbolos <> los debes de completar con tus propios datos.

La Clave-Hash de la contraseña que tenemos que indicara en PassNTLMv2 la vamos a generar mediante el siguiente comando:

cntlm -I -M http://www.google.es -u
Generar la clava Hash para PassNTLv2

Nota: i mayúscula => modo interactivo. m mayúscula => modo magico)

Con los datos proporcionados en el fichero de configuración, se realiza una petición NTLM previa al proxy para llegar a una URL externa (en el ejemplo hemos usado Google, pero puedes usar otra URL externa si lo deseas).
Se nos solicitará nuestra clave de acceso, una vez realizada la conexión nos devuelve el HASH de la clave usada.

6AC6535378FD8B69CF6C6234532932CA

Debemos copiar este hash e incluirlo en el fichero /etc/cntlm.conf en la linea:

PassNTLMv2 6AC6535378FD8B69CF6C6234532932CA

Tras grabar el fichero, reiniciamos el servicio de CNTLM.

En las variables PROXY de todo nuestro sistema en vez de apuntar al proxy indicado por el departamento de seguridad apuntaremos a nuestro proxy CNTLM:

URL Proxy --> 127.0.0.1
Puerto -----> 3128

A partir de este momento nuestro Proxy Local, se encarga de realizar la negociación con el proxy de la red, enviandole nuestro usuario y contraseña y dispondremos de una navegación transparente.

Proxy mediante conexión a Directorio Activo
Algunos proxys de red, están "conectados" al Servidor de Directorio Activo, con lo que la solución de indicar al proxy un usuario y contraseña no funciona.

Esto es debido a que es el propio Directorio activo quien comunica al servicio del proxy quien se ha logado y quien puede navegar a través de él.

Tambien aquí disponemos de otra solución sencilla, simplmente se trata de engañara al Directorio Actimo, simulando que nos hemos logado en él..

Los pasos a realizar (como root) son los siguientes:

Nos creamos un fichero de credenciales /etc/credenciales con las siguientes líneas:

# --- Credenciales para mi A.D ---
username=
password=
domain=DOMINIOINTERNO.COM
# --------------------------------

Fijamos propietario root y permisos 440 al fichero /etc/credenciales:

chown root:root /etc/credenciales
chmod 440 /etc/credenciales

Creamos un punto de montaje para simular el LOGIN en el Dominio:

mkdir -p /mnt/LOGIN

Vamos a crear un script que podemos llamar en cualquier momento para iniciar/reiniciar la conexion al proxy.

Este script, lo podemos incluir en 'Aplicaciones al inicio' que nos ofrece nuestro escritorio y de esta forma nos funcionará de modo transparente cada vez que iniciemos sesión en nuestro equipo, esta es la solución mas comoda y sencilla.

Si no lo incluimos en las Aplicaciones al inicio, podemos ejecutarlo cada vez que necesitemos usar el proxy.

Por ejemplo creamos en la ruta /opt el fichero activarproxy (sin necesidad de poner la extension .sh)

Contenido del fichero /opt/activarproxy:

#!/bin/bash
# Emular conexion a A.D
# Desmontaje previo para posibles reconexiones
sudo umount /mnt/LOGIN 2>/dev/null
# Montar SYSVOL (trampa para el DA)
sudo mount.cifs -o file_mode=0700,dir_mode=0700 //DOMINIO/sysvol/ /mnt/LOGIN/ -o credentials=/etc/credenciales
Simular Login en AD, mediante montaje de un recurso del AD.

Guardamos y damos permisos de ejecucion al fichero:

chmod 0755 /opt/activarproxy

NOTA: Sustituir por el nombre del Dominio del Directorio Activo o la IP de alguno de los servidores del A.D.

Simplemente quedaria indicar en nuestro Linux en las variables del proxy la URL y el Puerto del proxy.
Como con esta "simulación de login" hemos conseguido indicar al AD que estamos autorizados (ya que somos capaces de usar un recurso de red), y podemos usar el proxy como si nuestro equipo perteneciese al dominio.

PROXY PARA APLICACIONES SIN VARIABLES DE ENTORNO

Hay algunas aplicaciones que se resisten a usar las variables de entorno por más que nos esforcemos, o incluso 'nos ignoran' cuando amablemente les pasamos por parámetro todos los valores necesarios para que hagan las peticiones por el proxy que les indicamos.

En estos casos no nos queda más remedio que indicar al sistema que fuerce a que esta aplicación o su servicio navegue por el proxy deseado. La solución pasa necesariamente por crear un 'servicio' para conseguir usar un proxy.

Proxy para Docker
Para poder utilizar el cliente de docker con tu usuario deberas editar o crear el fichero ~/.docker/config.json

# Nos aseguramos que existe ruta y fichero
mkdir -p ~/.docker
touch ~/.docker/config.json

Edita el fichero, deberas quedar con una estructura similar a la siguiente:

{
  "proxies":
    {
      "default":
        {
          "httpProxy": "http://proxy.dominiointerno.com:3128",
          "httpsProxy": "http://proxy.dominiointerno.com:3128",
          "noProxy": "*.dominterno.com,.otroexcluido.com,127.0.0.0/8"
        }
    }
}

Cuando construyas imágenes que se ejecuten dentro de un entorno con proxy deberás configurar como variables de entorno en el Dockerfile las variables de proxy que necesites.
Ejemplo de sintaxis para tu Dockerfile:

ENV HTTP_PROXY="http://proxy.dominiointerno.com:3128"
ENV HTTPS_PROXY="http://proxy.dominiointerno.com:3128"
ENV FTP_PROXY="ftp://proxy.dominiointerno.com:3128"
ENV NO_PROXY="*.dominiointerno.com,.otroexcluido.com,127.0.0.0/8"

Tambien puedes necesitar que el propio servicio de Docker use un proxy, en este caso debes incluir un fichero con una configuración especial para este servicio en una ruta específica:

sudo mkdir -p /etc/systemd/system/docker.service.d
touch /etc/systemd/system/docker.service.d/http-proxy.conf

Edita ahora el fichero http-proxy.conf que has creado e incluye en él como 'Environment' la configuración necesaria para el proxy:

[Service]
Environment="HTTP_PROXY=http://proxy.dominiointerno.com:3128"
Environment="HTTPS_PROXY=http://proxy.dominiointerno.com:3128"
Environment="NO_PROXY=localhost,127.0.0.1,registry.interno.com,.dominiointerno.com"

Si tu proxy necesita de un usuario/clave se puede indicar también:

[Service]
Environment="HTTP_PROXY=http://usuario:clave@proxy.dominiointerno.com:3128"

Nota: si el usuario o clave incluye los caracteres: #?!()[]{} debes 'escaparlos' mediante un porcentaje % más su valor UTF-8 codificado

Por ejemplo si el usuario tiene como contraseña: super!segura# habría que escribir la admiración como '%21' y la almohadilla como '%23'(sin olvidarnos de escaparlo con %)

[Service]
Environment="HTTP_PROXY=http://usuario:super%%21segura%%23@proxy.dominiointerno.com:3128"

Te dejo un script en bash, para codificar una cadena:

#!/bin/bash
# SoloConLinux - Script para Codificar/Decodificar cadena con %
codifica() {
    echo "$1 Codificado:"
    # codifica <cadena> recibidad como parametro
    local longitud="${#1}"
    for (( i = 0; i < longitud; i++ )); do
        local c="${1:i:1}"
        case $c in
            [a-zA-Z0-9.~_-]) printf "$c" ;;
        *) printf '%%%02X' "'$c"
        esac
    done
    echo
}
decodifica() {
    echo "$1 Decodificado:"
    # decodifica <cadena> recibida como parametro
    local cadena="${1//+/ }"
    printf '%b' "${cadena//%/\\x}"
    echo
}
ayuda() {
    echo "USO DEL PROGRAMA"
    echo "Codificar/encode: $0 -e 'cadena-texto'"
    echo "Decodificar/decode: $0 -d 'cadena-texto'"
}
# Main - Principal
if [ "$#" != "2" ] ; then
    ayuda
else
case $1 in
    '-e')
        codifica $2
        ;;
    '-d')
        decodifica $2
        ;;
    *)
        ayuda
        ;;
esac
fi

Una vez creado el fichero de Servicio para la configuracion del proxy, debes de reiniciar el servicio de Docker, para ello ejecuta:

sudo systemctl daemon-reload
sudo systemctl restart docker

Etiquetas

Luis GuLo

🐧 SysAdmin GNU/Linux - 🐳 Docker - 🖥️ Bash Scripting - 🐪 Perl - 🐬 MySQL - 👥 Formador de TI - 👥 Formador de SysAdmin's - 💢 Ansible - ☁️ Cloud Computing - ❤️ Debian GNU/Linux