first commit

This commit is contained in:
emptyynes 2025-09-17 16:39:03 +07:00
commit 21737592da
27 changed files with 744 additions and 0 deletions

1
debug.sh Normal file
View file

@ -0,0 +1 @@
nix repl --extra-experimental-features 'flakes' .

38
flake.nix Normal file
View file

@ -0,0 +1,38 @@
{
description = "Project-A flake!";
inputs = {
nixpkgs.url = "nixpkgs/nixos-25.05";
nixpkgs-unstable.url = "github:nixos/nixpkgs/nixos-unstable";
secret.url = "git+ssh://forgejo@git.project-a.space/Project-A/project-secret.git";
project-a-software.url = "git+ssh://forgejo@git.project-a.space/Project-A/project-software.git";
home-manager = {
url = "github:nix-community/home-manager/release-25.05";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, nixpkgs-unstable, project-a-software, home-manager, secret, ... }:
let
linux64 = "x86_64-linux";
nixosServer = { name, system ? linux64, modules ? [] }:
nixpkgs.lib.nixosSystem {
system = system;
specialArgs.pkgs-unstable = nixpkgs-unstable.legacyPackages.${system};
specialArgs.secret = secret.${name};
specialArgs.common-secret = secret.common;
modules = [
./servers/common/main.nix
./servers/${name}/main.nix
] ++ modules;
};
in {
nixosConfigurations = {
artemisia = nixosServer { name = "artemisia"; modules = [ project-a-software.marzban ]; };
reine = nixosServer { name = "reine"; };
mio = nixosServer { name = "mio"; modules = [ project-a-software.marzban ]; };
vanessa = nixosServer { name = "vanessa"; modules = [ project-a-software.marzban ]; };
};
};
}

45
secret.nix Normal file
View file

@ -0,0 +1,45 @@
{ lib, ... }:
let
marzban-config = {
port = mkOption { type = types.int; default = 8000; };
sudo-username = mkOption { type = types.str; default = "admin"; };
sudo-password = mkOption { type = types.str; default = "admin"; };
vless-port = mkOption { type = types.int; default = 1080; };
dest = mkOption { type = types.str; default = "yahoo.com:443"; };
privateKey = mkOption { type = types.str; default = ""; };
shortId = mkOption { type = types.str; default = ""; };
spiderX = mkOption { type = types.str; default = "/"; };
};
affine-config = with lib; {
env = {
PORT = mkOption { type = int; default = 3010; };
DB_USERNAME = mkOption { type = str; default = "affine"; };
DB_PASSWORD = mkOption { type = str; default = "affine"; };
DB_DATABASE = mkOption { type = str; default = "affine"; };
};
revision = mkOption { type = str; default = "stable"; };
};
in {
options = with lib; {
secret = {
artemisia = {
marzban = marzban-config;
};
mio = {
marzban = marzban-config;
};
vanessa = {
marzban = marzban-config;
};
reine = {
yggdrasil.PrivateKey = mkOption { type = str; default = ""; };
};
common = {
yggdrasil = {
reine = mkOption { type = str; default = ""; };
};
};
};
};
}

View file

@ -0,0 +1,40 @@
{ lib, pkgs, config, ... }:
let
domain = "git.project-a.space";
ssh_port = 22;
http_port = 3000;
in {
services.forgejo = {
enable = true;
lfs.enable = true;
database.type = "postgres";
settings = {
server = {
DOMAIN = domain;
ROOT_URL = "https://${domain}/";
START_SSH_SERVER = true;
SSH_DOMAIN = domain;
SSH_PORT = ssh_port;
SSH_LISTEN_PORT = ssh_port;
SSH_LISTEN_HOST = "0.0.0.0";
HTTP_PORT = http_port;
};
actions = {
ENABLED = true;
DEFAULT_ACTIONS_URL = "github";
};
federation.ENABLED = true;
service.DISABLE_REGISTRATION = false;
ui.SHOW_USER_EMAIL = false;
};
};
systemd.sockets.forgejo = {
requiredBy = [ "forgejo.service" ];
wantedBy = [ "sockets.target" ];
listenStreams = [ (toString ssh_port) ];
};
networking.firewall.allowedTCPPorts = [ ssh_port ];
}

View file

@ -0,0 +1,17 @@
{ modulesPath, ... }:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot = {
loader.grub.device = "/dev/vda";
initrd = {
kernelModules = [ "nvme" ];
availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
};
tmp.cleanOnBoot = true;
};
fileSystems."/" = { device = "/dev/mapper/debian12--vg-root"; fsType = "ext4"; };
swapDevices = [ { device = "/dev/dm-1"; } ];
}

View file

@ -0,0 +1,34 @@
{ config, pkgs, secret, ... }:
{
imports = [
./hardware-configuration.nix
./nginx.nix
./forgejo.nix
];
networking.hostName = "artemisia";
system.stateVersion = "25.05";
services.yggdrasil.persistentKeys = true;
marzban = {
env = {
UVICORN_HOST = "artemisia.project-a.space";
UVICORN_PORT = secret.marzban.port;
SUDO_USERNAME = secret.marzban.sudo-username;
SUDO_PASSWORD = secret.marzban.sudo-password;
DOCS = true;
};
cert = true;
domain = "artemisia.project-a.space";
xray = import ../common/xray.nix {
server-domain = "artemisia.project-a.space";
port = secret.marzban.vless-port;
dest = secret.marzban.dest;
privateKey = secret.marzban.privateKey;
shortId = secret.marzban.shortId;
spiderX = secret.marzban.spiderX;
};
};
networking.firewall.allowedTCPPorts = [ secret.marzban.port ];
}

View file

@ -0,0 +1,48 @@
{ config, pkgs, ... }:
{
security.acme.defaults.email = "porject-a@project-a.space";
security.acme.acceptTerms = true;
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
defaultSSLListenPort = 444;
virtualHosts = {
"git.project-a.space" = {
forceSSL = true;
enableACME = true;
locations."/" = {
proxyPass = "http://localhost:3000";
};
};
};
streamConfig = ''
map $ssl_preread_server_name $name {
git.project-a.space git;
default marzban;
}
upstream git {
server 127.0.0.1:444;
}
upstream marzban {
server 127.0.0.1:1080;
}
server {
listen 0.0.0.0:443;
listen [::0]:443;
proxy_pass $name;
ssl_preread on;
proxy_connect_timeout 1s;
proxy_timeout 1h;
proxy_buffer_size 16k;
}
'';
};
}

View file

@ -0,0 +1,9 @@
{ config, pkgs, ... }:
{
networking.firewall = {
enable = true;
allowedTCPPorts = [ 80 443 1004 666 ];
allowedUDPPorts = [ 80 443 1004 666 ];
};
}

16
servers/common/main.nix Normal file
View file

@ -0,0 +1,16 @@
{ config, pkgs, pkgs-unstable, ... }:
{
imports = [
./ssh.nix
./users.nix
./yggdrasil.nix
./firewall.nix
./sudo.nix
./packages.nix
];
programs.fish.enable = true;
nix.settings.experimental-features = [ "nix-command" "flakes" ];
nix.settings.trusted-users = [ "root" "@wheel" ];
}

View file

@ -0,0 +1,13 @@
{ config, pkgs, pkgs-unstable, ... }:
{
environment.systemPackages =
(with pkgs; [ # STABLE PACKAGES
btop
screen
])
++
(with pkgs-unstable; [ # UNSTABLE PACKAGES
bun
]);
}

12
servers/common/ssh.nix Normal file
View file

@ -0,0 +1,12 @@
{ config, pkgs, ... }:
{
services.openssh = {
enable = true;
ports = [ 1004 ];
settings = {
AllowGroups = [ "remote" ];
PasswordAuthentication = false;
};
};
}

10
servers/common/sudo.nix Normal file
View file

@ -0,0 +1,10 @@
{ config, pkgs, ... }:
{
security.sudo.extraRules = [
{
groups = [ "wheel" ];
commands = [ { command = "ALL"; options = [ "NOPASSWD" ]; } ];
}
];
}

21
servers/common/users.nix Normal file
View file

@ -0,0 +1,21 @@
{ config, pkgs, ... }:
{
users = {
groups = {
remote = {};
};
users = {
in5ar = {
isNormalUser = true;
description = "IN5-AR";
extraGroups = [ "wheel" "docker" "remote"];
shell = pkgs.fish;
openssh.authorizedKeys.keys = [
''ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPg2GEI2xcR0E1LzJWDvF5eHNt93TcYy7W/qEI3XoVWr almiriqi@aqore-nix''
];
initialPassword = "ra5ni";
};
};
};
}

62
servers/common/xray.nix Normal file
View file

@ -0,0 +1,62 @@
{ server-domain, port, dest, privateKey, shortId, spiderX }:
{
log.loglevel = "warning";
dns = {
servers = [ "1.1.1.1" ];
queryStrategy = "UseIPv4";
};
routing = {
rules = [
{
ip = [ "geoip:private" ];
outboundTag = "BLOCK";
type = "field";
}
];
};
inbounds = [
{
tag = "VLESS TCP REALITY";
listen = "0.0.0.0";
port = port;
protocol = "vless";
settings = {
clients = [];
decryption = "none";
};
streamSettings = {
network = "tcp";
tcpSettings = {};
security = "reality";
realitySettings = {
show = false;
dest = dest;
xver = 0;
serverNames = [
server-domain
];
privateKey = privateKey;
SpiderX = spiderX;
shortIds = [
shortId
];
};
};
sniffing = {
enabled = true;
destOverride = [ "http" "tls" "quic" ];
};
}
];
outbounds = [
{
protocol = "freedom";
tag = "DIRECT";
}
{
protocol = "blackhole";
tag = "BLOCK";
}
];
}

View file

@ -0,0 +1,18 @@
{ config, pkgs, ... }:
{
services.yggdrasil = {
enable = true;
settings = {
Peers = [
"tls://kuber.project-a.space:666"
"tls://arti.project-a.space:666"
"tls://reine.project-a.space:666"
];
Listen = [
"tls://0.0.0.0:666"
];
IfName = "ygg0";
};
};
}

View file

@ -0,0 +1,8 @@
{ modulesPath, ... }:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.loader.grub.device = "/dev/sda";
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
boot.initrd.kernelModules = [ "nvme" ];
fileSystems."/" = { device = "/dev/sda1"; fsType = "ext4"; };
}

49
servers/mio/main.nix Normal file
View file

@ -0,0 +1,49 @@
{ config, pkgs, secret, ... }:
{
imports = [
./hardware-configuration.nix
./nginx.nix
];
networking = {
hostName = "mio";
interfaces.ens18 = {
useDHCP = false;
ipv4.addresses = [{
address = "66.78.40.227";
prefixLength = 24;
}];
};
defaultGateway = "66.78.40.1";
nameservers = ["1.1.1.1"];
};
services.openssh.enable = true;
boot.tmp.cleanOnBoot = true;
zramSwap.enable = true;
system.stateVersion = "25.05";
services.yggdrasil.persistentKeys = true;
marzban = {
env = {
UVICORN_HOST = "mio.project-a.space";
UVICORN_PORT = secret.marzban.port;
SUDO_USERNAME = secret.marzban.sudo-username;
SUDO_PASSWORD = secret.marzban.sudo-password;
DOCS = true;
};
cert = true;
domain = "mio.project-a.space";
xray = import ../common/xray.nix {
server-domain = "mio.project-a.space";
port = secret.marzban.vless-port;
dest = secret.marzban.dest;
privateKey = secret.marzban.privateKey;
shortId = secret.marzban.shortId;
spiderX = secret.marzban.spiderX;
};
};
networking.firewall.allowedTCPPorts = [ secret.marzban.port secret.marzban.vless-port ];
}

37
servers/mio/nginx.nix Normal file
View file

@ -0,0 +1,37 @@
{ config, pkgs, ... }:
{
security.acme.defaults.email = "porject-a@project-a.space";
security.acme.acceptTerms = true;
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
defaultSSLListenPort = 444;
streamConfig = ''
map $ssl_preread_server_name $name {
default marzban;
}
upstream git {
server 127.0.0.1:444;
}
upstream marzban {
server 127.0.0.1:1080;
}
server {
listen 0.0.0.0:443;
listen [::0]:443;
proxy_pass $name;
ssl_preread on;
proxy_connect_timeout 1s;
proxy_timeout 1h;
proxy_buffer_size 16k;
}
'';
};
}

View file

@ -0,0 +1,5 @@
{config, pkgs, ... }:
{
networking.firewall.allowedTCPPorts = [ 8080 ];
}

View file

@ -0,0 +1,55 @@
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot = {
initrd = {
kernelModules = [ "amdgpu" ];
availableKernelModules = [ "xhci_pci" "ahci" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
};
loader = {
efi = {
canTouchEfiVariables = true;
efiSysMountPoint = "/boot/efi";
};
grub = {
enable = true;
device = "nodev";
efiSupport = true;
configurationLimit = 16;
gfxmodeEfi = "1920x1080";
extraEntries = ''
menuentry "UEFI Firmware Setup" {
fwsetup
}
'';
};
};
kernelModules = [ "kvm-amd" ];
extraModulePackages = [ ];
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/39d941ed-a87d-4341-85b8-5343f502fdaa";
fsType = "btrfs";
};
fileSystems."/boot/efi" = {
device = "/dev/disk/by-uuid/1E12-07EE";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ];
};
fileSystems."/home" = {
device = "/dev/disk/by-uuid/842c5f4e-88a4-41f5-ad9d-6a13aad1f3e6";
fsType = "btrfs";
};
swapDevices = [ ];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}

View file

@ -0,0 +1,17 @@
{config, pkgs, pkgs-unstable, ...}:
{
services.jellyfin = {
enable = true;
openFirewall = true;
};
services.jellyseerr = {
enable = true;
port = 5055;
openFirewall = true;
package = pkgs-unstable.jellyseerr; # Use the unstable package if stable is not up-to-date
};
}

15
servers/reine/main.nix Normal file
View file

@ -0,0 +1,15 @@
{ config, pkgs, secret, ... }:
{
imports = [
./hardware-configuration.nix
./jellyfin.nix
./traefik.nix
./firewall.nix
];
networking.hostName = "reine";
services.yggdrasil.settings.PrivateKey = secret.yggdrasil.PrivateKey;
services.yggdrasil.persistentKeys = false;
hardware.amdgpu.opencl.enable = true;
system.stateVersion = "25.05";
}

66
servers/reine/traefik.nix Normal file
View file

@ -0,0 +1,66 @@
{ config, pkgs, ... }:
{
services.traefik = {
enable = true;
staticConfigOptions = {
entryPoints = {
web = {
address = ":80";
http.redirections.entryPoint = {
to = "websecure";
scheme = "https";
};
};
websecure = {
address = ":443";
http.tls = {
certResolver = "letsencrypt";
};
};
};
api = {
dashboard = false;
insecure = false; # Включить только для отладки, лучше использовать безопасный доступ
};
certificatesResolvers.letsencrypt.acme = {
email = "luc_ren@blnt-cult.ru";
storage = "${config.services.traefik.dataDir}/acme.json";
httpChallenge.entryPoint = "web";
};
};
dynamicConfigOptions = {
http = {
routers = {
jellyfin = {
rule = "Host(`jellyfin.project-a.space`)";
service = "jellyfin";
entryPoints = ["websecure"];
tls = {
certResolver = "letsencrypt";
};
};
jellyseerr = {
rule = "Host(`jellyseerr.project-a.space`)";
service = "jellyseerr";
entryPoints = ["websecure"];
tls = {
certResolver = "letsencrypt";
};
};
};
services = {
jellyfin.loadBalancer.servers = [
{ url = "http://127.0.0.1:8096"; }
];
jellyseerr.loadBalancer.servers = [
{ url = "http://127.0.0.1:5055"; }
];
};
};
};
};
}

View file

@ -0,0 +1,31 @@
{ modulesPath, ... }:
{
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
boot.loader.grub.device = "/dev/vda";
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "xen_blkfront" "vmw_pvscsi" ];
boot.initrd.kernelModules = [ "nvme" ];
fileSystems."/" = { device = "/dev/vda2"; fsType = "ext4"; };
networking = {
hostName = "vanessa";
interfaces.ens3 = {
useDHCP = false;
ipv4 = {
addresses = [{
address = "138.124.112.127";
prefixLength = 32;
}];
routes = [{
address = "10.0.0.1";
prefixLength = 32;
}];
};
};
defaultGateway = "10.0.0.1";
nameservers = ["1.1.1.1"];
};
boot.tmp.cleanOnBoot = true;
zramSwap.enable = true;
system.stateVersion = "25.05";
}

31
servers/vanessa/main.nix Normal file
View file

@ -0,0 +1,31 @@
{ config, pkgs, secret, ... }:
{
imports = [
./hardware-configuration.nix
./nginx.nix
];
services.yggdrasil.persistentKeys = true;
marzban = {
env = {
UVICORN_HOST = "vanessa.project-a.space";
UVICORN_PORT = secret.marzban.port;
SUDO_USERNAME = secret.marzban.sudo-username;
SUDO_PASSWORD = secret.marzban.sudo-password;
DOCS = true;
};
cert = true;
domain = "vanessa.project-a.space";
xray = import ../common/xray.nix {
server-domain = "vanessa.project-a.space";
port = secret.marzban.vless-port;
dest = secret.marzban.dest;
privateKey = secret.marzban.privateKey;
shortId = secret.marzban.shortId;
spiderX = secret.marzban.spiderX;
};
};
networking.firewall.allowedTCPPorts = [ secret.marzban.port secret.marzban.vless-port ];
}

37
servers/vanessa/nginx.nix Normal file
View file

@ -0,0 +1,37 @@
{ config, pkgs, ... }:
{
security.acme.defaults.email = "porject-a@project-a.space";
security.acme.acceptTerms = true;
services.nginx = {
enable = true;
recommendedTlsSettings = true;
recommendedOptimisation = true;
defaultSSLListenPort = 444;
streamConfig = ''
map $ssl_preread_server_name $name {
default marzban;
}
upstream git {
server 127.0.0.1:444;
}
upstream marzban {
server 127.0.0.1:1080;
}
server {
listen 0.0.0.0:443;
listen [::0]:443;
proxy_pass $name;
ssl_preread on;
proxy_connect_timeout 1s;
proxy_timeout 1h;
proxy_buffer_size 16k;
}
'';
};
}

9
update.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh
nix flake check
nixos-rebuild switch --target-host reine --flake . --use-remote-sudo
nixos-rebuild switch --target-host kuber --flake . --use-remote-sudo
nixos-rebuild switch --target-host artemisia --flake . --use-remote-sudo
nixos-rebuild switch --target-host mio --flake . --use-remote-sudo
nixos-rebuild switch --target-host vanessa --flake . --use-remote-sudo