Intro a Appjail
Es una tool desarrollada por @DtxdF directamente de la mismísima patria 🇻🇪, dicha tool nos permite administrar nuestros jail en FreeBSD, con una cantidad de settings bastante amplia, e incluso fue inspirado en docker.
Esta es una lista donde se comparan las otras tools para administrar jails donde vemos que Appjail ofrece sus ventajas sin quedarse atrás.
Instalación
Con pkg install -y appjail
la instalamos, pero si se quiere tener la versón mas actual debemos compilar desde el repo de github
como lo indica la documentación.
-
getting-started/ importante hacer
appjail fetch
para extraer componentes para la creación de jails.
Todas las imagenes actuales de AppJail
Habilitando column y printenv
En XigmaNAS, necesitamos printenv
pero por alguna razón no esta, ya es cosa de los devs por diseño.
which printenv
servernas: appjail# which printenv
printenv: shell built-in command.
Listando nuestros jails
servernas: ~# appjail jail list (1)
/usr/local/bin/appjail: column: not found
1 | Al intentar listar nuestros jails tenemos este error |
Lo resolvemos con esto:
cd /tmp
mkdir -p repair
cd ./repair/
fetch https://download.freebsd.org/releases/amd64/13.2-RELEASE/base.txz
tar -xvf base.txz ./usr/bin/column ./usr/bin/mkfifo ./usr/bin/printenv
cp -i usr/bin/column /usr/bin/column (1)
cp -i usr/bin/mkfifo /usr/bin/mkfifo (2)
cp -i usr/bin/printenv /usr/bin/printenv (3)
1 | Habilitando column |
2 | Habilitando mkfifo |
3 | Habilitando printenv |
Configurando el Packet Filter
Incialmente con xigmanas tenemos este error
servernas: ~# service pf restart
Disabling pf.
Enabling pfpfctl: : No such file or directory
pfctl: cannot open the main config file!: No such file or directory
pfctl: Syntax error in config file: pf rules not loaded
/etc/rc.d/pf: WARNING: Unable to load .
sysrc pf_enable="YES"
sysrc pflog_enable="YES"
cat << "EOF" >> /etc/pf.conf
nat-anchor 'appjail-nat/jail/*'
nat-anchor "appjail-nat/network/*"
rdr-anchor "appjail-rdr/*"
EOF
service pf restart
service pflog restart
Y lo resolvemos con:
sysrc pf_rules=/etc/pf.conf
service pf restart
Disabling pf.
Enabling pf. (1)
1 | Esta ok. |
Esto también es importante
sysrc gateway_enable="YES"
sysctl net.inet.ip.forwarding=1
Ajustando el resolv.conf
Tenemos en el jail creado por appjail un enlace simbólico al /etc/resolv.conf
pero incorrecto.
Entonces debemos borrarle y creamos de nuevo con los dns correctos, para lograr tener internet en el.
La mejor manera es editar directamente el fichero appjail.conf antes de crear el jail dicho fichero esta en nuestro host y de aquí se copiará al jail al crearse. |
DEFAULT_RESOLV_CONF=/usr/local/etc/appjail/resolv.conf (1)
1 | Aquí en esta ruta creamos el fichero resolv.conf con los dns necesarios |
Mi fichero actual esta así luego de configurarlo correctamente:
servernas: ~# appjail cmd jexec nextcloud cat /etc/resolv.conf
domain local
nameserver 1.1.1.1
nameserver 1.0.0.1
existe una manera más eficiente de crearlo con el MakeJail muy parecido al dockerfile
|
Configurando el appjail.conf
/usr/local/etc/appjail/appjail.conf
EXT_IF=lagg0 (1)
ON_IF=$EXT_IF
FREEBSD_VERSION=13.2-RELEASE (2)
FREEBSD_ARCH=amd64
IMAGE_ARCH=amd64
SHORTEN_DOMAIN_NAMES=1
# Descomentalo si usas ZFS y deseas que AppJail tome ventaja de él:
ENABLE_ZFS=1
DEFAULT_RESOLV_CONF=/usr/local/etc/appjail/resolv.conf
1 | Importante establecer nuestra interface de red aquí con ifconfig podemos verla |
2 | También cambiar la RELEASE que se ajuste en este momento. |
(1)
lagg0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=4a520b9<RXCSUM,VLAN_MTU,VLAN_HWTAGGING,JUMBO_MTU,VLAN_HWCSUM,WOL_MAGIC,VLAN_HWFILTER,VLAN_HWTSO,RXCSUM_IPV6,NOMAP>
ether 00:25:90:2a:fb:52
inet 192.168.1.250 netmask 0xffffff00 broadcast 192.168.1.255
laggproto lacp lagghash l2,l3,l4
laggport: igb0 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>
laggport: igb1 flags=1c<ACTIVE,COLLECTING,DISTRIBUTING>
groups: lagg
media: Ethernet autoselect
status: active
nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
1 | Esta interface de red, es la que tengo lagg0 con LAG que me permite unir dos interfaces de red. |
Borrando Jails de AppJail
Si queremos borrar los jails hacemos los siguiente
-
Paramos todas la Jaulas
-
chflags -R 0 /usr/local/appjail en un pasado tuvimos un detalle con esto a la hora de borrar un directorio inmutable.
-
rm -rf /usr/local/appjail
También podemos borrar una jaula específica con
appjail jail destroy <jaula>
MakeJail de Nextcloud
Inicialmente intentamos usar SQLite
, pero no pudimos, daba errores raros y tampoco permitío hacer login, muy raro la verdad.
Para facilitar las cosas podemos automatizar y crear un directorio con 5 ficheros, ejemplo:
-
template.conf
-
create-volumes.sh
nos permite crear directorios que persistan en el host, y ellos seran compartidos dentro del jail por medio del fstab. -
Makejail
-
mariadb.sh
este es el primero que vamos a ejecutar -
nextcloud.sh
será el otro script a ejecutar luego de tener mariadb lista.
El template.conf
exec.start: "/bin/sh /etc/rc"
exec.stop: "/bin/sh /etc/rc.shutdown jail"
sysvshm: new
sysvsem: new
sysvmsg: new
mount.devfs
El create.volumes.sh
#!/bin/sh
VOLUMEDIR=".volumes" (1)
NEXTCLOUD_VOLUME="${VOLUMEDIR}/nextcloud"
MARIADB_VOLUME="${VOLUMEDIR}/mariadb"
#
# nextcloud
#
mkdir -p "${NEXTCLOUD_VOLUME}/apps"
mkdir -p "${NEXTCLOUD_VOLUME}/config"
mkdir -p "${NEXTCLOUD_VOLUME}/data" (2)
mkdir -p "${NEXTCLOUD_VOLUME}/themes"
mkdir -p "${NEXTCLOUD_VOLUME}/done"
mkdir -p "${NEXTCLOUD_VOLUME}/log"
#
# mariadb
#
mkdir -p "${MARIADB_VOLUME}/db"
mkdir -p "${MARIADB_VOLUME}/done"
1 | Esta linea hace la magia, nos permite crear un directorio .volumes en la misma ruta donde es ejecutado permitiendo separar
los datos persistentes de los que no seran persistentes. |
2 | Este es un directorio con datos queremos mantenerlo fuera del directorio webroot de nextcloud, siempre es lo mas recomendable, si nuestro jail es borrado, no importara, tendremos nuestros datos aqui |
El Makejail
El Makejail con un parecido al Dockerfile pero, funcionan para contrucción y runtime.
INCLUDE gh+AppJail-makejails/nextcloud
CMD mkdir /media/software-electronica (1)
CMD mkdir /media/public
CMD chown -R www:www /media/software-electronica
CMD chown -R www:www /media/public
CMD chmod 775 /media/software-electronica /media/public
SERVICE apache24 restart
1 | Nosotros crearemos un directorio llamado software-electronica dentro del directorio media, que apunta al dataset del host por medio del fstab, este directorio media estara en el userland del jail, no en el host. |
El script de MariaDB
#!/bin/sh
VOLUMEDIR="$PWD/.volumes"
MARIADB_VOLUME="${VOLUMEDIR}/mariadb"
mkdir -p files/usr/local/etc/mysql/conf.d
cat << EOF > files/usr/local/etc/mysql/conf.d/nextcloud.cnf
[mysqld]
transaction_isolation = READ-COMMITTED
binlog_format = ROW
EOF
./create-volumes.sh
appjail makejail \
-j nextcloud-mariadb \
-f gh+AppJail-makejails/mariadb \
-o virtualnet=":<random> address:10.0.0.51 default" \
-o nat \
-o copydir="$PWD/files" \
-o file=/usr/local/etc/mysql/conf.d/nextcloud.cnf \
-o fstab="${MARIADB_VOLUME}/db mariadb-db <volumefs>" \
-o fstab="${MARIADB_VOLUME}/done mariadb-done <volumefs>" \
-- \
--mariadb_tag "13.2-106" \
--mariadb_user "xxx" \
--mariadb_password "xxx" \
--mariadb_database "xxx" \
--mariadb_root_password "xxx"
El scrip de nextcloud
#!/bin/sh
VOLUMEDIR="$PWD/.volumes"
NEXTCLOUD_VOLUME="${VOLUMEDIR}/nextcloud"
./create-volumes.sh (1)
appjail makejail \
-j nextcloud \
-o virtualnet=":<random> default" \
-o nat \
-o expose=8082:80 \ (2)
-o fstab="${NEXTCLOUD_VOLUME}/apps nextcloud-apps <volumefs>" \
-o fstab="${NEXTCLOUD_VOLUME}/config nextcloud-config <volumefs>" \
-o fstab="${NEXTCLOUD_VOLUME}/data nextcloud-data <volumefs>" \ (3)
-o fstab="${NEXTCLOUD_VOLUME}/themes nextcloud-themes <volumefs>" \
-o fstab="${NEXTCLOUD_VOLUME}/done nextcloud-done <volumefs>" \
-o fstab="${NEXTCLOUD_VOLUME}/log nextcloud-log <volumefs>" \
-o template="$PWD/template.conf" \
-V NEXTCLOUD_TRUSTED_DOMAINS=192.168.1.250 \ (4)
-V MYSQL_DATABASE=xxxx \
-V MYSQL_USER=xxxx \
-V MYSQL_PASSWORD=xxxx \
-V MYSQL_HOST=10.0.0.51 \ (5)
-V NEXTCLOUD_ADMIN_USER=xxxx \
-V NEXTCLOUD_ADMIN_PASSWORD=xxxx
appjail fstab jail nextcloud set -d /mnt/pool/software-electronica -m /media/software-electronica (6)
appjail fstab jail nextcloud set -d /mnt/pool/public -m /media/public
appjail fstab jail nextcloud set -d /mnt/pool/extensions/bastille/jails/jdownloader/root/media/downloads -m /media/movies-jdownloader
appjail fstab jail nextcloud set -d /mnt/pool/movies -m /media/movies
appjail fstab jail nextcloud compile
appjail fstab jail nextcloud mount -a
1 | Importante crear los volúmenes en el directorio actual. |
2 | El puerto del host será 8082 y el puerto de la jaula será 8082, por ejemplo http://ip_nas:8082 |
3 | Con el fstab permite que el directorio de datos pueda ser usado mientras se está en el host a través del create-volumes.sh |
4 | Dirección ip para acceder al nextcloud. |
5 | Dirección ip de la base de datos mariadb. |
6 | Con el fstab de appjail montamos el dataset dentro de la jail de una vez. |
Variables de entorno, comparación con docker
Appjail permite establecer variables de entorno como docker, cosas que @DtxdF supo para su diseño.
Desplegamos primero MariaDB y luego Nextcloud todo debería estar bien y acceder a la UI.
Habilitando Servidor NTP para el 2FA
Si, sin la hora correcta, al final tendra como resultado el mal funcionamiento del TOTP (Authenticator app) entonces, la generación del código inicial al introducirla en el input de nextcloud no funcionaría.
La notificación siguente de error no es nada útil, y en los logs, no dice que esta pasando. |
Cuando configuremos correctamente el servidor NTP en nuestro server, la hora se sincronizará correctamente y el 2FA estará ready |
Info |
Tunning en el config.php
Este fichero esta en la ruta de
/usr/local/appjail/jails/nextcloud/jail/usr/local/www/nextcloud/config
'default_phone_region' => 'ES', (1)
'opcache.enable' => 1,
'opcache.enable_cli' => 1,
'opcache.memory_consumption' => 512,
'opcache.interned_strings_buffer' => 10, (2)
'opcache.max_accelerated_files' => 10000,
'opcache.revalidate_freq' => 1,
'opcache.save_comments' => 1,
1 | Esta es una sugerencia de nextcloud en el apartado Overview Security & setup warnings. |
2 | Esta es otra sugerencia de dicho apartado. |
Redis cache
Para habilitar el redis cache, añadimos esta config, puede ser opcional pero preferi hacerla de una vez, de seguro el performance se vera cuando exista una alta cantidad de ficheros.
'memcache.local' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'filelocking.enabled' => 'true',
'redis' =>
array (
'host' => '/var/run/redis/redis.sock',
'port' => 0,
'timeout' => 0.0,
),
Es importante tener redis cache instalada correctamente, porque sino puede afectarnos a la hora de visualizar los documentos en el nextcloud por ejemplo. |
Logs de nextcloud
appjail cmd jexec nextcloud cat /var/log/nextcloud/nextcloud.log
O desde la interface web también es util
Usando el occ
“ownCloud Console”
Bastante útil este comando para ejecutarlo en FreeBSD, como prueba vamos a quitar el index.php de las URL’s
'htaccess.RewriteBase' => '/', (1)
1 | Añadimos esto en el fichero config.php |
Y ejecutamos esto:
appjail cmd jexec nextcloud occ maintenance:update:htaccess (1)
1 | Esto actualizará el .htaccess |
Antes y después de remover el index.php
Escribimos la url en el navegador, independientemente si borramos cache en él. |
Sería lo mismo si accedemos remotamente en él. |
Acceso remoto
Para el acceso remoto debemos hacer cosas, como tener un DNS dinámico con cualquier proveedor que nos guste.
En el config.php es importante tener esto.
|
'trusted_domains' =>
array (
0 => 'localhost',
1 => '192.168.1.250',
2 => 'subdomain.domain.com', (1)
),
'overwrite.cli.url' => 'https://subdomain.domain.com', (2)
'overwriteprotocol' => 'https', (3)
1 | Importante para el acceso remoto. |
2 | Esta también será una línea importante. |
3 | Esto permite acceso desde el cliente nextcloud de Android, y sin que el cliente genere error, pero la conexion local no se podrá. |
Para simular que estamos fuera de nuestra red y acceder a un servicio interno nuestro ( nextcloud por ejemplo )
, necesitamos un proxy y TOR se me hace cómodo.
Al descomprimir simplemente uso
./start-tor-browser.desktop --register-app (1)
1 | Me creea un icono para usarlo en Ubuntu y listo nada complicado. |
Social login
La autenticación que conocemos todos, con distintos tipos de apps, suele ser bastante comoda, claramente debemos ajustar
un poco. También con el paso anterior para tener acceso remoto, nuestro servidor nginx y config.php
debe estar ajustado correctamente para permitir que estas apps funcionen bien.
Con Google
Para habilitar el Google sign in se debe ir a google cloud para hacer la configuración, no debemos pagar nada.
El OAuth consent screen si no lo tenemos, debemos hacerlo y no es nada complicado, pero sí que tiene campos con términos un poco raros, aquí definiremos el nombre de nuestra app. |
Para llegar a esta vista, se supone que tenemos la aplicación creada, y podemos visualizar esto: |
-
Client ID
-
Client secret
Con Twitter
Con las intrucciones de Twitter debemos ir al Developer portal, aún siguen usando el nombre de Twitter, raro que no tenga el nombre de y logo aún 😂
Con Twitter necesitamos habilitar el Oauth 1.0 lo que permitirá autenticarnos con él.
Luego crear nuestra app con los requisitos necesarios, vamos al apartado User authentication settings |
Siguiendo el apartado número 3, usamos la URL de redirección, muy paracida a la de google, llenamos esos dos campos si o si.
Justo en esta parte, tenemos lo que es el consumer api key para lograr autenticarnos con una cuenta de twitter, dichos datos los usaremos en el nextcloud
-
API key
-
Secret
En un inicio pense que debería usar el OAuth 2.0 Client ID and Client Secret pero no, no es eso. |
fstab con AppJail
Se llega a un punto donde necesitamos añadir un directorio existente en nuestro jail.
Con appjail podemos ajustar el fstab de una manera distinta a como se haría normalmente, pero se debe tomar en cuenta que dependiendo si tenemos el jail activo o no, es mejor tener precaución.
Con el jail parado
Podemos hacer
appjail cmd jexec nextcloud chown -R www:www /media/data/admin/software-electronica (1)
1 | Creamos el directorio software-electronica |
appjail fstab jail nextcloud set -d /mnt/pool/software-electronica -m /media/data/admin/software-electronica
Con el jail activo
appjail fstab jail nextcloud set -d /mnt/pool/software-electronica -m /media/data/admin/software-electronica
appjail fstab jail nextcloud compile
[00:00:00] [ debug ] Compiling fstab #0: /mnt/pool/dir /path/new-data-dir-for-nextcloud nullfs rw 0 0
appjail fstab jail nextcloud mount -a
Eso es para permitir más caracteres que un fstab normal no podría
Al final tenemos esto, el check verde indica que todo esta bien con el path y directorio nuevo dentro del jail.
Marcando directorio como read-only
-
En esos 3 puntos, tenemos 3 opciones.
-
Si habilitamos esto, nos permite compartir desde esta ruta, esto es opcional.
-
Esto marca el directorio en read-only, muy útil, para no borrar nada, de todas maneras tenemos una papelera de reciclaje.
Actualización de permisos en el External Storage
Si tenemos un directorio que utiliza el almacenamiento externo y por alguna razón se han cambiado los permisos, para que se reflejen en la interfaz de usuario correctamente, hay que ejecutar un comando con occ files:scan --all
.
-
occ files:scan --all --home-only
Esto le permite evitar la exploración de las rutas de almacenamiento externo.
occ files:scan --all -help |
Entonces tendríamos esta salida por ejemplo:
root@nextcloud:~ # occ files:scan --all
Starting scan for user 1 out of 4 (admin)
... removed for brevity
+---------+-------+-----+---------+---------+--------+--------------+
| Folders | Files | New | Updated | Removed | Errors | Elapsed time |
+---------+-------+-----+---------+---------+--------+--------------+
| 2545 | 11646 | 0 | 533 | 0 | 7 | 00:05:06 | (1)
+---------+-------+-----+---------+---------+--------+--------------+
1 | Esto indica que la exploración ha finalizado. |
Demontar directorio con fstab
Si queremos desmontar una unidad
appjail fstab jail nextcloud umount \
path/directorio-a-desmontar (1)
1 | Especificando el nombre del directorio sin el slash / inicial. |
Tips respaldos de nextcloud
Siempre es la misma historia así que vemos como reusar un dump, y tener por ahí el password del root.
En realidad cuando construyo la jaula de mariadb, hago un restore con el dump, y luego continúo con la instalación de nextcloud. |
Dentro del contenedor hacemos el dump
de esta manera:
root@mariadb:~ # mariadb-dump -u root -p --all-databases > dump-nextcloud.sql
Enter password:
root@mariadb:~ # ls
.cshrc .k5login .mysql_history .shrc
.history .login .profile dump-nextcloud.sql (1)
1 | El dump creado y se llama dump-nextcloud.sql |
DROP
de la base de datos que creamos en un inicio, o sea nextcloud
root@mariadb:~ # mariadb -h 127.0.0.1 -u root -p nextcloud -e "DROP DATABASE nextcloud"
CREATE
root@mariadb:~ # mariadb -h 127.0.0.1 -u root -p -e "CREATE DATABASE nextcloud"
RESTORE
root@mariadb:~ # mariadb -u root -p nextcloud < dump-nextcloud.sql
nextcloud@127.0.0.1 [(none)]> SELECT VERSION()
-> ;
+-----------------+
| VERSION() |
+-----------------+
| 10.6.16-MariaDB | (1)
+-----------------+
1 row in set (0.000 sec)
1 | Viendo la versión que tenemos, por si acaso en un futuro, pero no en este caso. |
issue con TOTP
Si tenemos error con el 2FA de TOTP de momento me imagino creando un usario nuevo como admin podria restaurar el QR, sino borrarlo y empezar de nuevo.