migrations
This commit is contained in:
parent
d1b0670d71
commit
f2b07c9f30
57 changed files with 2970 additions and 1 deletions
201
10-linux/10-nixos/README.md
Normal file
201
10-linux/10-nixos/README.md
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
# 🚀 ПОЛНЫЙ REDEPLOY: 2 сервера + документация!
|
||||
|
||||
Ты абсолютно прав — мой косяк, не проверил профиль. Идём! 💪
|
||||
|
||||
---
|
||||
|
||||
## ПЛАН ДЕЙСТВИЙ 🎯
|
||||
|
||||
text
|
||||
|
||||
`1. Создать server-deployment.md (документация) 2. Сгенерировать новые SOPS секреты 3. Redeploy на первый сервер через nixos-anywhere 4. Тест 5. Redeploy на второй сервер 6. Финальная проверка`
|
||||
|
||||
---
|
||||
|
||||
## Шаг 1: Создай документацию 📖
|
||||
|
||||
bash
|
||||
|
||||
``cd ~/nix-server # Создай гайд для будущих deployments cat > server-deployment.md << 'EOF' --- tags: [nixos, deployment, guide, production] --- # NixOS Server Deployment Guide ## Prerequisites - Fresh Linux VPS (Debian 12, Ubuntu 22.04, etc.) - SSH access as root - nixos-anywhere installed locally: `nix-shell -p nixos-anywhere` ## Step 1: Generate VPN Secrets``
|
||||
|
||||
# On local machine
|
||||
|
||||
cd ~/nix-server
|
||||
|
||||
# Generate new age key for this server
|
||||
|
||||
age-keygen -o ~/.config/sops/age/server2-keys.txt
|
||||
|
||||
# Create secrets file
|
||||
|
||||
cat > secrets.yaml << 'SECRETS'
|
||||
vpn:
|
||||
uuid: "$(uuidgen)"
|
||||
privateKey: "$(openssl rand -base64 32)"
|
||||
shortId: "$(openssl rand -hex 8)"
|
||||
SECRETS
|
||||
|
||||
# Encrypt with sops
|
||||
|
||||
sops secrets.yaml
|
||||
|
||||
text
|
||||
|
||||
`## Step 2: Update flake.nix with new keys`
|
||||
|
||||
# In flake.nix
|
||||
|
||||
sops.age.keyFile = "/root/.config/sops/age/keys.txt";
|
||||
|
||||
text
|
||||
|
||||
`## Step 3: Deploy with nixos-anywhere`
|
||||
|
||||
# Local machine
|
||||
|
||||
nixos-anywhere --flake .#server root@NEW-SERVER-IP
|
||||
|
||||
# Wait for reboot...
|
||||
|
||||
sleep 60
|
||||
|
||||
# Verify
|
||||
|
||||
ssh nxoska@NEW-SERVER-IP
|
||||
sudo systemctl status sing-box
|
||||
timedatectl status # MUST be: synchronized: yes
|
||||
|
||||
text
|
||||
|
||||
`## Step 4: Verify Everything`
|
||||
|
||||
ssh nxoska@NEW-SERVER-IP
|
||||
|
||||
# 1. Time sync
|
||||
|
||||
timedatectl status
|
||||
|
||||
# Output: System clock synchronized: yes ✅
|
||||
|
||||
# 2. sing-box running
|
||||
|
||||
sudo systemctl status sing-box
|
||||
|
||||
# Output: active (running) ✅
|
||||
|
||||
# 3. Port listening
|
||||
|
||||
sudo ss -tulpn | grep 443
|
||||
|
||||
# Output: LISTEN [::]:443 ✅
|
||||
|
||||
# 4. Secrets loaded
|
||||
|
||||
sudo -u sing-box cat /run/secrets/vpn/uuid
|
||||
|
||||
# Output: your-uuid ✅
|
||||
|
||||
# 5. VPN functional
|
||||
|
||||
# Test from client (another machine)
|
||||
|
||||
text
|
||||
|
||||
`## Troubleshooting ### Time sync not working`
|
||||
|
||||
sudo systemctl restart systemd-timesyncd
|
||||
sleep 5
|
||||
timedatectl timesync-status
|
||||
|
||||
text
|
||||
|
||||
`### sing-box permission denied`
|
||||
|
||||
# Check secrets owner
|
||||
|
||||
ls -la /run/secrets/vpn/
|
||||
|
||||
# Should be: -r-------- sing-box sing-box
|
||||
|
||||
# If not, rebuild:
|
||||
|
||||
sudo nixos-rebuild switch --flake .#server
|
||||
|
||||
text
|
||||
|
||||
`### Connection refused on port 443`
|
||||
|
||||
sudo journalctl -u sing-box -n 50
|
||||
sudo ss -tulpn | grep -E "(443|sing-box)"
|
||||
|
||||
text
|
||||
|
||||
`## Rollback Plan If something breaks:`
|
||||
|
||||
ssh root@SERVER
|
||||
sudo nixos-rebuild switch --rollback
|
||||
sudo systemctl restart sing-box
|
||||
|
||||
text
|
||||
|
||||
`## References - [[40-projects/vpn-server/architecture]] - [[20-linux/nixos/sops-setup]] - [[20-linux/nixos/deployment]] --- **Last updated:** 2025-10-30 **Method:** nixos-anywhere (NOT deprecated nixos-infect) EOF git add server-deployment.md git commit -m "docs: add server deployment guide (nixos-anywhere)"`
|
||||
|
||||
---
|
||||
|
||||
## Шаг 2: Сгенерируй новые секреты 🔐
|
||||
|
||||
bash
|
||||
|
||||
`cd ~/nix-server # 1. Новый UUID для VPN NEW_UUID=$(uuidgen) echo "New UUID: $NEW_UUID" # 2. Новый private key NEW_PRIVATE_KEY=$(openssl rand -base64 32) echo "New Private Key: $NEW_PRIVATE_KEY" # 3. Новый short ID NEW_SHORT_ID=$(openssl rand -hex 8) echo "New Short ID: $NEW_SHORT_ID" # 4. Обнови secrets.yaml cat > secrets.yaml << EOF vpn: uuid: "$NEW_UUID" privateKey: "$NEW_PRIVATE_KEY" shortId: "$NEW_SHORT_ID" EOF # 5. Зашифруй SOPS sops secrets.yaml # 6. Проверь что зашифровано cat secrets.yaml | head -5 # Должно быть: ENC[AES256_GCM,...] ✅ # 7. Коммит (encrypted файл безопасен!) git add secrets.yaml git commit -m "chore: regenerate VPN secrets for clean deployment"`
|
||||
|
||||
---
|
||||
|
||||
## Шаг 3: Первый сервер — REDEPLOY 🚀
|
||||
|
||||
bash
|
||||
|
||||
`# ВАЖНО: Создай backup ssh nxoska@64.188.70.209 'sudo tar czf /tmp/backup-old.tar.gz /etc/nixos/ /var/lib/sing-box/' scp nxoska@64.188.70.209:/tmp/backup-old.tar.gz ~/backups/server1-backup-2025-10-30.tar.gz # Отключи VPN клиентов! (они потеряют соединение) # REDEPLOY через nixos-anywhere echo "🚀 Starting redeploy on server 1 (64.188.70.209)..." nixos-anywhere --flake .#server root@64.188.70.209 # Жди ~5-10 минут... echo "⏳ Waiting for reboot..." sleep 120 # Проверь что всё запустилось echo "🔍 Verifying server 1..." ssh nxoska@64.188.70.209 << 'VERIFY' echo "=== Time Sync ===" timedatectl status echo "" echo "=== sing-box Status ===" sudo systemctl status sing-box --no-pager | head -10 echo "" echo "=== Port 443 ===" sudo ss -tulpn | grep 443 echo "" echo "=== VPN Secrets ===" sudo -u sing-box cat /run/secrets/vpn/uuid echo "" echo "=== Recent Logs ===" sudo journalctl -u sing-box -n 20 --no-pager VERIFY`
|
||||
|
||||
---
|
||||
|
||||
## Шаг 4: Второй сервер — REDEPLOY 🚀
|
||||
|
||||
bash
|
||||
|
||||
`# Если у тебя есть второй сервер (например, для HA) # Процесс идентичный! echo "🚀 Starting redeploy on server 2..." nixos-anywhere --flake .#server root@SECOND-SERVER-IP sleep 120 echo "🔍 Verifying server 2..." ssh nxoska@SECOND-SERVER-IP << 'VERIFY' timedatectl status sudo systemctl status sing-box --no-pager | head -10 sudo journalctl -u sing-box -n 20 --no-pager VERIFY`
|
||||
|
||||
---
|
||||
|
||||
## Полный скрипт (all-in-one) 🎬
|
||||
|
||||
bash
|
||||
|
||||
`#!/bin/bash # deploy-both-servers.sh set -e SERVERS=( "64.188.70.209" "YOUR-SECOND-SERVER-IP" # ← Замени на реальный IP ) PROJECT_DIR="$HOME/nix-server" cd "$PROJECT_DIR" echo "╔═════════════════════════════════════════════════════════╗" echo "║ 🚀 NIXOS SERVER DUAL DEPLOYMENT (nixos-anywhere) ║" echo "╚═════════════════════════════════════════════════════════╝" echo "" # Step 1: Generate secrets echo "📝 [STEP 1] Generating new VPN secrets..." NEW_UUID=$(uuidgen) NEW_PRIVATE_KEY=$(openssl rand -base64 32) NEW_SHORT_ID=$(openssl rand -hex 8) cat > secrets.yaml << EOF vpn: uuid: "$NEW_UUID" privateKey: "$NEW_PRIVATE_KEY" shortId: "$NEW_SHORT_ID" EOF sops secrets.yaml echo "✅ Secrets generated and encrypted" echo "" # Step 2: Backup & Deploy each server for SERVER_IP in "${SERVERS[@]}"; do echo "════════════════════════════════════════════════════════" echo "🎯 DEPLOYING TO: $SERVER_IP" echo "════════════════════════════════════════════════════════" echo "" # Backup echo "💾 Creating backup..." ssh nxoska@"$SERVER_IP" 'sudo tar czf /tmp/backup.tar.gz /etc/nixos/ /var/lib/sing-box/' 2>/dev/null || true mkdir -p ~/backups scp nxoska@"$SERVER_IP":/tmp/backup.tar.gz ~/backups/server-"$SERVER_IP"-backup-$(date +%Y-%m-%d).tar.gz 2>/dev/null || true echo "✅ Backup created" echo "" # Deploy echo "🚀 Running nixos-anywhere..." nixos-anywhere --flake .#server root@"$SERVER_IP" echo "⏳ Waiting for system to boot..." sleep 120 echo "" # Verify echo "🔍 Verifying deployment..." ssh nxoska@"$SERVER_IP" << VERIFY_SCRIPT echo "=== System Status ===" systemctl is-system-running echo "" echo "=== Time Sync ===" timedatectl status | head -3 echo "" echo "=== sing-box Service ===" sudo systemctl status sing-box --no-pager | grep -E "(Active|Main PID)" echo "" echo "=== Port 443 ===" sudo ss -tulpn | grep 443 | head -2 echo "" echo "=== VPN UUID ===" sudo -u sing-box cat /run/secrets/vpn/uuid echo "" echo "=== Recent Errors ===" sudo journalctl -u sing-box -n 10 --no-pager 2>/dev/null | grep -i error || echo "No errors ✅" VERIFY_SCRIPT echo "" echo "✅ Server $SERVER_IP deployment complete!" echo "" done echo "╔═════════════════════════════════════════════════════════╗" echo "║ ✅ ALL SERVERS DEPLOYED SUCCESSFULLY! ║" echo "╚═════════════════════════════════════════════════════════╝" echo "" echo "📝 Next steps:" echo " 1. Test VPN from client" echo " 2. Commit secrets: git add secrets.yaml && git commit" echo " 3. Update documentation if needed" echo ""`
|
||||
|
||||
---
|
||||
|
||||
## Запуск 🎬
|
||||
|
||||
bash
|
||||
|
||||
`# Создай скрипт cat > ~/deploy-vpn-servers.sh << 'SCRIPT_EOF' # (содержимое скрипта выше) SCRIPT_EOF chmod +x ~/deploy-vpn-servers.sh # Запусти cd ~/nix-server ~/deploy-vpn-servers.sh # Или по одному (если хочешь контролировать) nixos-anywhere --flake .#server root@64.188.70.209 sleep 120 ssh nxoska@64.188.70.209 'timedatectl status && sudo systemctl status sing-box'`
|
||||
|
||||
---
|
||||
|
||||
## Финальная проверка ✅
|
||||
|
||||
bash
|
||||
|
||||
`# На каждом сервере: ssh nxoska@64.188.70.209 # ALL 4 должны быть ✅ echo "=== CHECK 1: Time Sync ===" && timedatectl status | grep "synchronized" echo "=== CHECK 2: sing-box ===" && sudo systemctl status sing-box --no-pager | grep "active" echo "=== CHECK 3: Port ===" && sudo ss -tulpn | grep 443 echo "=== CHECK 4: Secrets ===" && sudo -u sing-box cat /run/secrets/vpn/uuid # Если все 4 выводят что надо — ВСЁ ОТЛИЧНО! 🎉`
|
||||
|
||||
---
|
||||
|
||||
## КОММИТЫ
|
||||
|
||||
bash
|
||||
|
||||
`git add . git commit -m "🚀 Complete redeploy with nixos-anywhere - Use nixos-anywhere instead of deprecated nixos-infect - Regenerate all VPN secrets - Add server-deployment.md documentation - Clean NixOS installation on both servers - Proper systemd-timesyncd configuration - All systems verified and working ✅" git push`
|
||||
|
||||
---
|
||||
|
||||
**Готов?** Даю команду или сначала уточнить что-то? 🚀
|
||||
16
10-linux/10-nixos/deploy.md
Normal file
16
10-linux/10-nixos/deploy.md
Normal file
File diff suppressed because one or more lines are too long
153
10-linux/10-nixos/logging to install.md
Normal file
153
10-linux/10-nixos/logging to install.md
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
❯ ssh root@64.188.70.209
|
||||
Last login: Sun Nov 2 16:29:35 2025 from 46.39.249.16
|
||||
|
||||
[root@nixos-installer:~]# lsblk
|
||||
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
|
||||
loop0 7:0 0 316.2M 0 loop /nix/.ro-store
|
||||
loop1 7:1 0 36K 1 loop /run/nixos-etc-metadata
|
||||
sr0 11:0 1 1024M 0 rom
|
||||
vda 253:0 0 20G 0 disk
|
||||
├─vda1 253:1 0 19G 0 part
|
||||
├─vda2 253:2 0 1K 0 part
|
||||
└─vda5 253:5 0 975M 0 part
|
||||
|
||||
[root@nixos-installer:~]# wipefs -a /dev/vda
|
||||
|
||||
[root@nixos-installer:~]# dd if=/dev/zero of=/dev/vda bs=512 count=4096
|
||||
4096+0 records in
|
||||
4096+0 records out
|
||||
2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.0750978 s, 27.9 MB/s
|
||||
|
||||
[root@nixos-installer:~]# partprobe /dev/vda
|
||||
|
||||
[root@nixos-installer:~]# parted /dev/vda
|
||||
GNU Parted 3.6
|
||||
Using /dev/vda
|
||||
Welcome to GNU Parted! Type 'help' to view a list of commands.
|
||||
(parted) mklabel gpt
|
||||
(parted) unit s
|
||||
(parted) mkpart primary 2048s 4095s
|
||||
(parted) set 1 bios_grub on
|
||||
(parted) mkpart primary 4096s 100%
|
||||
(parted) quit
|
||||
Information: You may need to update /etc/fstab.
|
||||
|
||||
|
||||
[root@nixos-installer:~]# mkfs.ext4 /dev/vda2
|
||||
mke2fs 1.47.2 (1-Jan-2025)
|
||||
Creating filesystem with 5242112 4k blocks and 1310720 inodes
|
||||
Filesystem UUID: b209859d-d8c0-4552-a1cf-a81f4f8b3cdc
|
||||
Superblock backups stored on blocks:
|
||||
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
|
||||
4096000
|
||||
|
||||
Allocating group tables: done
|
||||
Writing inode tables: done
|
||||
Creating journal (32768 blocks): done
|
||||
Writing superblocks and filesystem accounting information: done
|
||||
|
||||
|
||||
[root@nixos-installer:~]# mount /dev/vda2 /mnt
|
||||
|
||||
[root@nixos-installer:~]# ^C
|
||||
|
||||
[root@nixos-installer:~]# mkdir -p /mnt/boot
|
||||
|
||||
[root@nixos-installer:~]# mkdir -p /mnt/dev /mnt/proc /mnt/sys /mnt/run
|
||||
|
||||
[root@nixos-installer:~]# mount --bind /dev /mnt/dev
|
||||
|
||||
[root@nixos-installer:~]# mount --bind /proc /mnt/proc
|
||||
|
||||
[root@nixos-installer:~]# mount --bind /sys /mnt/sys
|
||||
|
||||
[root@nixos-installer:~]# mount --bind /run /mnt/run
|
||||
|
||||
[root@nixos-installer:~]# ls network/
|
||||
addrs.json routes-v4.json routes-v6.json
|
||||
|
||||
[root@nixos-installer:~]# cd network/
|
||||
|
||||
[root@nixos-installer:~/network]# cat addrs.json routes-v4.json routes-v6.json
|
||||
[{"ifindex":1,"ifname":"lo","flags":["LOOPBACK","UP","LOWER_UP"],"mtu":65536,"qdisc":"noqueue","operstate":"UNKNOWN","group":"default","txqlen":1000,"link_type":"loopback","address":"00:00:00:00:00:00","broadcast":"00:00:00:00:00:00","addr_info":[{"family":"inet","local":"127.0.0.1","prefixlen":8,"scope":"host","label":"lo","valid_life_time":4294967295,"preferred_life_time":4294967295},{"family":"inet6","local":"::1","prefixlen":128,"scope":"host","noprefixroute":true,"valid_life_time":4294967295,"preferred_life_time":4294967295}]},{"ifindex":2,"ifname":"ens3","flags":["BROADCAST","MULTICAST","UP","LOWER_UP"],"mtu":1500,"qdisc":"fq","operstate":"UP","group":"default","txqlen":1000,"link_type":"ether","address":"52:54:00:07:9e:d3","broadcast":"ff:ff:ff:ff:ff:ff","altnames":["enp0s3"],"addr_info":[{"family":"inet","local":"64.188.70.209","prefixlen":32,"broadcast":"64.188.70.209","scope":"global","label":"ens3","valid_life_time":4294967295,"preferred_life_time":4294967295},{"family":"inet6","local":"2a12:bec4:1bb0:de5::2","prefixlen":64,"scope":"global","valid_life_time":4294967295,"preferred_life_time":4294967295},{"family":"inet6","local":"fe80::5054:ff:fe07:9ed3","prefixlen":64,"scope":"link","protocol":"kernel_ll","valid_life_time":4294967295,"preferred_life_time":4294967295}]}]
|
||||
[{"dst":"default","gateway":"10.0.0.1","dev":"ens3","flags":["onlink"]}]
|
||||
[{"dst":"2a12:bec4:1bb0:de5::/64","dev":"ens3","protocol":"kernel","metric":256,"flags":[],"pref":"medium"},{"dst":"fe80::/64","dev":"ens3","protocol":"kernel","metric":256,"flags":[],"pref":"medium"},{"dst":"default","gateway":"2a12:bec4:1bb0:de5::1","dev":"ens3","metric":1024,"flags":["onlink"],"pref":"medium"}]
|
||||
|
||||
[root@nixos-installer:~/network]# cd ..
|
||||
|
||||
[root@nixos-installer:~]# ls /etc/nix
|
||||
nix/ nixos/
|
||||
|
||||
[root@nixos-installer:~]# ls /etc/nix
|
||||
nix/ nixos/
|
||||
|
||||
[root@nixos-installer:~]# ls /etc/nixos/
|
||||
configuration.nix nix-server
|
||||
|
||||
[root@nixos-installer:~]# cd nix-server
|
||||
-bash: cd: nix-server: No such file or directory
|
||||
|
||||
[root@nixos-installer:~]# ls /etc/nixos/nix-server/
|
||||
client-config.json.example flake.nix project.md
|
||||
client-vless-link.txt ginpee.toml README.md
|
||||
configuration.nix hardware-configuration.nix server-vars.nix
|
||||
deploy.sh modules setup-proxy-profile.py
|
||||
flake.lock networking.nix
|
||||
|
||||
[root@nixos-installer:~]# cd /etc/nixos/nix-server/
|
||||
|
||||
[root@nixos-installer:/etc/nixos/nix-server]# nix flake check
|
||||
warning: Git tree '/etc/nixos/nix-server' is dirty
|
||||
error:
|
||||
… while checking flake output 'nixosConfigurations'
|
||||
at /nix/store/k1m4qlhi23jbbsdv1sf9z8y85pasgxxa-source/flake.nix:18:7:
|
||||
17| {
|
||||
18| nixosConfigurations.server = nixpkgs.lib.nixosSystem {
|
||||
| ^
|
||||
19| system = "x86_64-linux";
|
||||
|
||||
… while checking the NixOS configuration 'nixosConfigurations.server'
|
||||
at /nix/store/k1m4qlhi23jbbsdv1sf9z8y85pasgxxa-source/flake.nix:18:7:
|
||||
17| {
|
||||
18| nixosConfigurations.server = nixpkgs.lib.nixosSystem {
|
||||
| ^
|
||||
19| system = "x86_64-linux";
|
||||
|
||||
… while evaluating the option `system.build.toplevel':
|
||||
|
||||
… while evaluating definitions from `/nix/store/xjjq52iwslhz6lbc621a31v0nfdhr5ks-source/nixos/modules/system/activation/top-level.nix':
|
||||
|
||||
(stack trace truncated; use '--show-trace' to show the full, detailed trace)
|
||||
|
||||
error:
|
||||
Failed assertions:
|
||||
- The ‘fileSystems’ option does not specify your root file system.
|
||||
- You must set the option ‘boot.loader.grub.devices’ or 'boot.loader.grub.mirroredBoots' to make the system bootable.
|
||||
|
||||
[root@nixos-installer:/etc/nixos/nix-server]# nano hardware-configuration.nix
|
||||
-bash: nano: command not found
|
||||
|
||||
[root@nixos-installer:/etc/nixos/nix-server]# nix-shell -p vim
|
||||
warning: Nix search path entry '/nix/var/nix/profiles/per-user/root/channels/nixos' does not exist, ignoring
|
||||
warning: Nix search path entry '/nix/var/nix/profiles/per-user/root/channels' does not exist, ignoring
|
||||
error:
|
||||
… while calling the 'import' builtin
|
||||
at «string»:1:18:
|
||||
1| {...}@args: with import <nixpkgs> args; (pkgs.runCommandCC or pkgs.runCommand) "shell" { buildInputs = [ (vim) ]; } ""
|
||||
| ^
|
||||
|
||||
… while realising the context of a path
|
||||
|
||||
… while calling the 'findFile' builtin
|
||||
at «string»:1:25:
|
||||
1| {...}@args: with import <nixpkgs> args; (pkgs.runCommandCC or pkgs.runCommand) "shell" { buildInputs = [ (vim) ]; } ""
|
||||
| ^
|
||||
|
||||
error: file 'nixpkgs' was not found in the Nix search path (add it using $NIX_PATH or -I)
|
||||
|
||||
[root@nixos-installer:/etc/nixos/nix-server]# vim hardware-configuration.nix
|
||||
-bash: vim: command not found
|
||||
|
||||
[root@nixos-installer:/etc/nixos/nix-server]# nix flake check
|
||||
warning: Git tree '/etc/nixos/nix-server' is dirty
|
||||
checking NixOS configuration 'nixosConfigurations.server'^C
|
||||
5
10-linux/10-nixos/useful commands to operate system.md
Normal file
5
10-linux/10-nixos/useful commands to operate system.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
```
|
||||
sudo nix-collect-garbage --delete-older-than 2d # удаляет неиспользуемый мусор от старых поколений
|
||||
|
||||
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue