Ao iniciar este post percebi que venho mantendo a infraestrutura pessoal há mais de uma década!
A maioria das coisas que hospedei por conta própria é para uso pessoal. Servidor de e-mail, blog, servidor IRC, hospedagem de imagens, leitor RSS e assim por diante. Todas essas coisas foram um pouco confusas e nunca foram devidamente simplificadas. Alguns estavam em contêineres, alguns eram apenas arquivos simples com um serviço nginx na frente e alguns eram pacotes Debian instalados aleatoriamente de algum lugar que esqueci.
Quando decidi desistir dos serviços de streaming no início do ano passado, percebi que deveria repensar um pouco a abordagem e tentar simplificar a forma como queria hospedar coisas diferentes.
O objetivo é ter infraestrutura e serviços pessoais hospedados localmente em casa. A maioria das coisas deve ser fácil de configurar, mas fundamentalmente estou disposto a trocar um pouco de conveniência pela auto-hospedagem. Eu também tenho um ISP de merda em casa que faz NAT de tudo, então preciso expor as coisas à Internet através de um túnel wireguard e, de preferência, hospedar as coisas de uma forma que eu não precise pensar sobre isso.
O hardware em que estou executando esta infra varia do antigo ao bastante moderno.
- Um NAS construído com disco de 2×8 TB e todo o hardware do que eu acho que é 2012?
- Intel NUC de 2015. Intel i5-6260U e 16 GB de RAM
- AMD NUC com AMD Ryzen 7 8745HS e 64 GB de RAM de AliExpress
- OpenWRT Um
Há algumas coisas sobre as quais não entrarei em muitos detalhes. Para minha configuração de NAS, estou planejando escrever um post sobre minha configuração de imagem. Ele foi criado principalmente para suportar minha edição e armazenamento de fotos, e o uso em minha infraestrutura não foi realmente planejado nesse sentido.
Para minha configuração de rede, não tenho nada de especial. Está tudo plano.
Também escrevi anteriormente sobre minha configuração de DNS. E estou feliz em informar que está funcionando muito bem. Também está servindo meu domínio doméstico, .home.arpa, do mesmo servidor, apenas permiti listar meus IPs internos. Ele também tem uma configuração acme CA sobre a qual pretendo escrever em outro momento.
Para mais DNS: DNS auto-hospedado sem diversão, mas com um pouco de lucro!
Bigorna
eu tenho usado bigorna (anteriormente lxd) por vários anos neste momento. Tem sido minha escolha para zombar e testar infraestrutura localmente, mas nunca o usei para hospedar serviços pessoais. Com a introdução de Suporte a contêiner OCI tudo isso ficou mais fácil!
Posso hospedar praticamente todos os meus serviços como um contêiner lxc normal, uma VM QEMU ou um contêiner OCI extraído de um registro de contêiner.
Tenho executado o Incus em várias configurações há anos. É super confiável e nunca precisei me preocupar com atualizações entre versões de coisas que quebram repentinamente. Isso tem sido muito importante para mim ter apenas uma infraestrutura na qual posso confiar, sem ter que pensar muito sobre isso.
O cluster abrange o AMD NUC (chamado amd) e o Intel NUC (chamado
byggmester).
λ ~ » incus cluster list -c nuas
+------------+---------------------------+--------------+--------+
| NAME | URL | ARCHITECTURE | STATUS |
+------------+---------------------------+--------------+--------+
| amd | https://10.100.100.3:8443 | x86_64 | ONLINE |
+------------+---------------------------+--------------+--------+
| byggmester | https://10.100.100.2:8443 | x86_64 | ONLINE |
+------------+---------------------------+--------------+--------+
Se eu quiser ativar um contêiner Valkey, posso simplesmente iniciá-lo diretamente do docker.
λ ~ » incus remote add docker https://docker.io/ --protocol=oci --public
λ ~ » incus launch docker:valkey/valkey valkey
Launching valkey
λ ~ » incus list valkey -cns4tL
+--------+---------+----------------------+-----------------+------------+
| NAME | STATE | IPV4 | TYPE | LOCATION |
+--------+---------+----------------------+-----------------+------------+
| valkey | RUNNING | 192.168.1.148 (eth0) | CONTAINER (APP) | byggmester |
+--------+---------+----------------------+-----------------+------------+
Por vários motivos (não conheço muito bem redes), toda a minha rede é plana. Em ambos amd e byggmester Eu tenho um dispositivo bridge chamado br0e todos os contêineres usam apenas essa rede em ponte como NIC. O que significa que recebo um IP local e meu roteador permite que eu resolva domínios para eles.
λ ~ » ping valkey.local
PING valkey.local (192.168.1.148) 56(84) bytes of data.
64 bytes from valkey.local (192.168.1.148): icmp_seq=1 ttl=64 time=0.613 ms
64 bytes from valkey.local (192.168.1.148): icmp_seq=2 ttl=64 time=0.328 ms
64 bytes from valkey.local (192.168.1.148): icmp_seq=3 ttl=64 time=0.500 ms
Eles usam systemd-networkd e os arquivos de configuração ficam assim:
# /etc/systemd/network/20-wired.network
(Match)
Name=en*
(Network)
Bridge=br0
# /etc/systemd/network/50-br0.netdev
(NetDev)
Name=br0
Kind=bridge
# /etc/systemd/network/50-br0.network
(Match)
Name=br0
(Network)
Address=192.168.1.2/24
Gateway=192.168.1.1
DNS=192.168.1.1
O default perfil no Incus apenas aponta para este dispositivo.
# λ ~ » incus profile show default
description: Default Incus profile
devices:
eth0:
nictype: bridged
parent: br0
type: nic
root:
path: /
pool: default
type: disk
name: default
used_by:
- /1.0/instances/valkey
project: default
No futuro, quando eu fizer um pouco mais de segmentação de rede, provavelmente obterei sua própria vlan. Mas para uma configuração simples e agradável, acho que funciona muito bem.
Isso funciona muito bem, mas não quero me lembrar de vários comandos do Incus, então claramente queremos algo um pouco mais declarativo.
Opentofu
Incus estes um bom provedor para opentofu. Ele nos permite definir nossos recursos de incus de forma declarativa e tratar tudo como efêmero com todos os dados persistentes armazenados em meu NAS.
Meus arquivos terraform para bigorna podem ser encontrados aqui:
https://github.com/Foxboron/ansible/tree/master/terraform/incus
Todos os meus serviços são separados em projetos com um modelo comum de permissões, rede e perfis padrão que são compartilhados. Isso é fácil de ter tudo semelhante nas diferentes coisas que eu implanto.
Também torna as coisas mais compartimentadas ao mexer em novas infraestruturas.
Tudo isso é gerenciado por um único módulo opentofu chamado project do qual todos os meus outros módulos opentofu são derivados.
https://github.com/Foxboron/ansible/blob/master/terraform/incus/modules/project/main.tf
Como resultado, acumulei alguns projetos!
λ ~ » incus project list -c ndu
+-------------------+------------------------------------------+---------+
| NAME | DESCRIPTION | USED BY |
+-------------------+------------------------------------------+---------+
| ca | ca project | 4 |
+-------------------+------------------------------------------+---------+
| default (current) | Default Incus project | 48 |
+-------------------+------------------------------------------+---------+
| dns | dns project | 7 |
+-------------------+------------------------------------------+---------+
| immich | immich project | 14 |
+-------------------+------------------------------------------+---------+
| mediaserver | Mediaserver project | 18 |
+-------------------+------------------------------------------+---------+
| miniflux | miniflux project | 6 |
+-------------------+------------------------------------------+---------+
| syncthing | syncthing project | 3 |
+-------------------+------------------------------------------+---------+
| test | | 2 |
+-------------------+------------------------------------------+---------+
| user-1000 | User restricted project for "fox" (1000) | 2 |
+-------------------+------------------------------------------+---------+
Não acho que tudo isso seja interessante, mas achei que seria legal mostrar a configuração do Immich opentofu que acabei usando.
Código Terraform:
https://github.com/Foxboron/ansible/tree/master/terraform/incus/modules/immich
λ ~ » incus list -c ntL
+-------------------------+-----------------+----------+
| NAME | TYPE | LOCATION |
+-------------------------+-----------------+----------+
| auto-album-jpg | CONTAINER (APP) | amd |
+-------------------------+-----------------+----------+
| auto-album-raw | CONTAINER (APP) | amd |
+-------------------------+-----------------+----------+
| database | CONTAINER (APP) | amd |
+-------------------------+-----------------+----------+
| immich | CONTAINER (APP) | amd |
+-------------------------+-----------------+----------+
| immich-machine-learning | CONTAINER (APP) | amd |
+-------------------------+-----------------+----------+
| redis | CONTAINER (APP) | amd |
+-------------------------+-----------------+----------+
Como o incus oferece suporte a contêineres docker, é trivial traduzir arquivos upstream docker-compose em arquivos opentofu que podem ser implantados. Isso é ótimo e realmente me faz não ter que pensar em como implantar a infraestrutura quando eles geralmente fornecem apenas uma configuração do docker.
A configuração do contêiner valkey que efetivamente lançamos anteriormente é semelhante a esta:
resource "incus_image" "redis" {
# This references the main project name, "immich" in this case
project = incus_project.immich.name
alias {
name = "redis"
}
source_image = {
remote = "docker"
name = "valkey/valkey:8-bookworm"
}
}
resource "incus_instance" "immich_redis" {
name = "redis"
image = incus_image.redis.fingerprint
project = incus_project.immich.name
target = "amd"
config = {
"boot.autorestart" = true
}
}
Além do nome confuso “redis”, é tudo bastante simples. Definimos a imagem e depois definimos uma instância. O descanso é todo cuidado pelo
default perfil incus que inclui uma configuração de rede e opções para o disco raiz.
Agora que temos uma instância immich em execução localmente, podemos querer expô-la. Hospedar tudo isso em uma rede local é legal, mas na verdade queremos que um pouco disso seja exposto na Internet também.
Rede e exposição de coisas
O principal objetivo disso é auto-hospedar serviços voltados para a Internet, bem como serviços internos. Tenho tentado um monte de coisas. Ideias menos inteligentes também! Acabei conectando minha rede local ao hackerspace.
Acontece que liberar minhas concessões de DHCP para os racks de servidores no porão do nosso hackerspace é uma ideia menos inteligente.
No entanto, Matthew Garrett acabou postando sobre como fazer uma VPN ponto a site wireguard, onde você encaminha todo o tráfego que chega à caixa para sua rede local.
Hospedar localmente um servidor conectado à Internet
Quando você deseja expor serviços à Internet a partir da sua rede local, você acaba tendo que lidar com ISPs de merda que fazem NAT em todo o tráfego e têm IPs flutuantes que mudam. Isso torna o trabalho tedioso!
Hospedando um túnel reverso a partir de uma pequena caixa VPS que pode ter IPv4 e IPv6 estáticos você tem uma conexão mais confiável e pode fingir que os IPs são seus.
O que fiz atualmente foi provisionar um pequeno VPS em meu local
espaço hacker e deu a ele um endereço IPv4 e IPv6. Eu então fiz um túnel wireguard para o meu byggmester node como mjg descreve em sua postagem no blog.
Sobre byggmester eu hospedo nginx que apenas reverte proxies coisas que eu quero que a Internet exponha em meus servidores incus. Tento resolver as coisas em relação ao meu servidor DNS interno para não precisar reter IPs na minha configuração nginx.
Com nginx-acme Também posso ignorar amplamente o certbot para certificados TLS e deixar nginx lidar com isso sozinho. Isso torna o proxy reverso bastante simples para serviços que desejo expor externamente.
Alguns trechos da minha configuração do nginx:
# /etc/nginx/nginx.d/10-acme.conf
acme_issuer letsencrypt {
uri https://acme-v02.api.letsencrypt.org/directory;
contact root@linderud.dev;
state_path /var/lib/nginx/acme;
accept_terms_of_service;
}
acme_shared_zone zone=ngx_acme_shared:1M;
server {
listen 80;
location / {
return 404;
}
}
# /etc/nginx/snippets/acme.conf
acme_certificate letsencrypt;
ssl_certificate $acme_certificate;
ssl_certificate_key $acme_certificate_key;
ssl_certificate_cache max=2;
# /etc/nginx/nginx.d/30-bilder.linderud.dev.conf
server {
(listen)(listen) 443 ssl;
listen (::):443 ssl;
server_name bilder.linderud.dev;
access_log /var/log/nginx/bilder.linderud.dev/access.log;
error_log /var/log/nginx/bilder.linderud.dev/error.log;
include snippets/acme.conf;
include snippets/sslsettings.conf;
client_max_body_size 50000M;
resolver 192.168.1.1 ipv6=off;
location / {
set $immich immich.local;
proxy_pass http://$immich:2283;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_redirect off;
}
}
Isso apenas deixa meus arquivos estáticos!
Sites sobre sincronização?
Tenho alguns sites estáticos, como este blog. Durante anos, fui direto para o git e, em seguida, executei uma função ansible que construiria minha página e a enviaria. Durante anos pensei em apenas mover tudo isso para as páginas do Github, mas com a direção atual do Github isso não desperta alegria.
E tipo, ter uma configuração de CI completa para alguns arquivos estáticos parece um exagero. É evidente que podemos fazer pior… melhor!
Acho que fui exposto a essa ideia por alguém do Arch Linux anos atrás, mas tenho um sistema de usuário único. Root é minha ostra e posso fazer o que quiser com qualquer diretório do meu sistema. Eu tenho /srv! De acordo com algum lugar, ele deveria “armazenar a carga útil geral do servidor”. OK.
Vamos mkdir /srv/linderud.dev e sirva sincronização para o meu servidor web!
λ /srv » tree -L2
.
└── linderud.dev
├── blog <- this blog
├── coredns01 <- my dns server configs (long story)
└── pub <- my public/shared files
Servir este blog agora é apenas uma questão de construir o hugo com um diretório de saída!
$ hugo build -d /srv/linderud.dev/blog/
Feito! Funciona. Publiquei minha página da web. Nenhuma dependência de serviço. Nenhuma configuração de CI/CD. Nenhum executor de ação do Github. Sem manuais ansible!
Não creio que esta seja uma ideia particularmente nova. Mas gosto da simplicidade disso em comparação com outras opções e torna meus computadores e sites sentir como uma rede adequada, em vez de etapas complicadas de construção que preciso lembrar.
OpenWRT Um
Por último, mas não menos importante, uma pequena observação sobre minha rede.
OpenWRT Um é um roteador focado no desenvolvedor OpenWRT. Comprei no AliExpress e escrevi um fornecedor opentofu para ele.
Honestamente, não entendo muito de rede, então a configuração é simples e tudo é simples. A configuração do terraform pode ser encontrada no meu
GitHub.
Tenho alguns planos de obter um switch compatível com openwrt e talvez fazer algumas vlans em algum momento, mas não acho que haja muitas coisas interessantes a dizer sobre a configuração além disso.
usbkvm
Para lidar com vários computadores pequenos, tive que arrastar uma tela e conectar-me a eles. Durante o 38º Congresso de Comunicação do Caos me deparei com um hackerspace vendendo pequenos usbkvm dispositivos por cerca de 20 euros. Comprei dois! Eles têm sido incríveis.

Posso apenas ter um cabo HDMI e um cabo USB-C e posso conectar ao computador que preciso configurar. Super simples, pequeno e bacana de trabalhar. Torna muito mais simples lidar com a infraestrutura doméstica.
Conclusão
Este é um rápido resumo de como estou consertando e configurando minha infraestrutura pessoal. Este não pretendia ser um guia completo, mas talvez fornecer um pouco de inspiração para pessoas que recentemente começaram a procurar auto-hospedar mais coisas em casa. Vou me esforçar para manter minha infra-estrutura pessoal o mais aberta possível, pois acho que há muito o que aprender apenas lendo o código de outras pessoas sobre essas coisas.
Voltar às postagens
Deseja saber mais sobre Software Livre Clique Aqui!

Perito em Computação Forense e Crimes Cibernéticos
Investigação Digital | Laudos Técnicos | Resposta a Incidentes
Bacharel em Sistemas da Informação, Certificado Microsoft Azure IA e MOS. Trabalho como Administrador de Redes, Firewall e Servidores Windows e Linux!
Minhas atividades favoritas são: Caminhar, Fazer Trilhas, Natureza, Insetos e claro ler sobre Tecnologia.

