Raspberry Pi 4B+: Servidor ARM
Anteriormente vimos como crear un Servidor doméstico con base de procesador PC 64bits en esta ocasión vamos a realizar la misma operación pero tomando como base una placa SBC con procesador ARM.
La placa elegida para el mini-Servidor es una Raspberry Pi 4B+ 4Gb
, aunque el procedimiento también es compatible con modelos anteriores y otros modelos de placas SBC.
Vamos a realizar un pequeño repaso de las especificaciones técnicas del dispositivo en cuestión:
Raspberry Pi 4B+ | |
---|---|
Procesador | ARM Cortex-A72 (ARMv8-A64 64 bit) |
Frecuencia de reloj | 1.5 GHz |
TDP | 7.5 W |
GPU | VideoCore VI (Soporte para OpenGL ES 3.x) |
Memoria | 1 GB / 2 GB / 4 GB / 8GB LPDDR4 SDRAM |
Conectividad | Bluetooth 5.0, Wi-Fi 802.11ac, Gigabit Ethernet |
Almacenamiento | microSD |
Puertos | 2x microHDMI, 2xUSB2.0, 2xUSB3.0, 1xRJ45, GPIO 40 pines, 1xCSI (Cámara), 1xDSI (Pantalla Táctil), 1xJack, 1xUSB-C (Alimentación) |
Dimensiones | 88mm x 58mm x 19.5mm, 46g |
Como vemos las posibilidades/capacidades son bastante interesantes para montar un mini-servidor.
Instalación
Nos dirigimos a la web de descargas y podremos elegir la distribución que más se adapte a nuestras necesidades.
En mi caso voy a recomendar la Raspberry Pi OS Lite, que es la más recomendable para usarse a modo Servidor al optimizar recursos especialmente en el apartado gráfico. En el momento de escribir la entrada el Sistema Operativo esta basado en Debian Buster aunque en arquitectura 32bits.
Una vez bajada la imagen ISO comprimida ya solo nos queda grabarla en la tarjeta microSD por ejemplo con:
Sistema Base
El usuario de sistema sobre el que realizare la guía es pi
que por defecto es el de Raspberry Pi.
Primer arranque RPi
Una vez finalizada la grabación de la tarjeta microSD esta la insertamos en la Raspberry Pi y conectamos un cable de red a la toma RJ45, un teclado USB, cable microHDMI a un Monitor/TV y alimentamos la placa por el conector USB-C.
Durante el proceso de arranque, la partición root de la tarjeta se expandira a la totalidad del espacio libre de la misma y veremos una pantalla de login donde se nos solicita un usuario y contraseña:
Usuario | Contraseña |
---|---|
pi |
raspberry |
El primer paso a realizar es cambiar la contraseña del usuario por defecto:
passwd
Salida en terminal:
pi@raspberrypi:~ $ passwd
Changing password for pi.
Current password: raspberry
New password: ***
Retype new password: ***
passwd: password updated successfully
A continuación consulto IP del dispositivo en la red, para ello en la terminal envio el comando:
ip a
En mi caso la respuesta obtenida fue:
pi@raspberrypi:~ $ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether dc:a6:32:99:8e:0c brd ff:ff:ff:ff:ff:ff
inet 192.168.1.227/24 brd 192.168.1.255 scope global dynamic noprefixroute eth0
valid_lft 3436sec preferred_lft 2986sec
inet6 fe80::b443:1ced:c1c6:75e5/64 scope link
valid_lft forever preferred_lft forever
3: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether dc:a6:32:99:8e:0d brd ff:ff:ff:ff:ff:ff
Anoto la IP: 192.168.1.227
y procedo a habilitar la conexión SSH para poder trabajar en remoto:
sudo raspi-config
Nos aparece en pantalla un menú de dialogo:
3 Interface Options: Configure connections to peripherals
P2 SSH: Enable/disable remote command line access using SSH
¿Quieres habilitar el servidor SSH?: YES
Finish
A continuación configuro franja horaria sistema con el asistente:
sudo dpkg-reconfigure tzdata
Ejemplo salida comando:
pi@raspberrypi:~ $ sudo dpkg-reconfigure tzdata
Current default time zone: 'Europe/Madrid'
Local time is now: Sun Jan 17 08:19:36 CET 2021.
Universal Time is now: Sun Jan 17 08:19:36 UTC 2021.
Configuro idioma sistema con el siguiente asistente:
sudo dpkg-reconfigure locales
Para poner nuestro sistema en Español, tenemos que marcar las siguientes opciones en el asistente configuración de locales y deseleccionar cualquier otra que pudiese estar activa:
- en_GB.UTF-8 UTF-8
- es_ES.UTF-8 UTF-8
Para la configuración regional predeterminada seleccionamos:
- es-ES.UTF-8
Ejemplo salida comando:
pi@raspberrypi:~ $ sudo dpkg-reconfigure locales
Generating locales (this might take a while)...
es_ES.UTF-8... done
Generation complete.
Tras haber realizado estos pasos, apago la Raspberry Pi:
sudo poweroff
Desconecto teclado USB y salida Monitor/TV microHDMI, ya que el resto de configuración voy a realizarla por SSH, al ser un servidor headless.
Los parametros de la conexión SSH seran en mi caso:
IP RPi | Puerto SSH |
---|---|
192.168.1.227 |
22 |
Fix RPi - Memoria & Wifi
Tras el arranque vemos que en la terminal de SSH nos devuelve la siguiente advertencia:
Wi-Fi is currently blocked by rfkill.
Use raspi-config to set the country before use.
Editamos el fichero rc.local
para desactivar la hibernación wifi:
sudo nano /etc/rc.local
Y agregamos el siguiente código en la linea anterior de la orden exit 0:
# Deshabilitar hibernación Wifi
/sbin/iwconfig wlan0 power off
Guardamos el fichero, salimos del editor y volvemos a ejecutar raspi-config
:
sudo raspi-config
Nos aparece en pantalla un menú de dialogo:
1 System Options: Configure system settings
S4 Hostname: Set name for this computer on a network
rpi4b
4 Perfomance Options: Configure perfomance settings
P2 GPU Memory: Change the amount of memory made available to the GPU
How much memory (MB) should the GPU have? 16
5 Localisation Options: Configure language and regional settings
L4 WLAN Country: Set legal wireless channels for your country
ES Spain
Finish
Would you like to reboot now? YES
Alías
Para simplificar la administración del sistema añado los siguientes alías
cat << EOF | sudo tee -a /etc/bash.bashrc
#
# Alias
#
alias reiniciar="sudo reboot"
alias apagar="sudo poweroff"
alias instalar="sudo apt-get -y install"
alias desinstalar="sudo apt-get -y purge"
alias actualizar="sudo apt-get autoclean && sudo apt-get clean && sudo apt-get -y autoremove && sudo apt-get update && sudo apt-get -y upgrade && sudo apt-get -y dist-upgrade && sudo apt-get moo"
alias eepromfix="sudo rpi-eeprom-update -d -a"
alias enlaces="sudo nano /etc/bash.bashrc"
EOF
Vamos a repasar los alías creados:
Alías | Acción |
---|---|
reiniciar |
Reiniciar la RPi |
apagar |
Apagar la RPi |
instalar |
Instala paquete/s de repositorios |
desinstalar |
Desinstala paquete/s de repositorios |
actualizar |
Actualiza Sistema Operativo |
eepromfix |
Actualiza el firmware del bootloader RPi |
enlaces |
Abre en el editor nano el fichero de configuración de alías |
Para no tener que reiniciar/cerrar el sistema, recargo el fichero con las nuevas configuraciones:
source /etc/bash.bashrc
Vamos a actualizar el sistema y el firmware del bootlader de la Raspberry Pi con los alías:
actualizar && eepromfix
En mi caso la terminal devuelve el siguiente código:
pi@rpi4b:~ $ actualizar && eepromfix
Leyendo lista de paquetes... Hecho
Creando árbol de dependencias
Leyendo la información de estado... Hecho
Leyendo lista de paquetes... Hecho
Creando árbol de dependencias
Leyendo la información de estado... Hecho
0 actualizados, 0 nuevos se instalarán, 0 para eliminar y 0 no actualizados.
Obj:1 http://archive.raspberrypi.org/debian buster InRelease
Obj:2 http://raspbian.raspberrypi.org/raspbian buster InRelease
Leyendo lista de paquetes... Hecho
Leyendo lista de paquetes... Hecho
Creando árbol de dependencias
Leyendo la información de estado... Hecho
Calculando la actualización... Hecho
0 actualizados, 0 nuevos se instalarán, 0 para eliminar y 0 no actualizados.
Leyendo lista de paquetes... Hecho
Creando árbol de dependencias
Leyendo la información de estado... Hecho
Calculando la actualización... Hecho
0 actualizados, 0 nuevos se instalarán, 0 para eliminar y 0 no actualizados.
(__)
(oo)
/------\/
/ | ||
* /\---/\
~~ ~~
..."Have you mooed today?"...
BCM2711 detected
Dedicated VL805 EEPROM detected
BOOTLOADER: up-to-date
CURRENT: jue sep 3 12:11:43 UTC 2020 (1599135103)
LATEST: jue sep 3 12:11:43 UTC 2020 (1599135103)
FW DIR: /lib/firmware/raspberrypi/bootloader/default
VL805: up-to-date
CURRENT: 000138a1
LATEST: 000138a1
Utilidades Sistema
Si necesitamos des/comprimir algún fichero de nuestro sistema y no se encuentra dentro de los formatos más habituales de GNU/Linux, deberemos de darle soporte para poder interactuar:
instalar zip unzip unace bzip2 lzop p7zip p7zip-full sharutils \
lzip xz-utils mpack arj cabextract
Otro conjunto de utilidades adicionales a instalar que necesitaremos para futuros usos son:
instalar mc htop curl git wget curl dnsutils ntfs-3g hfsprogs \
hfsplus build-essential automake libtool uuid-dev psmisc yasm \
subversion tofrodos git-core subversion dos2unix make mercurial \
gcc automake cmake dpkg-dev fakeroot pbuilder dh-make debhelper \
cvs devscripts bc
$USER/.BASHRC
Editamos el fichero .bashrc de nuestro usuario:
nano $HOME/.bashrc
Añadimos al final del fichero el siguiente contenido:
# MOTD
show_temp(){
echo "`cat /sys/class/thermal/thermal_zone0/temp`/1000"|bc -q
}
#
let upSeconds="$(/usr/bin/cut -d. -f1 /proc/uptime)"
#let secs=$((${upSeconds}%60))
let mins=$((${upSeconds}/60%60))
let horas=$((${upSeconds}/3600%24))
let dias=$((${upSeconds}/86400))
UPTIME=`printf "%d dias, %02dh%02dm%02ds" "$dias" "$horas" "$mins" "$secs"`
read one five fifteen rest < /proc/loadavg
#
echo "$(tput setaf 2)
`date +"%A, %e %B %Y, %r"`
`uname -srmo`$(tput setaf 1)
Tiempo de actividad..: ${UPTIME}
Memoria RAM..........: `cat /proc/meminfo | grep MemFree | awk {'print $2'}`kB (Free) / `cat /proc/meminfo | grep MemTotal | awk {'print $2'}`kB (Total)
Promedios de carga...: ${one}, ${five}, ${fifteen} (1, 5, 15 min)
Procesos activos.....: `ps ax | wc -l | tr -d " "`
Temperatura Sistema..: $(show_temp)ºC
IP conexion por SSH..: $(echo $SSH_CLIENT | awk '{ print $1}')
$(tput sgr0)"
Guardamos el fichero (Control + O), salimos del editor (Control + X) y ejecutamos el siguiente comando:
cat << EOF > $HOME/.inputrc
# Flecha arriba
"\e[A":history-search-backward
# Flecha abajo
"\e[B":history-search-forward
EOF
Y recargamos el fichero .bashrc
para visualizar los cambios:
source $HOME/.bashrc
Log2RAM
Ampliar información en esta entrada
ZRAM
Ampliar información en esta entrada
Redes
Tras haber configurado nuestro sistema base, vamos a configurar y segurizar nuestra red doméstica.
Configurando Red
Vamos a habilitar la redicción de puertos sobre IPv4 que posteriormente usaremos para entre otros configurar otros servicios.
sudo sed -i "s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g" "/etc/sysctl.conf"
Recargamos las variables en el sistema:
sudo sysctl -p
Habilitamos la carga del modulo bonding en el arranque del sistema:
cat << EOF | sudo tee -a /etc/modprobe.d/bonding.conf
alias bond0 bonding
options bonding mode=0 miimon=0
EOF
Actualizamos repositorios e instalamos dependencias:
sudo apt-get update && \
instalar ifenslave wpasupplicant \
bridge-utils net-tools ifupdown
Configuramos el acceso a la red wifi, para poder balancear carga entre eth0 & wlan0
:
sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
Añadimos el siguiente contenido, sustituyendo los valores SSID & PSK
por los datos de nuestra conexión Wifi respetando comillas:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=ES
network={
ssid="Nombre_de_Wifi"
psk="Clave_de_Wifi"
}
Guardamos, salimos del editor y configuramos el fichero interfaces para definir la conexión bridge del bond:
cat << EOF | sudo tee -a /etc/network/interfaces
#
# Interfaz Loopback
#
auto lo
iface lo inet loopback
#
# Interfaz Ethernet
#
auto eth0
iface eth0 inet manual
bond-master bond0
bond-primary eth0 wlan0
#
# Interfaz Wifi
#
auto wlan0
iface wlan0 inet manual
bond-master bond0
bond-primary eth0 wlan0
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
#
# Interfaz Bond
#
auto bond0
iface bond0 inet manual
bond-slaves none
bond-mode active-backup
bond-miimon 100
bond-downdelay 200
bond-updelay 200
#
# Interfaz Bridge (IP dinámica)
#
auto br0
iface br0 inet dhcp
bridge_ports bond0
bridge_stp off
bridge_fd 0
bridge_maxwait 0
#
# Interfaz Bridge (IP estática)
#
#auto br0
#iface br0 inet static
#address 192.168.1.90
#netmask 255.255.255.0
#network 192.168.1.0
#broadcast 192.168.1.255
#gateway 192.168.1.1
#bridge_ports bond0
#bridge_stp off
#bridge_fd 0
#bridge_maxwait 0
#
# Red Bridge IPv6
#
iface br0 inet6 auto
accept_ra 1
EOF
TIP: Al ejecutar el comando previo hemos habilitado la IP dinámica de br0
, en caso de querarla estática (recomendado) tendras que editar el fichero con privilegios root (sudo) e intercambiar comentarios (#)
Desactivamos el gestor de conexiones que usa la Raspberry por defecto (dhcpcd
), para evitar conflictos en arranque:
sudo systemctl disable dhcpcd
Hacemos un backup de nuestro fichero de resolución DNS y configuramos uno nuevo con la DNS de Cloudflare
:
sudo mv /etc/resolv.conf /etc/resolv.conf.bak && \
echo "nameserver 1.1.1.1" | sudo tee -a /etc/resolv.conf
Reiniciamos el sistema para activar la nueva configuración de red:
reiniciar
Tras el reinicio comprobamos la red:
ip -br addr show
En mi caso me muestra el siguiente resultado:
pi@rpi4b:~ $ ip -br addr show
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP
wlan0 UP
bond0 UP
br0 UP 192.168.1.227/24 fe80::dea6:32ff:fe99:8e0c/64
NOTA: Lo que hemos hecho es tener levantadas las redes eth0 & wlan0 para que en caso de fallo de la conexión se pueda balancear la carga gracias a la red bond0 y esa a su vez regulada mediante un puente br0.
Dockerizar Servidor
FIX ARM 32bits: Bug: libsecccomp Thanks to Sensineger
Antes de continuar debemos de realizar estos pasos:
- Instalamos y configuramos: Docker
- Configuramos e instalamos: Portainer CE, gestor de contenedores vía web.
- Configuramos e instalamos: Watchtower, actualizador de contenedores.
- Configuramos e instalamos: DockerTG, notificador de cambios estado de contenedores vía Telegram.
- Configuramos e instalamos: P3DNS, seguridad redes y conexiones DNS.
- Configuramos e instalamos: DuckDNS, DNS externa.
- Configuramos e instalamos: Wireguard, VPN de gestión remota.
- Configuramos e instalamos: MiniDLNA, servidor de DLNA.
- Configuramos e instalamos: Transmission, gestor de descargas P2P.
- Configuramos e instalamos: File Browser, gestor de archivos vía web.
Más servicios consultar aquí
Y listo!