feat(kasmvnc): Chrome CDP visible pour Playwright MCP
- modules/nixos/kasmvnc-chrome-cdp.nix : lance un Chromium dans le desktop KasmVNC avec --remote-debugging-port=9222, profil persistant /home/marc/chrome-cdp-profile - Le MCP Playwright s'y attache (--cdp-endpoint http://127.0.0.1:9222) : les actions d'automatisation se font dans CETTE fenetre, donc visibles en direct sur le bureau distant (8443 en LAN, kasm.marcpartensky.com) - CDP reste sur 127.0.0.1 : un port CDP joignable donne le controle total du navigateur par quiconque l'atteint, donc jamais au LAN ni via Pangolin - newt : healthcheck HTTP sur le vhost local 8288 (KasmVNC repond 200 sur "/" avec disableBasicAuth) ; sans lui la cible sortait du load-balancer
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
# Module KasmVNC Chrome CDP : lance Chromium avec le Chrome DevTools Protocol
|
||||
# (remote debugging) dans la session Plasma de KasmVNC, pour Playwright MCP.
|
||||
#
|
||||
# POURQUOI un module separe et pas du code inline dans le profil : un module NixOS
|
||||
# ne doit PAS lire `config.<ses propres options>` dans son `let` au niveau racine
|
||||
# (ca part en « infinite recursion »). La forme correcte est options + `config =
|
||||
# mkIf cfg.enable { ... }`, comme ici.
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.kasmvnc.chrome-cdp;
|
||||
kasmUser = config.services.kasmvnc.user;
|
||||
browserPkg = if cfg.browser == "google-chrome" then pkgs.google-chrome else pkgs.chromium;
|
||||
browserBin = if cfg.browser == "google-chrome" then "google-chrome-stable" else "chromium";
|
||||
# NixOS ne connait PAS users.users.<u>.xdg.autostart (c'est du home-manager, et
|
||||
# le home de marc n'est pas gere par cette nixosConfiguration) : on ecrit le
|
||||
# .desktop via tmpfiles, pointant sur un lanceur.
|
||||
chromeCdpLauncher = pkgs.writeShellScript "chrome-cdp-launch" ''
|
||||
exec ${browserPkg}/bin/${browserBin} \
|
||||
--remote-debugging-port=${toString cfg.port} \
|
||||
--remote-debugging-address=${cfg.bindAddress} \
|
||||
--user-data-dir=${cfg.profileDir} \
|
||||
${lib.concatStringsSep " " cfg.extraFlags} \
|
||||
about:blank
|
||||
'';
|
||||
chromeCdpDesktop = pkgs.writeText "chrome-cdp.desktop" ''
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Chrome CDP
|
||||
Comment=Chrome with Chrome DevTools Protocol for Playwright MCP
|
||||
Exec=${chromeCdpLauncher}
|
||||
Terminal=false
|
||||
Categories=Network;WebBrowser;
|
||||
OnlyShowIn=KDE;
|
||||
'';
|
||||
in {
|
||||
options.services.kasmvnc.chrome-cdp = {
|
||||
enable = lib.mkEnableOption "Chrome/Chromium avec CDP dans la session KasmVNC";
|
||||
browser = lib.mkOption {
|
||||
type = lib.types.enum [ "chromium" "google-chrome" ];
|
||||
default = "chromium";
|
||||
description = "Navigateur a installer et lancer";
|
||||
};
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 9222;
|
||||
description = "Port de debug CDP";
|
||||
};
|
||||
bindAddress = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "127.0.0.1";
|
||||
description = "Adresse d'ecoute CDP (loopback par defaut : jamais au LAN)";
|
||||
};
|
||||
profileDir = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "/home/${kasmUser}/chrome-cdp-profile";
|
||||
description = "Repertoire de profil Chrome persistant";
|
||||
};
|
||||
extraFlags = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [ ];
|
||||
description = "Flags Chrome supplementaires";
|
||||
};
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Ouvrir le port CDP au firewall (deconseille : CDP = controle total)";
|
||||
};
|
||||
exposePublic = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = "Exposer CDP via Pangolin (SSO requis)";
|
||||
};
|
||||
publicDomain = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.str;
|
||||
default = null;
|
||||
description = "Domaine public CDP";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.kasmvnc.extraPackages = [ browserPkg ];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${cfg.profileDir} 0700 ${kasmUser} users - -"
|
||||
"d /home/${kasmUser}/.config/autostart 0755 ${kasmUser} users - -"
|
||||
"L+ /home/${kasmUser}/.config/autostart/chrome-cdp.desktop - - - - ${chromeCdpDesktop}"
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.port ];
|
||||
};
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
# Client WireGuard vers le VPS (voir la section WIREGUARD CLIENT en bas).
|
||||
wgClientEnable = false;
|
||||
in {
|
||||
|
||||
imports = [
|
||||
../../hosts/tower/disko.nix
|
||||
../../hosts/laptop/hardware-configuration.nix
|
||||
@@ -140,6 +141,34 @@ in {
|
||||
disableBasicAuth = true;
|
||||
};
|
||||
|
||||
# ========================================================================
|
||||
# KASMVNC CHROME CDP - Chrome/Chromium avec remote debugging pour Playwright MCP
|
||||
# ========================================================================
|
||||
# But : VOIR en direct ce que fait l'automatisation. Un Chromium visible tourne
|
||||
# dans le desktop Kasm (affichable sur 8443 en LAN et kasm.marcpartensky.com en
|
||||
# Internet), et le MCP s'y attache via --cdp-endpoint http://127.0.0.1:9222 :
|
||||
# toutes les actions Playwright se font alors dans CETTE fenetre.
|
||||
# CDP en loopback uniquement (un port CDP joignable = controle total du
|
||||
# navigateur par quiconque l'atteint, donc jamais au LAN ni sur Internet).
|
||||
services.kasmvnc.chrome-cdp = {
|
||||
enable = true;
|
||||
browser = "chromium";
|
||||
port = 9222;
|
||||
bindAddress = "127.0.0.1";
|
||||
profileDir = "/home/marc/chrome-cdp-profile";
|
||||
extraFlags = [
|
||||
"--no-first-run"
|
||||
"--no-default-browser-check"
|
||||
"--disable-background-networking"
|
||||
"--disable-translate"
|
||||
"--password-store=basic"
|
||||
"--disable-component-extensions-with-background-pages"
|
||||
"--disable-features=IsolateOrigins,site-per-process"
|
||||
];
|
||||
openFirewall = false;
|
||||
exposePublic = false;
|
||||
};
|
||||
|
||||
# /home/marc/.kasmpasswd : fichier au format kasmvncpasswd. Attention,
|
||||
# kasmvncpasswd n'a PAS d'option -f et refuse de tourner sans terminal
|
||||
# (« getpassword error: Inappropriate ioctl for device ») ; il lit le mot de
|
||||
@@ -250,6 +279,25 @@ in {
|
||||
hostname = "127.0.0.1";
|
||||
port = 8288;
|
||||
method = "http";
|
||||
# Healthcheck sur le vhost nginx local (8288 -> https KasmVNC 8443).
|
||||
# KasmVNC repond 200 text/html sur "/" (desactiveBasicAuth) : mesure
|
||||
# du 11/10/2026 sur http://127.0.0.1:8288/ -> 200. Meme schema que
|
||||
# noVNC/winnie dans services/newt (schema ancien : proxy-resources +
|
||||
# protocol, valide par ce Pangolin).
|
||||
healthcheck = {
|
||||
enabled = true;
|
||||
hostname = "127.0.0.1";
|
||||
port = 8288;
|
||||
path = "/";
|
||||
scheme = "http";
|
||||
mode = "http";
|
||||
method = "GET";
|
||||
interval = 30;
|
||||
unhealthy-interval = 30;
|
||||
timeout = 5;
|
||||
healthy-threshold = 1;
|
||||
unhealthy-threshold = 3;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
../modules/nixos/vault-rustguac
|
||||
../modules/nixos/rustguac
|
||||
../modules/nixos/kasmvnc
|
||||
../modules/nixos/kasmvnc-chrome-cdp.nix
|
||||
../modules/nixos/rustdesk
|
||||
../modules/nixos/nginx/rustguac
|
||||
../modules/nixos/nginx/kasmvnc
|
||||
|
||||
Reference in New Issue
Block a user