Bienvenido
Mis notas

Codeberg (Git + SSH)
Autenticación SSH
git config --global user.name "John Doe"
git config --global user.email "johnDoe123@email.com"
ssh-keygen -t ed25519 -a 100
# Presiona Enter para usar el valor por defecto
# Define una contraseña
cat ~/.ssh/id_ed25519.pub
Copia el ssh-ed… hasta el final, sin el user@algo.
Agrega esto en Codeberg -> config -> add ssh.
Configurar usuario para commits
Haz lo que indica el mensaje, pero usa el correo con @noreply que aparece en los ajustes del perfil (al final de la página).
Git
Básico
git clone <repositorio>
git status # Mostrará si hay cambios
git add <Archivos/Directorios>
git commit -m "Mensaje de commit"
git push # Envía los cambios al remoto configurado
git reset --soft HEAD~1 # Eliminar último commit
Varios
# 1. Crear y cambiar a una rama nueva
git checkout -b [nombre-rama]
# Ej: git checkout -b feature/login → Crea la rama "feature/login" y se mueve a ella.*
# 2. Cambiar a una rama existente
git checkout [nombre-rama]
# Ej: git checkout main → Te mueve a la rama main.*
# 3. Subir una rama nueva al repositorio remoto (solo la primera vez)
git push -u origin [nombre-rama]
# El -u vincula la rama local con la remota para futuros push.*
# 4. Listar ramas locales y remotas
git branch -a
# Muestra todas las ramas (locales en verde, remotas en rojo).*
# 5. Sincronizar rama actual con cambios remotos
git pull
# Descarga cambios del repositorio remoto y los fusiona con tu rama local.*
# 6. Fusionar una rama con la rama actual
git merge [nombre-rama]
# Ej: Si estás en main → git merge feature/login une feature/login con main.*
# 7. Eliminar rama local
git branch -d [nombre-rama]
# -d solo borra si está fusionada; usa -D para forzar eliminación.*
# 8. Eliminar rama remota
git push origin --delete [nombre-rama]
# Ej: git push origin --delete feature/login → Borra la rama en GitHub.*
# 9. Ver estado actual (cambios, rama, conflictos)
git status
# 10. Ver historial de commits
git log --oneline
# Muestra commits resumidos en una línea.*
# 11. Tag
git tag name-tag
git push origin name-tag
# 12. Worktree
git worktree add <ruta/del/nuevo/directorio> <rama>
# Crea otro directorio para manejar dos ramas
mdBook
Instalación
cargo install mdbook
Resumen rápido
Crear libros online escribiendo archivos Markdown.
Más información: <https://rust-lang.github.io/mdBook/>.
Crear un proyecto mdBook en el directorio actual:
mdbook init
Crear un proyecto mdBook en un directorio específico:
mdbook init ruta/al/directorio
Limpiar el directorio con el libro generado:
mdbook clean
Servir un libro en <http://localhost:3000>, con auto build al cambiar archivos:
mdbook serve
Observar archivos y construir automáticamente cuando cambien:
mdbook watch
Pages
En Codeberg con mdBook.
git checkout --orphan pages
git rm -rf . # Borra todos los archivos del tracking
git commit --allow-empty -m "Initial commit for pages branch"
git push origin pages
git checkout main # Vuelve a tu rama principal
git worktree add ../repo-pages pages
Modificar los scripts deploy.sh y clean.sh.
PostgreSQL
Instalación
sudo dnf install -y postgresql postgresql-server
sudo postgresql-setup --initdb --unit postgresql
sudo systemctl start postgresql
Ejecutar psql
sudo -i -u postgres
psql
Configurar postgres y usuarios
CREATE USER mi_usuario WITH PASSWORD 'Mi Contraseña';
psql -U tu_usuario -d tu_base_de_datos
ALTER USER nombre_usuario WITH PASSWORD 'nueva_contraseña'; # Cambiar contraseña de un usuario
ALTER USER postgres WITH PASSWORD 'nueva_contraseña'; # Poner contraseña a postgres de ser necesario
DROP USER nombre_usuario; # Eliminar usuario
Conectar a la base desde afuera
Para conectarte con herramientas como pgAdmin4 o pgModeler.
sudo -i -u postgres
psql
ALTER USER postgres WITH PASSWORD 'nueva_contraseña';
\q
Ir a /var/lib/pgsql/data/pg_hba.conf. Al final del archivo cambia las lineas que dicen:
local all all peer # Original
local all all md5 # Cambio
host all all 127.0.0.1/32 ident # Original (el 127 no va asi, pero se entiende)
host all all 127.0.0.1/32 md5 # Cambio
host all all ::1/128 ident # Original
host all all ::1/128 md5 # Cambio
Luego, en el mismo directorio de datos, abre postgresql.conf y agrega al final:
listen_addresses = 'localhost' # Si no funciona, prueba '*'
Con esto ya está listo. Reinicia el servicio de Postgres y usa la contraseña correcta en la herramienta que vayas a usar.
sudo systemctl restart postgresql # Como usuario normal
Bases de datos
CREATE DATABASE mi_base_de_datos;
GRANT ALL PRIVILEGES ON DATABASE mi_base_de_datos TO mi_usuario;
DROP DATABASE nombre_base_de_datos; # Eliminar base de datos
ALTER DATABASE nombre_base_de_datos RENAME TO nuevo_nombre; # Renombrar base de datos
Comandos
\l; # Muestra todas las bases de datos que existen en tu sistema PostgreSQL.
\dt; # Muestra todas las tablas en la base de datos en la que estás trabajando actualmente.
\c nombre_de_base_de_datos; # Conectarse base de datos
\dt nombre_de_tabla; # Muestra detalles sobre la tabla específica llamada nombre_de_tabla.
\d nombre_de_tabla;
\di nombre_de_tabla; # Indices de una tabla
\q; # Salir de psql
\du; # Ver permisos de usuario
Export and Import
Exportar
pg_dump -U mi_usuario -d mi_base_de_datos -f archivo_de_respaldo.sql
Exportar solo esquema (sin datos):
pg_dump -U usuario -s -d base_de_datos -f esquema.sql
Exportar solo datos (sin esquema):
pg_dump -U usuario -a -d base_de_datos -f datos.sql
Importar
psql -U mi_usuario -d mi_base_de_datos -f archivo_de_respaldo.sql
Tables
CREATE TABLE nombre_tabla (
columna1 tipo_dato,
columna2 tipo_dato,
...
);
DROP TABLE nombre_tabla; # Borrar tabla
ALTER TABLE nombre_tabla ADD COLUMN nombre_columna tipo_dato; # Agregar una columna a una tabla:
ALTER TABLE nombre_tabla DROP COLUMN nombre_columna; # Eliminar columna de una tabla
ALTER TABLE nombre_tabla RENAME TO nuevo_nombre; # Renombrar tabla
Configuración
La configuración principal se guarda en:
/var/lib/pgsql/data/postgresql.conf
Tipos de datos
-
INTEGER o INT (-/+ 2,147,483,648)
-
BIGINT (-/+ 9,223,372,036,854,775,808)
-
SMALLINT (-/+ 32,768)
-
DECIMAL o NUMERIC (precio DECIMAL(10,2), 10 dígitos en total, 2 después del punto decimal)
-
REAL (Almacena números con precisión simple en coma flotante (menos preciso que DOUBLE PRECISION))
-
DOUBLE PRECISION (Almacena números con mayor precisión en coma flotante)
-
VARCHAR(n) (Longitud variable máxima n)
-
TEXT (Longitud variable sin límite explícito)
-
CHAR(n) (Longitud fija de n)
-
DATE (año, mes, día)
-
TIME
-
TIMESTAMP (Fecha y hora con precisión hasta fracciones de segundo)
-
TIMESTAMPTZ (Con zona horaria)
-
INTERVAL (Periodo de tiempo, diferencia entre dos fechas u horas)
-
BOOLEAN (TRUE, FALSE, NULL)
-
SERIAL (Autoincremental. Usualmente usado en ejemplo: id SERIAL PRIMARY KEY)
-
BIGSERIAL (Lo mismo pero más grande)
-
UUID (Almacena un identificador único universal)
-
JSON
-
JSONB (Lo mismo que json pero en formato binario)
-
XML (Datos en formato xml)
-
BYTEA (Binarios como imágenes o archivos)
-
ARRAY (Lista de valores de tipo determinado, ejemplo: números ARRAY[INTEGER])
-
RANGE (Rango de valores)
Restricciones comunes
Formato: nombre DATA_TYPE RESTRICCION Ej: nombre VARCHAR(100) NOT NULL
- NOT NULL
- DEFAULT ‘Valor por defecto’ (estado VARCHAR(10) DEFAULT ‘activo’)
- UNIQUE (Asegura que los valores de una columna sean únicos (sin duplicados))
- CHECK (edad INT CHECK (edad >= 18))
- CONSTRAINT [fk_usuario FOREIGN KEY (usuario_id) REFERENCES usuarios(id)] ( Define una clave foránea para relacionar tablas.)
- PRIMARY [id SERIAL PRIMARY KEY]
Clave primaria y clave foránea
- id SERIAL PRIMARY KEY,
- estudiante_id INT REFERENCES estudiante(id),
JavaFX (OpenJFX)
Dependencias
Tener instalado openjdk
# java-21-openjdk-1:21.0.7.0.6-1.fc42.x86_64
# java-21-openjdk-devel-1:21.0.7.0.6-1.fc42.x86_64
doas dnf install -y java javac
Instalar Java-fx y configurar
doas dnf install -y openjfx
Usa estos alias
alias javac-fx="javac --module-path /usr/lib/jvm/openjfx/ --add-modules javafx.controls"
alias java-fx="java --module-path /usr/lib/jvm/openjfx/ --add-modules javafx.controls"
Cuidado
Revisar el –module-path con:
find / -name '*openjfx*' 2>/dev/null
Desde Gluon
Descargar la versión deseada, luego extraer y mover el directorio a /.local/share/ Luego en .bash_profile o .zprofile
export PATH_TO_FX="$HOME/.local/share/javafx-sdk-21.0.7/lib"
alias javac-fx="javac --module-path $PATH_TO_FX --add-modules javafx.controls,javafx.fxml,javafx.media"
alias java-fx="java --module-path $PATH_TO_FX --add-modules javafx.controls,javafx.media"
Nushell
Primero sigue esta guía: Instalar Rust.
Si tu distro lo tiene, solo instala nu o nushell. En Fedora:
sudo dnf install nu
Compilar desde fuente
Dependencias
# Debian
sudo apt install pkg-config libssl-dev build-essential
# RedHat/Fedora based
sudo yum install libxcb openssl-devel libX11-devel
cargo install nu --locked
Uso
Eliminar archivos con más de 3 semanas
ls | where modified <= (date now) - 3wk | each {|file| rm $file.name}
Ansible
sudo dnf install ansible
Configurar el inventario
Crear un inventory.ini
[myhosts]
192.0.2.50
192.0.2.51
192.0.2.52
Pendiente
Homebrew
No en Nushell
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval "$(<Homebrew prefix path>/bin/brew shellenv)"
En Nushell
curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash
Luego agrega en env.nu
$env.PATH = ($env.PATH | split row (char esep) | prepend '/home/linuxbrew/.linuxbrew/bin')
Ollama
podman run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
Ejemplo:
podman exec -it ollama ollama run llama3
Alias
alias gemma="podman start ollama && podman exec -it ollama ollama run gemma3:4b"
alias deepseekr1="podman start ollama && podman exec -it ollama ollama run deepseek-r1:8b"
alias qwen="podman start ollama && podman exec -it ollama ollama run qwen3:8b"
Automatización con Woodpecker CI
Este repositorio utiliza Woodpecker CI para compilar y desplegar automáticamente la documentación en Codeberg Pages.
Workflow de Woodpecker
Cada vez que se hace un push a la rama main (o la que se ponga en when), Woodpecker ejecuta los siguientes pasos en un contenedor aislado:
- Clone: Descarga el código fuente de
main. - Build:
- Usa una imagen de
alpine:edge. - Instala
mdbook. - Compila el libro (genera la carpeta
book/con el HTML).
- Publish:
- Clona la rama
pages(donde se aloja el sitio web) en una carpeta temporal. - Copia el HTML generado (
book/) dentro de esa carpeta. - Configura git con identidad de bot.
- Hace un
commitypushde vuelta al repositorio.
Configuración (.woodpecker.yml)
El archivo de configuración se encuentra en la raíz del repositorio.
Puntos clave:
when: branch: main: Solo se activa al modificar la rama principal.image: alpine:edge: Usamos Alpine para tener un entorno ligero y rápido.[SKIP CI]: Etiqueta obligatoria en el mensaje de commit del bot para evitar que Woodpecker entre en un bucle infinito al detectar su propio push.
Secretos Requeridos
Para que el despliegue funcione, Woodpecker necesita permisos de escritura. Estos se configuran en Settings -> Secrets (del repositorio o del usuario).
| Secreto | Valor | Descripción |
|---|---|---|
codeberg_token | Token de acceso | Debe tener permisos write:repo (o Repository: Read and write). Generado en User Settings -> Applications. |
mail | Email para git | Se recomienda usar usuario@noreply.codeberg.org para mantener privacidad. |
Lógica de Seguridad
En el paso de publicación, usamos este comando defensivo:
if ! git diff --cached --quiet; then
git commit -m "chore(deploy): Woodpecker CI ${CI_BUILD_CREATED} [SKIP CI]" && git push;
fi
git diff --cached --quiet: Verifica si hubo cambios reales en el HTML generado.if ! ...: Si NO está quieto (hay cambios), procede. Si el sitio es idéntico, no hace nada (evita commits vacíos).[SKIP CI]: Le dice a Woodpecker que ignore este commit y no dispare una nueva compilación.
Rust Cheatsheet para Principiantes (desde C++/Java)
Este cheatsheet se centra en los conceptos fundamentales que necesitas para empezar a ser productivo en Rust, basándose en la tabla que proporcionaste.
1. Rust Básico
Variables y Mutabilidad
Rust prioriza la inmutabilidad por defecto. Usa let para declarar variables. Para hacerlas mutables, añade mut. Los tipos se infieren a menudo, pero puedes especificarlos.
- Inmutable:
#![allow(unused)] fn main() { let x: i32 = 5; // x es inmutable let y = 10; // Tipo i32 inferido, y es inmutable // x = 6; // Error! No se puede reasignar una variable inmutable } - Mutable:
#![allow(unused)] fn main() { let mut z = 15; // z es mutable z = 20; // ¡Ok! println!("z es: {}", z); } - Constantes (siempre inmutables, tipo debe ser anotado, evaluadas en tiempo de compilación):
#![allow(unused)] fn main() { const MAX_POINTS: u32 = 100_000; } - Shadowing (puedes declarar una nueva variable con el mismo nombre, incluso cambiando el tipo):
#![allow(unused)] fn main() { let spaces = " "; let spaces = spaces.len(); // Ahora 'spaces' es un número (3) }
Tipos de Datos Comunes
- Enteros:
i8,u8,i16,u16,i32,u32,i64,u64,i128,u128,isize,usize(tamaño de puntero). - Flotantes:
f32,f64(por defectof64). - Booleanos:
bool(true,false). - Caracteres:
char(Unicode, 4 bytes). - Tuplas: Colección fija de diferentes tipos.
#![allow(unused)] fn main() { let tup: (i32, f64, u8) = (500, 6.4, 1); let (x, y, z) = tup; // Destructuración println!("El valor de y es: {}", y); // 6.4 println!("El primer valor es: {}", tup.0); // Acceso por índice } - Arrays: Colección fija del mismo tipo, en el stack.
#![allow(unused)] fn main() { let a = [1, 2, 3, 4, 5]; let first = a[0]; // let b: [i32; 5] = [1, 2, 3, 4, 5]; // Con anotación de tipo y tamaño // a[0] = 10; // Error si 'a' no es mutable } - Strings:
&str(string slice): Inmutable, referencia a datos de string (usualmente en el binario o en el heap).#![allow(unused)] fn main() { let s_literal = "hola"; // &str }String: Mutable, buffer de string en el heap. Similar astd::stringen C++ oStringen Java.#![allow(unused)] fn main() { let mut s_heap = String::from("hola"); s_heap.push_str(", mundo!"); println!("{}", s_heap); // hola, mundo! }
Funciones
Declaradas con fn. Los tipos de los parámetros y el tipo de retorno (si lo hay) deben ser especificados. La última expresión en una función es su valor de retorno implícito si no se usa return.
fn saludar(nombre: &str) {
println!("Hola, {}!", nombre);
}
fn sumar(a: i32, b: i32) -> i32 {
a + b // No se necesita ';' ni 'return' si es la última expresión
}
fn main() {
saludar("Mundo");
let resultado = sumar(5, 3);
println!("5 + 3 = {}", resultado);
}
Control de Flujo
if/else if/else: Similar a C++/Java. Las condiciones deben serbool.ifes una expresión.#![allow(unused)] fn main() { let numero = 6; if numero % 4 == 0 { println!("El número es divisible por 4"); } else if numero % 3 == 0 { println!("El número es divisible por 3"); } else { println!("El número no es divisible ni por 4 ni por 3"); } let condicion = true; let valor = if condicion { 5 } else { 6 }; // 'if' como expresión println!("El valor es: {}", valor); }- Bucles:
loop: Bucle infinito (usabreakpara salir).#![allow(unused)] fn main() { let mut contador = 0; let resultado_loop = loop { contador += 1; if contador == 10 { break contador * 2; // 'break' puede devolver un valor } }; println!("El resultado del loop es {}", resultado_loop); // 20 }while: Bucle condicional.#![allow(unused)] fn main() { let mut numero = 3; while numero != 0 { println!("{}!", numero); numero -= 1; } println!("¡DESPEGUE!"); }for: Para iterar sobre colecciones (más común y seguro).#![allow(unused)] fn main() { let a = [10, 20, 30, 40, 50]; for elemento in a.iter() { // .iter() crea un iterador sobre referencias println!("El valor es: {}", elemento); } for numero in (1..4).rev() { // Rango (1, 2, 3) en reversa println!("{}!", numero); } }
Módulos
Para organizar el código.
// En lib.rs o main.rs
mod mi_modulo {
pub fn funcion_publica() {
println!("Llamada a funcion_publica()");
funcion_privada();
}
fn funcion_privada() {
println!("Llamada a funcion_privada()");
}
pub mod sub_modulo {
pub fn otra_funcion() {
println!("Llamada a otra_funcion() en sub_modulo");
}
}
}
fn main() {
// Ruta completa
crate::mi_modulo::funcion_publica();
// Usando 'use'
use crate::mi_modulo::sub_modulo::otra_funcion;
otra_funcion();
// Si 'mi_modulo' está en otro archivo llamado 'mi_modulo.rs'
// mod mi_modulo; // En main.rs o lib.rs para declarar el módulo
// mi_modulo::funcion_publica();
}
crate: Raíz del crate (paquete).pub: Hace un ítem público. Por defecto, todo es privado.use: Importa ítems a un scope.
2. Gestión de Paquetes con Cargo
Cargo es el gestor de paquetes y sistema de construcción de Rust.
- Crear un nuevo proyecto:
cargo new mi_proyecto # Crea una aplicación binaria cargo new --lib mi_libreria # Crea una librería - Estructura típica del proyecto:
mi_proyecto/ ├── Cargo.toml # Manifiesto del paquete (metadatos, dependencias) ├── src/ │ └── main.rs # Código fuente principal para binarios │ # O lib.rs para librerías - Comandos comunes de Cargo:
cargo build: Compila el proyecto (entarget/debug/).cargo build --release: Compila con optimizaciones (entarget/release/).cargo run: Compila y ejecuta el binario.cargo test: Ejecuta las pruebas.cargo check: Comprueba el código sin generar un ejecutable (más rápido).cargo doc --open: Genera y abre la documentación.cargo add <crate_name>: Añade una dependencia aCargo.toml.
Cargo.toml(ejemplo básico):[package] name = "mi_proyecto" version = "0.1.0" edition = "2021" # Edición de Rust [dependencies] # rand = "0.8.5" # Ejemplo de dependencia de crates.io # ratatui = { version = "0.26.0", features = ["crossterm"] } # crossterm = "0.27.0"
3. Propiedad y Préstamos (Ownership & Borrowing)
Este es el concepto más distintivo de Rust. Asegura la seguridad de memoria sin un recolector de basura.
Reglas de Propiedad (Ownership)
- Cada valor en Rust tiene una variable que es su dueña (owner).
- Solo puede haber un dueño a la vez.
- Cuando el dueño sale del ámbito (scope), el valor se libera (dropped).
#![allow(unused)]
fn main() {
{
let s1 = String::from("hola"); // s1 es dueña de "hola"
// let s2 = s1; // ¡MOVIMIENTO! s1 ya no es válida.
// Similar a std::unique_ptr en C++ (sin copia implícita)
// Para tipos simples como i32, se copian (implementan el trait 'Copy')
let s2 = s1.clone(); // Copia profunda (heap data copiado)
println!("s1 = {}, s2 = {}", s1, s2); // Ambas válidas
} // s1 (si no fue movida) y s2 salen del scope, la memoria se libera.
}
Préstamos y Referencias (Borrowing & References)
Permiten acceder a datos sin tomar posesión.
- Referencias Inmutables (
&T):- Puedes tener múltiples referencias inmutables a un dato.
- No puedes modificar el dato a través de ellas.
#![allow(unused)] fn main() { let s1 = String::from("hola"); let len = calcular_longitud(&s1); // Se presta s1 inmutablemente println!("La longitud de '{}' es {}.", s1, len); fn calcular_longitud(s: &String) -> usize { // s es una referencia a un String s.len() } // s sale del scope, pero no libera nada porque no es dueña } - Referencias Mutables (
&mut T):- Solo puedes tener una referencia mutable a un dato en un scope particular.
- Esto previene data races en tiempo de compilación.
- No puedes tener referencias inmutables si existe una mutable.
Restricción importante:#![allow(unused)] fn main() { let mut s = String::from("hola"); cambiar(&mut s); println!("{}", s); // "hola, mundo" fn cambiar(algun_string: &mut String) { algun_string.push_str(", mundo"); } }#![allow(unused)] fn main() { let mut s = String::from("hello"); let r1 = &s; // Referencia inmutable, OK let r2 = &s; // Otra referencia inmutable, OK // let r3 = &mut s; // ¡ERROR! No puedes tener una referencia mutable mientras existan inmutables // println!("{}, {}, and {}", r1, r2, r3); let mut s_mut = String::from("hello"); let r_mut1 = &mut s_mut; // let r_mut2 = &mut s_mut; // ¡ERROR! Solo una referencia mutable a la vez // println!("{}, {}", r_mut1, r_mut2); }
Lifetimes (Tiempos de Vida) 'a
Aseguran que las referencias sean siempre válidas. A menudo son inferidos por el compilador. Los necesitas explícitamente cuando las relaciones de lifetimes entre referencias no son obvias para el compilador, especialmente en firmas de funciones y structs que contienen referencias.
- Objetivo: Evitar dangling references (referencias que apuntan a memoria que ha sido liberada).
- Ejemplo donde se necesitan:
La idea es que el dato referenciado por// Devuelve una referencia, el compilador necesita saber si vive tanto como 'x' o 'y' fn el_mas_largo<'a>(x: &'a str, y: &'a str) -> &'a str { if x.len() > y.len() { x } else { y } } fn main() { let string1 = String::from("cadena larga es larga"); { let string2 = String::from("xyz"); let resultado = el_mas_largo(string1.as_str(), string2.as_str()); println!("La cadena más larga es {}", resultado); } // string2 se libera aquí. Si resultado apuntara a string2, sería un dangling reference. // Pero el lifetime 'a' del resultado está atado al más corto de string1 y string2. }'adebe vivir al menos tanto como la referencia anotada con'a.
4. POO en Rust (Estilo Rust)
Rust no tiene “clases” como Java/C++, pero ofrece estructuras (structs), enumeraciones (enums), y comportamientos (traits) para lograr encapsulación y polimorfismo.
struct (Estructuras)
Agrupan datos relacionados. Similar a struct en C o los campos de una clase en Java/C++.
struct Usuario {
activo: bool,
nombre_usuario: String,
email: String,
contador_sesion: u64,
}
fn main() {
let mut usuario1 = Usuario {
email: String::from("alguien@ejemplo.com"),
nombre_usuario: String::from("alguien123"),
activo: true,
contador_sesion: 1,
};
usuario1.email = String::from("otroemail@ejemplo.com");
println!("Email: {}", usuario1.email);
let usuario2 = construir_usuario(
String::from("usuario2@ejemplo.com"),
String::from("usuario2")
);
}
fn construir_usuario(email: String, nombre_usuario: String) -> Usuario {
Usuario {
email, // Abreviatura si el nombre del parámetro y el campo son iguales
nombre_usuario,
activo: true,
contador_sesion: 1,
}
}
// Structs tupla (sin nombres de campo)
struct Color(i32, i32, i32);
struct Punto(i32, i32, i32);
let negro = Color(0, 0, 0);
let origen = Punto(0, 0, 0);
println!("Primer valor de negro: {}", negro.0);
impl (Implementación de Métodos)
Define métodos para structs y enums.
struct Rectangulo {
ancho: u32,
alto: u32,
}
// Bloque de implementación para Rectangulo
impl Rectangulo {
// Método (toma &self, &mut self, o self)
fn area(&self) -> u32 { // &self es una referencia inmutable a la instancia
self.ancho * self.alto
}
fn puede_contener(&self, otro: &Rectangulo) -> bool {
self.ancho > otro.ancho && self.alto > otro.alto
}
// Función asociada (no toma self), a menudo usada como constructor
// Similar a un método estático en Java/C++
fn cuadrado(tamano: u32) -> Self { // Self es un alias para Rectangulo
Self { ancho: tamano, alto: tamano }
}
}
fn main() {
let rect1 = Rectangulo { ancho: 30, alto: 50 };
let rect2 = Rectangulo { ancho: 10, alto: 40 };
let rect_cuadrado = Rectangulo::cuadrado(25); // Llamada a función asociada
println!("El área del rectángulo es {} pixeles cuadrados.", rect1.area());
println!("¿Puede rect1 contener a rect2? {}", rect1.puede_contener(&rect2));
println!("Área del cuadrado: {}", rect_cuadrado.area());
}
enum (Enumeraciones)
Tipos que pueden ser uno de varios valores posibles (variantes). Las variantes pueden tener datos asociados. Son mucho más potentes que los enums de C/C++ y Java (más cercanos a uniones discriminadas o tipos algebraicos de datos).
enum Mensaje {
Salir, // Sin datos asociados
Mover { x: i32, y: i32 }, // Con campos nombrados (como un struct)
Escribir(String), // Con un String
CambiarColor(i32, i32, i32), // Con una tupla de datos
}
impl Mensaje {
fn procesar(&self) {
match self {
Mensaje::Salir => println!("Saliendo..."),
Mensaje::Mover { x, y } => {
println!("Moviendo a x: {}, y: {}", x, y);
}
Mensaje::Escribir(texto) => {
println!("Mensaje de texto: {}", texto);
}
Mensaje::CambiarColor(r, g, b) => {
println!("Cambiando color a R:{}, G:{}, B:{}", r, g, b);
}
}
}
}
fn main() {
let msg1 = Mensaje::Mover { x: 10, y: 20 };
let msg2 = Mensaje::Escribir(String::from("Hola enum"));
msg1.procesar();
msg2.procesar();
}
trait (Rasgos)
Definen un conjunto de métodos que un tipo puede implementar. Similar a interfaces en Java o clases base puramente virtuales en C++. Permiten el polimorfismo.
// Definición de un trait
pub trait Resumible {
fn resumir_autor(&self) -> String; // Método que debe ser implementado
fn resumir(&self) -> String { // Método con implementación por defecto
format!("(Leer más de {}...)", self.resumir_autor())
}
}
pub struct Noticia {
pub titular: String,
pub autor: String,
pub contenido: String,
}
// Implementación del trait Resumible para Noticia
impl Resumible for Noticia {
fn resumir_autor(&self) -> String {
format!("@{}", self.autor)
}
// Podríamos sobreescribir resumir() aquí si quisiéramos
}
pub struct Tweet {
pub nombre_usuario: String,
pub contenido: String,
pub respuesta: bool,
pub retweet: bool,
}
impl Resumible for Tweet {
fn resumir_autor(&self) -> String {
format!("@{}", self.nombre_usuario)
}
fn resumir(&self) -> String {
format!("{}: {}", self.nombre_usuario, self.contenido)
}
}
// Polimorfismo usando traits (parámetros genéricos con trait bounds)
pub fn notificar<T: Resumible>(item: &T) {
println!("¡Noticia de última hora! {}", item.resumir());
}
// Polimorfismo usando trait objects (dinámico)
pub fn notificar_dinamico(item: &dyn Resumible) {
println!("¡Noticia dinámica! {}", item.resumir());
}
fn main() {
let tweet = Tweet {
nombre_usuario: String::from("caballo_ebooks"),
contenido: String::from("por supuesto, como ustedes saben, la gente"),
respuesta: false,
retweet: false,
};
let articulo = Noticia {
titular: String::from("¡Los pingüinos ganan la Stanley Cup!"),
autor: String::from("Iceburgh"),
contenido: String::from("El equipo de hockey de Pittsburgh, los Pingüinos..."),
};
println!("1 nuevo tweet: {}", tweet.resumir());
println!("Nuevo artículo disponible: {}", articulo.resumir());
notificar(&tweet);
notificar_dinamico(&articulo);
}
5. Tratamiento de Errores
Rust no tiene excepciones como Java o C++. En su lugar, usa tipos para representar posibles errores.
Option<T>
Para valores que pueden ser opcionales (o estar ausentes). Similar a Optional<T> en Java 8+.
- Variantes:
Some(T)(el valor está presente) oNone(el valor está ausente).
fn encontrar_caracter(texto: &str, caracter_buscado: char) -> Option<usize> {
for (indice, caracter_actual) in texto.char_indices() {
if caracter_actual == caracter_buscado {
return Some(indice); // Valor encontrado
}
}
None // Valor no encontrado
}
fn main() {
let texto = "hola mundo";
match encontrar_caracter(texto, 'm') {
Some(indice) => println!("'m' encontrada en el índice: {}", indice),
None => println!("'m' no encontrada."),
}
match encontrar_caracter(texto, 'z') {
Some(indice) => println!("'z' encontrada en el índice: {}", indice),
None => println!("'z' no encontrada."),
}
// 'if let' es una forma concisa de manejar una variante de Option/Result
if let Some(indice) = encontrar_caracter(texto, 'o') {
println!("'o' encontrada con if let en: {}", indice);
}
// Métodos útiles de Option:
// unwrap(): Devuelve el valor en Some(T) o hace panic! si es None (¡usar con cuidado!)
// unwrap_or(default_value): Devuelve el valor o un valor por defecto.
// unwrap_or_else(closure): Devuelve el valor o el resultado de una clausura.
// map(closure): Aplica una función al valor dentro de Some.
// and_then(closure): Encadena operaciones que devuelven Option.
let quizas_numero: Option<i32> = Some(5);
let _numero_mas_uno = quizas_numero.map(|n| n + 1); // Some(6)
let _otro_numero = None::<i32>.unwrap_or(0); // 0
}
Result<T, E>
Para operaciones que pueden fallar (éxito o error). T es el tipo del valor en caso de éxito, E es el tipo del error.
- Variantes:
Ok(T)(operación exitosa) oErr(E)(operación fallida).
use std::fs::File;
use std::io::{self, Read};
// Función que devuelve un Result
fn leer_archivo(nombre_archivo: &str) -> Result<String, io::Error> {
let mut f = match File::open(nombre_archivo) {
Ok(archivo) => archivo,
Err(e) => return Err(e), // Propaga el error temprano
};
let mut s = String::new();
match f.read_to_string(&mut s) {
Ok(_) => Ok(s),
Err(e) => Err(e),
}
}
// Usando el operador '?' para propagar errores (más idiomático)
// '?' solo puede usarse en funciones que devuelven Result o Option.
fn leer_archivo_con_interrogante(nombre_archivo: &str) -> Result<String, io::Error> {
let mut f = File::open(nombre_archivo)?; // Si es Err, retorna Err(e) desde esta función
let mut s = String::new();
f.read_to_string(&mut s)?; // Si es Err, retorna Err(e)
Ok(s) // Si todo va bien, retorna Ok(s)
// Incluso más corto:
// std::fs::read_to_string(nombre_archivo)
}
fn main() {
match leer_archivo_con_interrogante("hola.txt") {
Ok(contenido) => println!("Contenido del archivo: {}", contenido),
Err(error) => println!("Error al leer el archivo: {:?}", error),
}
// expect(): Similar a unwrap(), pero con un mensaje de panic personalizado.
// let _contenido = File::open("no_existe.txt").expect("Falló al abrir no_existe.txt");
}
El operador ? desenvuelve Ok(T) a T o retorna Err(E) de la función actual.
6. Asincronía (Básico) (Opcional, según tu proyecto TUI)
Si tu TUI necesita realizar operaciones de I/O (red, disco) sin bloquear el hilo principal, necesitarás asincronía.
async fn: Define una función asíncrona. Devuelve unFuture..await: Espera a que unFuturese complete sin bloquear el hilo. Solo se puede usar dentro de unaasync fn.
// Este es un ejemplo conceptual. Necesitarías un runtime como tokio o async-std.
// Añade a Cargo.toml:
// tokio = { version = "1", features = ["full"] }
/*
async fn obtener_datos_web(url: &str) -> Result<String, reqwest::Error> {
// reqwest es una librería popular para HTTP, también asíncrona
let respuesta = reqwest::get(url).await?;
let cuerpo = respuesta.text().await?;
Ok(cuerpo)
}
async fn tarea_larga() {
println!("Iniciando tarea larga...");
// Simula trabajo, como una llamada de red
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
println!("Tarea larga completada.");
}
// En tu función main (o una función marcada con el macro del runtime)
#[tokio::main] // Si usas tokio
async fn main() {
println!("Iniciando programa asíncrono.");
let handle1 = tokio::spawn(async { // Ejecuta en una nueva "tarea" (green thread)
tarea_larga().await;
});
let handle2 = tokio::spawn(async {
match obtener_datos_web("https://www.rust-lang.org").await {
Ok(pagina) => println!("Página obtenida (primeros 100 chars): {:.100}", pagina),
Err(e) => eprintln!("Error al obtener la página: {}", e),
}
});
println!("Tareas iniciadas, esperando...");
// Espera a que todas las tareas spawneadas terminen
let _ = tokio::try_join!(handle1, handle2);
println!("Programa asíncrono finalizado.");
}
*/
- Runtimes asíncronos (
tokio,async-std): Proveen el ejecutor para losFutures, manejo de I/O, timers, etc.tokioes muy popular, especialmente para networking.async-stdbusca ser un análogo asíncrono de la librería estándar.
7. Ratatui + Crossterm (Específico para TUI)
Estas bibliotecas te ayudarán a construir tu Interfaz de Usuario en Terminal (TUI).
- Crossterm: Proporciona funcionalidades de bajo nivel para interactuar con la terminal (manipulación del cursor, colores, entrada de teclado/ratón, modo raw). Ratatui lo usa como backend.
- Ratatui: Es una biblioteca para construir TUIs, inspirada en React. Se basa en dibujar “widgets” en un “buffer” y luego mostrar ese buffer en la terminal.
- Ciclo principal (conceptual):
- Inicializar la terminal (usando Crossterm).
- Entrar en un bucle:
a. Leer eventos de entrada (teclado, ratón) de forma no bloqueante (Crossterm).
b. Actualizar el estado de tu aplicación según la entrada.
c. Dibujar la UI en un
Framede Ratatui: i. DefinirLayoutspara dividir el área de la terminal. ii. RenderizarWidgetsen las áreas del layout. d. Si el usuario quiere salir, romper el bucle. - Restaurar la terminal.
- Ciclo principal (conceptual):
Conceptos Clave de Ratatui:
Terminal: El objeto principal para interactuar con la terminal.Frame: Se pasa a tu función de dibujado en cada iteración, es donde dibujas.Layout: Define cómo dividir un área rectangular en sub-áreas.Direction:HorizontaloVertical.Constraint: Define el tamaño de cada celda del layout (Percentage,Length,Min,Max).
#![allow(unused)] fn main() { // Ejemplo de Layout // use ratatui::layout::{Layout, Direction, Constraint, Rect}; // fn ui(frame: &mut Frame) { // let chunks = Layout::default() // .direction(Direction::Vertical) // .margin(1) // .constraints( // [ // Constraint::Percentage(10), // 10% para el título // Constraint::Percentage(80), // 80% para el contenido // Constraint::Percentage(10), // 10% para el pie // ] // .as_ref(), // ) // .split(frame.size()); // frame.size() es el Rect de toda la terminal // // chunks[0] es el Rect para el título, chunks[1] para contenido, etc. // } }Widget: Componentes visuales. Sonstructsque implementan el traitWidget.Block: Un contenedor con bordes opcionales y título. A menudo envuelve a otros widgets.Paragraph: Para mostrar texto, con opciones de alineación y autoajuste.List: Para mostrar una lista de ítems.Tabs: Para crear una interfaz con pestañas.- Muchos más:
Table,Chart,Gauge,Sparkline, etc.
#![allow(unused)] fn main() { // Ejemplo de Widget (dentro de la función ui) // use ratatui::widgets::{Block, Borders, Paragraph}; // use ratatui::text::Text; // // // En chunks[0] (definido arriba) // let titulo = Paragraph::new(Text::styled("Mi TUI con Ratatui", Style::default().fg(Color::Yellow))) // .block(Block::default().borders(Borders::ALL)) // .alignment(Alignment::Center); // frame.render_widget(titulo, chunks[0]); // // // En chunks[1] // let contenido_texto = "Este es el contenido principal...\nPresiona 'q' para salir."; // let parrafo_contenido = Paragraph::new(contenido_texto) // .block(Block::default().title("Contenido").borders(Borders::ALL)); // frame.render_widget(parrafo_contenido, chunks[1]); }Style: Para definir colores (foreground, background) y modificadores (bold, italic).- Eventos (con Crossterm):
#![allow(unused)] fn main() { // use crossterm::event::{self, Event as CrosstermEvent, KeyCode, KeyEvent}; // loop { // // Esperar un evento por un tiempo máximo (para no bloquear indefinidamente) // if crossterm::event::poll(std::time::Duration::from_millis(50))? { // if let CrosstermEvent::Key(key_event) = event::read()? { // match key_event.code { // KeyCode::Char('q') => break, // Salir del bucle // KeyCode::Up => { /* mover selección hacia arriba */ }, // KeyCode::Down => { /* mover selección hacia abajo */ }, // // ... otros KeyCode // _ => {} // } // } else if let CrosstermEvent::Mouse(mouse_event) = event::read()? { // // Procesar eventos de ratón (posición, clics) // // mouse_event.kind, mouse_event.column, mouse_event.row // } // } // // Lógica de la app y dibujar UI aquí // // terminal.draw(|f| ui(f, &app_state))?; // } }
Configuración inicial para Ratatui + Crossterm:
- Añade a
Cargo.toml:[dependencies] ratatui = { version = "0.27.0", features = ["crossterm"] } # O la versión más reciente crossterm = "0.27.0" # O la versión más reciente - Código básico de inicialización/restauración:
// En tu main.rs /* use std::io; use ratatui::Terminal; use ratatui::backend::CrosstermBackend; use crossterm::{terminal::{enable_raw_mode, disable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, execute}; fn main() -> Result<(), Box<dyn std::error::Error>> { // Setup terminal enable_raw_mode()?; // Entrar en modo raw para control total de entrada let mut stdout = io::stdout(); execute!(stdout, EnterAlternateScreen)?; // Cambiar a una pantalla alternativa let backend = CrosstermBackend::new(stdout); let mut terminal = Terminal::new(backend)?; // Bucle principal de la aplicación aquí... // loop { // terminal.draw(|f| { // // ui(f, &app_state); // Tu función de dibujado // })?; // // Manejo de eventos aquí... // // if quit { break; } // } // Restaurar terminal disable_raw_mode()?; execute!(terminal.backend_mut(), LeaveAlternateScreen)?; // terminal.show_cursor()?; // Si lo ocultaste Ok(()) } */
Herramientas de Rust
Primero instala rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup update
rustup component add rust-analyzer
Seguridad
cargo install cargo-audit
cargo install cargo-update
cargo install cargo-download
Cómo revisar con cargo audit
cargo download pkg > pkg.gz
tar -xvf pkg.gz
cd pkg*
cargo audit
Cómo usar cargo-update
cargo install-update -l
Instalar paquetes
# Buscar dependencias si es necesario
cargo install paquete
cargo install --locked paquete
Cargo (Rust)
Cargo es el gestor de paquetes y sistema de build de Rust. Sirve para crear proyectos, compilar, ejecutar, testear y manejar dependencias.
Crear proyecto
# Binario
cargo new mi_app
# Librería
cargo new mi_lib --lib
# Inicializar en un directorio existente
cargo init
Estructura básica
Cargo.toml: configuración y dependencias.Cargo.lock: versiones exactas de dependencias.src/main.rs: entrada de binarios.src/lib.rs: entrada de librerías.
Comandos básicos
# Compilar en debug (por defecto)
cargo build
# Compilar optimizado
cargo build --release
# Ejecutar
cargo run
# Pasar argumentos a tu programa
cargo run -- --help
# Ver errores rápido sin generar binario
cargo check
# Tests
cargo test
# Formato y lints
cargo fmt
cargo clippy
Dependencias
Editar Cargo.toml y agregar en [dependencies]:
[dependencies]
serde = "1"
Luego:
cargo build
Instalar herramientas
# Instalar un binario global (por ejemplo ripgrep)
cargo install ripgrep
# Actualizar dependencias del proyecto
cargo update
Tips
- Si algo tarda mucho en compilar, usa
cargo checkmientras iteras. - Para generar documentación:
cargo doc --open.
Rust Coreutils
En Fedora:
sudo dnf install uutils-coreutils
# Recomendado
sudo dnf install bat ripgrep zoxide nu skim
Modificar el PATH por ejemplo en .bash_profile
export PATH="/usr/libexec/uutils-coreutils:$HOME:$PATH"
RustScan
Instalación
Primero instala Nmap. En Fedora:
sudo dnf install nmap
Configurar Rustup/Cargo Luego:
cargo install rustscan
Consejos
Para revisar puertos abiertos
rustscan -a <ip-local> --ulimit 5000
rustscan -a 192.168.x.y --ulimit 5000
TLDR
Escáner de puertos moderno escrito en Rust.
Nota: `nmap` debe estar instalado para que funcionen algunos ejemplos.
Más información: <https://github.com/bee-san/RustScan/wiki>.
Escanear todos los puertos de una o más direcciones separadas por comas:
rustscan [-a|--addresses] ip_or_hostname
Escanear los top 1000 puertos con detección de servicio y versión:
rustscan --top [-a|--addresses] address_or_addresses
Escanear una lista específica de puertos:
rustscan [-p|--ports] port1,port2,... [-a|--addresses] address_or_addresses
Escanear un rango específico de puertos:
rustscan [-r|--range] start-end [-a|--addresses] address_or_addresses
Invocar funciones de `nmap` (detección de SO y scripts por defecto):
rustscan [-a|--addresses] address_or_addresses -- -O [-sC|--script=default]
Escanear con batch size y timeout personalizados (default: 4500 y 1500ms):
rustscan [-b|--batch-size] batch_size [-t|--timeout] timeout [-a|--addresses] address_or_addresses
Escanear con orden específico de puertos:
rustscan --scan-order serial|random [-a|--addresses] address_or_addresses
Escanear en modo greppable (solo puertos, sin `nmap`):
rustscan [-g|--greppable] [-a|--addresses] address_or_addresses
Podman
Crear contenedor básico
podman run -it --name prueba-debian --hostname debi debian
-itpara terminal interactivo--namenombre del contenedor--hostnamehostname dentro del contenedor
Copiar archivo del host al contenedor
podman cp /ruta/en/host/mi_archivo.txt nombre-contenedor:/ruta/destino/
Crear usuario con sudo en Debian
apt update && apt install -y sudo
useradd -m -s /bin/bash devuser
usermod -aG sudo devuser
echo "devuser ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
su - devuser
Entrar a un contenedor creado
# Usuario root (por defecto)
podman exec -it nombre_contenedor bash
# Usuario específico
podman exec -it --user usuario nombre_contenedor bash
# Ejemplo con usuario creado:
podman exec -it --user devuser prueba-debian bash
GUI
X11
podman run -it --rm \
-v /tmp/.X11-unix:/tmp/.X11-unix:ro \
-e DISPLAY=$DISPLAY \
--security-opt label=type:container_runtime_t \
--name test \
debian \
/bin/bash
Wayland (no probado)
podman run -it --rm \
-v "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:/tmp/wayland-0" \
-e XDG_RUNTIME_DIR=/tmp \
-e WAYLAND_DISPLAY=wayland-0 \
--security-opt label=type:container_runtime_t \
docker.io/library/debian:latest \
sh -c "apt update && apt install -y weston && weston --socket=wayland-0"
¿Qué hace cada parte?
-v "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:/tmp/wayland-0"
Monta el socket de Wayland del host en el contenedor.
-e XDG_RUNTIME_DIR=/tmp
Configura el directorio runtime dentro del contenedor.
-e WAYLAND_DISPLAY=wayland-0
Define el nombre del socket Wayland.
--security-opt label=type:container_runtime_t
Política de SELinux segura (mejor que label=disable).
sh -c "..."
Instala solo lo necesario y ejecuta Weston (compositor minimalista).
Containers
podman run -it \
--name bllsht \
--hostname fedora \
-v "$XDG_RUNTIME_DIR/$WAYLAND_DISPLAY:/tmp/wayland-0" \
-e XDG_RUNTIME_DIR=/tmp \
-e WAYLAND_DISPLAY=wayland-0 \
--security-opt label=type:container_runtime_t \
fedora
EN PODMAN DESKTOP
Volumes: /run/user/1000/wayland-1 : /tmp/wayland-0
ENV:
XDG_RUNTIME_DIR : /tmp WAYLAND_DISPLAY : wayland-0 QT_QPA_PLATFORM : wayland
PARA EL DE KEEPASS AGREGAR ESTE ENV
KVM
systemctl enable --now libvirtd
usermod -aG libvirt user
firewall-cmd --add-service=libvirt --permanent
sed -i 's/#unix_sock_group = "libvirt"/unix_sock_group = "libvirt"/' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_unix_ro = "none"/auth_unix_ro = "none"/' /etc/libvirt/libvirtd.conf
sed -i '
/^#.*unix_sock_group = "libvirt"/s/^#//
s/unix_sock_ro_perms = "0777"/unix_sock_ro_perms = "0770"/
s/^#auth_unix_ro = "none"/auth_unix_ro = "polkit"/
s/^#auth_unix_rw = "none"/auth_unix_rw = "polkit"/
' /etc/libvirt/libvirtd.conf
En kvm activar edicion de xml, y en la distro a eleccion ir a la network poner xml y em vez de network poner user arriba Para que rinda perfecto poner spice server y video con qxl
Whonix KVM

KVM/Libvirt
Ver: KVM
Descarga
Aceptar licencia
tar -xvf Whonix*.libvirt.xz
touch WHONIX_BINARY_LICENSE_AGREEMENT_accepted
Importar plantillas de VM
- Agregar las redes virtuales:
sudo virsh -c qemu:///system net-define Whonix_external*.xml ;
sudo virsh -c qemu:///system net-define Whonix_internal*.xml
- Activar las redes virtuales:
sudo virsh -c qemu:///system net-autostart Whonix-External ;
sudo virsh -c qemu:///system net-start Whonix-External ;
sudo virsh -c qemu:///system net-autostart Whonix-Internal ;
sudo virsh -c qemu:///system net-start Whonix-Internal
- Importar las imágenes de Whonix Gateway y Workstation:
sudo virsh -c qemu:///system define Whonix-Gateway*.xml ;
sudo virsh -c qemu:///system define Whonix-Workstation*.xml
Instalación por archivos de imagen
- Opción 1: Lenta
sudo mv Whonix-Gateway*.qcow2 /var/lib/libvirt/images/Whonix-Gateway.qcow2 ;
sudo mv Whonix-Workstation*.qcow2 /var/lib/libvirt/images/Whonix-Workstation.qcow2
- Opción 2: Recomendada Como root:
sudo su
cp Whonix*.qcow2.libvirt.xz /var/lib/libvirt/images/
cd /var/lib/libvirt/images/
tar -xvf Whonix*.qcow2.libvirt.xz
rm WH* Wh*.xml Wh*.xz
mv Whonix-Workstation*.qcow2 Whonix-Workstation.qcow2
mv Whonix-Gateway*.qcow2 Whonix-Gateway.qcow2
Extra
Solo modificar cosas como RAM o CPU.
Pasar archivos
Existen 2 formas:
- virtio-9p: más antigua y más lenta
- virtio-fs: más nueva y rápida. A costa de activar Shared memory, lo que puede afectar la seguridad, así que ir con precaución.
Settings -> Add hardware -> Filesystem -> virtio-9p/virtio-fs
Brave en Wayland
Ir a /usr/share/applications/brave-browser.desktop Y cambiar todas las líneas que tengan Exec con –enable-features=UseOzonePlatform –ozone-platform=wayland. Por ejemplo:
Exec=brave-browser --enable-features=UseOzonePlatform --ozone-platform=wayland %U
Mullvad VPN en Wayland
Ir a /usr/share/applications/mullvad-vpn.desktop Y cambiar todas las líneas que tengan Exec con –enable-features=UseOzonePlatform,WaylandWindowDecorations –ozone-platform=wayland. Por ejemplo:
# Desactivar GPU (opcional)
Exec="/opt/Mullvad VPN/mullvad-vpn" --enable-features=UseOzonePlatform,WaylandWindowDecorations --ozone-platform=wayland %U
VSCodium en Wayland
Ir a /usr/share/applications/codium.desktop Y cambiar todas las líneas que tengan Exec con –enable-features=UseOzonePlatform,WaylandWindowDecorations –ozone-platform=wayland. Por ejemplo:
Exec=/usr/share/codium/codium --enable-features=UseOzonePlatform,WaylandWindowDecorations --ozone-platform=wayland --new-window %F
Eww
Instalación
sudo dnf install gtk3-devel gtk-layer-shell-devel libdbusmenu-gtk3-devel pango-devel gdk-pixbuf2-devel cairo-devel glib2-devel
cargo install --locked --no-default-features --features=wayland --git https://github.com/elkowar/eww eww
sudo dnf remove gtk3-devel gtk-layer-shell-devel libdbusmenu-gtk3-devel pango-devel gdk-pixbuf2-devel cairo-devel glib2-devel
Ironbar
Me rendí antes de terminarla
Instalación en Fedora
sudo dnf install gtk3-devel gtk-layer-shell-devel openssl-devel libdbusmenu-gtk3-devel pulseaudio-libs-devel libinput-devel luajit-devel lua-lgi libevdev-devel
cargo install --locked --git https://github.com/jakestanger/ironbar.git ironbar
sudo dnf remove gtk3-devel gtk-layer-shell-devel openssl-devel libdbusmenu-gtk3-devel pulseaudio-libs-devel libinput-devel luajit-devel lua-lgi libevdev-devel
Labwc
sudo dnf install labwc
En ~/.config/labwc copia el rc.xml
Alacritty
sudo dnf install cmake freetype-devel fontconfig-devel libxcb-devel libxkbcommon-devel g++
cargo install alacritty
Extra
El .desktop
git clone https://github.com/alacritty/alacritty/
cd alacritty
sudo desktop-file-install extra/linux/Alacritty.desktop
Tuigreet en Fedora
sudo dnf install greetd tuigreet
En /etc/greetd/config.toml
[terminal]
vt = 1
[default_session]
command = "tuigreet --cmd 'niri --session' --time --remember --asterisks"
user = "greetd"
Luego:
sudo systemctl set-default graphical.target
sudo systemctl enable greetd
sudo systemctl start greetd
Autologin en TTY1
sudo EDITOR=hx systemctl edit getty@tty1
Agregar este bloque:
[Service]
ExecStart=
ExecStart=-/usr/bin/agetty --autologin <user> --noclear %I $TERM
sudo systemctl daemon-reload
sudo systemctl restart getty@tty1.service
Forzar modo oscuro en el navegador
- Abre el Administrador de marcadores del navegador (por ejemplo
Ctrl+Shift+OoCtrl+Shift+B). - Haz clic en Agregar marcador.
- En Nombre pon “Dark Mode” (o el que prefieras).
- En URL pega:
javascript:(function(){var s=document.getElementById('darkmode-toggle');s?s.remove():(s=document.createElement('style'),s.id='darkmode-toggle',s.textContent="html{filter:invert(1)hue-rotate(180deg)!important;}img,video,iframe{filter:invert(1)hue-rotate(180deg)!important;}",document.head.appendChild(s));})();
- Guarda el marcador.
- (Opcional) Habilita la barra de marcadores para acceder rápido.
- Haz clic en el bookmarklet “Dark Mode” en cualquier página para invertir colores.
SHA
Trucos de sha256sum
Hacer sha256sum a todos los archivos dentro de un directorio y sus subdirectorios.
find path/to/directory -type f -exec sha256sum {} + > hashes.sha256
-type f: significa tipo archivo.{}: representa el nombre del archivo actual en find.+: indica el final del comando que se ejecuta con-exec. Cuando se usa find, agrupa los nombres de archivo y ejecuta el comando una sola vez con una lista de archivos, lo que es más eficiente que usar;.
doas
Ejemplo en Fedora
sudo su
dnf install -y doas # pacman también funciona y la mayoría de gestores sirven
echo "permit persist setenv {PATH=/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin} :wheel" > /etc/doas.conf
chown -c root:root /etc/doas.conf
chmod -c 0400 /etc/doas.conf
SSH
Conexión simple entre Linux
Hacer esto en el servidor de destino
sudo dnf install -y sshd # openssh-server, creo
sudo systemctl start sshd # habilitar para que quede activo
ip addr show # Buscar la IP local
ssh user@192.168.x.x # IP local
Copiar archivos
scp /path/to/my/file user@192.168.x.x:/path/in/destiny/desire # usuario@ip_local:ruta/destino
GPG
Cifrar
Empaquetar una carpeta (no comprimir, más rápido)
tar -cvf carpeta.tar carpeta_a_encriptar
Cifrar carpeta
gpg -c carpeta.tar
Limpiar
rm -rf carpeta_a_encriptar
Descifrar
Descifrar el GPG
gpg carpeta.tar.gpg
Desempaquetar
tar -xvf carpeta.tar
LUKS
Creando una partición:
sudo fdisk /dev/sdb
n
# Presiona Enter en todo
w
Encriptando la partición creada:
sudo cryptsetup luksFormat /dev/sdb1
sudo cryptsetup open /dev/sdb1 a
sudo mkfs.ext4 /dev/mapper/a
sudo cryptsetup close a
sync
USBGuard
sudo dnf install usbguard usbguard-selinux
sudo systemctl enable --now usbguard
sudo bash -c "usbguard generate-policy > /etc/usbguard/rules.conf"
Manejar dispositivos temporalmente
sudo usbguard list-devices
sudo usbguard allow-device #ID/Numero
sudo usbguard block-device #ID/Numero
Permitir dispositivos permanentemente
Primera vez
usbguard generate-policy > rules.conf
hx rules.conf
sudo install -m 0600 -o root -g root rules.conf /etc/usbguard/rules.conf
sudo systemctl restart usbguard
Cambio normal
Agregar toda la ruta que aparece en usbguard list-devices, sin el primer número y poniendo allow.
sudo hx /etc/usbguard/rules.conf
sudo systemctl restart usbguard
Firewalld
Entendiendo Firewalld: Tu Guardián en Linux
Firewalld es el demonio de firewall por defecto en distribuciones como Fedora, AlmaLinux, CentOS y RHEL. A diferencia de su predecesor, iptables (que también está por debajo, pero firewalld es una capa de abstracción superior), firewalld utiliza un concepto de zonas para gestionar las reglas de firewall, lo que lo hace más fácil de usar y más dinámico.
El Concepto de Zonas en Firewalld
Imagina tu red dividida en diferentes áreas de “confianza”. Cada una de estas áreas es una zona, y a cada zona se le asigna un nivel de confianza y un conjunto de reglas que definen qué tipo de tráfico se permite o se bloquea. Las interfaces de red (Ethernet, Wi-Fi) o las direcciones IP de origen se asignan a estas zonas.
Cuando un paquete de red llega a tu sistema, firewalld intenta asignarlo a una zona. Una vez que el paquete está en una zona, se aplican las reglas de esa zona para decidir si se permite, se rechaza o se descarta.
Zonas Predefinidas Comunes:
Firewalld viene con varias zonas predefinidas, cada una con un nivel de confianza y reglas por defecto:
public: La zona por defecto para redes públicas. No confías en otros ordenadores en la red. Solo se aceptan las conexiones entrantes explícitamente permitidas. Es un buen punto de partida para servidores.home: Para redes domésticas. Confías la mayoría de los otros ordenadores en la red.work: Para redes de trabajo. Confías la mayoría de los otros ordenadores.internal: Para redes internas. Mayor nivel de confianza quehomeowork.trusted: La zona de mayor confianza. Todas las conexiones de red son aceptadas. ¡Úsala con precaución!dmz(Demilitarized Zone): Para servidores que son públicos pero con acceso limitado a tu red interna.drop: Cualquier paquete entrante es descartado sin ninguna respuesta. Solo son posibles las conexiones salientes. Es la más restrictiva.block: Rechaza cualquier paquete entrante con un mensaje de “host prohibido”.external: Usada para redes externas, a menudo con enmascaramiento (NAT) habilitado, típico de routers.
Las interfaces de red se asignan a una zona. Por defecto, tu interfaz de red principal a menudo se asigna a la zona public.
Funcionamiento Básico de firewalld
firewall-cmd: Esta es la herramienta de línea de comandos principal para interactuar confirewalld.--permanent: Las reglas que añades se pueden aplicar de forma temporal (solo hasta el siguiente reinicio o recarga del firewall) o de forma permanente. Para que una regla persista después de un reinicio, debes usar la opción--permanent.--reload: Después de añadir o quitar reglas con--permanent, necesitas recargar el firewall para que los cambios permanentes se apliquen al firewall en ejecución. Si no usas--permanent, las reglas se aplican inmediatamente pero se pierden.
Comandos Clave de firewalld
1. Ver Reglas Actuales
Para ver las reglas activas en una zona específica (o en la zona por defecto si no especificas una):
sudo firewall-cmd --list-all --zone=public
- Esto mostrará el estado de la zona
public: servicios permitidos, puertos abiertos, reglas ricas, etc. - Si no especificas
--zone=public, mostrará las reglas de la zona por defecto (que a menudo espublic).
Para ver todas las zonas y sus configuraciones:
sudo firewall-cmd --list-all-zones
Para ver qué interfaces están asignadas a qué zonas:
sudo firewall-cmd --get-active-zones
2. Añadir Reglas (Permitir Tráfico)
Para permitir tráfico entrante a un puerto específico en una zona:
sudo firewall-cmd --permanent --add-port=PUERTO/protocolo --zone=zona_deseada
sudo firewall-cmd --reload
PUERTO: El número del puerto (ej.,18089).protocolo:tcpoudp.zona_deseada: La zona donde quieres aplicar la regla (ej.,public).- Ejemplo para Monero RPC:
sudo firewall-cmd --permanent --add-port=18089/tcp --zone=public
Para permitir tráfico entrante para un servicio conocido (SSH, HTTP, HTTPS, etc.) en una zona:
sudo firewall-cmd --permanent --add-service=nombre_servicio --zone=zona_deseada
sudo firewall-cmd --reload
nombre_servicio: El nombre del servicio (ej.,ssh,http). Firewalld tiene definiciones preestablecidas para los puertos y protocolos de muchos servicios comunes.
Para permitir tráfico de una fuente específica (dirección IP o rango) a una zona (esto es más restrictivo y seguro):
sudo firewall-cmd --permanent --add-source=IP_o_rango_CIDR --zone=zona_deseada
sudo firewall-cmd --reload
IP_o_rango_CIDR: Por ejemplo,192.168.1.0/24para toda tu subred local.- Ejemplo para Monero con fuente específica:
(Reemplazasudo firewall-cmd --permanent --add-source=192.168.1.0/24 --add-port=18089/tcp --zone=public sudo firewall-cmd --reload192.168.1.0/24con el rango de tu red local si es diferente).
3. Eliminar Reglas
Para quitar una regla de puerto:
sudo firewall-cmd --permanent --remove-port=PUERTO/protocolo --zone=zona_deseada
sudo firewall-cmd --reload
Para quitar una regla de servicio:
sudo firewall-cmd --permanent --remove-service=nombre_servicio --zone=zona_deseada
sudo firewall-cmd --reload
Para quitar una regla de fuente:
sudo firewall-cmd --permanent --remove-source=IP_o_rango_CIDR --zone=zona_deseada
sudo firewall-cmd --reload
4. Recargar el Firewall
Siempre que hagas cambios permanentes, ¡no olvides recargar!
sudo firewall-cmd --reload
Esto aplica los cambios permanentes al firewall en ejecución sin interrumpir las conexiones existentes.
¿Qué significa --zone=public?
Cuando usas --zone=public, estás indicando que la regla que estás añadiendo o modificando debe aplicarse a la zona public.
En el contexto de tu VM de AlmaLinux:
- Si la interfaz de red de tu VM está asignada a la zona
public(que es lo más común por defecto, especialmente si la VM está en modo puente y no hay otras zonas configuradas explícitamente), entonces al añadir una regla a la zonapublic, estás permitiendo que el tráfico del puerto 18089/tcp llegue a esa VM desde tu red local (o cualquier red asociada a la zonapublic). - La zona
publicse considera “no confiable” por defecto, lo que significa que a menos que una conexión esté explícitamente permitida, será bloqueada. Al añadir el puerto 18089 a esta zona, estás haciendo esa excepción específica.
Mullvad VPN CLI
Más usados
| Comando | Descripción |
|---|---|
mullvad account login | Inicia sesión en tu cuenta Mullvad. |
mullvad account get | Muestra la info de tu cuenta, incluyendo número, dispositivo y fecha de expiración. |
mullvad relay list | Lista ubicaciones de servidores disponibles. |
mullvad relay set location <country_code> <city_code> | Selecciona una ubicación. Reemplaza <country_code> y <city_code> con los valores deseados. |
mullvad relay set location <server_name> | Selecciona un servidor específico por nombre. |
mullvad connect | Conecta a la ubicación seleccionada. |
mullvad disconnect | Desconecta la VPN. |
mullvad status -v | Revisa el estado de conexión con detalles. |
mullvad auto-connect set on | Habilita auto-conexión al inicio. |
mullvad lockdown-mode set on | Habilita Lockdown para bloquear todo el tráfico hasta conectar con Mullvad. |
mullvad dns set default --block-ads --block-trackers --block-malware --block-adult-content | Para activar todos los filtros DNS excepto redes sociales, usa este comando. |
mullvad relay set tunnel-protocol wireguard | Usa WireGuard como protocolo de túnel (por defecto). |
mullvad tunnel set wireguard --quantum-resistant on | Habilita Quantum Resistant. |
Comandos básicos
| Comando | Descripción |
|---|---|
mullvad account login <account_number> | Inicia sesión en tu cuenta Mullvad. Reemplaza <account_number> por tu número real. |
mullvad account get | Muestra la info de tu cuenta, incluyendo número, dispositivo y fecha de expiración. |
mullvad account list-devices | Lista los dispositivos asociados a tu cuenta. |
mullvad relay list | Lista ubicaciones de servidores disponibles. |
mullvad relay set location <country_code> <city_code> | Selecciona una ubicación. Reemplaza <country_code> y <city_code> con los valores deseados. |
mullvad relay set location <server_name> | Selecciona un servidor específico por nombre. |
mullvad connect | Conecta a la ubicación seleccionada. |
mullvad disconnect | Desconecta la VPN. |
mullvad relay update | Fuerza actualización de la lista de servidores. |
mullvad status -v | Revisa el estado de conexión con detalles. |
Comandos avanzados
| Comando | Descripción |
|---|---|
mullvad relay set tunnel-protocol openvpn | Usa OpenVPN como protocolo de túnel. |
mullvad relay set tunnel openvpn --transport-protocol tcp | Usa OpenVPN sobre TCP. |
mullvad relay set tunnel-protocol wireguard | Usa WireGuard como protocolo de túnel (por defecto). |
mullvad auto-connect set on | Habilita auto-conexión al inicio. |
mullvad auto-connect set off | Deshabilita auto-conexión al inicio. |
mullvad lan set allow | Habilita acceso LAN. |
mullvad lockdown-mode set on | Habilita Lockdown para bloquear todo el tráfico hasta conectar con Mullvad. |
mullvad tunnel set ipv6 on | Habilita IPv6 dentro del túnel. |
Split tunneling (Linux)
| Comando | Descripción |
|---|---|
mullvad-exclude <program> | Inicia un proceso excluido de Mullvad. |
mullvad split-tunnel add <pid> | Excluye un proceso en ejecución usando su PID. |
mullvad split-tunnel list | Lista procesos excluidos. |
mullvad split-tunnel delete <pid> | Para restaurar un proceso excluido usa este comando. |
mullvad split-tunnel clear | Para restaurar todos los procesos excluidos usa este comando. |
Comandos de Shadowsocks
| Comando | Descripción |
|---|---|
mullvad bridge set location <location> | Define ubicación para Shadowsocks. Reemplaza <location> con país o ciudad. |
mullvad bridge set state on | Habilita modo puente para Shadowsocks. |
mullvad bridge set state off | Deshabilita modo puente. |
mullvad bridge set custom set shadowsocks --cipher <CIPHER> <REMOTE_IP> <REMOTE_PORT> <PASSWORD> | Configura ajustes avanzados de Shadowsocks. |
Comandos DNS
| Comando | Descripción |
|---|---|
mullvad dns set default --help | Para ver la ayuda usa este comando. |
mullvad dns set default --block-ads --block-trackers --block-malware --block-gambling --block-adult-content | Para activar todos los filtros DNS excepto redes sociales, usa este comando. |
mullvad dns set default | Para desactivar todos los bloqueadores usa este comando. |
Listas personalizadas
| Comando | Descripción |
|---|---|
mullvad custom-list new Favorites | Para crear una lista personalizada llamada “Favorites” usa este comando. |
mullvad custom-list edit add Favorites se-mma-wg-001 | Para agregar un servidor, ciudad o país a la lista usa uno de estos comandos. |
mullvad custom-list edit add Favorites se got | Para agregar un servidor, ciudad o país a la lista usa uno de estos comandos. |
mullvad custom-list edit add Favorites se | Para agregar un servidor, ciudad o país a la lista usa uno de estos comandos. |
mullvad relay set custom-list Favorites | Para seleccionar tu lista personalizada y conectarte, usa este comando. |
mullvad custom-list edit remove Favorites se-mma-wg-001 | Para eliminar un servidor, ciudad o país de la lista usa uno de estos comandos (igual que agregar). |
mullvad custom-list edit rename Favorites Favourites | Para renombrar una lista personalizada usa este comando. |
mullvad custom-list list | Para listar todas tus listas personalizadas y su contenido usa este comando. |
Restablecer ajustes
| Comando | Descripción |
|---|---|
mullvad factory-reset | Este comando restablece ajustes de fábrica, borra logs y cache, desconecta la app y cierra sesión. |
Página oficial
WebRTC
Firefox
Nota: Firefox es el único navegador que puede desactivar WebRTC por completo.
-
- Escribe about:config en la barra de direcciones y presiona Enter.
-
- Haz clic en I accept the risk!.
-
- Escribe media.peerconnection.enabled en el buscador. Debe aparecer una sola entrada.
-
- Haz doble clic en la entrada para cambiarla a false.
Para habilitar WebRTC nuevamente, vuelve a cambiarlo a “true”.
Brave (desktop y Android)
Desktop
Abre Ajustes y haz clic en el icono de la lupa arriba a la derecha y busca webrtc. En WebRTC IP Handling Policy selecciona Disable Non-Proxied UDP.
Android
Abre Ajustes y toca Brave Shields & privacy. Luego baja y toca WebRTC IP Handling Policy. Selecciona Disable Non-Proxied UDP y toca la X arriba a la derecha.
Pruebas
Mullvad SOCKS5
Brave
Agrega esta línea –proxy-server=socks5://10.64.0.1 en el .desktop (en /home/user/.local/share/applications para que no se sobrescriba)
Exec=/usr/bin/brave-browser-stable --proxy-server=socks5://10.64.0.1 --enable-features=UseOzonePlatform --ozone-platform=wayland %U
ssss
ssss-split -t 3 -n 5
Generating shares using a (3,5) scheme with dynamic security level.
Enter the secret, at most 128 ASCII characters: my secret root password
Using a 184 bit security level.
1-1c41ef496eccfbeba439714085df8437236298da8dd824
2-fbc74a03a50e14ab406c225afb5f45c40ae11976d2b665
3-fa1c3a9c6df8af0779c36de6c33f6e36e989d0e0b91309
4-468de7d6eb36674c9cf008c8e8fc8c566537ad6301eb9e
5-4756974923c0dce0a55f4774d09ca7a4865f64f56a4ee0
ssss-combine -t 3
Enter 3 shares separated by newlines:
Share [1/3]: 3-fa1c3a9c6df8af0779c36de6c33f6e36e989d0e0b91309
Share [2/3]: 5-4756974923c0dce0a55f4774d09ca7a4865f64f56a4ee0
Share [3/3]: 2-fbc74a03a50e14ab406c225afb5f45c40ae11976d2b665
Resulting secret: my secret root password
Qrrs
Uso
Generar QR rápido
qrrs "Your input here"
qrrs "Your input here" --invert_colors
Generar QR y luego leerlo
qrrs "Something" /tmp/qr.png
$ qrrs --read /tmp/qr.png
Something
Imprimir el código generado en la terminal
qrrs -t "Something" /tmp/qr.png
█████████████████████████████
█████████████████████████████
████ ▄▄▄▄▄ █▄ █▄▄█ ▄▄▄▄▄ ████
████ █ █ █▀▄████ █ █ ████
████ █▄▄▄█ █ ▄█▀▄█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█ ▀ ▀ █▄▄▄▄▄▄▄████
████▄███ █▄▄ ▄▀ ▀▄▄▄ █▀▄████
████▄ ▀█▀▄▄▀▄▀▀▄█▀▄█ █▄ ▀████
████▄█▄██▄▄▄▀▀▀█ ▄▀█ ▀█▄ ████
████ ▄▄▄▄▄ █▄▀▄▀ ▄▄▀ ██ █████
████ █ █ █▄█▀ ▀▄▄█ ▀▀ ▀████
████ █▄▄▄█ ██▀ ▄█▀ ▀ ████████
████▄▄▄▄▄▄▄█▄▄▄█▄▄▄▄█▄██▄████
█████████████████████████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Mostrar el código como texto en la terminal
qrrs --read --terminal /tmp/qr.png
█████████████████████████████
█████████████████████████████
████ ▄▄▄▄▄ █▄ █▄▄█ ▄▄▄▄▄ ████
████ █ █ █▀▄████ █ █ ████
████ █▄▄▄█ █ ▄█▀▄█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█ ▀ ▀ █▄▄▄▄▄▄▄████
████▄███ █▄▄ ▄▀ ▀▄▄▄ █▀▄████
████▄ ▀█▀▄▄▀▄▀▀▄█▀▄█ █▄ ▀████
████▄█▄██▄▄▄▀▀▀█ ▄▀█ ▀█▄ ████
████ ▄▄▄▄▄ █▄▀▄▀ ▄▄▀ ██ █████
████ █ █ █▄█▀ ▀▄▄█ ▀▀ ▀████
████ █▄▄▄█ ██▀ ▄█▀ ▀ ████████
████▄▄▄▄▄▄▄█▄▄▄█▄▄▄▄█▄██▄████
█████████████████████████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Guardarlo en otro archivo
qrrs --read --terminal /tmp/qr.png /tmp/qr1.png
Casi el mismo resultado, pero sin la opción de terminal. En vez de imprimir el QR en la terminal, verás el texto.
qrrs --read /tmp/qr.png /tmp/qr1.png
Contraseña GRUB2
En Libreboot
-
- Generar el hash de la contraseña
grub2-mkpasswd-pbkdf2
La salida debería ser algo como:
grub.pbkdf2.sha512.10000.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-
- Abrir con sudo /etc/grub.d/40_custom. Al final agrega:
#──────────────────────────────────────
set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.XXXXXXXXXXXXXXXXXXXXXXXX
#──────────────────────────────────────
-
- Actualizar GRUB
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot
-
- Probar Probar con “e”, debería pedir un usuario y una contraseña.
Guía de Impresión Minimalista Fedora
1. Instalación de paquetes necesarios
Instala el motor de impresión, el cliente y el driver específico (en este caso para impresoras láser Brother):
sudo dnf install cups cups-client printer-driver-brlaser
2. Activación del servicio (Modo Eficiente)
Activa solo el socket de systemd. El servicio principal de CUPS solo se encenderá cuando mandes un archivo a imprimir, ahorrando recursos:
sudo systemctl disable cups
sudo systemctl enable --now cups.socket
3. Configuración inicial
- Accede a la interfaz local: http://localhost:631
- Ve a Administration > Add Printer (usa tu usuario y contraseña de sistema).
- Selecciona la impresora detectada por USB o red.
- Elige el fabricante y el modelo correspondiente en la lista (usando el driver
brlasersi es compatible). - En Set Default Options, selecciona el tamaño de papel (ej. A4) y guarda.
4. Definir impresora predeterminada (CLI)
Para que el sistema sepa a dónde enviar los archivos por defecto sin errores:
# Listar nombre exacto asignado a la impresora
lpstat -p
# Establecer como predeterminada (reemplaza con tu nombre)
lpadmin -d [NOMBRE_IMPRESORA]
5. Comandos rápidos de uso
- Imprimir cualquier archivo:
lp archivo.pdf - Imprimir imagen ajustada a la página:
lp -o fit-to-page imagen.png - Ver estado de la cola:
lpq - Limpiar todos los trabajos pendientes:
cancel -a
Cómo instalar temas GRUB en Fedora (Libreboot)
Instalar un tema
1. Descargar el tema:
cd /tmp
git clone https://github.com/usuario/nombre-tema.git
2. Copiar a la carpeta de temas de GRUB:
sudo mkdir -p /boot/grub2/themes
sudo cp -r /tmp/nombre-tema/carpeta-del-tema /boot/grub2/themes/mi-tema
Verifica que dentro exista theme.txt:
ls /boot/grub2/themes/mi-tema/theme.txt
3. Editar configuración de GRUB:
sudo hx /etc/default/grub
Añade o modifica:
GRUB_THEME="/boot/grub2/themes/mi-tema/theme.txt"
Si existe GRUB_TERMINAL=console, coméntala (los temas necesitan modo gráfico):
#GRUB_TERMINAL=console
4. Regenerar grub.cfg:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
5. Reiniciar:
sudo reboot
Desinstalar / volver al menú normal
Edita /etc/default/grub y quita la línea GRUB_THEME. Regenera:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
Cambiar de tema
Repite los pasos 1-5 con el nuevo tema. Solo puede haber un GRUB_THEME activo a la vez.
Dónde encontrar temas
Notas
- Un tema GRUB es solo imágenes (PNG), fuentes (.pf2) y un archivo de texto (theme.txt). No ejecuta código. Es seguro.
- Si el tema se ve mal, puede ser incompatibilidad de resolución. Busca temas que coincidan con tu pantalla (1920x1080 = 16:9).
- Esto funciona porque Libreboot carga el grub.cfg de Fedora, que incluye la directiva del tema.
Guía de Dual-Boot en Libreboot
Guía práctica para configurar dual-boot (o multi-boot) de distribuciones Linux en un sistema con Libreboot. Basada en Libreboot 26.01 “Magnanimous Max” con GRUB 2.14.
Conceptos clave
En Libreboot, GRUB vive en la ROM (chip SPI), no en el disco. Cuando instalas una distro y ejecuta grub-install, ese GRUB en disco nunca se ejecuta como bootloader. Libreboot solo lee el archivo grub.cfg de cada distro mediante el comando configfile.
El flujo de arranque es: coreboot → GRUB (desde ROM) → escanea discos → encuentra grub.cfg → carga kernel.
No existe chainloading (chainloader +1 no funciona). No necesitas ESP (EFI System Partition). El GRUB de la ROM ya trae los módulos necesarios compilados (ext2, btrfs, luks2, search, configfile, etc.), por lo que no necesitas insmod.
Nombres de dispositivo en GRUB de Libreboot
Los discos NVMe se ven como (nvme0n1,gptX). Los SATA como (ahci0,gptX). USB como (usb0). Puedes verificarlos presionando c en el menú de Libreboot y escribiendo ls.
Esquema mínimo de particiones
Cada distro necesita como mínimo:
/dev/nvme0n1pX — ext4 — /boot de la distro (~1 GiB)
/dev/nvme0n1pY — crypto_LUKS — / de la distro (resto)
Ejemplo con Fedora + Linux Mint:
nvme0n1p1 — (reservada/vacía)
nvme0n1p2 — ext4 — /boot Fedora
nvme0n1p3 — LUKS2 — / Fedora (cifrado)
nvme0n1p4 — ext4 — /boot Distro 2
nvme0n1p5 — LUKS2 — / Distro 2 (cifrado)
Para agregar una tercera distro, simplemente añades dos particiones más (boot + LUKS).
Reglas importantes:
- Cada distro debe tener su propio
/bootseparado (ext4). - Cada distro puede tener su propia partición LUKS independiente.
- No se necesita ESP ni partición EFI.
- Al instalar, deja que el instalador instale GRUB normalmente. Aunque no se usa como bootloader, el proceso genera el
grub.cfgque Libreboot necesita.
Cómo agregar una distro al menú de arranque
Paso 1: Instalar la distro
Usa particionado manual en el instalador. Asigna su /boot y su partición raíz (con LUKS si quieres cifrado). No toques las particiones de las distros existentes.
Paso 2: Verificar que generó grub.cfg
Desde tu distro principal:
sudo mkdir -p /mnt/newboot
sudo mount /dev/nvme0n1pX /mnt/newboot # X = partición /boot de la nueva distro
ls /mnt/newboot/grub/grub.cfg # Debian/Ubuntu/Mint usan /grub/
ls /mnt/newboot/grub2/grub.cfg # Fedora usa /grub2/
sudo umount /mnt/newboot
Si no existe grub.cfg, hay que generarlo vía chroot (ver sección “Solución de problemas”).
Paso 3: Obtener el UUID del /boot de la nueva distro
lsblk -f
Busca el UUID de la partición ext4 que es /boot de la nueva distro.
Paso 4: Agregar entrada en 40_custom de la distro principal
Edita el archivo de entradas personalizadas de GRUB en tu distro principal (la que Libreboot carga por defecto):
sudo hx /etc/grub.d/40_custom
El archivo debe verse así:
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry 'Nombre de la Distro' --class nombredistro --class gnu-linux --class os {
search --no-floppy --fs-uuid --set=root UUID_DEL_BOOT
configfile /grub/grub.cfg
}
Reemplaza:
Nombre de la Distro→ lo que quieras ver en el menú.--class→ el icono que se usaraUUID_DEL_BOOT→ el UUID de la partición/bootde esa distro (paso 3)./grub/grub.cfg→ usa/grub2/grub.cfgsi es Fedora.
Para múltiples distros, simplemente añade más bloques menuentry:
#!/bin/sh
exec tail -n +3 $0
menuentry 'Linux Mint' {
search --no-floppy --fs-uuid --set=root aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
configfile /grub/grub.cfg
}
menuentry 'Debian GNU/Linux' {
search --no-floppy --fs-uuid --set=root ffffffff-1111-2222-3333-444444444444
configfile /grub/grub.cfg
}
menuentry 'Arch Linux' {
search --no-floppy --fs-uuid --set=root 55555555-6666-7777-8888-999999999999
configfile /grub/grub.cfg
}
Paso 5: Asegurar que es ejecutable y regenerar
sudo chmod +x /etc/grub.d/40_custom
En Fedora:
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
En Debian/Ubuntu/Mint:
sudo update-grub
Paso 6: Reiniciar y probar
sudo reboot
La nueva distro aparecerá al final del menú de arranque.
Arranque manual desde consola GRUB
Si algo falla, presiona c en el menú de Libreboot para obtener la consola GRUB.
Ver dispositivos disponibles
ls
Arrancar manualmente cargando grub.cfg de una distro
search --no-floppy --fs-uuid --set=root UUID_DEL_BOOT
configfile /grub/grub.cfg
Arrancar manualmente sin grub.cfg
set root=(nvme0n1,gptX)
linux /vmlinuz-VERSION root=/dev/mapper/NOMBRE_LUKS
initrd /initrd.img-VERSION
boot
Solución de problemas
La distro no generó grub.cfg
Desde tu distro principal, hacer chroot:
# Abrir LUKS si es cifrado
sudo cryptsetup open /dev/nvme0n1pY nombre-root
# Montar raíz (ajustar opciones según filesystem)
sudo mkdir -p /mnt/distro
sudo mount /dev/mapper/nombre-root /mnt/distro
# Si es btrfs con subvolumen:
# sudo mount -o subvol=@rootfs /dev/mapper/nombre-root /mnt/distro
# Montar /boot
sudo mount /dev/nvme0n1pX /mnt/distro/boot
# Montar sistemas virtuales
sudo mount --bind /dev /mnt/distro/dev
sudo mount --bind /dev/pts /mnt/distro/dev/pts
sudo mount --bind /proc /mnt/distro/proc
sudo mount --bind /sys /mnt/distro/sys
# Chroot y generar grub.cfg
sudo chroot /mnt/distro
update-grub # Debian/Ubuntu/Mint
# grub2-mkconfig -o /boot/grub2/grub.cfg # Fedora
exit
# Limpiar
sudo umount /mnt/distro/sys
sudo umount /mnt/distro/proc
sudo umount /mnt/distro/dev/pts
sudo umount /mnt/distro/dev
sudo umount /mnt/distro/boot
sudo umount /mnt/distro
sudo cryptsetup close nombre-root
Cae a initramfs (BusyBox) al arrancar
El initramfs no tiene instrucciones para desbloquear LUKS. Verificar crypttab y regenerar initramfs vía chroot:
# Dentro del chroot:
cat /etc/crypttab # Debe tener una entrada para el volumen LUKS
update-initramfs -u -k all # Debian/Ubuntu/Mint
# dracut --regenerate-all # Fedora
Notas sobre distros específicas
- Fedora: usa
/grub2/grub.cfg(no/grub/). Usa BLS por defecto. Si da problemas, editar/etc/default/gruby ponerGRUB_ENABLE_BLSCFG=false, luego regenerar. ConfigurarGRUB_TERMINAL=console. - Debian/Ubuntu/Mint: usa
/grub/grub.cfg. Formato tradicional, compatible sin ajustes. - Arch Linux: usa
/grub/grub.cfg. Compatible sin ajustes.
Notas sobre encriptación LUKS
- Libreboot 26.01+ soporta LUKS2 con argon2id nativamente (GRUB 2.14).
- El desbloqueo en GRUB es más lento que en el kernel (sin aceleración hardware). Si tarda mucho, ajustar parámetros KDF con:
cryptsetup luksConvertKey /dev/sdX --pbkdf argon2id --pbkdf-force-iterations 4 --pbkdf-memory 131072 - Si
/bootestá fuera del LUKS (como en esta guía), GRUB no necesita descifrar nada — el initramfs se encarga.
Referencia rápida
| Acción | Comando |
|---|---|
| Ver UUIDs | lsblk -f |
| Editar entradas custom | sudo hx /etc/grub.d/40_custom |
| Regenerar GRUB (Fedora) | sudo grub2-mkconfig -o /boot/grub2/grub.cfg |
| Regenerar GRUB (Debian/Mint) | sudo update-grub |
| Consola GRUB en Libreboot | Presionar c en el menú |
| Ver dispositivos en GRUB | ls |
| Regenerar initramfs (Debian) | sudo update-initramfs -u -k all |
| Regenerar initramfs (Fedora) | sudo dracut --regenerate-all |
| Abrir LUKS | sudo cryptsetup open /dev/nvme0n1pX nombre |
| Cerrar LUKS | sudo cryptsetup close nombre |
GNU Stow
sudo dnf install stow
Funciona así:
Home normal:
~
|
|-> .zshrc
-> .config
-> alacritty
-> alacritty.toml
-> *
Luego en Stow:
stow_dir
|
|-> zsh
| -> .zshrc
|
-> alacritty
-> .config
-> alacritty
-> alacritty.toml
-> *
Luego para hacer los enlaces simbólicos:
stow zsh alacritty
dd
sudo dd if=tails.img of=device bs=16M oflag=direct status=progress
sudo dd if=~/Descargas/kali-linux.iso of=/dev/sdb bs=4M status=progress oflag=sync
Búsqueda en CLI (grep, rg, find, locate, fd)
Guía rápida para buscar texto y archivos desde la terminal.
Qué usar según el caso
grep: buscar texto dentro de archivos.rg(ripgrep): igual que grep, pero más rápido y respeta.gitignore.find: buscar archivos por nombre, fecha, tamaño o permisos.locate: buscar rutas rápido usando una base de datos local.fd: alternativa moderna afindpara búsqueda por nombre.
grep
# Buscar texto en archivos (recursivo)
grep -RIn "patron" ruta/
# Ignorar mayúsculas/minúsculas
grep -RIn -i "patron" ruta/
# Buscar y excluir líneas
grep -RIn "patron" ruta/ | grep -v "excluir"
rg (ripgrep)
# Buscar texto en el repo actual
rg "patron"
# Buscar solo en .md
rg -n -g "*.md" "patron"
# Listar archivos que contienen el patrón
rg -l "patron"
find
# Buscar archivos por extensión
find . -type f -name "*.md"
# Buscar archivos modificados en los últimos 7 días
find . -type f -mtime -7
# Buscar texto usando find + grep
find . -type f -name "*.conf" -exec grep -n "patron" {} +
locate
# Buscar rutas en la base de datos
locate nombre_archivo
# Actualizar la base (según distro)
sudo updatedb
fd
# Buscar por nombre (regex)
fd "config" ~/.config
# Filtrar por extension
fd -e rs
# Incluir ocultos y no respetar .gitignore
fd -H -I "patron" .
Tips rápidos
- Si buscas texto:
rgogrep. - Si buscas archivos por nombre:
fd(simple) ofind(filtros avanzados). - Si quieres máxima velocidad para rutas conocidas:
locate.
Yazi
Requisitos
Para usar Yazi necesitas lo siguiente:
file(detección de tipo de archivo)
Opcional
Puedes ampliar Yazi con herramientas de línea de comandos:
nerd-fonts(recomendado)ffmpeg(miniaturas de video)7-Zip(extracción y vista previa de archivos)jq(vista previa de JSON)poppler(vista previa de PDF)fd(búsqueda de archivos)rg(búsqueda dentro de archivos)fzf(navegación rápida por subárboles, >= 0.53.0)zoxide(navegación por historial, requiere fzf)resvg(vista previa de SVG)ImageMagick(vista previa de fuentes, HEIC y JPEG XL)xclip/wl-clipboard/xsel(portapapeles en Linux)
Compilar
sudo dnf install chafa fzf
cargo install --locked yazi-fm yazi-cli
Uso
yazi
O crea una función en bash para que respete el cwd:
y() {
local tmp
tmp="$(mktemp -t "yazi-cwd.XXXXXX")"
yazi "$@" --cwd-file="$tmp"
if [ -s "$tmp" ]; then
local cwd
cwd="$(cat "$tmp")"
[ -n "$cwd" ] && [ "$cwd" != "$PWD" ] && cd "$cwd"
fi
rm -f "$tmp"
}
Luego ejecuta:
yazi
Atajos de teclado
F1 para ver keybindings
Recursos oficiales
ln
-
ln(hard link)-
Crea un segundo nombre (alias) para el mismo archivo en el sistema de ficheros.
-
Ambos nombres comparten el mismo inode y, por tanto, los mismos datos; borrar uno no afecta al otro hasta que ambos se eliminen.
-
Sintaxis básica:
ln <ruta_origen> <ruta_destino> -
Limitaciones:
- Debe residir en la misma partición.
- Git lo trata como un archivo normal (bueno), pero no detecta que hay “vínculo” (todo bien).
-
-
ln -s(symbolic link / symlink)-
Crea un pequeño archivo que apunta a otro por su ruta. No comparten inode.
-
Borrar el objetivo deja un “enlace roto”.
-
Sintaxis básica:
ln -s <ruta_origen> <ruta_destino> -
Ventajas:
- Funciona entre distintas particiones o sistemas de ficheros.
- Con rutas relativas, es portátil si se conserva la estructura de carpetas.
-
Consideraciones con Git:
- Git almacena la ruta del symlink, no el contenido.
- Quienes clonen el repo obtendrán el enlace, que puede fallar si no existe la misma ruta en sus máquinas.
-
Resumen de usos
- Usa hard link (
ln) cuando quieras un segundo nombre indistinguible para el mismo fichero y estés en la misma partición. - Usa symlink (
ln -s) cuando necesites apuntar a archivos en otra ubicación o mantener portabilidad con rutas relativas.
Ghostscript (Reducir tamaño de PDF)
Para reducir el tamaño de un PDF.
sudo dnf install ghostscript
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dNOPAUSE -dQUIET -dBATCH -dDetectDuplicateImages=true -dCompressFonts=true -dSubsetFonts=true -dAutoRotatePages=/None -dPDFSETTINGS=/ebook -dColorImageDownsampleType=/Bicubic -dColorImageResolution=150 -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=150 -dMonoImageDownsampleType=/Subsample -dMonoImageResolution=300 -sOutputFile=output.pdf input.pdf
Carapace
Descargar el rpm, esto es para Nushell
sha256sum carapace-bin*linux*.rpm
sudo dnf install carapace-bin*linux*.rpm
# ~/.config/nushell/env.nu
mkdir ~/.cache/carapace
carapace _carapace nushell | save --force ~/.cache/carapace/init.nu
# ~/.config/nushell/config.nu
source ~/.cache/carapace/init.nu
LocalSend
tar -xvf LocalSend-X.XX.X-linux-XXX.tar.gz
sudo mkdir -p /opt/localsend
sudo cp data/ lib/ localsend_app /opt/localsend
cp localsend.desktop .local/share/applications/localsend.desktop
Extra
sudo firewall-cmd --add-port=53317/tcp --zone=drop
Fedora + Nix
Índice
- Preparando Todo
- Usuarios (mínimo privilegio)
- Login: greetd + tuigreet + niri
- Sudo-rs
- Instalar Nix (multiusuario)
- Configurar Nix en
/etc/nix/nix.conf - Sistema base con DNF
- Flake Home Manager
- Notas útiles y rollbacks
Preparación
sudo dnf up -y
sudo dnf install -y helix tar git NetworkManager-wifi NetworkManager-tui iwlwifi-mvm-firmware
Usuarios (mínimo privilegio)
admin→ con sudomain/safe→ sin sudo.
Crear usuarios:
sudo groupadd -f nhm
sudo useradd -m -s /bin/bash -G nhm main && sudo passwd main
sudo useradd -m -s /bin/bash -G nhm safe && sudo passwd safe
Login: greetd + tuigreet + niri
sudo dnf install -y niri greetd tuigreet xdg-desktop-portal xdg-desktop-portal-wlr
sudo dnf remove -y fuzzel nano bluez
Configurar /etc/greetd/config.toml:
[terminal]
vt = 1
[default_session]
command = "tuigreet --cmd 'niri --session' --time --remember --asterisks"
user = "greetd"
Habilitar:
sudo systemctl set-default graphical.target
sudo systemctl enable greetd
Sudo-rs
su
dnf -y in sudo-rs
install -d /usr/local/bin
cat >/usr/local/bin/sudo <<'EOF'
#!/bin/sh
exec /usr/bin/sudo-rs "$@"
EOF
chmod 0755 /usr/local/bin/sudo
restorecon -v /usr/local/bin/sudo || true
type -a sudo # debe listar /usr/local/bin/sudo primero
Su-rs
su
cat >/usr/local/bin/su <<'EOF'
#!/bin/sh
exec /usr/bin/su-rs "$@"
EOF
chmod 0755 /usr/local/bin/su
restorecon -v /usr/local/bin/su || true
type -a su # debe listar /usr/local/bin/su primero
Instalar Nix (multiusuario)
curl --proto '=https' --tlsv1.2 -sSf -L https://artifacts.nixos.org/experimental-installer | sh -s -- install
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
Configurar Nix en /etc/nix/nix.conf
Preparar directorio:
sudo mkdir /nhm
sudo chown admin:nhm /nhm
sudo chmod 750 /nhm
cd /nhm
git clone https://codeberg.org/Kyronix/dotfiles.git
cd dotfiles
git checkout nix-fedora
sudo git config --system --add safe.directory /nhm/dotfiles
Editar como root:
experimental-features = nix-command flakes
sandbox = true
sandbox-fallback = false
trusted-users = root @wheel
keep-outputs = true
keep-derivations = true
Aplicar:
sudo systemctl restart nix-daemon
Sistema base con DNF
sudo dnf config-manager addrepo --from-repofile=https://repository.mullvad.net/rpm/stable/mullvad.repo
sudo dnf config-manager addrepo --from-repofile=https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo
sudo dnf install -y setroubleshoot nmap dnf-plugins-core power-profiles-daemon wlogout \
libguestfs-tools usbguard-selinux @virtualization brave-browser mullvad-vpn mullvad-browser \
lxqt-policykit clamav swayidle pulseaudio-utils foot mako
Flake Home Manager
# Genera/Actualiza flake.lock
cd /nhm/dotfiles
nix flake update
Desde el usuario correr este comando:
nix run /nhm/dotfiles#home-manager -- switch --flake /nhm/dotfiles#<usuario>
# Logeado como admin
nix run /nhm/dotfiles#home-manager -- switch --flake /nhm/dotfiles#admin
# Logeado como main
nix run /nhm/dotfiles#home-manager -- switch --flake /nhm/dotfiles#main
# Logeado como safe
nix run /nhm/dotfiles#home-manager -- switch --flake /nhm/dotfiles#safe
Extra
Si estas en /nhm/dotfiles se puede usar:
nix run .#home-manager -- switch --flake .#admin
Notas útiles
- Update:
cd /nhm/dotfiles
nix flake update # refresca nixpkgs/home-manager en flake.lock
# aplica por usuario:
nix run .#home-manager -- switch --flake .#admin
nix run .#home-manager -- switch --flake .#main
nix run .#home-manager -- switch --flake .#safe
- HM:
home-manager generations
home-manager switch --rollback
- Limpieza:
sudo nix store gc
# Por usuario
home-manager expire-generations "-30 days"
Monero Node
Store Monero Node on an external drive.
- First, do the same as in the LUKS guide for the drive.
- Assuming that /dev/sdb is the drive

If you don’t use sudo, just change it to sudo
Preparing the Drive
sudo fdisk /dev/sdb
n
# Enter
# Enter
# Enter
# Enter
w
Optional encryption
sudo cryptsetup luksFormat /dev/sdb1
sudo cryptsetup open /dev/sdb1 a
sudo mkfs.ext4 /dev/mapper/a
sudo cryptsetup close a
sync
Downloading monerod
Install monerod in your distro of choice
# In Archlinux
sudo pacman -S monero
# In Debian
sudo apt install monero
# With Homebrew
brew install monero
or
In other distros install wget and ->
wget https://downloads.getmonero.org/gui/linux64
# Or if you prefer only cli
wget https://downloads.getmonero.org/cli/linux64
tar -xvf linux64
# ...
sudo cp monerod /usr/local/bin/
sudo cp monero-wallet-cli /usr/local/bin/
# Or just
sudo mv monero* /usr/local/bin/
or
Recommended to create a user without sudo for only monero
Setting up Monero
sudo useradd --system --shell /usr/sbin/nologin --home-dir /var/lib/monero monero
sudo mkdir -p /mnt/monero-node/
sudo mount /dev/xxx /mnt/monero-node
sudo mkdir -p /mnt/monero-node/.bitmonero # Your blockchain storage location
sudo mkdir -p /var/log/monero # Log directory
sudo mkdir -p /etc/monero # Configuration directory
sudo mkdir -p /run/monero
sudo chown monero:monero /run/monero
# Set ownership for blockchain directory
sudo chown -R monero:monero /mnt/monero-node/.bitmonero
sudo chmod 750 /mnt/monero-node/.bitmonero
# Set ownership for log directory
sudo chown -R monero:monero /var/log/monero
sudo chmod 750 /var/log/monero
# Create the monerod configuration file
sudo vim /etc/monero/monerod.conf
sudo chown root:monero /etc/monero/monerod.conf
sudo chmod 640 /etc/monero/monerod.conf
Firewall
sudo firewall-cmd --permanent --add-port=18089/tcp --zone=drop
sudo firewall-cmd --reload
Run Monerod
There are 2 alternatives; Service or Terminal
Monerod Service
# Create the systemd service file
sudo vim /etc/systemd/system/monerod.service
sudo systemctl daemon-reload
sudo systemctl enable monerod
sudo systemctl start monerod
sudo systemctl status monerod
Monerod in Terminal
sudo -u monero /usr/local/bin/monerod --config-file=/etc/monero/monerod.conf
Homebrew (In Linux)
sudo -u monero /home/linuxbrew/.linuxbrew/bin/monerod --config-file=/etc/monero/monerod.conf
Cli Wallet
monero-wallet-cli --trusted-daemon --daemon-login username
Monero Ban List
In monero
Cake Wallet
sha256sum Cake_Wallet_v5.1.2_Linux.tar.xz # Check in the release page
tar -xvf Cake_Wallet_v5.1.2_Linux.tar.xz
sudo mv Cake_Wallet*Linux /opt/cakewallet
Entrada de escritorio
sudo hx ~/.local/share/applications/cakewallet.desktop
Copia esto:
[Desktop Entry]
Version=1.0
Type=Application
Name=CakeWallet
Comment=Wallet (CakeWallet Desktop)
Exec=/opt/cakewallet/cake_wallet %U
Icon=/opt/cakewallet/data/flutter_assets/assets/images/cake_logo_dark.svg
Terminal=false
Categories=Finance;Wallet;Cryptocurrency;
StartupNotify=true