-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 92746d4
Showing
34 changed files
with
1,848 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# Oxodao's Homelab | ||
|
||
Documentation de mon homelab | ||
|
||
## Architecture | ||
|
||
Mon homelab est composé de trois machines: | ||
- Un NAS Synology pour le stockage (Actuellement 2x2TB WDC WD20EFRX-68EUZN0) | ||
- Un PC "multimédia" qui est utilisé sur la TV (Thinkcentre m75q / Athlon 300GE) | ||
- Un PC serveur (i3-10100 / 24Gb DDR4 / 1to nvme) | ||
- Un router TP Link Archer C6 (AC1200) sous OpenWRT (Pas encore mis en place) | ||
|
||
Le serveur est un host XCP-NG (hostname `rubeus`) avec deux VM principales, une dédiée aux services accessible en publique, l'autre avec les services accessible uniquement sur le réseau interne. | ||
|
||
Note: le serveur n'a pas de VM pour XenOrchestra, j'utilise sur mon PC une VM sur laquelle j'ai installé XOA via [XenOrchestraInstallerUpdater](https://github.com/ronivay/XenOrchestraInstallerUpdater), cela permet d'économiser de la RAM / du CPU utilisé pour autre chose. | ||
|
||
Le NAS Synology possède toutes les data et expose plusieurs montage samba: | ||
- sauvegarde (Mon espace de stockage générique ou je met un peu tout) | ||
- iso (Mon SR d'iso pour xcp-ng) | ||
- shares (Espace pour stocker mes films / séries / musiques / ...) | ||
- documents (Montage utilisé pour Paperless) | ||
- images (Montage utilisé pour Immich) | ||
|
||
Pour la gestion des droits, j'ai mon utilisateur perso pour la connexion depuis mes machines, et des utilisateurs scopés en RO sur iso et shares pour les différents services ansi qu'un utilisateur RW pour Paperless, chacun n'ayant accès qu'aux shares qu'ils ont besoin. | ||
|
||
Enfin le PC multimédia est un simple debian 12 qui accèdes aux services hébergés sur le serveur. | ||
|
||
Ce guide note particulièrement le setup du serveur puisque le reste est basique et ne nécessite rien de spécial. | ||
|
||
## Sommaire | ||
|
||
1. [Setup XCP-NG](docs/setup_xcp.md) | ||
2. [Setup basique des VMs](docs/setup_vm.md) | ||
|
||
> A partir de ce point la, les divers ansible | ||
> vont setup tout ça. | ||
> | ||
> Il faut tout de même suivre chaque page pour s'assurer | ||
> la config des logiciels est complète car tout n'est | ||
> pas fait dans ansible pour l'instant (e.g. config | ||
> interne de Jellyfin, création de compte utilisateur, etc...) | ||
3. [Setup des utilitaires communs](docs/setup_common.md) | ||
4. [Setup serveur DNS](docs/setup_dns.md) | ||
5. [Setup reverse-proxy](docs/setup_reverseproxy.md) | ||
|
||
-- Setup des apps -- | ||
|
||
6. [Setup Jellyfin](docs/setup_jellyfin.md) | ||
7. [Setup Navidrome](docs/setup_navidrome.md) | ||
8. [Setup Paperless](docs/setup_paperless.md) | ||
9. [Setup Gitea](docs/setup_gitea.md) | ||
10. [Setup Immich](docs/setup_immich.md) | ||
11. [Setup JDownloader](docs/setup_jdownloader.md) | ||
12. [Setup HomeAssistant](docs/setup_ha.md) | ||
|
||
-- Setup sécu -- | ||
|
||
13. [Setup serveurs VPN](docs/setup_vpn.md) | ||
14. [Setup firewall](docs/setup_firewall.md) | ||
15. [Setup cloudflared](docs/setup_cloudflared.md) | ||
16. [Setup backups](docs/setup_backups.md) | ||
|
||
> A partir de ce point la, il s'agît d'informations sur | ||
> l'utilisation usuelle des VMs et du serveur ainsi que | ||
> comment faire du disaster recovery. | ||
17. [Ajouter un utilisateur sur le VPN](docs/add_user_vpn.md) | ||
18. [Renouveller les certificats SSL](docs/renew_ssl.md) | ||
19. [Restorer un backup](docs/disaster_recovery.md) | ||
20. [Backup day](docs/backup_day.md) | ||
|
||
## Roadmap | ||
|
||
Chose que je vais potentiellement ajouter après que tout soit fonctionnel | ||
|
||
- Authentik / Authelia: Active Directory / OAuth | ||
- [Gitea](https://docs.gitea.com/usage/authentication): LDAP | ||
- [Jellyfin](https://github.com/jellyfin/jellyfin-plugin-ldapauth): LDAP | ||
- [Immich](https://www.reddit.com/r/selfhosted/comments/zrkokx/immich_and_ldap/): OAuth | ||
- [Paperless](https://github.com/paperless-ngx/paperless-ngx/pull/100): Ils ont pas l'air de vouloir ni ldap ni oauth | ||
- [Navidrome](https://github.com/navidrome/navidrome/pull/590): huuuh ça à pas l'air très fun non plus | ||
- JDownloader: Accès externe donc via LEUR login, à voir pour dev un client self-hosted mais API non documentée |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
inventory.yaml | ||
files/*.key | ||
files/*.crt | ||
.envrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Homelab ansible | ||
|
||
Pour utiliser cet ansible, il faut copier-coller le `inventory.yaml.dist` en `inventory.yaml` et le compléter en suivant les commentaires. | ||
|
||
Installation des roles: | ||
```sh | ||
$ ansible-galaxy install -r requirements.yaml --force | ||
$ ansible-galaxy collection install -r requirements.yaml --force | ||
``` | ||
|
||
Exécution du playbook: | ||
```sh | ||
$ export ANSIBLE_BECOME_PASSWORD="MON MOT DE PASSE SUDO" # A exécuter une seule fois | ||
$ ansible-playbook -i inventory.yaml setup.yaml | ||
``` | ||
|
||
Si on souhaite exécuter seulement certaines parties, on peut limiter avec les tags, ou les hosts: | ||
```sh | ||
$ export ANSIBLE_BECOME_PASSWORD="MON MOT DE PASSE SUDO" # A exécuter une seule fois | ||
$ ansible-playbook -i inventory.yaml setup.yaml --limit public -t dns | ||
``` | ||
|
||
Pour une réinstallation future, chiffrer le `inventory.yaml` et le stocker dans un endroit sécurisé. Il suffira alors de le reprendre et modifier en cas de mise à jour sur la version git. | ||
|
||
Pour cela, on peut utiliser `ansible-vault` pour utiliser un utilitaire tout-en-un: | ||
```sh | ||
$ ansible-vault encrypt --vault-id homelab@prompt inventory.yaml # Chiffrer | ||
$ ansible-vault decrypt inventory.yaml # Déchiffrer | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
#------------------------------------------------------------------------------- | ||
# Sunrise theme for oh-my-zsh by Adam Lindberg ([email protected]) | ||
# Intended to be used with Solarized: http://ethanschoonover.com/solarized | ||
# (Needs Git plugin for current_branch method) | ||
# | ||
# Probably modified by mattboll | ||
# https://raw.githubusercontent.com/mattboll/zshrc/master/mattboll.zsh-theme | ||
#------------------------------------------------------------------------------- | ||
|
||
# Color shortcuts | ||
R=$fg_no_bold[red] | ||
G=$fg_no_bold[green] | ||
M=$fg_no_bold[magenta] | ||
Y=$fg_no_bold[yellow] | ||
B=$fg_no_bold[blue] | ||
RESET=$reset_color | ||
|
||
if [ "$(whoami)" = "root" ]; then | ||
PREPROMPT="%{$R%}ROOT"; | ||
else | ||
if [[ -z "$SSH_CLIENT" ]]; then | ||
PREPROMPT=""; | ||
else | ||
PREPROMPT="$(whoami)"; | ||
fi | ||
fi | ||
if [[ -z "$SSH_CLIENT" ]]; then | ||
prompt_host="" | ||
else | ||
prompt_host=%{$fg_bold[white]%}@%{$reset_color$fg[yellow]%}$(hostname -s) | ||
fi | ||
|
||
local return_code="%(?..%{$R%}%? ☢ %{$RESET%})" | ||
|
||
git_remote_status() { | ||
remote=${$(command git rev-parse --verify ${hook_com[branch]}@{upstream} --symbolic-full-name 2>/dev/null)/refs\/remotes\/} | ||
if [[ -n ${remote} ]] ; then | ||
ahead=$(command git rev-list ${hook_com[branch]}@{upstream}..HEAD 2>/dev/null | wc -l) | ||
behind=$(command git rev-list HEAD..${hook_com[branch]}@{upstream} 2>/dev/null | wc -l) | ||
|
||
if [ $ahead -eq 0 ] && [ $behind -gt 0 ] | ||
then | ||
echo "$ZSH_THEME_GIT_PROMPT_BEHIND_REMOTE" | ||
elif [ $ahead -gt 0 ] && [ $behind -eq 0 ] | ||
then | ||
echo "$ZSH_THEME_GIT_PROMPT_AHEAD_REMOTE" | ||
elif [ $ahead -gt 0 ] && [ $behind -gt 0 ] | ||
then | ||
echo "$ZSH_THEME_GIT_PROMPT_DIVERGED_REMOTE" | ||
fi | ||
fi | ||
} | ||
|
||
# Checks if there are commits ahead from remote | ||
function git_prompt_ahead_number() { | ||
nbcommits=${$(command git log origin/$(current_branch)..HEAD 2> /dev/null | grep '^commit' | wc -l )// /} | ||
if [[ -n ${nbcommits} ]] ; then | ||
if [ $nbcommits -gt 0 ] | ||
then | ||
echo %{$R%}\($nbcommits\) | ||
else | ||
echo %{$G%}\($nbcommits\) | ||
fi | ||
fi | ||
} | ||
|
||
# ZSH function that shortens | ||
# a very long path for display by removing | ||
# the left most parts and replacing them | ||
# with a leading ... | ||
# | ||
# + keep some left part of the path if asked | ||
# thanks to liquidprompt for that | ||
_lp_shorten_path() | ||
{ | ||
# the character that will replace the part of the path that is masked | ||
local mask=" … " | ||
# index of the directory to keep from the root (starts at 0 whith bash, 1 with zsh) | ||
local keep=2 | ||
|
||
local p="${PWD/$HOME/~}" | ||
local len="${#p}" | ||
|
||
local max_len=$((${COLUMNS:-80}*25/100)) | ||
|
||
if [[ "$len" -gt "$max_len" ]]; then | ||
echo "%-${keep}~%${max_len}<${mask}<%~%<<" | ||
else | ||
echo "%~" | ||
fi | ||
} | ||
|
||
|
||
# Get the status of the working tree (copied and modified from git.zsh) | ||
custom_git_prompt_status() { | ||
INDEX=$(git status --porcelain 2> /dev/null) | ||
STATUS="" | ||
# Non-staged | ||
if $(echo "$INDEX" | grep '^?? ' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_UNTRACKED$STATUS" | ||
fi | ||
if $(echo "$INDEX" | grep '^UU ' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_UNMERGED$STATUS" | ||
fi | ||
if $(echo "$INDEX" | grep '^ D ' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS" | ||
fi | ||
if $(echo "$INDEX" | grep '^.M ' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" | ||
elif $(echo "$INDEX" | grep '^AM ' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" | ||
elif $(echo "$INDEX" | grep '^ T ' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS" | ||
fi | ||
# Staged | ||
if $(echo "$INDEX" | grep '^D ' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_STAGED_DELETED$STATUS" | ||
fi | ||
if $(echo "$INDEX" | grep '^R' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_STAGED_RENAMED$STATUS" | ||
fi | ||
if $(echo "$INDEX" | grep '^M' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_STAGED_MODIFIED$STATUS" | ||
fi | ||
if $(echo "$INDEX" | grep '^A' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_PROMPT_STAGED_ADDED$STATUS" | ||
fi | ||
|
||
if $(echo -n "$STATUS" | grep '.*' &> /dev/null); then | ||
STATUS="$ZSH_THEME_GIT_STATUS_PREFIX$STATUS" | ||
fi | ||
|
||
echo $STATUS | ||
} | ||
|
||
# get the name of the branch we are on (copied and modified from git.zsh) | ||
function custom_git_prompt() { | ||
ref=$(git symbolic-ref HEAD 2> /dev/null) || return | ||
echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(parse_git_dirty)$(git_prompt_ahead_number)$(custom_git_prompt_status)$ZSH_THEME_GIT_PROMPT_SUFFIX" | ||
} | ||
|
||
# %B sets bold text | ||
PROMPT='%B$PREPROMPT$prompt_host %{$G%} $(_lp_shorten_path) $(custom_git_prompt)%{$M%}%B»%b%{$RESET%} ' | ||
RPS1="${return_code} %D{%a %b %d, %I:%M}" | ||
|
||
ZSH_THEME_GIT_PROMPT_PREFIX="%{$Y%}‹" | ||
ZSH_THEME_GIT_PROMPT_SUFFIX="%{$Y%}›%{$RESET%} " | ||
|
||
ZSH_THEME_GIT_PROMPT_DIRTY="%{$R%}*" | ||
ZSH_THEME_GIT_PROMPT_CLEAN="" | ||
|
||
ZSH_THEME_GIT_PROMPT_AHEAD="%{$B%}➔" | ||
|
||
|
||
ZSH_THEME_GIT_STATUS_PREFIX=" " | ||
|
||
# Staged | ||
ZSH_THEME_GIT_PROMPT_STAGED_ADDED="%{$G%}A" | ||
ZSH_THEME_GIT_PROMPT_STAGED_MODIFIED="%{$G%}M" | ||
ZSH_THEME_GIT_PROMPT_STAGED_RENAMED="%{$G%}R" | ||
ZSH_THEME_GIT_PROMPT_STAGED_DELETED="%{$G%}D" | ||
|
||
# Not-staged | ||
ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$R%}?" | ||
ZSH_THEME_GIT_PROMPT_MODIFIED="%{$R%}M" | ||
ZSH_THEME_GIT_PROMPT_DELETED="%{$R%}D" | ||
ZSH_THEME_GIT_PROMPT_UNMERGED="%{$R%}UU" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
worker_processes 1; | ||
|
||
events { | ||
worker_connections 1024; | ||
} | ||
|
||
|
||
http { | ||
include mime.types; | ||
default_type application/octet-stream; | ||
sendfile on; | ||
keepalive_timeout 65; | ||
|
||
include sites-enabled/*; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
ssl_session_timeout 1d; | ||
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions | ||
ssl_session_tickets off; | ||
|
||
# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam | ||
ssl_dhparam /opt/ssl/dhparam.pem; | ||
|
||
# intermediate configuration | ||
ssl_protocols TLSv1.2 TLSv1.3; | ||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305; | ||
ssl_prefer_server_ciphers off; | ||
|
||
# HSTS (ngx_http_headers_module is required) (63072000 seconds) | ||
add_header Strict-Transport-Security "max-age=63072000" always; | ||
|
||
ssl_certificate /opt/ssl/cert.crt; | ||
ssl_certificate_key /opt/ssl/cert.key; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
ntp_timezone: 'Europe/Paris' | ||
ssh_port: '57982' | ||
|
||
tld: 'lan' | ||
|
||
hostname: '{{domain}}.{{tld}}' | ||
base_ip: '{{ ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0]) }}' | ||
|
||
smtp_hostname: "smtp.mailgun.org" | ||
smtp_port: "587" | ||
smtp_tls: yes | ||
smtp_starttls: yes | ||
|
||
lan_ip_prefix: "192.168.14." | ||
|
||
# https://www.opennic.org/ | ||
forwarded_dns_servers: | ||
- 51.158.108.203 | ||
- 152.53.15.127 | ||
- 195.10.195.195 | ||
|
||
predefined_machines: | ||
- { hostname: 'home', short_name: 'home', ip: '2', description: 'My local homelab VM' } | ||
- { hostname: 'severusdesk', short_name: 'severusdesk', ip: '10', description: 'Main desktop computer' } | ||
- { hostname: 'lockhart', short_name: 'lockhart', ip: '11', description: 'Main laptop (Huawei)' } | ||
- { hostname: 'tablet', short_name: 'tablet', ip: '12', description: 'Main tablet' } | ||
- { hostname: 'op6', short_name: 'op6', ip: '13', description: 'Main phone' } | ||
- { hostname: 'switch', short_name: 'switch', ip: '14', description: 'Main Nintendo Switch' } | ||
|
||
# Lets me append machines from the inventory | ||
# without having to add them all again | ||
machines: '{{ predefined_machines }}' |
Oops, something went wrong.