Compare commits

...

4 commits

Author SHA1 Message Date
68a4779107
upd 2025-11-13 21:04:21 +09:00
c2106ca1a6
first xray 2025-10-18 12:43:35 +09:00
bbacfb100e
chore: update 2025-09-22 18:37:19 +09:00
8f90650888
japan hotfix 2025-07-18 22:34:53 +09:00
29 changed files with 992 additions and 97 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/result
/.env

16
flake.lock generated
View file

@ -44,16 +44,16 @@
]
},
"locked": {
"lastModified": 1744117652,
"narHash": "sha256-t7dFCDl4vIOOUMhEZnJF15aAzkpaup9x4ZRGToDFYWI=",
"lastModified": 1758463745,
"narHash": "sha256-uhzsV0Q0I9j2y/rfweWeGif5AWe0MGrgZ/3TjpDYdGA=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "b4e98224ad1336751a2ac7493967a4c9f6d9cb3f",
"rev": "3b955f5f0a942f9f60cdc9cacb7844335d0f21c3",
"type": "github"
},
"original": {
"owner": "nix-community",
"ref": "release-24.11",
"ref": "release-25.05",
"repo": "home-manager",
"type": "github"
}
@ -158,16 +158,16 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1744309437,
"narHash": "sha256-QZnNHM823am8apCqKSPdtnzPGTy2ZB4zIXOVoBp5+W0=",
"lastModified": 1761999846,
"narHash": "sha256-IYlYnp4O4dzEpL77BD/lj5NnJy2J8qbHkNSFiPBCbqo=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f9ebe33a928b5d529c895202263a5ce46bdf12f7",
"rev": "3de8f8d73e35724bf9abef41f1bdbedda1e14a31",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-24.11",
"ref": "nixos-25.05",
"repo": "nixpkgs",
"type": "github"
}

View file

@ -1,12 +1,12 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";
nixos-wsl = {
url = "github:nix-community/NixOS-WSL/main";
inputs.nixpkgs.follows = "nixpkgs";
};
home-manager = {
url = "github:nix-community/home-manager/release-24.11";
url = "github:nix-community/home-manager/release-25.05";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-generators = {
@ -44,6 +44,8 @@
hostname = "kp2pml30.moe";
nginx = true;
forgejo = true;
nix-cache = true;
xray = true;
};
}
@ -66,7 +68,7 @@
networking.hostName = "kp2pml30-personal-pc";
networking.hostId = "e31a5cc2";
time.timeZone = "Asia/Yerevan";
time.timeZone = "Asia/Tokyo";
}
./nix/hardware/mini.nix

View file

@ -1,4 +1,3 @@
{ pkgs
, inputs
, lib
@ -6,7 +5,10 @@
, ...
}:
{
imports = [ ./common.nix ];
imports = [
./common.nix
# ./nvidia.nix
];
fileSystems."/" = {
device = "/dev/disk/by-uuid/1ec7bbd6-cb83-427a-a901-d5fb7a4ef3ba";
@ -19,15 +21,15 @@
options = [ "fmask=0077" "dmask=0077" ];
};
fileSystems."/mnt/d" = {
device = "/dev/sda1";
fsType = "exfat";
options = [
"users"
"exec"
"nofail"
];
};
# fileSystems."/mnt/d" = {
# device = "/dev/sda1";
# fsType = "exfat";
# options = [
# "users"
# "exec"
# "nofail"
# ];
# };
swapDevices = [ { device = "/dev/disk/by-uuid/c68daa9f-f165-4e23-8710-2aab0ad8d282"; } ];

16
nix/hardware/nvidia.nix Normal file
View file

@ -0,0 +1,16 @@
{ pkgs
, inputs
, lib
, config
, ...
}:
{
services.xserver.videoDrivers = ["nvidia"];
hardware.nvidia = {
package = config.boot.kernelPackages.nvidiaPackages.production;
modesetting.enable = true;
open = false;
nvidiaSettings = true;
};
}

View file

@ -54,6 +54,7 @@ in {
"C.UTF-8/UTF-8"
"en_US.UTF-8/UTF-8"
"ru_RU.UTF-8/UTF-8"
"ja_JP.UTF-8/UTF-8"
];
programs = {
@ -71,6 +72,7 @@ in {
nixpkgs.config.allowUnfreePredicate = pkg:
builtins.elem (pkgs.lib.getName pkg) [
"anytype-heart"
"vscode"
"steam"
"steam-run"
@ -80,7 +82,7 @@ in {
"nvidia-settings"
"nvidia-persistenced"
"opera"
"discord-ptb"
"discord"
"slack"
"anytype"
];

View file

@ -20,11 +20,16 @@ in {
environment.systemPackages = [ pkgs.anytype ];
fonts.enableDefaultFonts = true;
fonts.packages = with pkgs; [
noto-fonts
noto-fonts-cjk-sans
noto-fonts-cjk-sans
fira-code
fira-code-nerdfont
fira-code-symbols
(nerdfonts.override { fonts = [ "FiraCode" ]; })
nerd-fonts.fira-code
];
}

View file

@ -7,11 +7,15 @@
}:
let
cfg = config.kp2pml30;
signalSuffix = if system == "x86_64-linux" then "amd64" else "arm64";
signal-pkgs = import (builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/71cbb752aa36854eb4a7deb3685b9789256d643c.tar.gz";
sha256 = "10dnjv2c28bjgplyj6nbk2q9lng6f95jf75i5yh541zngrr8b2qg";
}) {
system = pkgs.system;
};
in lib.mkIf cfg.messengers.personal {
users.users.${cfg.username}.packages = with pkgs; [
discord-ptb
discord
telegram-desktop
pkgs.signal-desktop
];
] ++ [signal-pkgs.signal-desktop];
}

View file

@ -6,10 +6,37 @@
}:
let
cfg = config.kp2pml30;
version = "123.0.5669.23";
legacy-nixpkgs = import (builtins.fetchTarball {
url = "https://github.com/NixOS/nixpkgs/archive/refs/tags/24.11.tar.gz";
sha256 = "1gx0hihb7kcddv5h0k7dysp2xhf1ny0aalxhjbpj2lmvj7h9g80a";
}) {
system = pkgs.system;
config.allowUnfreePredicate = pkg:
builtins.elem (pkgs.lib.getName pkg) [
"vscode"
"steam"
"steam-run"
"steam-original"
"steam-unwrapped"
"nvidia-x11"
"nvidia-settings"
"nvidia-persistenced"
"opera"
"discord"
"slack"
"anytype"
];
};
in lib.mkIf cfg.opera {
home-manager.users.${cfg.username}.home = {
packages = with pkgs; [
(opera.override { proprietaryCodecs = true; })
packages = with legacy-nixpkgs; [
((opera.override { proprietaryCodecs = true; }).overrideAttrs (finalAttrs: previousAttrs: {
src = fetchurl {
url = "https://get.geo.opera.com/pub/opera/desktop/${version}/linux/opera-stable_${version}_amd64.deb";
hash = "sha256-j2kHdg8d60S9j3bLychjmH/cRAXHGIjOgGKqmNIhnHU=";
};
}))
];
};
}

View file

@ -10,30 +10,36 @@ in lib.mkIf cfg.vscode {
home-manager.users.${cfg.username} = {
programs.vscode = {
enable = true;
package = pkgs.vscode;
package = (pkgs.vscode.overrideAttrs (oldAttrs: rec {
src = (builtins.fetchTarball {
url = "https://update.code.visualstudio.com/1.104.1/linux-x64/stable";
sha256 = "sha256:109mdk1v323dyhzrq0444gjjhfpjxbllkqkhsapfj44ypjzdjcy8";
});
version = "1.102.2";
}));
mutableExtensionsDir = false;
userSettings = lib.importJSON("${rootPath}/vscode/settings.json");
extensions = with pkgs; [
vscode-extensions.eamodio.gitlens
vscode-extensions.editorconfig.editorconfig
# extensions = with pkgs; [
# vscode-extensions.eamodio.gitlens
# vscode-extensions.editorconfig.editorconfig
#
# vscode-extensions.bierner.markdown-mermaid
vscode-extensions.bierner.markdown-mermaid
# vscode-extensions.tamasfe.even-better-toml
vscode-extensions.tamasfe.even-better-toml
vscode-extensions.streetsidesoftware.code-spell-checker
(pkgs.vscode-utils.buildVscodeMarketplaceExtension {
mktplcRef = {
name = "code-spell-checker-russian";
publisher = "streetsidesoftware";
version = "0.2.2";
sha256 = "a3b00c76a4aafecb962d6c292a3b9240a27d84b17de2119bb8007d0ad90ab443";
};
meta = {
license = lib.licenses.mit;
};
})
];
# vscode-extensions.streetsidesoftware.code-spell-checker
# (pkgs.vscode-utils.buildVscodeMarketplaceExtension {
# mktplcRef = {
# name = "code-spell-checker-russian";
# publisher = "streetsidesoftware";
# version = "0.2.2";
# sha256 = "a3b00c76a4aafecb962d6c292a3b9240a27d84b17de2119bb8007d0ad90ab443";
# };
# meta = {
# license = lib.licenses.mit;
# };
# })
# ];
};
};
}

View file

@ -27,7 +27,9 @@ in
nerdtree
tokyonight-nvim
barbar-nvim
feline-nvim
((fromGitHub "3587f57480b88e8009df7b36dc84e9c7ff8f2c49" "famiu/feline.nvim").overrideAttrs (old: {
doCheck = false;
}))
(fromGitHub "d63c811337b2f75de52f16efee176695f31e7fbc" "timakro/vim-yadi")
(fromGitHub "aafa5c187a15701a7299a392b907ec15d9a7075f" "nvim-tree/nvim-web-devicons")
];

View file

@ -14,8 +14,9 @@ in {
htop.enable = true;
};
environment.systemPackages = with pkgs; [
environment.systemPackages = with pkgs; [
ncdu
timewarrior
];
};

View file

@ -20,17 +20,26 @@ in {
forgejo = lib.mkEnableOption "";
dns = lib.mkEnableOption "";
nix-cache = lib.mkEnableOption "";
xray = lib.mkEnableOption "";
sitePath = lib.mkOption {
type = lib.types.str;
};
};
imports = [
./ports.nix
./ssh.nix
./nginx.nix
./boot.nix
./site.nix
./forgejo.nix
./dns.nix
./nix-cache.nix
./xray.nix
./secrets.nix
];
config = {

35
nix/server/dns.nix Normal file
View file

@ -0,0 +1,35 @@
{ config
, pkgs
, lib
, self
, nixpkgs
, kp2pml30-moe
, system
, ...
}@args:
let
cfg = config.kp2pml30.server;
ports = config.kp2pml30.server.ports;
in lib.mkIf cfg.nginx {
services.coredns.enable = true;
services.coredns.config = ''
dns://.:53 {
forward . tls://1.1.1.1 {
tls
tls_servername cloudflare-dns.com
}
cache
}
https://.:${toString ports.coredns-https} {
forward . dns://127.0.0.1:53 {
tls
tls_servername cloudflare-dns.com
policy random
}
cache
}
'';
# networking.networkmanager.insertNameservers = [ "127.0.0.1" ];
}

View file

@ -5,6 +5,7 @@
}:
let
cfg = config.kp2pml30.server;
ports = config.kp2pml30.server.ports;
in lib.mkIf cfg.forgejo {
services.forgejo = {
enable = true;
@ -14,7 +15,7 @@ in lib.mkIf cfg.forgejo {
server = {
DOMAIN = "git.${cfg.hostname}";
ROOT_URL = "https://git.${cfg.hostname}/";
HTTP_PORT = 8002;
HTTP_PORT = ports.forgejo;
};
service.DISABLE_REGISTRATION = true;
};

26
nix/server/modify-secrets.sh Executable file
View file

@ -0,0 +1,26 @@
#!/bin/sh
set -e
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
if ! command -v nvim
then
echo "no nvim"
exit 1
fi
if ! command -v base64
then
echo "no base64"
exit 1
fi
if ! command -v openssl
then
echo "no openssl"
exit 1
fi
env $(cat /var/lib/secrets/.env | xargs) nvim --clean -n \
-u "$SCRIPT_DIR/modify-secrets.vim" \
"$SCRIPT_DIR/secrets.yaml"

View file

@ -0,0 +1,43 @@
set nobackup nowritebackup noundofile noswapfile viminfo= history=0 noshelltemp secure
function! s:OpenSSLReadPre()
endfunction
function! s:OpenSSLReadPost()
silent! execute "0,$!openssl enc -aes-256-cbc -pbkdf2 -iter 1000000 -base64 -d -k '" . $KP2_DOTFILES_SECRET_KEY . "'"
if v:shell_error
silent! 0,$y
silent! undo
echo "Note that your version of openssl may not have the given cipher engine built-in"
echo "even though the engine may be documented in the openssl man pages."
echo "ERROR FROM OPENSSL:"
echo @"
echo "COULD NOT DECRYPT"
return
endif
redraw!
endfunction
function! s:OpenSSLWritePre()
silent! execute "0,$!openssl enc -aes-256-cbc -pbkdf2 -iter 1000000 -base64 -k '" . $KP2_DOTFILES_SECRET_KEY . "'"
if v:shell_error
silent! 0,$y
silent! undo
echo "Note that your version of openssl may not have the given cipher engine built in"
echo "even though the engine may be documented in the openssl man pages."
echo "ERROR FROM OPENSSL:"
echo @"
echo "COULD NOT ENCRYPT"
return
endif
endfunction
function! s:OpenSSLWritePost()
"silent! undo
"redraw!
endfunction
autocmd BufReadPre,FileReadPre * call s:OpenSSLReadPre()
autocmd BufReadPost,FileReadPost * call s:OpenSSLReadPost()
autocmd BufWritePre,FileWritePre * call s:OpenSSLWritePre()
autocmd BufWritePost,FileWritePost * call s:OpenSSLWritePost()

View file

@ -5,6 +5,7 @@
}:
let
cfg = config.kp2pml30.server;
ports = config.kp2pml30.server.ports;
acmeRoot = "/var/lib/acme/acme-challenge";
pref = "kp2";
in lib.mkIf cfg.nginx {
@ -14,7 +15,7 @@ in lib.mkIf cfg.nginx {
defaults.email = "kp2pml30@gmail.com";
#defaults.server = "https://acme-staging-v02.api.letsencrypt.org/directory";
certs."${cfg.hostname}" = {
extraDomainNames = [ "pr.${cfg.hostname}" "www.${cfg.hostname}" "git.${cfg.hostname}" "backend.${cfg.hostname}" ];
extraDomainNames = [ "pr.${cfg.hostname}" "www.${cfg.hostname}" "git.${cfg.hostname}" "backend.${cfg.hostname}" "dns.${cfg.hostname}" "cache.nix.${cfg.hostname}" "x.${cfg.hostname}" ];
webroot = acmeRoot;
group = "nginx";
};
@ -23,47 +24,180 @@ in lib.mkIf cfg.nginx {
services.nginx = {
enable = true;
virtualHosts."git.${cfg.hostname}" = {
enableACME = true;
acmeRoot = acmeRoot;
logError = "stderr debug";
listen = [
{ addr = "0.0.0.0"; port = 80; }
];
locations."/" = {
proxyPass = "http://127.0.0.1:8002";
virtualHosts = {
"git.${cfg.hostname}" = {
enableACME = true;
acmeRoot = acmeRoot;
listen = [
{ addr = "0.0.0.0"; port = 80; }
];
locations."/" = {
proxyPass = "http://127.0.0.1:${toString ports.forgejo}";
};
};
};
virtualHosts."backend.${cfg.hostname}" = {
enableACME = true;
acmeRoot = acmeRoot;
"backend.${cfg.hostname}" = {
enableACME = true;
acmeRoot = acmeRoot;
listen = [
{ addr = "0.0.0.0"; port = 80; }
];
listen = [
{ addr = "0.0.0.0"; port = 80; }
];
locations."/" = {
proxyPass = "http://127.0.0.1:8001";
locations."/" = {
proxyPass = "http://127.0.0.1:${toString ports.backend}";
};
};
};
virtualHosts."${cfg.hostname}" = {
# addSSL = true;
# forceSSL = true;
enableACME = true;
acmeRoot = acmeRoot;
"dns.${cfg.hostname}" = {
enableACME = true;
acmeRoot = acmeRoot;
listen = [
{ addr = "0.0.0.0"; port = 80; }
];
listen = [
{ addr = "0.0.0.0"; port = 80; }
];
locations."/" = {
root = cfg.sitePath;
tryFiles = "$uri $uri/ /index.html";
locations."/" = {
proxyPass = "http://127.0.0.1:${toString ports.coredns-https}";
};
};
};
"x.${cfg.hostname}" = {
enableACME = true;
acmeRoot = acmeRoot;
listen = [
{ addr = "0.0.0.0"; port = 80; }
];
locations."/" = {
proxyPass = "https://www.lovelive-anime.jp";
extraConfig = ''
sub_filter $proxy_host $host;
sub_filter_once off;
proxy_set_header Host $proxy_host;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
resolver 1.1.1.1;
'';
};
};
"${cfg.hostname}" = {
# addSSL = true;
# forceSSL = true;
enableACME = true;
acmeRoot = acmeRoot;
listen = [
{ addr = "0.0.0.0"; port = 80; }
];
locations."/" = {
root = cfg.sitePath;
tryFiles = "$uri $uri/ /index.html";
};
};
} // (if cfg.xray then {
# Xray fallback proxy servers
"127.0.0.1:${toString ports.xray-fallback}" = {
listen = [
{ addr = "127.0.0.1"; port = ports.xray-fallback; proxyProtocol = true; }
];
locations."/" = {
proxyPass = "https://www.lovelive-anime.jp";
extraConfig = ''
sub_filter $proxy_host $host;
sub_filter_once off;
proxy_set_header Host $proxy_host;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
resolver 1.1.1.1;
'';
};
};
"127.0.0.1:${toString ports.xray-websocket}" = {
listen = [
{ addr = "127.0.0.1"; port = ports.xray-websocket; proxyProtocol = true; }
];
locations."/" = {
proxyPass = "https://www.lovelive-anime.jp";
extraConfig = ''
sub_filter $proxy_host $host;
sub_filter_once off;
proxy_set_header Host $proxy_host;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_ssl_server_name on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
resolver 1.1.1.1;
'';
};
};
} else {}) // (if cfg.nix-cache then {
"cache.nix.${cfg.hostname}" = {
enableACME = true;
acmeRoot = acmeRoot;
listen = [
{ addr = "0.0.0.0"; port = 80; }
];
locations."/" = {
proxyPass = "http://${config.services.nix-serve.bindAddress}:${toString config.services.nix-serve.port}";
};
};
} else {});
streamConfig = (builtins.readFile ./stream.nginx);
};

18
nix/server/nix-cache.nix Normal file
View file

@ -0,0 +1,18 @@
{ config
, pkgs
, lib
, self
, nixpkgs
, kp2pml30-moe
, system
, ...
}@args:
let
cfg = config.kp2pml30.server;
in lib.mkIf cfg.nix-cache {
services.nix-serve = {
enable = true;
secretKeyFile = "/var/cache-priv-key.pem";
};
}

45
nix/server/ports.nix Normal file
View file

@ -0,0 +1,45 @@
{ lib, ... }:
{
# Server Port Usage Configuration
# This file documents and centralizes all port assignments
options.kp2pml30.server.ports = {
# Application Services
backend = lib.mkOption {
type = lib.types.int;
default = 8001;
description = "Backend service port (kp2pml30-moe-backend)";
};
forgejo = lib.mkOption {
type = lib.types.int;
default = 8002;
description = "Forgejo Git service port";
};
coredns-https = lib.mkOption {
type = lib.types.int;
default = 8003;
description = "CoreDNS HTTPS interface port";
};
# Available ports for new services
xray-main = lib.mkOption {
type = lib.types.int;
default = 8010;
description = "Xray VLESS inbound port";
};
xray-fallback = lib.mkOption {
type = lib.types.int;
default = 8011;
description = "Xray fallback proxy port";
};
xray-websocket = lib.mkOption {
type = lib.types.int;
default = 8012;
description = "Xray websocket fallback port";
};
};
}

97
nix/server/secrets.nix Normal file
View file

@ -0,0 +1,97 @@
{ config
, pkgs
, lib
, ...
}:
let
cfg = config.kp2pml30.server;
# Script to decrypt secrets.yaml and extract XRAY_UIDS
decryptSecrets = pkgs.writeShellScript "decrypt-secrets" ''
set -euo pipefail
source /var/lib/secrets/.env
if [ -z "''${KP2_DOTFILES_SECRET_KEY:-}" ]; then
echo "Error: KP2_DOTFILES_SECRET_KEY environment variable not set" >&2
exit 1
fi
if [ ! -f "${./secrets.yaml}" ]; then
echo "Error: secrets.yaml not found" >&2
exit 1
fi
# Decrypt and parse XRAY_UIDS
${pkgs.openssl}/bin/openssl enc -aes-256-cbc -pbkdf2 -iter 1000000 -base64 -d -k "$KP2_DOTFILES_SECRET_KEY" -in "${./secrets.yaml}" | ${pkgs.yq}/bin/yq '.XRAY_UIDS[]' -r
'';
xray-config-base = builtins.toFile "xray.json" (builtins.readFile ./xray.json);
# Script to generate complete xray configuration
generateXrayConfig = pkgs.writeShellScript "generate-xray-config" ''
set -euo pipefail
ALL_IDS="["
first=true
while IFS= read -r uuid; do
if [ "$first" = true ]; then
first=false
else
ALL_IDS="$ALL_IDS,"
fi
ALL_IDS="$ALL_IDS{\"id\":\"$uuid\",\"flow\": \"xtls-rprx-vision\"}"
done < <(${decryptSecrets})
ALL_IDS="$ALL_IDS]"
cat "${xray-config-base}" | \
jq --argjson val "$ALL_IDS" '.inbounds.[0].settings.clients = $val'
'';
in {
options.kp2pml30.server.secretsDir = lib.mkOption {
type = lib.types.str;
default = "/var/lib/secrets";
description = "Directory for secrets management";
};
config = lib.mkIf cfg.xray {
# Ensure xray user and group exist
users.users.xray = {
isSystemUser = true;
group = "xray";
};
users.groups.xray = {};
# Create a systemd service to decrypt and prepare xray clients config
systemd.services.xray-secrets = {
description = "Decrypt Xray client configuration";
wantedBy = [ "xray.service" ];
before = [ "xray.service" ];
serviceConfig = {
Type = "oneshot";
User = "root";
EnvironmentFile = "${cfg.secretsDir}/.env";
};
script = ''
mkdir -p /run/secrets
${generateXrayConfig} > /run/secrets/xray-config.json
chown xray:xray /run/secrets/xray-config.json
chmod 440 /run/secrets/xray-config.json
'';
path = [ pkgs.jq ];
};
# Ensure secrets directory exists
systemd.tmpfiles.rules = [
"d ${cfg.secretsDir} 0750 root root -"
"d /run/secrets 0755 root root -"
];
};
}

4
nix/server/secrets.yaml Normal file
View file

@ -0,0 +1,4 @@
U2FsdGVkX18N4BW9sin9kPVNkpbtVNoDqBAm+080vcYSS7qySHVOCfe94a7S8mh4
G5tbvoRrOFxJ+RW/WYNMsEZ7wgsJM8b9AiKPaT30BMHXriTdtai80i6xKqv9zdCb
moGUlBSgMtqEhvAnvpYBxHQ+NtDhxw7K9UjaO7eodNp+l9PR6z+IeL29rC2DMxQc
jXAjbfPa3aeSikXF0g118HbUwVJQwlXq99n/fjkJ8XOhBo/S4tWbt0U8O97VKlA6

View file

@ -9,6 +9,7 @@
}@args:
let
cfg = config.kp2pml30.server;
ports = config.kp2pml30.server.ports;
backend = kp2pml30-moe.packages.${system}.kp2pml30-moe-backend;
frontend = kp2pml30-moe.packages.${system}.kp2pml30-moe-frontend;
in lib.mkIf cfg.nginx {
@ -45,7 +46,7 @@ in lib.mkIf cfg.nginx {
Restart = "on-failure";
RestartSec = "3";
ExecStart = ''${pkgs.bash}/bin/bash -c "source /home/kp2pml30-moe-backend/env.sh && touch /home/kp2pml30-moe-backend/db.json && ${backend}/bin/kp2pml30-moe-backend --port 8001 --moderated-path /home/kp2pml30-moe-backend/chatbox-db.json"'';
ExecStart = ''${pkgs.bash}/bin/bash -c "source /home/kp2pml30-moe-backend/env.sh && touch /home/kp2pml30-moe-backend/db.json && ${backend}/bin/kp2pml30-moe-backend --port ${toString ports.backend} --moderated-path /home/kp2pml30-moe-backend/chatbox-db.json"'';
};
};
}

View file

@ -12,8 +12,15 @@ map $ssl_preread_server_name $name {
updates.signal.org updates;
updates2.signal.org updates2;
kp2pml30.moe self;
git.kp2pml30.moe self;
www.microsoft.com xray-entrypoint;
x.kp2pml30.moe xray-entrypoint;
pr.kp2pml30.moe signal-proxy;
kp2pml30.moe ssl-terminator;
dns.kp2pml30.moe ssl-terminator;
git.kp2pml30.moe ssl-terminator;
cache.nix.kp2pml30.moe ssl-terminator;
backend.kp2pml30.moe ssl-terminator;
default deny;
}
@ -62,6 +69,10 @@ upstream updates2 {
server updates2.signal.org:443;
}
upstream xray-entrypoint {
server 127.0.0.1:8010;
}
upstream deny {
server 127.0.0.1:9;
}
@ -70,23 +81,45 @@ upstream self {
server 127.0.0.1:80;
}
server {
listen 443 ssl;
server_name pr.kp2pml30.moe;
proxy_pass $name;
ssl_preread on;
upstream ssl-terminator {
server 127.0.0.1:8443;
}
ssl_certificate /var/lib/acme/kp2pml30.moe/fullchain.pem;
ssl_certificate_key /var/lib/acme/kp2pml30.moe/key.pem;
ssl_trusted_certificate /var/lib/acme/kp2pml30.moe/chain.pem;
upstream signal-proxy {
server 127.0.0.1:8444;
}
server {
listen 443 ssl;
server_name kp2pml30.moe git.kp2pml30.moe backend.kp2pml30.moe;
listen 443;
ssl_preread on;
proxy_pass $name;
}
server {
listen 8443 ssl;
server_name kp2pml30.moe git.kp2pml30.moe cache.nix.kp2pml30.moe backend.kp2pml30.moe dns.kp2pml30.moe;
proxy_pass self;
ssl_certificate /var/lib/acme/kp2pml30.moe/fullchain.pem;
ssl_certificate_key /var/lib/acme/kp2pml30.moe/key.pem;
ssl_trusted_certificate /var/lib/acme/kp2pml30.moe/chain.pem;
}
server {
listen 8444 ssl;
server_name pr.kp2pml30.moe;
ssl_preread on;
proxy_pass $name;
ssl_certificate /var/lib/acme/kp2pml30.moe/fullchain.pem;
ssl_certificate_key /var/lib/acme/kp2pml30.moe/key.pem;
ssl_trusted_certificate /var/lib/acme/kp2pml30.moe/chain.pem;
}
log_format proxy_log '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"'
'Proxy: "$ssl_preread_server_name" $name"';
access_log /var/log/nginx/aboba-access.log proxy_log buffer=1k flush=1m;

103
nix/server/xray-client.json Normal file
View file

@ -0,0 +1,103 @@
{
"log": {
"loglevel": "warning"
},
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": [
"regexp:\\.ru$",
"regexp:\\.рф$",
"domain:vk.com"
],
"outboundTag": "direct"
},
{
"type": "field",
"domain": [
"geosite:cn",
"geosite:private"
],
"outboundTag": "direct"
},
{
"type": "field",
"ip": [
"geoip:cn",
"geoip:ru",
"geoip:private"
],
"outboundTag": "direct"
}
]
},
"inbounds": [
{
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"udp": true
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
},
{
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "x.kp2pml30.moe",
"port": 443,
"users": [
{
"id": "",
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"serverName": "",
"allowInsecure": false,
"fingerprint": "chrome"
}
},
"tag": "proxy"
},
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
]
}

View file

@ -0,0 +1,81 @@
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"port": 1080,
"listen": "127.0.0.1",
"protocol": "socks",
"settings": {
"udp": true
}
},
{
"port": 1081,
"listen": "127.0.0.1",
"protocol": "http"
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vless",
"settings": {
"vnext": [
{
"address": "x.kp2pml30.moe",
"port": 443,
"users": [
{
"id": "YOUR-UUID-HERE",
"encryption": "none",
"flow": "xtls-rprx-vision"
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"fingerprint": "chrome",
"serverName": "www.microsoft.com",
"publicKey": "dRvlorHTupOukJ7aFZNPx-wXUMYJt3GQNrtSjMm9lAg",
"shortId": "deadbabe",
"spiderX": "/"
}
}
},
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"domain": [
"regexp:\\.ru$",
"geosite:category-ru",
"regexp:\\.рф$",
"regexp:(^|\\.)vk\\.com$"
],
"outboundTag": "block"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "proxy"
}
]
}
}

View file

@ -0,0 +1,90 @@
{
"log": {
"loglevel": "debug"
},
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": [
"regexp:\\.ru$",
"regexp:\\.рф$",
"domain:vk.com"
],
"outboundTag": "block"
},
{
"type": "field",
"ip": [
"geoip:cn",
"geoip:ru"
],
"outboundTag": "block"
},
{
"type": "field",
"network": "tcp,udp",
"outboundTag": "direct"
}
]
},
"inbounds": [
{
"listen": "127.0.0.1",
"port": 8010,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "YOUR-UUID-HERE",
"flow": "xtls-rprx-vision"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": true,
"dest": "www.microsoft.com:443",
"xver": 0,
"serverNames": [
"www.microsoft.com"
],
"privateKey": "",
"shortIds": [
"deadbabe"
],
"debug": true
}
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
],
"policy": {
"levels": {
"0": {
"handshake": 3,
"connIdle": 127
}
}
}
}

86
nix/server/xray.json Normal file
View file

@ -0,0 +1,86 @@
{
"log": {
"loglevel": "warning"
},
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"domain": [
"regexp:\\.ru$",
"regexp:\\.рф$",
"domain:vk.com"
],
"outboundTag": "block"
},
{
"type": "field",
"ip": [
"geoip:cn",
"geoip:ru"
],
"outboundTag": "block"
}
]
},
"inbounds": [
{
"listen": "127.0.0.1",
"port": 8010,
"protocol": "vless",
"settings": {
"clients": [
],
"decryption": "none",
"fallbacks": [
{
"dest": "8011",
"xver": 1
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls",
"tlsSettings": {
"rejectUnknownSni": true,
"minVersion": "1.2",
"alpn": ["http/1.1"],
"certificates": [
{
"ocspStapling": 3600,
"certificateFile": "/var/lib/acme/kp2pml30.moe/fullchain.pem",
"keyFile": "/var/lib/acme/kp2pml30.moe/key.pem"
}
]
}
},
"sniffing": {
"enabled": true,
"destOverride": [
"http",
"tls"
]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
],
"policy": {
"levels": {
"0": {
"handshake": 3,
"connIdle": 127
}
}
}
}

21
nix/server/xray.nix Normal file
View file

@ -0,0 +1,21 @@
{ config
, pkgs
, lib
, ...
}:
let
cfg = config.kp2pml30.server;
ports = config.kp2pml30.server.ports;
in lib.mkIf cfg.xray {
services.xray = {
enable = true;
settingsFile = "/run/secrets/xray-config.json";
};
# Ensure xray can read the certificates
users.users.xray.extraGroups = [ "nginx" ];
# Ensure the xray service starts after ACME certificates are available
systemd.services.xray.after = [ "acme-${cfg.hostname}.service" ];
systemd.services.xray.wants = [ "acme-${cfg.hostname}.service" ];
}