Actualizado a la versión 1.21pl78.

Introducción

AFT proporciona una infraestructura segura y flexible de transferencia de archivos para entornos heterogéneos que operan en un régimen períodico y requieren automatizar sus operaciones.

Los enlaces son sockets TCP y los datos son transmitidos encriptados con TLS.

Conceptos Básicos

AFT trabaja en dos roles básicos: hub o agente. Los hubs "toman el control" de un conjunto de agentes. Los hubs implementan las transferencias de archivos en tres modos:

  1. GET para extracción de archivos desde un "agente fuente" (source agent)

  2. PUT para enviar archivo hacia un "agente destinatario" (destination agent)

  3. A2A (agente a agente) para extraer archivos desde un agente fuente (hacia un directorio temporal) y luego enviar estos archivos hacia un agente destinatario.

Los hubs y los agentes permiten la configuración de transferencias definidas por el usuario (en cualquier modo de oepración) identificadas por un identificador simple o "id".

Las transferencias del hub en modo GET (extracción) se identifican mediante secciones de configuración denotadas por [hub-get:id]; para modo PUT (envío) mediante secciones [hub-put:id]; finalmente para el modo A2A mediante secciones [hub-a2a:id].

Para una transferencia de hub tipo GET, debe haber una sección correspondiente en el agente de tipo [agent-src:id]; para una transferencia de hub tipo PUT, corresponde una sección en el agente de tipo [agent-dst:id]; finalmente, para una transferencia de hub de tipo "agente a agente" se debe configurar los agentes correspondientes con secciones [agent-src:id] y [agent-dst:id] respectivamente.

AGENT-SRC  =====>    HUB-GET

                     HUB-PUT    =====>    AGENT-DST

AGENT-SRC  =====>    HUB-A2A     =====>  AGENT-DST

La conexión de red TCP "física" puede ser establecida desde el hub a los agntes:

El hub inicia la conexión a los agentes (el hub es un cliente TCP)

O desde los agentes al hub:

Los agentes inician la conexión al hub (el hub es un servidor TCP)

En ambos casos, el hub puede extraer archivos (GET) de los agentes, enviar archivos (PUT) a los agentes, o combinar estas acciones con el modo A2A.

La comunicación es encriptada con TLS por omisión.

En el diseño de AFT, se consideró que una instancia de hub estará en comunicación con diverss agentes asociados; sin embargo, nada impide que el usuario configure diversos pares de instancias hub/agente para transferencias independientes, o instancias de agentes atendiendo más de un hub, incluso en simultáneo.

Ejecutando AFT

Paso 1

AFT requiere Java 8 o superior.

Paso 2

El usuario debe proporcionar un archivo llamado aft.cfg (ubicado en el subdirectorio etc.) El resto de este documento detalla su contenido.

Paso 3

Iniciar AFT con:

cd bin
./run-aft.sh

en sistemas Windows, dar click doble en el archivo batch bin\run-aft.bat o ejecutarlo manualmente:

cd bin
run-aft.bat

Para detener AFT se proporcionan los scripts stop-aft.sh y stop-aft.bat.

Configuración

El archivo aft.cfg se usa para configurar los hubs y los agentes. Es un archivo de texto plano con secciones delimitadas.

Los hubs definen un conjunto de "transferencias programadas" mediante las secciones [hub-a2a:nombre], [hub-get:nombre] y [hub-put:nombre]; opcionalmente se puede crear la sección especial [hub] para fijar algunos parámetros globales. Las transferencias se implementan mediante el hub tomando el control de los agentes por medio de un socket TCP.

Los agentes son definidos mediante un conjunto de transferencias programadas deliminatas por secciones [agent-src:name] o [agent-dst:name]; opcionalmente puede existir una sección [agent] para fijar algunos parámetros comunes.

Notar que el archivo de configuración puede ser modificado en cualquier momeno; es recargado aproximadamente cada minuto, exceptop cuando una transferencia está en curso.

Configuración de Agentes

AFT promueve una configuración mínima para los agentes. Los parámetros obligatorios se mantienen a fin de evitar dar al hub un poder excesivo sobre el computador; por ejemplo, exigimos que los directorios participantes del agente sean especificados localmente a fin de evitar accesos maliciosos a rutas sensibles desde un hub comprometido.

La configuración de los agentes admite una sección opcional [agent], para el que se proporcionan los siguientes parámetros:

agent-port

Puerto de escucha TCP. Un parámetro obligatorio para agentes que escuchan en la red.

max-children

Parámetro opcional (por omisión 5) para el máximo número de hubs simultáneamente conectados.

Ejemplo:

[agent]
agent-port = 20111

Transferencias de Archivos de Agentes

Luego, se define un conjunto de "transferencias de archivos" del lado del agente, que permiten al hub extraer o enviar archivos, desde y hacia el computador agente. Ambos casos corresponen a las secciones identificadas mediante [agent-src:nombre] y [agent-dst:nombre], respectivamente.

dir

El directorio desde el que los archivos serán extraídos (en configuraciones agent-src) o hacia donde los archivos serán enviados (en configuraciones agent-dst.)

Ejemplo:

[agent]
agent-port = 20111

[agent-src:bravo]
dir = /home/bravo/x-files
exec-after-transfer

Un comando a ser ejecutado mediante la facilidad ProcessBuilder de Java, después de que cada archivo es transferido hacia/desde el agente. el nombre del archivo es proporcionado al comando. Si la ejecución falla, se registra en el log, pero el proceso de transferencia continua.

Cuidado: el proceso agente AFT puede bloquearse indefinidamente si el comando no finaliza.

El commando debe ser un programa existente que será ejecutado mediante la facilidad de Java ProcessBuilder con el nombre de archivo como único argumento. No se admiten argumentos adicionales para el comando.

rename-destination

Un patrón de reemplazo para renombrar archivos que son transferidos (válido para [agent-dst].) La sintaxis es rename-destination=search-pattern⇒replacement-pattern. El search-pattern (patrón de búsqueda) se implementa mediante el método de Java Matcher#matches(), mientras que el replacement-patterns (patrón de reemplazo) lo hace mediante el el método de Java Matcher#replaceAll(). Es posible declarar directivas rename-destination más de una vez en la configuración de la transferencia, posibilitando distintos tipos de reemplazo.

Ejemplo:

[agent]
agent-port=55123

[agent-dst:tsr1]
dir=/tempo/agent-2
rename-destination=file(\d).txt=>file$1.dat

esto renombrará archivos tales como file1.txt, file2.txt…​ en file1.dat, file2.dat, etc.

Agente en modo Cliente

Cuando los agentes inician la conexión TCP (cliente TCP), las siguientes directivas deben ser configuradas:

hub-host

El hostname del hub, o su dirección IP.

hub-port

El número de puerto de escucha el hub.

hub-connect-check

Cuándo conectarse al hub para transferir archivos pendientes. Puede tomar la forma form delay:# para un tiempo fijo de reintentos especificando una cantidad de segundos; cron:expr donde expr es una expresión crontab; none (no intentar conectar; el hub iniciará la conexión (comportamiento por omisión.) Finalmente once significa intentar la conexión, hacer el trabajo, y terminar el proceso AFT.

El modo once se activa cuando AFT se inicia con la opción de línea de comando -agent=nombre; de lo contrario, se ignoran.

Notar que los agentes puden iniciar o esperar las conexiones TCP con el hub, pero esto es totalmente independiente de los modos de transferencia agent-src/agent-dst.

La expresión cron sigue el formato del framework Spring.

Ejemplo:

# una transferencia de agente cliente
# no se requiere seccion [agent]

[agent-src:bravo]
dir = /home/bravo/x-files
hub-host = 192.1.4.51
hub-port = 6001
hub-connect-check = delay:3600

Configuración del Hub

La sección de configuración global [hub] es opcional, pero es necesaria si el hub actúa como un servidor TCP. Las siguientes directivas están disponibles en esta sección:

hub-port

Puerto de escucha necesario si el hub recibirá conexiones desde los agentes clientes.

max-children

Máximo número de agentes cliente simultáneos; por omisión 100.

Ejemplo:

[hub]
hub-port = 6001

Transferencias de archivos del Hub

La configuración del hub incluye un conjunto de transferencias de archivos programadas.

Ejemplo:

En el siguiente configuración, my-transfer es una transferencia que envía archivos desde el computador 23.45.122.50 hacia el computador 23.45.121.33 usando un directorio de encolamiento /home/aft/queue1 localizado en el hub:

[hub-a2a:my-transfer]
src-host=23.45.122.50
src-port=14551
queue-dir=/home/aft/queue1
dst-host=23.45.121.33
dst-port=21001

Se proporcionan las siguientes directivas:

src-host

Nombre de host o dirección IP del "agente fuente" a donde el hub intentará extraer archivos. Válido para los modos "GET" y "A2A". Si no está presente se asume que el agente fuente iniciará la conexión.

src-port

Número de puerto de el agente fuente a fin de establecer la comunicación.

dst-dir

Directorio de destino final para los archivos en el hub. Válido sólo para transferencias GET. AFT no crea ese directorio por lo que debe ser creado por el usuario.

Ejemplo:

# una transferencia GET: extraer archivos cada 12 horas
[hub-get:t2]
src-host=fx8320.ana.com.uy
src-port=41232
src-connect-check=delay:43200
dst-dir=/tmp/hub-destination
dst-host

Nombre de host o dirección IP del "agente destinatario" a donde el hub intentará enviar archivos. Válido para los modos "PUT" y "A2A". Si no está presente, entonces se asume que el agente destinatario iniciará la conexión.

dst-port

Número de puerto de el agente destinatario a fin de establecer la comunicación.

src-dir

Directorio desde donde los archivos serán extraídos. Sólo válido para transferencias en modo PUT.

Ejemplo:

# una transferencia PUT
[hub-put:t1]
src-dir=/tmp/hub-dir
dst-host=fx8320
dst-port=55123
queue-dir

Directorio en el computador hub para almacenamiento temporal (encolamiento) de los archivos extraídos previamente a ser enviados a su destino final. Válido sólo para el modo "A2A". El directorio debe existir (AFT no lo crea) y debe permitir la creación de archivos. Los directorios de encolamiento no pueden ser compartidos por dos o más transferencias configuradas.

no-change-check-seconds

Cuando un archivo va a ser leído, AFT verifica su hora de modificación para evitar la transmisión de un archivo incompleto que está siendo escrito. Esta directiva configura la "antigüedad" (en segundos) que debe tener el archivo para garantizar razonablemente el término del proceso de escritura. Cuando el archivo es "muy nuevo" entonces se realizará otro intento tras un número de segundos definido en la directiva op-timeout-seconds. Un valor cero deshabilita esta verificación. Sólo es válido para el modo "PUT".

no-change-retry-times

Cuántas veces reintentar la extracción si el archivo es "muy nuevo" en función del valor de no-change-check-seconds.

src-connect-check

Cuándo conectarse al "agente fuente" para extraer archivos pendientes. Puede tomar las formas delay:#, cron:expr y none, siguiendo la explicación de la directiva hub-connect-check.

files

Qué archivos serán extraídos y transferidos. Los formatos válidos son all, list:name,…​, ereg:expr, y tereg:expr; por omisión es all (todos los archivos en el directorio.) El modo list permite una lista de archivos separada por comas conteniendo los nombres de archivos a extraer; el modo ereg es usado para especificar una expresión regular a fin de indicar los nombres de los archivos de interés. Finalmente, el modo tereg es un proceso en dos pasos donde las subexpresiones encerradas entre %…​% se usan como formateadores de la clase Java SimpleDateFormat con la fecha y hora actual (a fin de construir un patrón generado en función del tiempo) y finalmente el resultado se usa como expresión regular (como en el caso ereg.) Dos signos de porcentaje consecutivo se usan para generar un único signo de porcentaje.

Ejemplo:

# solo extrraer los tres archivos especificados
[hub-get:t2]
src-host=fx8320.ana.com.uy
src-port=41232
dst-dir=/tmp/hub-destination
files=list:file2.txt,file3.txt,file4.txt

El mismo resultado se puede obtener con:

# solo extrraer los tres archivos especificados
[hub-get:t2]
src-host=fx8320.ana.com.uy
src-port=41232
dst-dir=/tmp/hub-destination
files=ereg:file[234]\.txt

Una expresión relacionada al tiempo usando el formato treg::

# solo extraer archivos para hoy
[hub-get:t2]
src-host=fx8320.ana.com.uy
src-port=41232
dst-dir=/tmp/hub-destination
files=tereg:%yyyyMMdd%\.txt

Las formas list:, ereg: y tereg: también admiten una forma negada con los prefijos correspondientes !list:, !ereg: y !tereg:. Por ejemplo:

# extraer cualquier archivo YYYYMMDD.txt excepto el de hoy
[hub-get:t2]
src-host=fx8320.ana.com.uy
src-port=41232
dst-dir=/tmp/hub-destination
files=!tereg:%yyyyMMdd%\.txt
recursive

Indica si se debe transferir los archivos del directorio de origen conjuntamente con el contenido de sus subdirectorios. Por omisión es false. Esta es una directiva experimental por lo que debe ser utilizada con cuidado.

dst-connect-check

Cuándo intentar conectar para enviar archivos a un agente destinatario. Ver src-connect-check para su sintaxis.

dst-connect-after-transfer

En modo A2A, si se debe intentar conectar al agente de destino inmediatamente tras la extracción del agente fuente, adicionalmente al régimen programado en dst-connect-check. Fijar a true o false. Por omisión es false.

src-exec-after-transfer

Tras una extracción exitosa de un archivo desde un agente fuente, se puede ejecutar un comando con esta directva. El nombre de archivo es proporcionado como único argumento. Válido para los modos "GET" y "A2A".

dst-exec-after-transfer

Similar al anterior pero para archivos recién enviados a su destino. Válido para modos "PUT" y "A2A".

cleanup-mode

Qué hacer con el archivo fuente tras su transferencia exitosa. Las opciones válidas son remove (eliminar), truncate (eliminar contenido pero el archivo permanece vacío), y none (no hacer nada); por omisión es remove.

Note: esta acción se ejecuta después de la ejecución de un comando configurado si lo hubiera.

Cuidado: la opción por omisión remove puede ser inesperada para algunos usuarios. La justificación es que la información no se ha perdido puesto que la transferencia ha sido realizada efectivamente.

compress-mode

Modo de operación de la compresión. Los modos válidos son:

  1. none para deshabilitar la compresión

  2. network comprimir datos "en tránsito" para reducir consumo de la red

  3. gzip comprimir datos "en tránsito" y almacenar los archivos en formato comprimido Gzip

Por omisión es network. El modo none es útil cuando se transmiten archivos ya comprimidos o cualquier archivo no compresible (como aquellos que están encriptados.) Así se evita el consumo de CPU requerido para las operaciones de compresión y descompresión.

En transferencias GET, este parámetro es usado por los agentes fuente.

compress-level

Un entero en el rango 1-9, señalando 1=mejor velocidad, 9=mejor compresión. Por omisión es 1.

En transferencias GET, este parámetro es usado por los agentes fuente.

write-mode

Las opciones válidas son simple y tmp. El modo simple simplemente abre el archivo para escritura con su nombre de archivo correspondiente y graba los datos en tanto éstos son transferidos. El modo tmp abre un archivo temporal (en el mismo directorio de destino) y sólo cuando todos el contenido ha sido transferido, renombra el temporal al nombre final. Por omisión es simple.

op-timeout-seconds

El timeout para las respuestas del agente. Por omisión es 15 segundos. En redes muy congestionadas este parámetro puede requerir ser incrementado.

Cuando una transferencia será iniciada por un agente, el host src/dst y el puerto no deben ser configurados. Además, la directiva de tiempo para intento de conexión debe ser fijada a none. Por ejemplo, en una transferencia A2A donde los datos se extraen de un agente que se conecta al hub, y luego son enviados a un agente que espera la conexión del hub, la configuración del hub será:

# extraer de agente cliente y enviar hacia agente servidor tcp
[hub]
hub-port = 5122

[hub-a2a:the-transfer]
src-connect-check=none
queue-dir=/home/aft/queue4
dst-host=fx8320
dst-port=55123
# try to send from the hour 9AM to 5PM only working weekdays
dst-connect-check=cron:0 0 9-17 * * MON-FRI
rename-destination

Válido para [hub-get]. Mismo comportamiento que en el caso [agent-dst].

read-buffer-size

El tamaño del buffer de lectura de archivos en bytes. Por omisión es 131072 (128 kilobytes.) La calibración de este parámetro puede incrementar la tasa de transferencia en algunas infraestructuras de red (el usuario debe realizar las pruebas correspondientes.)

En las transferencias GET, este parámetro es usado por los agentes fuente.

Configuración TLS

Por omisión AFT usa un certificado autofirmado incorporado para las transferencias de archivos, lo que proporciona encriptación de datos pero no previene a actores no autenticados (que también disponen de AFT) la interacción con los nodos participantes.

AFT permite configurar "autenticación mútua" de las interconexiones a partir de certificados digitales que pueden ser creados con herramientas third-party o mediante el utilitario incluido en la distribución de AFT aft-cert.

El utilitario permite la creación de una autoridad ceritificadora autofirmada (CA) a fin de emitir certificados para los nodos participantes. El certificado raíz debe ser transferido a los nodos participantes y referenciado con la directiva tls-root-cert en la sección especial [tls].

Cada nodo debe tener un certificado TLS y sus correpondientes llaves privadas, referenciados con las directivas tls-node-cert y tls-node-pk de la mencionada sección. Una configuración típica luce así:

[tls]
tls-root-cert=etc/root-ca.crt
tls-node-cert=etc/NODE1.crt
tls-node-pk=etc/NODE1.key

Notar que la llave privada no debe estar encriptada (de lo contrario se requeriría una contraseña en el archivo de configuración lo que anula el propósito original.) La llave privada debe estar protegida mediante permisos del sistema operativo.

tls-enabled-protocols

A comma separated list of TLS protocols which will be enabled. This may be used to force a protocol level range. For example:

[tls]
tls-enabled-protocols=TLSv1.1,TLSv1.2
tls-enabled-cipher-suites

A comma separated list of TLS "cipher suites" which will be enabled. This may be used to force some encryption algorithms and parameters. Usually, this parameter must be configured in both peers. For example:

[tls]
tls-enabled-cipher-suites=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

Autenticación Mútua

Los nodos pueden ser configurados para autenticar el nodo opuesto de la conexión mediante la especificación del "common name" (CN) del nodo. La directiva tls-peer es usada con ese propósito.

Notar que la autenticación del nodo opuesto es opcional, pero muy recomendable.

Para nodos con transferencias en modo cliente TCP, la autenticación del nodo opuesto debe ser configurada por cada transferencia (hub o agente.) Por ejemplo:

# el nodo opuesto (agente) debe presentar un certificado valido con CN=FX8320
[hub-get:t2]
src-host=fx8320.ana.com.uy
src-port=41232
dst-dir=/tmp/hub-destination
files=ereg:file[234]\.txt
tls-peer=FX8320

Para nodos con transferencias en modo servidor TCP, la autenticación del nodo opuesto debe ser configurada junto con puerto de escucha. Por ejemplo:

# el nodo opuesto (agente) debe presentar un ceriticado vaido con CN=NODE-777
[hub]
hub-port = 6001
tls-peer=NODE-777

Esto es, los nodos opuestos no se pueden configurar por cada transferencia. El motivo es que el "handshake" TLS y la autenticación ocurren antes de la selección de la transferncia a ser ejecutada.

Desabilitar TLS

TLS puede ser deshabilitado para todo el nodo mediante la directiva tls-disabled fijada a true (por omisión es false.)

# deshabilitar TLS en el nodo
[tls]
tls-disabled=true