mirror of
https://github.com/itme-brain/nixos.git
synced 2026-05-08 14:50:12 -04:00
Compare commits
11 commits
6692807229
...
042820fb2a
| Author | SHA1 | Date | |
|---|---|---|---|
| 042820fb2a | |||
| 9ad55ac79a | |||
| d8be05169c | |||
| 573f5ec95d | |||
| 46adf8e9f0 | |||
| 3feb5ddc6b | |||
| 54b2a18d66 | |||
| cb5b10493f | |||
| c41a6ff637 | |||
| 07586a80ee | |||
| 27f765fe22 |
8 changed files with 96 additions and 52 deletions
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"WebSearch",
|
||||
"WebFetch(domain:forgejo.org)",
|
||||
"Bash(ssh:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
|||
*.qcow2
|
||||
result
|
||||
.direnv
|
||||
.claude
|
||||
|
|
|
|||
|
|
@ -12,13 +12,19 @@ creation_rules:
|
|||
key_groups:
|
||||
- age:
|
||||
- *desktop
|
||||
# Shared secrets (desktop + server)
|
||||
- path_regex: secrets/system/llama\.yaml$ # llama.cpp API key
|
||||
key_groups:
|
||||
- age:
|
||||
- *desktop
|
||||
- *server
|
||||
# Server secrets (cameras)
|
||||
- path_regex: secrets/system/cameras\.yaml$ # RTSP Feed
|
||||
key_groups:
|
||||
- age:
|
||||
- *server
|
||||
# Server secrets (searxng)
|
||||
- path_regex: secrets/system/searxng\.yaml$
|
||||
- path_regex: secrets/system/searxng\.yaml$ # searxng token
|
||||
key_groups:
|
||||
- age:
|
||||
- *server
|
||||
|
|
|
|||
25
secrets/system/llama.yaml
Normal file
25
secrets/system/llama.yaml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
LLAMA_API_KEY: ENC[AES256_GCM,data:ZVDpwGAxnHbHxt+JW3mYGyyBU5JfFAbjc/byq6Ok9wTlpQZBx969Z0wV74F5pR4axmpdGs7XlZDh1rJaQTn7lg==,iv:oAG9G25x+1FRkRNBRzLW2UJmbSxgx5Cu64Qo/6VzAyw=,tag:nkO/SdzjjLxH4fkgIdwUYQ==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- recipient: age17ejyzyk52unr6eyaa9rpunxpmf7u9726v6sx7me3ww3mdu5xzgjqsgj9gl
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzUmV6Q2dCMWU3TUFkZ0I0
|
||||
dHA3dXd2U0RSRzNtL3YvdG8rYWdnOTZoTkMwCkNnYnVlVmMyRDNnS1FmWktlNU9N
|
||||
UW1OMlJYODVzSHNIZWZMRkpPY05Ed3cKLS0tIDg0b0VkT0NrS3NIWE9EdWtWYXc1
|
||||
NjNESHpYbVptcnVRYWFKb3RlYkJ6OWMK3JsRXPDvJdKv2UyYIH8kr/WKbXgUDXbc
|
||||
fYOD0Huo73BA0vr8PlrsF4STVgJr/arKCMdI1C0bDdcwjExKnR1tIw==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
- recipient: age198jg29ryg3c0qj3yg6y9ha4ce2ue4hjdaa9kalf49fxju74dhchsquvjzp
|
||||
enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFTGNKOWczaityaXowWi9I
|
||||
dmh0MjJoelV3bVlzeGpLZmVTVzJjckwwQUFzCk81ZHlTcm5oWHRQNklreUR4bWNS
|
||||
OVdQelQ4YXkzeWZqOWZoNWlOVkZpWUkKLS0tIDZKQUU3LzV0UUhnRHVHQkFadkxm
|
||||
djRyUEYyZ2srMlVxR0JtQlFqSWV1QWcKMIF9Sq4TUUmpVZAukjTjFbIrMxcE3+el
|
||||
QSrHIm1HXLXwCKLDQ2N6b8Q9iUo/XMV0wsD3TLxdnUfegpQpfsDhag==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2026-04-14T05:45:37Z"
|
||||
mac: ENC[AES256_GCM,data:G+o6OhNF5AFBDKQEU3f1MZ+GOkxQj/m7NNk4Ti8PxPPOHdByoCrauvgB78SdQf5ubcfupElcNB0yF5QsG3/m7eGaSA+8J0cDL6jB3NEE5EUbW1Fuzzg2Ez1JnFu4BstkLiDRD/TribXMNFAjykmNrHt4zee6fhU3H0MOn7+Acok=,iv:IqBLSBq1kOMRHQn1IvU8OgmWGn6EFJcef/rNr38txmY=,tag:/mSWgbPbhUNoIm3x+6zyRA==,type:str]
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.12.1
|
||||
|
|
@ -5,6 +5,10 @@ let
|
|||
(user: user.modules.user.security.gpg.enable or false)
|
||||
(lib.attrValues config.home-manager.users);
|
||||
|
||||
devEnabled = lib.any
|
||||
(user: user.modules.user.utils.dev.enable or false)
|
||||
(lib.attrValues config.home-manager.users);
|
||||
|
||||
sysModules = config.modules.system;
|
||||
|
||||
in
|
||||
|
|
@ -19,6 +23,11 @@ in
|
|||
"WIFI_HOME_PSK" = wifi;
|
||||
"WIFI_CAMS_SSID" = wifi;
|
||||
"WIFI_CAMS_PSK" = wifi;
|
||||
} // lib.optionalAttrs devEnabled {
|
||||
"LLAMA_API_KEY" = {
|
||||
sopsFile = ../../../secrets/system/llama.yaml;
|
||||
owner = config.user.name;
|
||||
};
|
||||
};
|
||||
|
||||
sops.templates."wifi-env".content = ''
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
searxng.enable = mkEnableOption "Publicly exposed SearXNG endpoint with secret path via sops";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
|
|
@ -92,17 +91,6 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
virtualHosts."test.${domain}" = {
|
||||
useACMEHost = domain;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
return = "200 'nginx is working'";
|
||||
extraConfig = ''
|
||||
add_header Content-Type text/plain;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."wg.${domain}" = {
|
||||
useACMEHost = domain;
|
||||
forceSSL = true;
|
||||
|
|
@ -116,32 +104,49 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
virtualHosts."searxng.${domain}" = mkIf cfg.searxng.enable {
|
||||
useACMEHost = domain;
|
||||
forceSSL = true;
|
||||
locations."/".return = "404";
|
||||
extraConfig = ''
|
||||
include ${config.sops.templates."nginx-searxng-location.conf".path};
|
||||
virtualHosts."ai.${domain}" = let
|
||||
apiKeyAuth = ''
|
||||
set $api_key "";
|
||||
if ($http_authorization ~* "^Bearer (.+)$") {
|
||||
set $api_key $1;
|
||||
}
|
||||
if ($api_key = "") {
|
||||
return 401 '{"error": "Missing Authorization header"}';
|
||||
}
|
||||
include ${config.sops.templates."nginx-ai-auth.conf".path};
|
||||
'';
|
||||
};
|
||||
|
||||
virtualHosts."chat.${domain}" = {
|
||||
in {
|
||||
useACMEHost = domain;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://192.168.0.23:3080";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = privateAccessRules;
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."ai.${domain}" = {
|
||||
useACMEHost = domain;
|
||||
forceSSL = true;
|
||||
# Web UI + llama.cpp API (browser, /v1/* calls from the UI)
|
||||
# Auth handled by llama.cpp itself (--api-key flag)
|
||||
locations."/" = {
|
||||
proxyPass = "http://192.168.0.23:8000";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
|
||||
# Llama Stack API (opencode, programmatic clients)
|
||||
# Clients use baseURL: https://ai.ramos.codes/stack/v1
|
||||
locations."/stack/v1/" = {
|
||||
proxyPass = "http://192.168.0.23:8321/v1/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = apiKeyAuth + ''
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
'';
|
||||
};
|
||||
|
||||
# MCP servers (namespaced, for llama.cpp web UI + direct access)
|
||||
locations."/mcp/web_search/" = {
|
||||
proxyPass = "http://192.168.0.23:8002/";
|
||||
proxyWebsockets = true;
|
||||
extraConfig = ''
|
||||
include ${config.sops.templates."nginx-mcp-auth.conf".path};
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
virtualHosts."comfy.${domain}" = {
|
||||
|
|
|
|||
|
|
@ -9,20 +9,28 @@
|
|||
# Camera RTSP credentials (used by frigate/go2rtc)
|
||||
sops.secrets = let
|
||||
cameras = { sopsFile = ../../../secrets/system/cameras.yaml; };
|
||||
searxng = { sopsFile = ../../../secrets/system/searxng.yaml; };
|
||||
llama = { sopsFile = ../../../secrets/system/llama.yaml; };
|
||||
in {
|
||||
"RTSP_USER" = cameras;
|
||||
"RTSP_PASS" = cameras;
|
||||
"SEARXNG_TOKEN" = searxng;
|
||||
"LLAMA_API_KEY" = llama // { owner = config.user.name; };
|
||||
};
|
||||
|
||||
sops.templates."nginx-searxng-location.conf" = {
|
||||
# API key auth for ai.ramos.codes — nginx validates Bearer token against sops secret
|
||||
sops.templates."nginx-ai-auth.conf" = {
|
||||
content = ''
|
||||
location /${config.sops.placeholder."SEARXNG_TOKEN"}/ {
|
||||
proxy_pass http://192.168.0.23:8080/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
if ($api_key != "${config.sops.placeholder."LLAMA_API_KEY"}") {
|
||||
return 401 '{"error": "Invalid API key"}';
|
||||
}
|
||||
'';
|
||||
owner = "nginx";
|
||||
};
|
||||
|
||||
# MCP endpoint auth — validates X-API-Key header
|
||||
sops.templates."nginx-mcp-auth.conf" = {
|
||||
content = ''
|
||||
if ($http_x_api_key != "${config.sops.placeholder."LLAMA_API_KEY"}") {
|
||||
return 401 '{"error": "Unauthorized"}';
|
||||
}
|
||||
'';
|
||||
owner = "nginx";
|
||||
|
|
@ -31,7 +39,6 @@
|
|||
modules.system = {
|
||||
nginx = {
|
||||
enable = true;
|
||||
searxng.enable = true;
|
||||
};
|
||||
sandpack.enable = true;
|
||||
forgejo.enable = true;
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ in
|
|||
];
|
||||
|
||||
programs = {
|
||||
#bash = {
|
||||
# initExtra = import ./config/penpot.nix;
|
||||
#};
|
||||
bash = {
|
||||
initExtra = "export LLAMA_API_KEY=$(cat /run/secrets/LLAMA_API_KEY)";
|
||||
};
|
||||
direnv = {
|
||||
enable = true;
|
||||
enableBashIntegration = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue