Pentester Environment - A CLI tool for managing network and customer-specific environment variables across shell sessions on Linux.
penv auto-discovers network configuration and exposes it as shell variables. It supports saving/loading profiles for different customer environments, making it easy to switch contexts during engagements.
Variables are stored in ~/.local/share/penv/current.yaml and exported as lowercase shell variables (e.g., $ip, $dc, $domain) for direct use in commands like:
nxc smb $dc -d $domain -u $user -p $passwordDownload the latest pre-built binary directly from the releases page:
mkdir -p ~/.local/bin
curl -L https://github.com/evait-security/penv/releases/download/latest/penv-linux-x86_64 -o ~/.local/bin/penv
chmod +x ~/.local/bin/penvcargo build --release
cp target/release/penv ~/.local/bin/Add to your .bashrc or .zshrc:
eval "$(penv shell-init)"This installs a wrapper function that:
- Exports all variables from
current.yamlon shell startup - Auto-reloads variables after
penv set,penv unset,penv load, orpenv discover
For fish shell:
eval (penv shell-init fish)To also enable tab completion for commands, profile names, and variable names, pass --autocomplete:
# Bash / Zsh
eval "$(penv shell-init --autocomplete)"
# Fish
eval (penv shell-init fish --autocomplete)Completions are dynamic and include:
- All
penvsubcommands - Saved profile names for
load,drop,print,store - Current variable names for
setandunset - Shell names for
completionsandshell-init
Manual mode: If you prefer explicit control, use eval "$(penv init)" instead. You'll need to re-run it after each change.
penv discoverDetects and saves:
ip- Local IP of the primary LAN adaptergateway- Default gatewaydc- DNS server (useful as DC in AD environments)domain- DNS search domain
penv set user "USERNAME"
penv set password "P@ssw0rd!"
penv unset password
penv printSave the current configuration as a named profile:
penv store customer_1List all saved profiles:
penv listLoad a saved profile:
penv load customer_1Print a specific profile without loading it:
penv print customer_1Delete a saved profile:
penv drop customer_1With shell-init, variables are reloaded automatically.
Profiles are stored as ~/.local/share/penv/<name>.yaml.
Generate completions for your shell:
# Bash
penv completions bash > ~/.local/share/bash-completion/completions/penv
# Zsh
penv completions zsh > ~/.zfunc/_penv
# Fish
penv completions fish > ~/.config/fish/completions/penv.fish| Command | Description |
|---|---|
penv init |
Output export commands for eval |
penv shell-init [--autocomplete] [shell] |
Output shell wrapper with auto-reload; --autocomplete also installs tab completion |
penv discover |
Auto-detect network info and save to current.yaml |
penv set <key> <value> |
Add or update a variable |
penv unset <key> |
Remove a variable |
penv print [profile] |
Print active variables or a specific profile |
penv list |
List all saved profiles |
penv clean |
Wipe current.yaml |
penv store <name> |
Save current state as a profile |
penv load <name> |
Load a profile into current.yaml |
penv drop <name> |
Delete a saved profile |
penv completions <shell> |
Generate shell completions |
~/.local/share/penv/current.yaml- Active configuration~/.local/share/penv/<profile>.yaml- Saved profiles
Example YAML:
vars:
ip: 192.168.1.50
gateway: 192.168.1.1
dc: 192.168.1.10
domain: corp.local
user: administratorDiscovery uses standard Linux tools with automatic fallbacks:
IP and Gateway:
ip route- Default route interface and gatewayip addr- IP address of the default route interface
DNS Server and Domain (tried in order, merges results):
resolvectl- systemd-resolved (only if active)nmcli- NetworkManager- DHCP lease files:
/run/systemd/netif/leases/<ifindex>(systemd-networkd)/var/lib/dhcp/dhclient.*.leases(dhclient)
/run/systemd/resolve/resolv.conf- upstream DNS when using systemd stub/etc/resolv.conf- classic fallback
Works on systems with systemd-networkd, systemd-resolved, NetworkManager, dhclient, or plain resolv.conf.
MIT - see LICENSE