惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Full Disclosure
WordPress大学
WordPress大学
小众软件
小众软件
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
腾讯CDC
量子位
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
Scott Helme
Scott Helme
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Hacker News
The Hacker News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
Jina AI
Jina AI
Attack and Defense Labs
Attack and Defense Labs
S
SegmentFault 最新的问题
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
Last Week in AI
Last Week in AI
博客园 - 【当耐特】
Google Online Security Blog
Google Online Security Blog
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
罗磊的独立博客
L
LINUX DO - 最新话题
博客园 - Franky
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
The Last Watchdog
The Last Watchdog
J
Java Code Geeks
AI
AI
C
Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cyber Attacks, Cyber Crime and Cyber Security
Cisco Talos Blog
Cisco Talos Blog
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
Help Net Security
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
I
Intezer
S
Securelist

Chinmay D. Pai

I Think It's Time to Give Nix a Chance Digital Dams That Don't Hold: Why Internet Censorship Fails as Technical Policy Setting up Void Linux with Full-Disk Encryption Installing Termite on Void Linux Introduction to TensorFlow Variables
Hunting Down Mysterious NixOS Configuration with Nix REPL
Chinmay D. Pai · 2025-06-04 · via Chinmay D. Pai

Recently, while going through my routine system cleanup and “optimization”, I discovered my laptop was attempting to initialize a serial console on every boot. This was some feature I’d never configured and definitely didn’t need on a machine that spends its time rendering games, not serving headless in a datacenter!

Jun 01 23:30:17 zippyrus kernel: Kernel command line: ... console=ttyS0,115200 console=tty0 ...

Jun 01 23:30:17 zippyrus kernel: printk: legacy console [ttyS0] enabled

Jun 01 23:30:21 zippyrus systemd-tty-ask-password-agent[315]: Starting password query on /dev/ttyS0.

Jun 01 23:30:35 zippyrus systemd[1]: Expecting device /dev/ttyS0...

Jun 01 23:30:35 zippyrus systemd[1]: Condition check resulted in /dev/ttyS0 being skipped.

Jun 01 23:30:39 zippyrus systemd[1]: Started Serial Getty on ttyS0.

Jun 01 23:30:43 zippyrus agetty[1646]: /dev/ttyS0: not a tty

Jun 01 23:30:53 zippyrus systemd[1]: serial-getty@ttyS0.service: Main process exited, code=exited, status=1/FAILURE

My laptop, a device that had never seen a server rack, was desperately trying to start a serial console on a non-existent /dev/ttyS0 device. The kernel command line showed: console=ttyS0,115200 console=tty0. Now for those unaware, /dev/ttyS0 points to a serial console, allowing you to use a serial port to connect to the system when there’s no output display or input available. And the 115200 defines the baud rate, which is not a concern for this post. Sigh, I digress.

Sure enough, my laptop does not need a serial console. The journalctl logs were constantly being spammed with the error and I suspected that this also somehow affected my system’s battery life. This wasn’t breaking anything critical, but it bothered me deeply. If I didn’t put serial console parameters in my laptop config, where the hell were they coming from?

My first instinct was to grep through my entire configuration:

rg -i "console=\|ttyS0" . --glob="*.nix"

Nothing. Nada. Zilch. The serial console parameters weren’t hiding in any of my NixOS modules, hardware configurations, or system definitions. Out of curiosity, I checked all my other systems and found the same parameters everywhere: desktops, laptops, servers, all had these mysterious console=ttyS0,115200 console=tty0 entries. This confirmed my suspicion that something in my flake was adding them globally.

With most distros, you might hack a workaround and move on, never really knowing why. But NixOS is supposed to be explicit and traceable, and offers something exactly for scenarios like these.

How, you ask? The NixOS module system maintains provenance about every configuration option. You don’t have to guess where settings come from. Instead, you can interrogate the system directly and get definitive answers about what each input contributes to your final system state.

This is where nix repl nix.dev - nix repl comes handy. This interactive environment creates a live evaluation space where you can explore your fully evaluated NixOS configuration. And no, that’s not just the raw source code, but the actual evaluated result of all your modules, imports, and dependencies. It’s like having X-ray vision into your system’s configuration decisions. Let’s fire it up and see what we can find:

$ nix repl

# First, let's load the flake from the configuration path

flake = builtins.getFlake "/etc/nixos"

# Let's see what's actually in those kernel parameters

flake.outputs.nixosConfigurations.zippyrus.config.boot.kernelParams

[

"console=ttyS0,115200"

"console=tty0"

"nvidia-drm.modeset=1"

"nmi_watchdog=0"

"root=fstab"

"loglevel=0"

"lsm=landlock,yama,bpf"

]

Sure enough, there were my mystery parameters, sitting right alongside the legitimate ones I’d explicitly configured. But even then, where did these kernelParams come from?

Turns out, every evaluated NixOS option maintains provenance about its source, accessible through definitionsWithLocations NixOS/nixpkgs - GitHub . This is exactly what we need here!

# Time to trace the source

defs = flake.outputs.nixosConfigurations.zippyrus.options.boot.kernelParams.definitionsWithLocations

# Let's examine the first definition

builtins.elemAt defs 0

{

file = "/nix/store/kia92cyi6iqjq284xdk4wln1fv1jhb7m-source/nixos/common/serial.nix";

value = [ "console=ttyS0,115200" "console=tty0" ];

}

Voilà! I had my answer. Well, somewhat. It was coming from srvos nix-community/srvos - GitHub , a fantastic flake profile intended for servers, though the module does not belong here.

Now, the nix store path itself doesn’t immediately scream “this is from srvos,” but the path structure nixos/common/serial.nix suggests this isn’t from nixpkgs core or hardware-specific modules. Yes, an alternative, easier way to figure out would have been to check the contents of that specific directory in the nix store.

Looking back at my flake configuration, there it was:

systems.modules.nixos = with inputs; [

srvos.nixosModules.common # <-- The well-intentioned culprit

# ... other modules

];

Here, the srvos.nixosModules.common was being applied to all my systems since the srvos documentation indicates it is also suitable for desktops, to which, I now disagree.

The fix was straightforward once I understood the source:

systems.modules.nixos = with inputs; [

srvos.nixosModules.common

# ... other modules

];

This eliminated the journalctl errors on my system. Phew!

This debugging experience highlights something powerful about Nix. Rather than leave you guessing through layers of shell scripts and dusty forum posts, you get a direct answer to “where did this come from, and why?”. Next time you see weird config, don’t just grep blindly; fire up nix repl and let your system tell you its secrets.

Got any questions or comments? Drop me an email.