Command Reference
Environment Variables
# ISE API credentials
export ISE_PAN_IP=10.50.1.20
export ISE_API_TOKEN=<base64-encoded-credentials>
export ISE_MNT_TOKEN=<base64-encoded-credentials>
# Switch credentials (via dsec)
eval "$(dsec source d000 dev/network)"
Certificate Paths
| File | Path | Permissions |
|---|---|---|
Private Key |
/etc/ssl/private/workstation01.key |
600 root:root |
Certificate |
/etc/ssl/certs/workstation01.pem |
644 root:root |
CA Certificate |
/etc/ssl/certs/DOMUS-ROOT-CA.pem |
644 root:root |
wpa_supplicant config |
/etc/wpa_supplicant/wpa_supplicant-wired.conf |
600 root:root |
Systemd Services
# wpa_supplicant
sudo systemctl enable wpa_supplicant-wired@enp0s31f6
sudo systemctl start wpa_supplicant-wired@enp0s31f6
sudo systemctl status wpa_supplicant-wired@enp0s31f6
# ClamAV
sudo systemctl enable clamav-daemon
sudo systemctl start clamav-daemon
sudo systemctl status clamav-daemon
# UFW
sudo ufw enable
sudo ufw status
netapi ISE Commands
The netapi ise CLI automates ISE configuration and monitoring.
Network Access Conditions
# List all conditions
netapi ise get-conditions
# List posture conditions (Session dictionary)
netapi ise get-conditions --dict Session
# Get specific condition
netapi ise get-condition "Compliant_Devices"
# Create posture condition
netapi ise create-posture-condition "My_Compliant_Check" \
--attr PostureStatus --value Compliant
# Create generic condition (any dictionary)
netapi ise create-condition "My_Condition" \
--dict "Session" --attr "PostureStatus" --value "Compliant"
# Delete condition
netapi ise delete-condition "My_Condition"
netapi ise delete-condition "My_Condition" --force
Dictionary Discovery
# List all ISE dictionaries
netapi ise get-dictionaries
# Get dictionary details (shows available attributes)
netapi ise get-dictionary Session
netapi ise get-dictionary RADIUS
ISE Session Verification
|
Always use
|
Basic Session Information
# Get active sessions
netapi ise mnt sessions
# Get session by MAC address
netapi ise mnt session 98:bb:1e:1f:a7:13
# Get session by IP address
netapi ise mnt session-ip 10.50.10.100
# Get session by username
netapi ise mnt session-user modestus-razer$
# Get active session count
netapi ise mnt count
Detailed Authorization Context
# Get comprehensive session view (includes auth rule, profile, DACL)
netapi ise dc session 98:bb:1e:1f:a7:13
# Get authentication history timeline
netapi ise dc auth-history 98:bb:1e:1f:a7:13
# Get recent authentication attempts
netapi ise dc recent --limit 10
# Get failed authentication attempts
netapi ise dc failed --limit 10
Authorization Profile Management
# List all authorization profiles
netapi ise get-authz-profiles
# Get specific authorization profile details
netapi ise get-authz-profile Linux_EAPTLS_Admins
# Update VLAN assignment (use VLAN name, NOT number)
netapi ise update-authz-profile Linux_EAPTLS_Admins --vlan DATA_VLAN
# Update DACL assignment
netapi ise update-authz-profile Linux_EAPTLS_Admins --dacl LINUX_EAPTLS_PERMIT_ALL
# Update both VLAN and DACL
netapi ise update-authz-profile Linux_EAPTLS_Admins \
--vlan DATA_VLAN \
--dacl LINUX_EAPTLS_PERMIT_ALL
# Remove DACL from profile
netapi ise update-authz-profile Linux_EAPTLS_Admins --no-dacl
|
CRITICAL: Always use switch VLAN names (e.g., Using numeric VLAN IDs will cause authorization to fail silently - the switch won’t apply the VLAN even though ISE shows success. Correct vs Incorrect
|
DACL Management
# List all DACLs
netapi ise get-dacls
# Get specific DACL content
netapi ise get-dacl LINUX_EAPTLS_PERMIT_ALL
# Create new DACL
netapi ise create-dacl LINUX_EAPTLS_PERMIT_ALL \
--acl "permit ip any any" \
--descr "Full network access for Linux Admin workstations"
# Delete DACL
netapi ise delete-dacl OLD_DACL_NAME
Advanced Command Patterns
Senior engineer-level awk, sed, and pipeline patterns for diagnostics and configuration.
File Inspection with awk
# Show specific line range
awk 'NR>=10 && NR<=20' /etc/sssd/sssd.conf
# Show line with line number
awk 'NR==73 {print NR": "$0}' /etc/ssh/sshd_config
# Find pattern and show line number
awk '/GSSAPIAuthentication/{print NR": "$0}' /etc/ssh/sshd_config
# Find pattern and show N lines of context after
awk '/pattern/{found=NR} found && NR<=found+5' filename
SSH Config Block Inspection
# Show Host block from match until next Host or empty line (range pattern)
awk '/^Host.*modestus-aw/,/^Host [^*]|^$/' ~/.ssh/config
# Find Host entry and show N lines after (context capture)
awk '/modestus-aw/{found=NR} found && NR<=found+5' ~/.ssh/config
# Find IP pattern and print with line numbers
awk '/10\.50\.40/{print NR": "$0}' ~/.ssh/config
# Find all Host entries with their line numbers
awk '/^Host /{print NR": "$0}' ~/.ssh/config
# Show specific Host block
awk '/^Host modestus-aw$/,/^Host [^*]/' ~/.ssh/config | head -10
SSH Config Block Editing (Range-Scoped sed)
|
The Force: Edit ONLY within a specific Host block, not globally. This prevents accidentally modifying other hosts with similar patterns. |
# Update HostName ONLY within modestus-aw block
sed -i '/^Host modestus-aw$/,/^Host /s/HostName .*/HostName 10.50.10.130/' ~/.ssh/config
| Component | Purpose |
|---|---|
|
Start of range - exact match for Host line |
|
Range separator |
|
End of range - next Host line (any host) |
|
Substitution applied ONLY within range |
Why range-scoped? Without the range, s/HostName .*/… would change EVERY HostName in the file. The range /start/,/end/ constrains the substitution to only lines between those patterns.
# 1. Find line number first
awk '/modestus-aw/{found=1} found && /HostName/{print NR": "$0; exit}' ~/.ssh/config
# 2. Apply range-scoped edit
sed -i '/^Host modestus-aw$/,/^Host /s/HostName .*/HostName 10.50.10.130/' ~/.ssh/config
# 3. Verify change
awk '/modestus-aw/{found=NR} found && NR<=found+2' ~/.ssh/config
# Update User within a block
sed -i '/^Host modestus-aw$/,/^Host /s/User .*/User newuser/' ~/.ssh/config
# Add IdentityFile after HostName within a block
sed -i '/^Host modestus-aw$/,/^Host /{/HostName/a\ IdentityFile ~/.ssh/id_ed25519_new
}' ~/.ssh/config
# Delete a line within a block
sed -i '/^Host modestus-aw$/,/^Host /{/ProxyJump/d}' ~/.ssh/config
Network Diagnostics
# IP addresses (clean output)
ip -4 -o addr show | awk '{print $2, $4}' | grep -v "^lo"
# Filter to physical interfaces only
ip -4 -o addr show | awk '{print $2, $4}' | grep -E "^(enp|eth|wlan)"
# Listening ports (clean)
ss -tlnp | awk '{print $4}' | sort -u
# TCP connections with state
ss -tnp | awk 'NR>1 {print $1, $4, $5}' | column -t
# Port connectivity test (no nc required) - Kerberos to DC
timeout 3 bash -c "</dev/tcp/10.50.1.50/88" && echo "OK" || echo "BLOCKED"
Configuration Editing with sed
# Verify line before change
sed -n '73p' /etc/ssh/sshd_config
# In-place edit specific line
sed -i '73s/#GSSAPIAuthentication no/GSSAPIAuthentication yes/' /etc/ssh/sshd_config
# Insert after specific line
sed -i '47a\
GSSAPIAuthentication yes\
GSSAPIDelegateCredentials yes' ~/.ssh/config
# Uncomment a line
sed -i 's/^#\(GSSAPIAuthentication\)/\1/' /etc/ssh/sshd_config
# Comment a line
sed -i 's/^\(PasswordAuthentication\)/#\1/' /etc/ssh/sshd_config
# Replace in specific line range only
sed -i '10,20s/old/new/g' /etc/sssd/sssd.conf
NSSwitch Configuration
# View passwd/group/shadow lines
awk 'NR>=4 && NR<=6' /etc/nsswitch.conf
# Add sss to passwd line
sed -i '4s/passwd: files systemd/passwd: files sss systemd/' /etc/nsswitch.conf
# Add sss to all auth lines (lines 4-6)
sed -i '4s/passwd: files/passwd: files sss/' /etc/nsswitch.conf
sed -i '5s/group: files/group: files sss/' /etc/nsswitch.conf
sed -i '6s/shadow: files/shadow: files sss/' /etc/nsswitch.conf
Service Verification
# sshd effective config
sudo sshd -T | grep -E "gssapi|pubkey|password"
# SSSD domain status
sudo sssctl domain-status inside.domusdigitalis.dev
# Kerberos ticket status
klist | awk '/Default principal|Expires/{print}'
# Check if service offers GSSAPI
ssh -v user@host 2>&1 | awk '/Authentications that can continue/{print}'
Hexdump for Config File Debugging
# Detect hidden characters (BOM, CRLF)
hexdump -C /etc/sssd/sssd.conf | head -5
# Remove UTF-8 BOM
sed -i '1s/^\xEF\xBB\xBF//' /etc/sssd/sssd.conf
# Convert CRLF to LF
sed -i 's/\r$//' /etc/sssd/sssd.conf
| Hex | Character | Notes |
|---|---|---|
|
LF |
Unix newline - correct |
|
CRLF |
Windows newline - convert |
|
UTF-8 BOM |
Remove from configs |
ISE Profile/dACL Discovery Loops
# Find which profile uses a specific dACL
for p in Linux_EAPTLS_Admins Linux_EAPTLS_Permit Linux_Posture_Compliant; do
dacl=$(netapi ise get-authz-profile "$p" 2>/dev/null | awk '/daclName/{print $NF}')
echo "$p -> ${dacl:-NONE}"
done
# Search ALL profiles for a specific dACL pattern
PROFILES="Linux_EAPTLS_Admins Linux_EAPTLS_Permit Linux_Posture_Compliant \
Linux_Posture_NonCompliant Linux_Posture_Unknown Domus_Research_Profile \
Research_Onboard Domus_Secure_Profile Domus_Admin_Profile"
for p in $PROFILES; do
dacl=$(netapi ise get-authz-profile "$p" 2>/dev/null | awk '/daclName/{print $NF}')
[[ "$dacl" == *"ZERO_TRUST"* ]] && echo "FOUND: $p -> $dacl"
done
dACL Update Workflow (When In Use)
|
dACLs cannot be deleted while referenced by an authorization profile. Use the detach-delete-recreate-reattach pattern. |
# 1. Find profile using the dACL
for p in Linux_EAPTLS_Admins Linux_EAPTLS_Permit Linux_Posture_Compliant; do
dacl=$(netapi ise get-authz-profile "$p" 2>/dev/null | awk '/daclName/{print $NF}')
[[ "$dacl" == "TARGET_DACL_NAME" ]] && echo "FOUND: $p"
done
# 2. Detach dACL from profile
netapi ise update-authz-profile "<profile-name>" --dacl ""
# 3. Delete old dACL
netapi ise delete-dacl "<dacl-name>" --force
# 4. Create updated dACL
netapi ise create-dacl "<dacl-name>" --file /tmp/dacl-updated.txt --descr "Description"
# 5. Reattach dACL to profile
netapi ise update-authz-profile "<profile-name>" --dacl "<dacl-name>"
# 6. Apply via CoA
netapi ise mnt coa "<mac-address>"
Quick Reference
| Task | Command |
|---|---|
View line N |
|
View lines X-Y |
|
Find with line number |
|
Edit line N |
|
Insert after line N |
|
IP addresses |
|
Listening ports |
|
Port test (no nc) |
|
Profile dACL check |
|
Detach dACL |
|