Welcome
My docs

CODEBERG (Could work with github)
SSH AUTENTIFICACION
git config --global user.name "John Doe"
git config --global user.email "johnDoe123@email.com"
ssh-keygen -t ed25519 -a 100
[Press enter to select default]
set pwd
cat ~/.ssh/id_ed25519.pub
Copy ssh-ed... to the end without user@algo
Add this in codeberg -> config -> add ssh
Setup user to commit
Do as the msg says but the email should be the one that has the @noreply in user settings Profile at the bottom
POSTGRESQL
Install
sudo dnf install -y postgresql postgresql-server
sudo postgresql-setup --initdb --unit postgresql
sudo systemctl start postgresql
Running psql
sudo -i -u postgres
psql
Setup postgres and User
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 contrsaeña de un user
ALTER USER postgres WITH PASSWORD 'nueva_contraseña'; # Poner contraseña a postgres de ser necesario
DROP USER nombre_usuario; # Eliminar usuario
To Connect to the database from outside
To connect to tools like pgadmin4 or pgmodeler.
sudo -i -u postgres
psql
ALTER USER postgres WITH PASSWORD 'nueva_contraseña';
\q
Go to /var/lib/pgsql/data/pg_hba.conf. In the end of the file change the line that says
local all all peer # Original
local all all md5 # Cambio
host all all 127.0.0.1/32 ident # Original (no exactamente 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
Then in the same data dir open postgresql.conf and add at the end this:
listen_addresses = 'localhost' # If doesnt work try '*'
With this is all ready just restart the psql service, and put the correct pwd in the tool that your gonna use.
sudo systemctl restart postgresql # In normal user
DB
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
Commands
\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
Conf
La configuración principal se guarda en:
/var/lib/pgsql/data/postgresql.conf
Data Type
-
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 digitos en total, 2 despues 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 maxima n)
-
TEXT (Longitud variable sin limite explicito)
-
CHAR(n) (Longitud fija de n)
-
DATE (año, mes, dia)
-
TIME
-
TIMESTAMP (Fecha y hora con precisión hasta fracciones de segundo)
-
TIMESTAMPTZ (Con zona horaria)
-
INTERVAL (Periodo de timepo (diferencia entre dos fechas u horas))
-
BOOLEAN (TRUE, FALSE, NULL)
-
SERIAL (Autoincremental. Usualmente usado en ejemplo: id SERIAL PRIMARY KEY)
-
BIGSERIAL (Lo mismo pero mas grande)
-
UUID (Almacena un identificador unico universal)
-
JSON
-
JSONB (Lo mismo que json pero en formato binario)
-
XML (Datos en formato xml)
-
BYTEA (Binarios como imagenes o archivos)
-
ARRAY (Lista de valores de tipo determinado ejemplo: numeros 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]
Primary KEY and FOREING KEY
- id SERIAL PRIMARY KEY,
- estudiante_id INT REFERENCES estudiante(id),
Sha
Sha256sum Pro tips
Hacer shasum a todos los archivos dentro de un directorio que tambien esten dentro de otros subdirectorios
find path/to/directory -type f -exec sha256sum {} + > hashes.sha256
- -type f: Significa tipo file
- {}: Significa en nombre del archivo actual de find
- +: Indica el final del comando que se esta ejecutando 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 mas eficiente que usar ;
Setup doas
Example in fedora:
sudo su
dnf install -y doas # pacman also works and almost every package manager should work
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
Simple connection between linux
Do this in the destiny ssh
sudo dnf install -y sshd # openssh-server i think
sudo systemctl start sshd # enable for always running
ip addr show # Search for the local ip
ssh user@192.168.x.x # Local ip
Copy files
scp /path/to/my/file user@192.168.x.x:/path/in/destiny/desire # username@localip:path/to
GPG
CIFRAR
Empaquetar una carpeta (no comprimir, mas rapido)
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
Podman
Create Basic Container
podman run -it --name prueba-debian --hostname debi debian
- '-it' Para terminal interactivo
- '--name' Nombre de container
- '--hostname' Hostname dentro de container
Copy File From Host to Container
podman cp /ruta/en/host/mi_archivo.txt name-container:/ruta/destino/
Create User Sudoer in 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
Open a Created Container
# 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
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"
Java FX (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
Usar 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 version 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"
Brave Wayland
Ir a /usr/share/applications/brave-browser.desktop Y cambiar todas las lineas que tengan Exec con --enable-features=UseOzonePlatform --ozone-platform=wayland. Por ejemplo:
Exec=brave-browser --enable-features=UseOzonePlatform --ozone-platform=wayland %U
Mullvad VPN Wayland
Ir a /usr/share/applications/mullvad-vpn.desktop Y cambiar todas las lineas que tengan Exec con --enable-features=UseOzonePlatform,WaylandWindowDecorations --ozone-platform=wayland. Por ejemplo:
# Disable gpu opcional
Exec="/opt/Mullvad VPN/mullvad-vpn" --enable-features=UseOzonePlatform,WaylandWindowDecorations --ozone-platform=wayland %U
VSCodium Wayland
Ir a /usr/share/applications/codium.desktop Y cambiar todas las lineas 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
Git
Basic
git clone <repositorio>
git status # Mostrara si hay cambios
git add <Archvios/Directorios>
git commit -m "Mensaje de commit"
git push . # Pushea el directorio actual
git reset --soft HEAD~1 # Eliminar ultimo commit
Branch
# 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 (GitHub) SOLO LA PRIMERA VEZ DESPUES git push normal
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
Gnu Stow
sudo dnf in stow
Funciona Asi:
Normal Home:
~ | |-> .zshrc -> .config -> alacritty -> alacritty.toml -> *
Luego en Stow:
stow_dir | |-> zsh | -> .zshrc | -> alacritty -> .config -> alacritty -> alacritty.toml -> *
Luego para hacer los enlaces simbolicos
stow zsh alacritty
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(()) } */
Eww
sudo dnf in 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 rm gtk3-devel gtk-layer-shell-devel libdbusmenu-gtk3-devel pango-devel gdk-pixbuf2-devel cairo-devel glib2-devel
Ironbar
Me rendi antes de terminarla
Instalacion en fedora
dnf in 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
dnf rm gtk3-devel gtk-layer-shell-devel openssl-devel libdbusmenu-gtk3-devel pulseaudio-libs-devel libinput-devel luajit-devel lua-lgi libevdev-devel
Mdbook
Install
cargo install mdbook
TLDR
Create online books by writing Markdown files.
More information: <https://rust-lang.github.io/mdBook/>.
Create an mdbook project in the current directory:
mdbook init
Create an mdbook project in a specific directory:
mdbook init path/to/directory
Clean the directory with the generated book:
mdbook clean
Serve a book at <http://localhost:3000>, auto build when file changes:
mdbook serve
Watch a set of Markdown files and automatically build when a file is changed:
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 scripts deploy.sh y clean.sh.
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
Rust Tools
First of all, install rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup update
rustup component add rust-analyzer
Security
cargo install cargo-audit
cargo install cargo-update
cargo install cargo-download
How to check with cargo audit
cargo download pkg | save pkg.gz # > in bash
tar -xvf pkg.gz
cd pkg*
cargo audit
How to use cargo-update
cargo install-update -l
Install Packages
# Find dependencies if necesary
cargo install paquete
cargo install --locked paquete
Luks
Creando una partición:
sudo fdisk /dev/sdb
n
# Enter a 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
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
Yazi
Must
To use Yazi, you must have the following prerequisites installed:
file (for file type detection)
Optional
Yazi can be optionally extended with other command line tools to enable additional features.
nerd-fonts (recommended)
ffmpeg (for video thumbnails)
7-Zip (for archive extraction and preview)
jq (for JSON preview)
poppler (for PDF preview)
fd (for file searching)
rg (for file content searching)
fzf (for quick file subtree navigation, >= 0.53.0)
zoxide (for historical directories navigation, requires fzf)
resvg (for SVG preview)
ImageMagick (for Font, HEIC, and JPEG XL preview)
xclip / wl-clipboard / xsel (for Linux clipboard support)
Compile
sudo dnf in chafa fzf
cargo install --locked yazi-fm yazi-cli
Use
yazi
or in nushell with this use only y
def --env y [...args] {
let tmp = (mktemp -t "yazi-cwd.XXXXXX")
yazi ...$args --cwd-file $tmp
let cwd = (open $tmp)
if $cwd != "" and $cwd != $env.PWD {
cd $cwd
}
rm -fp $tmp
}
Then run yazi
y
Yazi Keymap
F1 for keybindings
Official Resources
Usb Guard
sudo dnf in usbguard usbguard-selinux
sudo sytemctl enable --now usbguard
sudo bash -c "usbguard generate-policy > /etc/usbguard/rules.conf"
Manejar Dispositivos Temporalmentes
sudo usbguard list-devices
sudo usbguard allow-device #ID/Numero
sudo usbguard block-device #ID/Numero
Permitir Dispositivos Permanentemente
Primera vez
Esto es en Nushell, para hacerlo en POSIX cambiar | save por -> >
usbguard generate-policy | save 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 todo el path que aparece en usbguard list-devices. Sin el primer número y poniendo allow
sudo hx /etc/usbguard/rules.conf
sudo systemctl restart usbguard
Niri
Instalar mediante fedora everything de la forma mas minimalista
Index
- Display Manager
- Polkit
- Swaylock
- Mako
- Waybar
- Color Scheme
- File Picker
- Nushell
- Macchina
- Tectonic
- Yazi
- Plymouth
- Labwc
- Grub Password
- Loupe
- Yofi
- Papers
- Homebrew
Tty/Display Manager
No display manager solo tty.
En .zprofile:
if [ -z "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ] && [ "$(tty)" = "/dev/tty1" ]; then
exec niri --session
fi
Polkit
sudo dnf in polkit-kde kf6-kirigami kf6-kirigami2
Agregar la siguiente linea al config de niri
spawn-at-startup "/usr/libexec/kf6/polkit-kde-authentication-agent-1"
systemctl --user daemon-reload
ln -s ~/.config/systemd/user/swayidle.service ~/.config/systemd/user/niri.service.wants/
Swaylock
mkdir -p ~/.config/swaylock
cp config ~/.config/swaylock/
Mako
mkdir -p ~/.config/mako
cp config ~/.config/mako/
Waybar
mkdir -p ~/.config/waybar
cp -r waybar/ ~/.config/waybar/
Color Scheme (TokyoNight)
Gtk
(https://github.com/Fausto-Korpsvart/Tokyonight-GTK-Theme):
sudo dnf in xdg-desktop-portal-gtk xdg-desktop-portal-gnome gtk-murrine-engine sassc
- Mover Tokyonight-Dark a ~/.themes/
- Mover gtk-4.0 a ~/.config/
dconf write /org/gnome/desktop/interface/gtk-theme "'Tokyonight-Dark'"
Qt
sudo dnf in qt5ct qt6ct
- en .profile: export QT_QPA_PLATFORMTHEME=qt5ct
sudo cp .dotfile/qt/tokyonight.conf /usr/share/qt5ct/colors
sudo cp .dotfile/qt/tokyonight.conf /usr/share/qt6ct/colors
- qt5ct -> tokyonight
- qt6ct -> tokyonight
File Picker
For browsers add in /usr/share/xdg-desktop-portal/niri-portals.conf:
org.freedesktop.impl.portal.FileChooser=gtk;
Nushell
sudo dnf install libxcb openssl-devel libX11-devel
cargo install nu --locked
sudo sh -c 'echo "/home/user/.cargo/bin/nu" >> /etc/shells'
Sin cambiar de terminal, correr desde .bashrc
Macchina
sudo dnf in wmctrl
cargo install macchina
Tectonic
sudo dnf in openssl-devel graphite2-devel ghc-gi-freetype2-devel fontconfig-devel harfbuzz-devel libpng-devel ghc-zlib-devel
cargo install tectonic
sudo dnf rm graphite2-devel ghc-gi-freetype2-devel fontconfig-devel harfbuzz-devel libpng-devel ghc-zlib-devel
Bottom
cargo install --locked bottom
Mdbook
cargo install mdbook
Yazi
sudo dnf in chafa fzf
cargo install --locked yazi-fm yazi-cli
Plymouth
plymouth-set-default-theme tribar -R
Labwc
sudo dnf in labwc
Grub Password
Follow this guide Grub Password
Loupe
An image viewer made in RUST made by gnome
sudo dnf in loupe bubblewrap
To make it default
ls /usr/share/applications | grep -i loupe
ls ~/.local/share/applications | grep -i loupe
xdg-mime default org.gnome.Loupe.desktop image/jpeg
xdg-mime default org.gnome.Loupe.desktop image/png
xdg-mime default org.gnome.Loupe.desktop image/gif
xdg-mime default org.gnome.Loupe.desktop image/bmp
xdg-mime default org.gnome.Loupe.desktop image/webp
xdg-mime default org.gnome.Loupe.desktop image/svg+xml
xdg-mime query default image/png
# → should print: org.gnome.Loupe.desktop
Yofi
sudo dnf in libxkbcommon-devel
cargo install yofi
Papers
Semi rust pdf reader
ls /usr/share/applications | grep -i papers
ls ~/.local/share/applications | grep -i papers
xdg-mime default org.gnome.Papers.desktop application/pdf
xdg-mime query default application/pdf
Homebrew
curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash
Then add in env.nu
$env.PATH = ($env.PATH | split row (char esep) | prepend '/home/linuxbrew/.linuxbrew/bin')
Virtualización
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
Here -> Kvm
Download
License Agreement
tar -xvf Whonix*.libvirt.xz
touch WHONIX_BINARY_LICENSE_AGREEMENT_accepted
Importing Whonix VM Templates
- Add the virtual networks:
sudo virsh -c qemu:///system net-define Whonix_external*.xml ;
sudo virsh -c qemu:///system net-define Whonix_internal*.xml
- Activate the virual networks
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
- Import the Whonix Gateway and Workstation images
sudo virsh -c qemu:///system define Whonix-Gateway*.xml ;
sudo virsh -c qemu:///system define Whonix-Workstation*.xml
Image File Installation
- Option 1: Slow
sudo mv Whonix-Gateway*.qcow2 /var/lib/libvirt/images/Whonix-Gateway.qcow2 ;
sudo mv Whonix-Workstation*.qcow2 /var/lib/libvirt/images/Whonix-Workstation.qcow2
- Option 2: Recommended Con 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: Mas antigua y mas lenta
- virtio-fs: Mas nuevo y rapido. A costo de tener que activar Shared memory. que puede afectar a la seguridad asi que ir con precaucion.
Settings -> Add hardware -> Filsesystem -> virtio-9p/virtio-fs
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 bi-n).
-
-
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.
Nushell
Follow this guide first: Install rust.
If your distro has it just install it as nu or nushell. In Fedora:
sudo dnf in nu
Compile it from source
Dependencies
# 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
Usage
Removing files older than 3 weeks
ls | where modified <= (date now) - 3wk | each {|file| rm $file.name}
Rust Coreutils
In Fedora:
sudo dnf in uutils-coreutils
# Recommended
sudo dnf in bat ripgrep zoxide nu skim
Modify path for example in .bash_profile
export PATH="/usr/libexec/uutils-coreutils:$HOME:$PATH"
Ansible
sudo dnf in ansible
Set up your Inventory
Create a inventory.ini
[myhosts]
192.0.2.50
192.0.2.51
192.0.2.52
CONTINUAR
RustScan
Installation
First install Nmap. In Fedora:
sudo dnf in nmap
Setup Rustup/Cargo Then:
cargo install rustscan
Tips
Para revisar puertos abiertos
rustscan -a <ip-local> --ulimit 5000
rustscan -a 192.168.x.y --ulimit 5000
TLDR
Modern Port Scanner written in Rust.
Note: `nmap` must be installed for some of the examples below to work.
More information: <https://github.com/bee-san/RustScan/wiki>.
Scan all ports of one or more comma-delimited addresses using the default values:
rustscan [-a|--addresses] ip_or_hostname
Scan the top 1000 ports with service and version detection:
rustscan --top [-a|--addresses] address_or_addresses
Scan a specific list of ports:
rustscan [-p|--ports] port1,port2,... [-a|--addresses] address_or_addresses
Scan a specific range of ports:
rustscan [-r|--range] start-end [-a|--addresses] address_or_addresses
Invoke `nmap` functionalities (Nmap's OS detection and default scripts):
rustscan [-a|--addresses] address_or_addresses -- -O [-sC|--script=default]
Scan with custom batch size (default: 4500) and timeout (default: 1500ms):
rustscan [-b|--batch-size] batch_size [-t|--timeout] timeout [-a|--addresses] address_or_addresses
Scan with specific port order:
rustscan --scan-order serial|random [-a|--addresses] address_or_addresses
Scan in greppable mode (only output of the ports, no `nmap`):
rustscan [-g|--greppable] [-a|--addresses] address_or_addresses
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.
Qrrs
Usage
Quickly generate qr code
qrrs "Your input here"
qrrs "Your input here" --invert_colors
Generate code, than read it
qrrs "Something" /tmp/qr.png
$ qrrs --read /tmp/qr.png
Something
Print generated code to term
qrrs -t "Something" /tmp/qr.png
█████████████████████████████
█████████████████████████████
████ ▄▄▄▄▄ █▄ █▄▄█ ▄▄▄▄▄ ████
████ █ █ █▀▄████ █ █ ████
████ █▄▄▄█ █ ▄█▀▄█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█ ▀ ▀ █▄▄▄▄▄▄▄████
████▄███ █▄▄ ▄▀ ▀▄▄▄ █▀▄████
████▄ ▀█▀▄▄▀▄▀▀▄█▀▄█ █▄ ▀████
████▄█▄██▄▄▄▀▀▀█ ▄▀█ ▀█▄ ████
████ ▄▄▄▄▄ █▄▀▄▀ ▄▄▀ ██ █████
████ █ █ █▄█▀ ▀▄▄█ ▀▀ ▀████
████ █▄▄▄█ ██▀ ▄█▀ ▀ ████████
████▄▄▄▄▄▄▄█▄▄▄█▄▄▄▄█▄██▄████
█████████████████████████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Show code as text in terminal
qrrs --read --terminal /tmp/qr.png
█████████████████████████████
█████████████████████████████
████ ▄▄▄▄▄ █▄ █▄▄█ ▄▄▄▄▄ ████
████ █ █ █▀▄████ █ █ ████
████ █▄▄▄█ █ ▄█▀▄█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█ ▀ ▀ █▄▄▄▄▄▄▄████
████▄███ █▄▄ ▄▀ ▀▄▄▄ █▀▄████
████▄ ▀█▀▄▄▀▄▀▀▄█▀▄█ █▄ ▀████
████▄█▄██▄▄▄▀▀▀█ ▄▀█ ▀█▄ ████
████ ▄▄▄▄▄ █▄▀▄▀ ▄▄▀ ██ █████
████ █ █ █▄█▀ ▀▄▄█ ▀▀ ▀████
████ █▄▄▄█ ██▀ ▄█▀ ▀ ████████
████▄▄▄▄▄▄▄█▄▄▄█▄▄▄▄█▄██▄████
█████████████████████████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Save it into another file
qrrs --read --terminal /tmp/qr.png /tmp/qr1.png
Almost the same result will be without terminal flag, but now instead of QrCode printed in terminal we will see text from it.
qrrs --read /tmp/qr.png /tmp/qr1.png
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
Labwc
sudo dnf in labwc
In this path ~/.config/labwc copy the rc.xml
Grub2 Password
In Libreboot
-
- Generate the HASH of the password
grub2-mkpasswd-pbkdf2
The output should be something like
grub.pbkdf2.sha512.10000.XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-
- Open with sudo /etc/grub.d/40_custom. At the end add:
#──────────────────────────────────────
set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.XXXXXXXXXXXXXXXXXXXXXXXX
#──────────────────────────────────────
-
- Update grub
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
sudo reboot
-
- Test Test with "e", it should ask for an user and a password.
Cake Wallet
sha256sum Cake_Wallet_v5.1.2_Linux.tar.xz # Check in the realease page
tar -xvf Cake_Wallet_v5.1.2_Linux.tar.xz
sudo mv Cake_Wallet*Linux /opt/cakewallet
Desktop Entry
sudo hx ~/.local/share/applications/cakewallet.desktop
Copy this:
[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
Carapace
Download the rpm, this is for nushell
sha256sum carapace-bin*linux*.rpm
sudo dnf in 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
Force Dark Mode In Browser
-
- Open your browser’s Bookmarks Manager (e.g.
Ctrl+Shift+OorCtrl+Shift+B).
- Open your browser’s Bookmarks Manager (e.g.
-
- Click Add New Bookmark.
-
- Set Name to “Dark Mode” (or your choice).
-
- Set URL to:
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));})();
-
- Save the bookmark.
-
- (Optional) Enable your Bookmarks Bar for easy access.
-
- Click the “Dark Mode” bookmarklet on any page to invert colors.
Alacritty
sudo dnf in cmake freetype-devel fontconfig-devel libxcb-devel libxkbcommon-devel g++
cargo install alacritty
Extra
The .desktop
git clone https://github.com/alacritty/alacritty/
cd alacritty
sudo desktop-file-install extra/linux/Alacritty.desktop
Mullvad VPN CLI Commands
Most Used
| Command | Description |
|---|---|
mullvad account login | Log in to your Mullvad account. |
mullvad account get | Show your account information, including account number, device name, and expiration date. |
mullvad relay list | List available server locations. |
mullvad relay set location <country_code> <city_code> | Select a server location. Replace <country_code> and <city_code> with your desired values. |
mullvad relay set location <server_name> | Select a specific server by name. |
mullvad connect | Connect to the selected server location. |
mullvad disconnect | Disconnect from the VPN. |
mullvad status -v | Check your connection status with detailed information. |
mullvad auto-connect set on | Enable auto-connect on startup. |
mullvad lockdown-mode set on | Enable Lockdown mode to block all Internet traffic until connected to Mullvad. |
mullvad dns set default --block-ads --block-trackers --block-malware --block-adult-content | To enable all DNS filters except social media, use the following command. |
mullvad relay set tunnel-protocol wireguard | Use Wireguard as the tunnel protocol (Is default). |
mullvad tunnel set wireguard --quantum-resistant on | Enable Quantum Resistant. |
Basic Commands
| Command | Description |
|---|---|
mullvad account login <account_number> | Log in to your Mullvad account. Replace <account_number> with your actual account number. |
mullvad account get | Show your account information, including account number, device name, and expiration date. |
mullvad account list-devices | List all device names associated with your account. |
mullvad relay list | List available server locations. |
mullvad relay set location <country_code> <city_code> | Select a server location. Replace <country_code> and <city_code> with your desired values. |
mullvad relay set location <server_name> | Select a specific server by name. |
mullvad connect | Connect to the selected server location. |
mullvad disconnect | Disconnect from the VPN. |
mullvad relay update | Force an update of the server location list. |
mullvad status -v | Check your connection status with detailed information. |
Advanced Commands
| Command | Description |
|---|---|
mullvad relay set tunnel-protocol openvpn | Use OpenVPN as the tunnel protocol. |
mullvad relay set tunnel openvpn --transport-protocol tcp | Use OpenVPN over TCP. |
mullvad relay set tunnel-protocol wireguard | Use Wireguard as the tunnel protocol (Is default). |
mullvad auto-connect set on | Enable auto-connect on startup. |
mullvad auto-connect set off | Disable auto-connect on startup. |
mullvad lan set allow | Enable LAN access. |
mullvad lockdown-mode set on | Enable Lockdown mode to block all Internet traffic until connected to Mullvad. |
mullvad tunnel set ipv6 on | Enable in-tunnel IPv6. |
Split Tunneling (Linux)
| Command | Description |
|---|---|
mullvad-exclude <program> | Start a new process excluded from Mullvad. |
mullvad split-tunnel add <pid> | Exclude a running process from Mullvad using its PID. |
mullvad split-tunnel list | List all currently excluded processes. |
mullvad split-tunnel delete <pid> | To restore a previously excluded process use this command. |
mullvad split-tunnel clear | To restore all previously excluded processes use this command. |
Shadowsocks Commands
| Command | Description |
|---|---|
mullvad bridge set location <location> | Set the location for Shadowsocks. Replace <location> with a specific country or city. |
mullvad bridge set state on | Enable bridge mode for Shadowsocks. |
mullvad bridge set state off | Disable bridge mode. |
mullvad bridge set custom set shadowsocks --cipher <CIPHER> <REMOTE_IP> <REMOTE_PORT> <PASSWORD> | Configure advanced Shadowsocks settings. |
DNS Commands
| Command | Description |
|---|---|
mullvad dns set default --help | To view the help, use this command. |
mullvad dns set default --block-ads --block-trackers --block-malware --block-gambling --block-adult-content | To enable all DNS filters except social media, use the following command. |
mullvad dns set default | To turn off all the content blockers use this command. |
Make custom server lists
| Command | Description |
|---|---|
mullvad custom-list new Favorites | To create a new custom list named "Favorites" use this command. |
mullvad custom-list edit add Favorites se-mma-wg-001 | To add a specific server, city or country to the list use one of these commands. |
mullvad custom-list edit add Favorites se got | To add a specific server, city or country to the list use one of these commands. |
mullvad custom-list edit add Favorites se | To add a specific server, city or country to the list use one of these commands. |
mullvad relay set custom-list Favorites | To select your custom list so you can connect to it, use this command. |
mullvad custom-list edit remove Favorites se-mma-wg-001 | To remove a specific server,city or country from the list use one of these commands. (The same as add) |
mullvad custom-list edit rename Favorites Favourites | To rename a custom list use this command. |
mullvad custom-list list | To list all your custom lists and their content use this command. |
Reset Settings
| Command | Description |
|---|---|
mullvad factory-reset | This command performs a factory reset on all settings, deletes app logs and cache files, disconnects the app, and logs you out. |
Official Page
Homebrew
Not in Nushell
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval "$(<Homebrew prefix path>/bin/brew shellenv)"
In Nushell
curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash
Then add in env.nu
$env.PATH = ($env.PATH | split row (char esep) | prepend '/home/linuxbrew/.linuxbrew/bin')
WebRTC
Firefox
Note: Firefox is the only browser that can properly disable WebRTC completely.
-
- Type about:config into the address bar and hit Enter.
-
- Click the button I accept the risk!.
-
- Type media.peerconnection.enabled in the search bar. Only one entry should appear.
-
- Double-click on the entry to change it to false.
To enable WebRTC again, change it back to "true".
Brave (desktop and Android)
Desktop
Open the Settings and click on the Magnifying glass icon in the top right corner and search for webrtc . Under WebRTC IP Handling Policy select Disable Non-Proxied UDP.
Android
Open the Settings and tap on Brave Shields & privacy. Then scroll down and tap on WebRTC IP Handling Policy. Select Disable Non-Proxied UDP and then tap on the X in the top right corner.
Test
Mullvad SOCK5
Brave
Add this line --proxy-server=socks5://10.64.0.1 at the .desktop (in /home/user/.local/share/applications so it dont overwrite)
Exec=/usr/bin/brave-browser-stable --proxy-server=socks5://10.64.0.1 --enable-features=UseOzonePlatform --ozone-platform=wayland %U
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
Ghostscript
To reduce pdf size
sudo dnf in 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
Autologin TTY1
sudo EDITOR=hx systemctl edit getty@tty1
[Service]
ExecStart=
ExecStart=-/usr/bin/agetty --autologin <user> --noclear %I $TERM
sudo systemctl daemon-reload
sudo systemctl restart getty@tty1.service
Tuigreet In Fedora
sudo dnf in greetd tuigreet
In /etc/greetd/config.toml
[terminal]
vt = 1
[default_session]
command = "tuigreet --cmd 'niri --session' --time --remember --asterisks"
user = "greetd"
Then:
sudo systemctl set-default graphical.target
sudo systemctl enable greetd
sudo systemctl start greetd
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 in -y helix tar git NetworkManager-wifi NetworkManager-tui iwlwifi-mvm-firmware
Usuarios (mínimo privilegio)
admin→ con sudomain/focus/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 focus && sudo passwd focus
sudo useradd -m -s /bin/bash -G nhm safe && sudo passwd safe
Login: greetd + tuigreet + niri
sudo dnf in -y niri greetd tuigreet xdg-desktop-portal xdg-desktop-portal-wlr
sudo dnf rm -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 in -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 focus
nix run /nhm/dotfiles#home-manager -- switch --flake /nhm/dotfiles#focus
# 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 .#focus
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"