Pennix is a next-generation, reproducible, and modular pentesting container built on NixOS. Inspired by RedNix and nix-security-box, Pennix brings you a curated arsenal of security tools—ready to deploy, hack, and analyze in a snap.
If you want the most up-to-date, flexible, and reproducible pentesting environment, NixOS is simply unmatched:
- Most Up-to-Date Packages: NixOS (especially
nixpkgs-unstable
) delivers newer versions of security tools than Kali, Parrot, or BlackArch. You get bleeding-edge features and fixes first. - Reproducibility: Nix flakes guarantee your environment is always the same—across machines, teams, and time.
- Isolation by Design: NixOS containers are lightweight, secure, and isolated, letting you hack without polluting your host.
- Declarative or Imperative: Manage your containers and toolsets declaratively (in config) or imperatively (on the fly).
- Modularity: Tools are organized by category, making customization and extension trivial.
git clone https://github.com/linuxmobile/pennix.git
cd pennix
This is the fastest way to get started.
# To get networking inside the container, specify local and host addresses:
sudo nixos-container create --flake .#pennix pennix --local-address 192.168.100.10 --host-address 192.168.100.2
sudo nixos-container start pennix
sudo nixos-container root-login pennix
How to choose your --local-address
and --host-address
:
- Pick a private subnet that does not conflict with your existing network (e.g.,
192.168.100.0/24
). - The
--host-address
is assigned to the host's virtual interface (e.g.,192.168.100.2
). - The
--local-address
is assigned to the container's interface (e.g.,192.168.100.42
). - Make sure both addresses are unique and not used elsewhere on your system.
How to check which addresses are available:
- Use the
ip addr
command on your host to see which subnets are already in use. - Choose two unused addresses from your chosen subnet.
Example:
# Check existing interfaces and subnets
ip addr
# Pick addresses not in use, e.g.:
sudo nixos-container create --flake .#pennix pennix --local-address 192.168.100.42 --host-address 192.168.100.2
After creation, to see the container's IP:
sudo nixos-container show-ip pennix
-
The container will be built and started. You can log in as root or as the default user (
pennix
/ password:pennix
). -
To check status:
systemctl status container@pennix
-
To destroy:
nixos-container destroy pennix
-
The container will be built and started. You can log in as root or as the default user (
pennix
/ password:pennix
). -
To check status:
systemctl status container@pennix
-
To destroy:
nixos-container destroy pennix
For full reproducibility and auto-updates.
Add Pennix as an input to your system flake, then in your configuration.nix
:
{
inputs.pennix.url = "github:yourusername/pennix";
outputs = { self, nixpkgs, ... }@inputs: {
nixosConfigurations.yourhost = nixpkgs.lib.nixosSystem {
# ...
imports = [
inputs.pennix.container
];
};
};
}
- Rebuild your system:
nixos-rebuild switch
- Start/stop container:
systemctl start container@pennix
/systemctl stop container@pennix
- To autostart: add
containers.pennix.autoStart = true;
to your config.
- By default, Pennix uses a private virtual Ethernet network (
192.168.100.0/24
). - NAT is required for outbound access. If your host uses nftables (the default on modern NixOS), you must add a masquerade rule for your container subnet. See below for details.
- Port forwarding is set up for SSH (
host:2222 → container:22
) and HTTP (host:8080 → container:80
). - You can customize addresses and ports in
container.nix
.
If your host system uses nftables (the default on modern NixOS), you must add a NAT masquerade rule for your container subnet. The NixOS container NAT module only sets up iptables rules, which are ignored if nftables is active.
Add this to your host's /etc/nixos/configuration.nix
:
networking.nftables = {
enable = true;
tables = {
nat = {
family = "ip";
chains = {
POSTROUTING = {
type = "nat";
hook = "postrouting";
priority = 100;
rules = [
''ip saddr 192.168.100.0/24 oifname "<your-external-interface>" masquerade''
];
};
};
};
};
};
- Replace
<your-external-interface>
with the name of your real network interface (e.g.,wlp2s0
for WiFi,eth0
orenpXsY
for Ethernet). You can find this by runningip addr
on your host and looking for the interface with your main IP address. - The subnet (
192.168.100.0/24
) should match the one you use for your container.
After editing, run sudo nixos-rebuild switch
on your host.
Why is this needed? NixOS containers set up NAT using iptables by default, but if your system uses nftables, you must add the rule yourself for outbound connectivity from the container.
- Hundreds of tools for pentesting, forensics, fuzzing, cloud, wireless, Windows, web, and more.
- Nushell as the default shell, with custom aliases, completions, and a beautiful Starship prompt.
- Home Manager-style profile in PATH.
- Easy customization: Just edit the Nix files in
pkgs/
or add your own modules.
The externalInterface
option in your container's Nix config must match your host's real network interface.
This is often not eth0
on laptops or desktops. For example:
- On WiFi, it's usually something like
wlp2s0
- On Ethernet, it might be
enp3s0
,enp0s31f6
, etc.
Always check with ip addr
on your host and set the correct interface name.
If you use the wrong interface, NAT will not work and your container will not have internet access.
pennix/
├── flake.nix # Flake entrypoint, defines all outputs
├── container-config.nix # Main NixOS configuration for the container
├── container.nix # Container definition (networking, mounts, ports)
├── pkgs/ # Tool categories, each as a Nix module
└── modules/ # Shell and prompt configuration
PRs, issues, and tool suggestions are welcome! Let’s make pentesting with Nix delightful.
- RedNix (and its wiki)
- nix-security-box
- The NixOS and infosec communities
MIT. See LICENSE.
“Hack the planet, but reproducibly—with the freshest tools.”