Compare commits

..
2 Commits
5 changed files with 69 additions and 10 deletions
+13 -1
View File
@@ -16,7 +16,7 @@ Flat, explicit NixOS modules with locked inputs. Required setup belongs here—n
| `tools.nix`, `network.nix` | Development toolkit, terminal/shell, rootless Podman, VPN/proxy clients, local Tor service and network diagnostics | | `tools.nix`, `network.nix` | Development toolkit, terminal/shell, rootless Podman, VPN/proxy clients, local Tor service and network diagnostics |
| `colors.nix`, `wallpaper.nix`, `wallpaper.svg` | Shared One Ring palette, hash-pinned wallpaper and original fallback artwork | | `colors.nix`, `wallpaper.nix`, `wallpaper.svg` | Shared One Ring palette, hash-pinned wallpaper and original fallback artwork |
| `desktop.nix`, `hyprland.lua`, `anyrun.css`, `swaync.css`, `desktop-help.py`, `desktop-actions.py` | Session/bar, launchers, described help, capture, clipboard, notifications, lock/idle and styling | | `desktop.nix`, `hyprland.lua`, `anyrun.css`, `swaync.css`, `desktop-help.py`, `desktop-actions.py` | Session/bar, launchers, described help, capture, clipboard, notifications, lock/idle and styling |
| `apps.nix`, `element-nightly.nix` | Firefox ESR, Tor Browser, KeePassXC, Thunderbird, Steam, pinned Element Nightly, Slack, file/media viewers and MIME defaults | | `apps.nix`, `element-nightly.nix` | Firefox ESR, Tor Browser, KeePassXC, Thunderbird, Steam, pinned Element Nightly, Slack, Tauon, file/media viewers and MIME defaults |
| `neovim.nix`, `neovim-test.lua` | Unmodified upstream editor deployment and opt-in native runtime audit | | `neovim.nix`, `neovim-test.lua` | Unmodified upstream editor deployment and opt-in native runtime audit |
| `updates.nix`, `update-system.sh`, `update-test.py` | Shared dev-owned checkouts, daily boot-staged updates and failure/concurrency regression tests | | `updates.nix`, `update-system.sh`, `update-test.py` | Shared dev-owned checkouts, daily boot-staged updates and failure/concurrency regression tests |
| `switch-system.sh`, `switch-test.py` | Same installed manual apply/preview command on both hosts, with host identity supplied by Nix | | `switch-system.sh`, `switch-test.py` | Same installed manual apply/preview command on both hosts, with host identity supplied by Nix |
@@ -129,6 +129,12 @@ includes **Playwright CLI + matching Firefox**, with a writable, once-seeded
Web profile on first startup, retained on restarts and updated explicitly. No host Web profile on first startup, retained on restarts and updated explicitly. No host
service is activated. service is activated.
### System DNS
`network.nix` enables **`systemd-resolved.service` on both hosts at boot**, with automatic restart after five seconds and no retry limit. NetworkManager supplies per-link DNS on the laptop; EC2 retains dhcpcd. NixOS connects `/etc/resolv.conf` to resolved's stub and provides the D-Bus service used by `resolvectl`. Upstream DNS still comes from DHCP/VPN configuration, not hard-coded public or private servers. An explicit `systemctl stop systemd-resolved` still stops it normally.
Use `systemctl status systemd-resolved` and `resolvectl status` to inspect it. `sudo resolvectl dns krishna-laptop 192.168.1.19` sets DNS on that existing interface at runtime; it does not persist across interface recreation or reboot. Put persistent VPN DNS and any routing domains in the VPN/NetworkManager profile.
### Local Tor client ### Local Tor client
On both hosts, `network.nix` installs Tor from the **system pin** and enables `tor.service` at boot. It runs as the dedicated `tor` user with the NixOS module's sandbox and private persistent state in `/var/lib/tor`. Systemd restarts an exited daemon after five seconds without a retry limit; an explicit `systemctl stop tor` still stops it normally. A running process does not guarantee network connectivity—check for `Bootstrapped 100%` in the journal. On both hosts, `network.nix` installs Tor from the **system pin** and enables `tor.service` at boot. It runs as the dedicated `tor` user with the NixOS module's sandbox and private persistent state in `/var/lib/tor`. Systemd restarts an exited daemon after five seconds without a retry limit; an explicit `systemctl stop tor` still stops it normally. A running process does not guarantee network connectivity—check for `Bootstrapped 100%` in the journal.
@@ -236,6 +242,12 @@ Manual refresh: `nix flake update nixpkgs home-manager nixpkgs-latest`, review `
## Editor and application data ## Editor and application data
**Tauon** is installed for `dev` from `nixpkgs-latest` (Nixpkgs master), with the
exact snapshot recorded in `flake.lock`. The current pin provides **12.0.0**,
matching the latest upstream stable release when added. It advances through the
existing daily input-update workflow. Launch `tauon` or choose **Tauon**
in the application launcher after applying; existing MIME defaults are unchanged.
Neovim imports [the existing neovim-dots source](https://git.cyber.ayyalasomayajula.net/marsultor/neovim-dots), pinned to `380eb86778a7c53a0f1c18e84f14037456155347`. Lua, AstroNvim, Lazy, Mason, plugins and keymaps are unchanged. No Nixvim, replacement loader or plugin-manager migration. Neovim imports [the existing neovim-dots source](https://git.cyber.ayyalasomayajula.net/marsultor/neovim-dots), pinned to `380eb86778a7c53a0f1c18e84f14037456155347`. Lua, AstroNvim, Lazy, Mason, plugins and keymaps are unchanged. No Nixvim, replacement loader or plugin-manager migration.
Home Manager links configuration files under `~/.config/nvim`. Lazy's writable lock lives under `~/.local/state/nvim/locks/<revision>.json`, seeded once per dotfile revision. An earlier manual checkout is preserved at `~/projects/neovim-dots-before-nix`; activation refuses to overwrite an existing backup. The host input is reproducible; Lazy/Mason's mutable runtime downloads are not claimed to be fully Nix-reproducible. Home Manager links configuration files under `~/.config/nvim`. Lazy's writable lock lives under `~/.local/state/nvim/locks/<revision>.json`, seeded once per dotfile revision. An earlier manual checkout is preserved at `~/projects/neovim-dots-before-nix`; activation refuses to overwrite an existing backup. The host input is reproducible; Lazy/Mason's mutable runtime downloads are not claimed to be fully Nix-reproducible.
+12
View File
@@ -1,5 +1,6 @@
{ {
config, config,
inputs,
lib, lib,
pkgs, pkgs,
... ...
@@ -7,6 +8,11 @@
let let
c = import ./colors.nix; c = import ./colors.nix;
# Tauon follows the fast-moving pin without overlaying the system libraries.
latest = import inputs.nixpkgs-latest {
inherit (pkgs.stdenv.hostPlatform) system;
config = pkgs.config;
};
elementNightly = import ./element-nightly.nix { inherit pkgs; }; elementNightly = import ./element-nightly.nix { inherit pkgs; };
browserAddon = pkgs.fetchurl { browserAddon = pkgs.fetchurl {
name = "keepassxc-browser-1.10.3.xpi"; name = "keepassxc-browser-1.10.3.xpi";
@@ -106,11 +112,17 @@ in
thunderbird thunderbird
file-roller file-roller
imv imv
latest.tauon
# Electron does not reliably detect a keyring under Hyprland. Use the # Electron does not reliably detect a keyring under Hyprland. Use the
# KeePassXC Secret Service explicitly; never fall back to basic_text. # KeePassXC Secret Service explicitly; never fall back to basic_text.
elementNightly elementNightly
slack slack
]; ];
# Fix the pinned package's stale launcher command, preserving its metadata.
xdg.dataFile."applications/tauonmb.desktop".source = pkgs.runCommand "tauonmb.desktop" { } ''
substitute ${latest.tauon}/share/applications/tauonmb.desktop "$out" \
--replace-quiet 'Exec=tauonmb ' 'Exec=${lib.getExe latest.tauon} '
'';
programs.mpv = { programs.mpv = {
enable = true; enable = true;
config = { config = {
+1 -1
View File
@@ -10,7 +10,7 @@
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
# Fast-moving developer tools can advance ahead of the tested channel. # Fast-moving standalone apps/tools can advance ahead of the tested channel.
# flake.lock still records the exact resolved snapshot. # flake.lock still records the exact resolved snapshot.
nixpkgs-latest.url = "github:NixOS/nixpkgs/master"; nixpkgs-latest.url = "github:NixOS/nixpkgs/master";
+13 -5
View File
@@ -1,5 +1,4 @@
{ {
config,
inputs, inputs,
lib, lib,
pkgs, pkgs,
@@ -8,14 +7,14 @@
let let
latest = import inputs.nixpkgs-latest { latest = import inputs.nixpkgs-latest {
inherit (pkgs.stdenv.hostPlatform) system; inherit (pkgs.stdenv.hostPlatform) system;
config = pkgs.config; inherit (pkgs) config;
}; };
in in
{ {
# NetworkManager owns local DNS on workstations. With dhcpcd (EC2), # Keep resolvectl available on both hosts. NixOS wires NetworkManager and
# NixOS wires resolvconf to resolved. Preserve both hosts' existing behavior. # /etc/resolv.conf to resolved; DHCP/VPNs still supply the upstream DNS.
services.resolved = { services.resolved = {
enable = lib.mkDefault (!config.networking.networkmanager.enable); enable = true;
settings.Resolve = { settings.Resolve = {
LLMNR = false; LLMNR = false;
MulticastDNS = false; MulticastDNS = false;
@@ -23,6 +22,15 @@ in
}; };
}; };
# The NixOS module enables resolved at boot. Retry exits without a start limit.
systemd.services.systemd-resolved = {
unitConfig.StartLimitIntervalSec = 0;
serviceConfig = {
Restart = "always";
RestartSec = "5s";
};
};
# Local, opt-in SOCKS client only. Keep the daemon on the system package pin. # Local, opt-in SOCKS client only. Keep the daemon on the system package pin.
# No relay/exit, control listener, transparent proxy or host DNS changes. # No relay/exit, control listener, transparent proxy or host DNS changes.
services.tor = { services.tor = {
+30 -3
View File
@@ -84,11 +84,38 @@ let
{ {
assertion = assertion =
config.networking.networkmanager.enable config.networking.networkmanager.enable
&& !config.services.resolved.enable && config.networking.networkmanager.dns == "systemd-resolved"
&& builtins.elem (lib.getName pkgs.networkmanager-openvpn) ( && builtins.elem (lib.getName pkgs.networkmanager-openvpn) (
map lib.getName config.networking.networkmanager.plugins map lib.getName config.networking.networkmanager.plugins
); );
message = "Keep NetworkManager/DNS and provide its OpenVPN integration."; message = "Keep NetworkManager with resolved DNS and its OpenVPN integration.";
}
{
assertion =
lib.all
(
c:
let
unit = c.systemd.services.systemd-resolved;
in
c.services.resolved.enable
&& builtins.elem "sysinit.target" unit.wantedBy
&& builtins.elem "dbus-org.freedesktop.resolve1.service" unit.aliases
&& unit.serviceConfig.Restart == "always"
&& unit.serviceConfig.RestartSec == "5s"
&& unit.unitConfig.StartLimitIntervalSec == 0
&& !c.networking.resolvconf.enable
&& c.networking.resolvconf.package == c.systemd.package
&& c.environment.etc."resolv.conf".source == "/run/systemd/resolve/stub-resolv.conf"
&& c.services.resolved.settings.Resolve.DNS == [ ]
&& !c.services.resolved.settings.Resolve.LLMNR
&& !c.services.resolved.settings.Resolve.MulticastDNS
)
[
config
ec2Config
];
message = "Both hosts need boot-enabled, restarting resolved with D-Bus/stub DNS integration, without hard-coded DNS servers.";
} }
{ {
assertion = assertion =
@@ -232,7 +259,7 @@ pkgs.runCommand "physical-config-check" { } ''
test -f "$sessions/wayland-sessions/hyprland-uwsm.desktop" test -f "$sessions/wayland-sessions/hyprland-uwsm.desktop"
test ! -e "$sessions/wayland-sessions/hyprland.desktop" test ! -e "$sessions/wayland-sessions/hyprland.desktop"
for tool in wg wg-quick openvpn iperf3 nmap traceroute whois mtr dig tcpdump ethtool nc socat \ for tool in wg wg-quick openvpn iperf3 nmap traceroute whois mtr dig tcpdump ethtool nc socat \
fping drill torsocks proxychains4 tor nm-connection-editor; do fping drill torsocks proxychains4 tor nm-connection-editor resolvectl; do
test -x "${config.system.path}/bin/$tool" test -x "${config.system.path}/bin/$tool"
done done
# Validate the exact generated torrc offline without touching live Tor state. # Validate the exact generated torrc offline without touching live Tor state.