Bareos (Backup Archiving Recovery Open Sourced) es una solución de software de código abierto diseñada para la gestión de backups, archivado y recuperación de datos. Entre sus funcionalidades Bareos permite realizar backups completos, incrementales y diferenciales en sistemas locales o remotos, admite varias bases de datos y sistemas operativos.
En este artÃculo se intalará Bareos bajo FreeBSD(14.1) en una jail Bastille y Linux(Ubuntu-24.04) en un contenedor LXD.
Conceptos y componentes:
Antes de empezar con la configuración debemos tener bien claros algunos conceptos clave.
Conceptos:
- Job: Trabajo de backup/restore a realizar.
- JobDef: Plantillas con parámetros base, si es necesario en el job se pueden sobreescribir.
- FileSet: Plantilla de configuración en la que se indican los ficheros a backupear, permite incluir directorios y excluir ciertos ficheros o subdirectorios.
- Schedule: Cuando deben hacerse los backups.
- Device: Disco, cinta, S3, GlusterFS donde se guardan los backups.
- Pool: Grupo de volúmenes.
- Volumen: Fichero en el disco, cinta, S3, GlusterFS donde se guardarán los datos de los backups.
Componentes:
- Director: Se encarga de gestionar los jobs de los backups y las conexiones de los clientes a los storage daemons.
- File daemon: Software instalado en el cliente que hará el backup.
- Storage daemon: Servicio instalado donde haya capacidad de almacenamiento.
- Bconsole: Interfaz CLI de administración del director.
- Web-UI: Interfaz web de administración del director.
- Tray monitor: Herramienta gráfica para monitorear el director y los storages.
Tipos de backup:
- Full: Full.
- Incremental: Datos que han cambiado desde el último backup, ya sea un Full Backup o un Incremental Backup.
- Differential: Datos que han cambiado desde el último Full Backup.
En el siguiente diagrama podemos ver de forma rápida las interacciones entre los componentes de Bareos:
Escenario FreeBSD/Linux:
FreeBSD:
Si estamos instalando Bareos bajo una jail de FreeBSD debemos tener en cuenta que internamente instala PostgreSQL el cual requiere de acceso a sysvipc.
Si la jail no tiene acceso a sysvipc obtendremos el siguiente error:
running bootstrap script ... 2024-10-22 20:11:16.834 CEST [23722] FATAL: could not create shared memory segment: Function not implemented
En mi caso se trata de una jail mediante Bastille .
Los pasos son: generar la jail y realizar la configuración básica del sistema mediante un template de Bastille propio .
bastille create -T BareosServer 14.1-RELEASE 192.168.69.30 nfe0
bastille template BareosServer datadyne.alfaexploit.com/bastille-basicconfiguration
Permitimos el acceso a sysvipc por jail, también se puede permitir de forma global en el host padre para todas las jails pero es preferible ser mas granular:
bastille config BareosServer set sysvmsg=new
bastille config BareosServer set sysvsem=new
bastille config BareosServer set sysvshm=new
bastille stop BareosServer
bastille start BareosServer
NOTA: No debemos utilizar allow.sysvipc ya que se considera deprecated y otorga mas permisos de los estrictamente necesarios.
Creamos también el cliente:
bastille create -T BareosClient 14.1-RELEASE 192.168.69.31 nfe0
bastille template BareosClient datadyne.alfaexploit.com/bastille-basicconfiguration
Linux:
En cuanto a Linux vamos a montarlo sobre un contenedor LXD que no requiere acceso a ningún recurso en particular.
lxc launch ubuntu:noble/amd64 sys-bareos-server
Creamos también el cliente:
lxc launch ubuntu:noble/amd64 sys-bareos-client
Bareos server:
El primer paso es añadir los repositorios oficiales de Bareos:
Bareos todavÃa no tiene versión para 14.1 asà que instalamos la versión para 14.0
wget https://download.bareos.org/current/FreeBSD_14.0/add_bareos_repositories.sh
sh ./add_bareos_repositories.sh
wget https://download.bareos.org/current/xUbuntu_24.04/add_bareos_repositories.sh
chmod 700 add_bareos_repositories.sh
./add_bareos_repositories.sh
apt update
Procedemos con la instalación de PostgreSQL ya que es un requisito de Bareos, además en Linux si no tiene instalado PostgreSQL antes de instalar Bareos, el asistente de dbconfig dá un error al intentar conectar contra la DB:
Instalamos la versión 16 de PostgreSQL ya que bareos-webui precisa de esta versión en concreto:
pkg install postgresql16-server
Habilitamos, configuramos y arrancamos el servicio de PostgreSQL:
sysrc postgresql_enable=yes
service postgresql initdb
service postgresql start
apt install postgresql
Ahora ya podemos instalar Bareos:
pkg install bareos.com-director bareos.com-storage bareos.com-filedaemon bareos.com-database-postgresql bareos.com-bconsole
Importamos la base de datos, las tablas y los permisos necesarios para que Bareos funcione:
su postgres -c /usr/local/lib/bareos/scripts/create_bareos_database
su postgres -c /usr/local/lib/bareos/scripts/make_bareos_tables
su postgres -c /usr/local/lib/bareos/scripts/grant_bareos_privileges
apt install bareos
Pedirá config de Postfix: Internet Site/$HOSTNAME
Pedirá config de la DB PostgreSQL:
Configure database for bareos-database-common with dbconfig-common? Yes
Host name of the PostgreSQL database server for bareos-database-common: localhost
PostgreSQL application password for bareos-database-common: POSTGRESQL_BAREOS_PASSWORD
NOTA: En la instalación de Bareos en FreeBSD no ha pedido password de acceso a PostgreSQL ya que por defecto conecta por socket unix.
El director debe saber donde y como conectar con el storage daemon, el parámetro Address
debe ser un FQDN o IP. Además el storage daemon debe tener el mismo password para permitir la conexión desde el director.
vi /usr/local/etc/bareos/bareos-dir.d/storage/File.conf
Storage {
Name = File
#Address = Bareos # N.B. Use a fully qualified name here (do not use "localhost" here).
Address = STORAGE_DAEMON_SERVER_IP # N.B. Use a fully qualified name here (do not use "localhost" here).
Password = "STORAGE_DAEMON_PASSWORD"
Device = FileStorage
Media Type = File
}
vi /usr/local/etc/bareos/bareos-sd.d/director/bareos-dir.conf
Director {
Name = bareos-dir
Password = "STORAGE_DAEMON_PASSWORD"
Description = "Director, who is permitted to contact this storage daemon."
}
Habilitamos los servicios relacionados con Bareos:
sysrc bareosfd_enable=YES
sysrc bareosdir_enable=YES
sysrc bareossd_enable=YES
Arrancamos los servicios relacionados con Bareos:
service bareos-fd start
service bareos-dir start
service bareos-sd start
vi /etc/bareos/bareos-dir.d/storage/File.conf
Storage {
Name = File
#Address = sys-bareos-server # N.B. Use a fully qualified name here (do not use "localhost" here).
Address = STORAGE_DAEMON_SERVER_IP # N.B. Use a fully qualified name here (do not use "localhost" here).
Password = "STORAGE_DAEMON_PASSWORD"
Device = FileStorage
Media Type = File
}
vi /etc/bareos/bareos-sd.d/director/bareos-dir.conf
Director {
Name = bareos-dir
Password = "STORAGE_DAEMON_PASSWORD"
Description = "Director, who is permitted to contact this storage daemon."
}
Reiniciamos el director y el storage daemon:
systemctl restart bareos-dir bareos-sd
Cada uno de los componentes de Bareos es configurado bajo un directorio especÃfico con subdirectorios para cada funcionalidad:
-
Director:
/usr/local/etc/bareos/bareos-dir.d/
- catalog: Configuración de conexión a la base de datos donde está el catálogo.
- client: Configuración de los clientes que realizarán backups.
- console: Configuración de los usuarios que administrarán el director mediante bconsole o webui.
- counter: Se utiliza para almacenar configuraciones de contadores en Bareos. Los contadores generan números secuenciales que se pueden usar para numerar volúmenes, trabajos de respaldo u otros recursos que requieren identificadores únicos.
- director: Configuración del director, password de acceso a este y demás.
- fileset: Plantillas de los ficheros a backupear.
- job: Configuración de los backups/restores vinculados a clientes.
- jobdefs: Plantillas con parámetros base, si es necesario en el job se pueden sobreescribir.
- messages: Configuración sobre como deben notificarse los mensajes de bareos.
- pool: Definición de los pools, con sus parámetros de retención.
- profile: Perfiles donde se definen ACLs de acceso por usuario(bconsole/webui).
- schedule: Configuración de rangos temporales donde se asocian tiempos con tipos de backups(Full/Differential/Incremental).
- storage: Parámetros de conexión contra el storage daemon.
-
File daemon:
/usr/local/etc/bareos/bareos-fd.d
- client: Configuración del cliente, parámetros de concurrencia, cuando hace el backup, uso de plugins y demás.
- director: Configuración de conexión contra el director, los datos deben de coincidir con los del director: /usr/local/etc/bareos/bareos-dir.d/client/CLIENT_NAME.conf.
- messages: Configuración sobre como deben notificarse los mensajes de bareos.
-
Storage daemon:
/usr/local/etc/bareos/bareos-sd.d
- autochanger: Utilizado para definir y configurar dispositivos autochanger (cambiadores automáticos de medios), que son sistemas de hardware diseñados para gestionar de manera automática el intercambio de medios de almacenamiento, como cintas en una librerÃa de cintas o dispositivos virtuales en almacenamiento basado en disco.
- device: Definición del disco, cinta, S3, GlusterFS donde se guardarán los backups.
- director: Configuración de conexión contra el director, los datos deben de coincidir con los del director: /usr/local/etc/bareos/bareos-dir.d/storage/File.conf
- messages: Configuración sobre como deben notificarse los mensajes de bareos.
- ndmp: Configuración de NDMP (Network Data Management Protocol), que es un protocolo diseñado para gestionar el respaldo y la restauración de datos a través de la red, especialmente en dispositivos de almacenamiento masivo como NAS.
- storage: Configuración del storage daemon, parámetros de concurrencia cuando hace el backup, uso de plugins y demás.
-
Bconsole:
/usr/local/etc/bareos/bconsole.conf
: Datos de conexión que el bconsole utilizará para conectar contra el director, los datos deben de coincidir con los del director: /usr/local/etc/bareos/bareos-dir.d/director/bareos-dir.conf
-
Director:
/etc/bareos/bareos-dir.d
- catalog: Configuración de conexión a la base de datos donde está el catálogo.
- client: Configuración de los clientes que realizarán backups.
- console: Configuración de los usuarios que administrarán el director mediante bconsole o webui.
- director: Configuración del director, password de acceso a este y demás.
- fileset: Plantillas de los ficheros a backupear.
- job: Configuración de los backups/restores vinculados a clientes.
- jobdefs: Plantillas con parámetros base, si es necesario en el job se pueden sobreescribir.
- messages: Configuración sobre como deben notificarse los mensajes de bareos.
- pool: Definición de los pools, con sus parámetros de retención.
- profile: Perfiles donde se definen ACLs de acceso por usuario(bconsole/webui).
- schedule: Configuración de rangos temporales donde se asocian tiempos con tipos de backups(Full/Differential/Incremental).
- storage: Parámetros de conexión contra el storage daemon.
- user: Directorio para configurar usuarios adicionales que precisen de acceso al director(parecido al directorio console), no suele utilizarse.
-
File daemon:
/etc/bareos/bareos-fd.d
- client: Configuración del cliente, parámetros de concurrencia, cuando hace el backup, uso de plugins y demás.
- director: Configuración de conexión contra el director, los datos deben de coincidir con los del director: /etc/bareos/bareos-dir.d/client/CLIENT_NAME.conf.
- messages: Configuración sobre como deben notificarse los mensajes de bareos.
-
Storage daemon:
/etc/bareos/bareos-sd.d
- device: Definición del disco, cinta, S3, GlusterFS donde se guardarán los backups.
- director: Configuración de conexión contra el director, los datos deben de coincidir con los del director: /etc/bareos/bareos-dir.d/storage/File.conf
- messages: Configuración sobre como deben notificarse los mensajes de bareos.
- storage: Configuración del storage daemon, parámetros de concurrencia cuando hace el backup, uso de plugins y demás.
-
Bconsole:
/etc/bareos/bconsole.conf
: Datos de conexión que el bconsole utilizará para conectar contra el director, los datos deben de coincidir con los del director: /etc/bareos/bareos-dir.d/director/bareos-dir.conf
-
Exportaciones:
/etc/bareos/bareos-dir-export
: Configuraciones actuales del Bareos Director exportadas en archivos individuales. Esto permite una forma sencilla de realizar copias de seguridad de las configuraciones de Bareos o de migrarlas a otro sistema.
Por defecto los volúmenes se crearán en /var/lib/bareos/storage tal como está definido en:
/usr/local/etc/bareos/bareos-sd.d/device/FileStorage.conf
/etc/bareos/bareos-sd.d/device/FileStorage.conf
Archive Device = /var/lib/bareos/storage
Las retenciones, reciclado y prune de datos de Bareos al principio pueden parecer un auténtico galimatÃas por lo que voy a intentar arrojar luz sobre esto de la mejor manera posible:
- Retention: Hay varios parámetros relacionados con las retenciones.
- Job Retention: Cuando se ejecuta un job(backup) se guarda un registro de dicha ejecución, este parámetro indica cuanto tiempo se mantendrá dicho registro en el catálogo. Cuando se supera la retención los datos de dicho job no se eliminan, tan solo se eliminan las entradas del catálogo, por lo tanto no podremos hacer búsquedas ni realizar ninguna operación sobre este mediante bconsole o la interfaz web. Pero debemos tener en cuenta que los datos siguen estando en los volúmenes junto con sus metadatos siendo recuperables y pudiendo ser reinsertados en el catálogo mediante un
scan
. - File Retention: Exactamente igual que el
Job Retention
pero esta vez no aplica al registro de la ejecución del job si no al resgistro de los ficheros backupeados por el job, si se supera el periodo de retención ya no se podrán hacer búsquedas de los ficheros backupeados en un job a no ser que se escanee el volúmen que contenga dicha información. - Volume Retention: Define cuanto tiempo un volumen se mantiene antes de ser reciclado, después de que el perÃodo de retención expire el volumen se marcará como reciclable(purged), lo que significa que podrá ser sobrescrito por nuevos backup. Que un volumen sea marcado como reciclable no implica un reciclado inmediato ni una liberación de espacio.
- Job Retention: Cuando se ejecuta un job(backup) se guarda un registro de dicha ejecución, este parámetro indica cuanto tiempo se mantendrá dicho registro en el catálogo. Cuando se supera la retención los datos de dicho job no se eliminan, tan solo se eliminan las entradas del catálogo, por lo tanto no podremos hacer búsquedas ni realizar ninguna operación sobre este mediante bconsole o la interfaz web. Pero debemos tener en cuenta que los datos siguen estando en los volúmenes junto con sus metadatos siendo recuperables y pudiendo ser reinsertados en el catálogo mediante un
Normalmente los únicos parámetros que vamos a tocar de los pools son:
- Volume Retention = 365 days -> Retención de los volúmenes.
- Auto Prune = yes -> Habilita el prune de los volúmenes.
- Recycle = yes -> Habilita el reciclado de los volúmenes.
Bareos Web-ui:
La interfaz web nos facilitará las tareas de administración ya que es mas sencillo ejecutar jobs desde esta que desde la bconsole.
Instalamos Bareos Web-ui:
pkg install bareos-webui
pkg install nginx php82
cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini
vi /usr/local/etc/php.ini
date.timezone = Europe/Madrid
vi /usr/local/etc/nginx/nginx.conf
...
http {
include mime.types;
default_type application/octet-stream;
include bareos.conf;
...
vi /usr/local/etc/nginx/bareos.conf
server {
listen 9100;
server_name _;
root /usr/local/www/bareos/public;
location / {
index index.php;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_keep_conn on;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass PHP_FPM_IP:9000;
}
}
chown -R www:www /usr/local/www/bareos/public
sysrc php_fpm_enable=YES
sysrc nginx_enable=YES
service php_fpm start
service nginx start
apt install bareos-webui
a2enmod proxy_fcgi setenvif
a2enconf php8.3-fpm
systemctl reload apache2
NOTA: En Linux la interfaz web queda funcionando con Apache porque es el servidor por defecto al instalar la interfaz, no se hace por nada especial, podrÃa funcionar igualmente bajo Nginx tal como hemos hecho en FreeBSD.
Creamos el usuario que la interfaz web utilizará para acceder a la consola del director:
vi /usr/local/etc/bareos/bareos-dir.d/console/admin.conf
#
# Restricted console used by bareos-webui
#
Console {
Name = admin
Password = "PASSWORD"
Profile = "webui-admin"
# As php does not support TLS-PSK,
# and the director has TLS enabled by default,
# we need to either disable TLS or setup
# TLS with certificates.
#
# For testing purposes we disable it here
TLS Enable = No
}
service bareos-dir restart
bconsole
reload
configure add console name=admin password=PASSWORD profile=webui-admin tlsenable=false
systemctl restart bareos-dir
NOTA: Editar el fichero /etc/bareos/bareos-dir.d/console/admin.conf parece no funcionar, en cambio por bconsole, si.
Ya podremos acceder desde el navegador:
http://DIRECTOR_IP:9100
http://DIRECTOR_IP/bareos-webui
admin / PASSWORD
Veremos una interfaz como esta:
Bareos client:
Para instalar el cliente(File daemon) debemos añadir los mismos repositorios que utilizamos para instalar el servidor de Bareos.
Bareos todavÃa no tiene versión para 14.1 asà que instalamos la versión para 14.0
wget https://download.bareos.org/current/FreeBSD_14.0/add_bareos_repositories.sh
sh ./add_bareos_repositories.sh
wget https://download.bareos.org/current/xUbuntu_24.04/add_bareos_repositories.sh
chmod 700 add_bareos_repositories.sh
./add_bareos_repositories.sh
apt update
Instalamos el cliente(File daemon):
pkg install bareos.com-filedaemon
Habilitamos el servicio y lo arrancamos:
sysrc bareosfd_enable=YES
service bareos-fd start
apt install bareos-filedaemon
Conmfiguramos los parámetros de acceso del director al file daemon:
vi /usr/local/etc/bareos/bareos-fd.d/director/bareos-dir.conf
vi /etc/bareos/bareos-fd.d/director/bareos-dir.conf
Director {
Name = bareos-dir
Password = "DIRECTOR_SECRET"
Description = "Allow the configured Director to access this file daemon."
}
NOTA: No es necesario configurar la IP del director ya que es el director el que conectará contra el file daemon, si coincide el password, la ejecución seguirá adelante.
Reiniciamos el file daemon:
service bareos-fd restart
systemctl restart bareos-fd
Realizamos la configuración de la contraparte, el director:
vi /usr/local/etc/bareos/bareos-dir.d/client/CLIENT_NAME-fd.conf
vi /etc/bareos/bareos-dir.d/client/CLIENT_NAME-fd.conf
Client {
Name = CLIENT_NAME-fd
Address = CLIENT_FQDN(or IP)
Password = "DIRECTOR_SECRET"
}
Reiniciamos el director:
service bareos-dir restart
systemctl restart bareos-dir
Añadimos un job:
bconsole
reload
configure add job name=CLIENT_NAME-job client=CLIENT_NAME-fd jobdefs=DefaultJob
El director de Bareos por defecto trae un FileSet que backupea los ficheros o directorios indicados por File
:
cat /usr/local/etc/bareos/bareos-dir.d/fileset/SelfTest.conf
FileSet {
Name = "SelfTest"
Description = "fileset just to backup some files for selftest"
Include {
Options {
Signature = XXH128 # calculate checksum per file
}
File = "/usr/local/sbin"
}
}
cat /etc/bareos/bareos-dir.d/fileset/SelfTest.conf
FileSet {
Name = "SelfTest"
Description = "fileset just to backup some files for selftest"
Include {
Options {
Signature = XXH128 # calculate checksum per file
}
File = "/usr/sbin"
}
}
Vamos a ejecutar el DefaultJob que tiene ese FileSet configurado:
cat /usr/local/etc/bareos/bareos-dir.d/jobdefs/DefaultJob.conf
JobDefs {
Name = "DefaultJob"
Type = Backup
Level = Incremental
Client = bareos-fd
FileSet = "SelfTest" # selftest fileset
Schedule = "WeeklyCycle"
Storage = File
Messages = Standard
Pool = Incremental
Priority = 10
Write Bootstrap = "/var/lib/bareos/%c.bsr"
Full Backup Pool = Full # write Full Backups into "Full" Pool
Differential Backup Pool = Differential # write Diff Backups into "Differential" Pool
Incremental Backup Pool = Incremental # write Incr Backups into "Incremental" Pool
}
cat /etc/bareos/bareos-dir.d/jobdefs/DefaultJob.conf
JobDefs {
Name = "DefaultJob"
Type = Backup
Level = Incremental
Client = bareos-fd
FileSet = "SelfTest" # selftest fileset
Schedule = "WeeklyCycle"
Storage = File
Messages = Standard
Pool = Incremental
Priority = 10
Write Bootstrap = "/var/lib/bareos/%c.bsr"
Full Backup Pool = Full # write Full Backups into "Full" Pool
Differential Backup Pool = Differential # write Diff Backups into "Differential" Pool
Incremental Backup Pool = Incremental # write Incr Backups into "Incremental" Pool
}
Para ello accedemos a la interfaz web de Bareos: Jobs
Jobs -> Run:
Rellenamos los campos haciendo click en los desplegables:
Le damos a Submit y veremos esta interfaz, donde podemos clickar sobre la lupita de la derecha:
Donde podremos ver el estado del backup:
Si queremos restaurar algún fichero debemos seguir los siguientes pasos: Restore
En el menú de la izquierda debemos seleccionar el Client y el backup a restaurar, es muy important deshabilitar la opción “Merge all client filesets” ya que si no lo hacemos el árbol de ficheros a restaurar de la derecha será una vista de la combinación de todos los backups de este cliente, nosotros solo queremos los ficheros del backup indicado. Seleccionamos los ficheros a restaurar en la lista de la derecha y le damos a Restore:
Aparecerá el siguiente bocadillo donde nos informa que un job va a ser encolado, le damos a Ok.
Aparecerá el siguiente bocadillo informativo donde le damos a Close.
Podemos ir a “Jobs” y ver el estado del restore:
Y en el servidor podemos ver que el fichero seleccionado ha sido restaurado en el path indicado:
ls -la /tmp/bareos-restores/usr/local/sbin/pkg
-rwxr-xr-x 1 root wheel 4040720 Oct 1 03:10 /tmp/bareos-restores/usr/local/sbin/pkg
Debug:
Algunos comandos útiles para debugear desde la bconsole son:
status
status dir
status jobid=nn
list pools
list volumes
list jobs
list jobid=XX
list jobtotals
messages
Si necesitamos ver que parámetros tenÃa configurados el FileSet del job cuando se backupeó:
bconsole
sqlquery
SELECT Job.JobId, Job.Name, FileSet.FileSet, FileSet.FileSetId FROM Job, FileSet WHERE Job.FileSetId = FileSet.FileSetId AND Job.JobId = XX;
list filesets
list files jobid=XX
Podemos exportar la configuración para comprobar que todo está en orden:
bareos-dir --export-config
bareos-fd --export-config
bareos-sd --export-config
Los procesos se pueden lanzar en foreground con el debug al máximo:
bareos-dir -f -d 100
bareos-fd -f -d 100
SystemD a veces hace el monguer si se reinicia el servicio muchas veces, deshabilitándolo y haciéndonos perder el tiempo porque pensamos que algo que hemos tocado falla, para quitarle la tonterÃa:
systemctl reset-failed bareos-director.service
Por supuesto siempre podremos consultar los logs de Bareos:
tail -f /var/log/bareos/bareos.log
tail -f /var/log/bareos/bareos-audit.log
O los logs del sistema:
tail -f /var/log/messages
tail -f /var/log/syslog
Si el password de conexión del director al cliente o del director al storage daemon no coinciden saca este error sin sentido sobre SSL:
7 2024-10-23 21:25:09 bareos-dir JobId 6: Fatal error: No Job status returned from FD.
6 2024-10-23 21:24:33 bareos-dir JobId 6: TLS negotiation failed (while probing client protocol)
5 2024-10-23 21:24:33 bareos-dir JobId 6: Fatal error: Connect failure: ERR=error:0A000417:SSL routines::sslv3 alert illegal parameter