mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-25 05:50:57 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# Implementing Zero Trust Network Access with Zscaler
|
||||
|
||||
---
|
||||
domain: cybersecurity
|
||||
subdomain: zero-trust-architecture
|
||||
author: mahipal
|
||||
tags: [zero-trust, ztna, zscaler, network-access, vpn-replacement]
|
||||
difficulty: advanced
|
||||
estimated_time: 4-6 hours
|
||||
prerequisites:
|
||||
- Understanding of zero trust principles (NIST SP 800-207)
|
||||
- Familiarity with identity providers (Okta, Azure AD, Ping Identity)
|
||||
- Knowledge of network security fundamentals
|
||||
- Access to Zscaler Private Access (ZPA) tenant
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Zero Trust Network Access (ZTNA) replaces traditional VPN architectures by enforcing identity-based, context-aware access to private applications without placing users on the corporate network. Zscaler Private Access (ZPA) is a leading ZTNA solution that brokers secure connections between authenticated users and internal applications through the Zscaler Zero Trust Exchange cloud platform.
|
||||
|
||||
This skill covers end-to-end deployment of ZPA including connector setup, application segmentation, policy configuration, and integration with identity providers for continuous verification.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Zscaler Private Access Components
|
||||
|
||||
1. **Client Connector**: Lightweight agent on user endpoints that establishes outbound TLS tunnels to the nearest ZPA Service Edge
|
||||
2. **ZPA Service Edge**: Cloud-hosted broker (or Private Service Edge on-premises) that stitches user-to-app connections after policy evaluation
|
||||
3. **App Connector**: Lightweight VM deployed in the application environment that creates outbound tunnels to the Service Edge
|
||||
4. **ZPA Admin Portal**: Centralized management console for defining applications, segments, and access policies
|
||||
|
||||
### Connection Flow
|
||||
|
||||
```
|
||||
User Device (Client Connector)
|
||||
|
|
||||
v [Outbound TLS tunnel]
|
||||
ZPA Service Edge (Policy Evaluation + IdP Auth)
|
||||
|
|
||||
v [Outbound TLS tunnel]
|
||||
App Connector --> Internal Application
|
||||
```
|
||||
|
||||
Key principle: No inbound connections are required. Both the Client Connector and App Connector initiate outbound-only connections, eliminating the attack surface of traditional VPNs.
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Application Segments
|
||||
Define specific applications or groups of applications by IP address, FQDN, port, and protocol. Segments enable granular microsegmentation rather than broad network access.
|
||||
|
||||
### Access Policies
|
||||
Policies combine user identity, group membership, device posture, and contextual signals (location, time) to grant or deny access to application segments.
|
||||
|
||||
### Server Groups
|
||||
Logical groupings of App Connectors that serve specific application segments, enabling high availability and geographic distribution.
|
||||
|
||||
### Browser Access
|
||||
ZPA supports clientless browser-based access for web applications, enabling ZTNA for unmanaged devices and third-party users without requiring the Client Connector.
|
||||
|
||||
## Procedure
|
||||
|
||||
### Phase 1: Foundation Setup
|
||||
|
||||
1. **Configure Identity Provider Integration**
|
||||
- Navigate to Administration > IdP Configuration in ZPA Admin Portal
|
||||
- Add SAML 2.0 or OIDC integration with your IdP (Azure AD, Okta, Ping)
|
||||
- Configure SCIM provisioning for automatic user/group synchronization
|
||||
- Test SSO authentication flow
|
||||
|
||||
2. **Deploy App Connectors**
|
||||
- Provision App Connector VMs in each application environment (data center, AWS VPC, Azure VNet)
|
||||
- Download the provisioning key from ZPA Admin Portal
|
||||
- Install and enroll the App Connector using the provisioning key
|
||||
- Verify connector status shows "Healthy" in the admin portal
|
||||
- Deploy at least two connectors per environment for high availability
|
||||
|
||||
3. **Create Server Groups**
|
||||
- Group App Connectors by geographic location or application tier
|
||||
- Configure health check intervals and failover behavior
|
||||
|
||||
### Phase 2: Application Segmentation
|
||||
|
||||
4. **Define Application Segments**
|
||||
- Create segments for each application or logical group
|
||||
- Specify domains/IPs, ports, and protocols
|
||||
- Associate segments with appropriate server groups
|
||||
- Enable or disable browser access as needed
|
||||
|
||||
5. **Create Segment Groups**
|
||||
- Organize application segments into logical groups (e.g., HR apps, Finance apps)
|
||||
- Use segment groups to simplify policy management
|
||||
|
||||
### Phase 3: Policy Configuration
|
||||
|
||||
6. **Configure Access Policies**
|
||||
- Define rules matching user groups to application segments
|
||||
- Apply conditions: device posture, client type, SAML attributes
|
||||
- Order rules by priority (most restrictive first)
|
||||
- Create deny rules for blocked access scenarios
|
||||
|
||||
7. **Enable Device Posture Checks**
|
||||
- Configure posture profiles requiring OS patch level, disk encryption, antivirus status
|
||||
- Integrate with endpoint management (CrowdStrike, Microsoft Intune, Carbon Black)
|
||||
- Associate posture profiles with access policies
|
||||
|
||||
### Phase 4: Client Deployment
|
||||
|
||||
8. **Deploy Client Connector**
|
||||
- Package the Zscaler Client Connector with enrollment token
|
||||
- Deploy via MDM (Intune, Jamf, SCCM) or manual installation
|
||||
- Configure forwarding profile to route private app traffic through ZPA
|
||||
- Test user authentication and application access
|
||||
|
||||
### Phase 5: Monitoring and Optimization
|
||||
|
||||
9. **Enable Logging and Monitoring**
|
||||
- Configure log streaming to SIEM (Splunk, Sentinel, QRadar)
|
||||
- Set up alerts for policy violations, connector health, and authentication failures
|
||||
- Review ZPA Insights dashboard for usage analytics
|
||||
|
||||
10. **Iterative Refinement**
|
||||
- Analyze access logs to identify shadow IT and unauthorized access attempts
|
||||
- Refine application segments based on actual traffic patterns
|
||||
- Expand coverage from pilot applications to full enterprise deployment
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
- [ ] Identity provider integration tested with SSO and SCIM sync
|
||||
- [ ] App Connectors deployed and showing healthy status in all environments
|
||||
- [ ] Application segments defined with correct IPs/FQDNs, ports, protocols
|
||||
- [ ] Access policies enforce least-privilege per user group
|
||||
- [ ] Device posture checks block non-compliant endpoints
|
||||
- [ ] Client Connector deployed to all managed endpoints
|
||||
- [ ] Log streaming to SIEM confirmed with test events
|
||||
- [ ] Failover tested by disabling one App Connector per server group
|
||||
- [ ] Browser Access configured for web apps requiring third-party access
|
||||
- [ ] VPN decommission plan documented with rollback procedures
|
||||
|
||||
## References
|
||||
|
||||
- NIST SP 800-207: Zero Trust Architecture
|
||||
- CISA Zero Trust Maturity Model v2.0 - Network Pillar
|
||||
- Zscaler Private Access Architecture Guide
|
||||
- CSA Software-Defined Perimeter and Zero Trust Specification v2.0
|
||||
@@ -0,0 +1,135 @@
|
||||
# ZTNA Deployment Plan Template
|
||||
|
||||
## Project Information
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Project Name | |
|
||||
| Organization | |
|
||||
| Project Lead | |
|
||||
| Start Date | |
|
||||
| Target Completion | |
|
||||
| ZPA Tenant ID | |
|
||||
|
||||
## Current State Assessment
|
||||
|
||||
### Existing Remote Access
|
||||
- **VPN Solution**: [e.g., Cisco AnyConnect, Palo Alto GlobalProtect]
|
||||
- **Concurrent VPN Users**: [number]
|
||||
- **VPN Concentrator Locations**: [list]
|
||||
- **Known VPN Issues**: [latency, split-tunnel risks, capacity]
|
||||
|
||||
### Application Inventory
|
||||
|
||||
| App Name | FQDN/IP | Port | Protocol | User Groups | Criticality | Migration Wave |
|
||||
|---|---|---|---|---|---|---|
|
||||
| | | | | | | |
|
||||
| | | | | | | |
|
||||
|
||||
### Identity Provider
|
||||
- **Primary IdP**: [Azure AD / Okta / Ping Identity / Other]
|
||||
- **MFA Enabled**: [Yes/No - Method]
|
||||
- **SCIM Supported**: [Yes/No]
|
||||
- **Federation Protocol**: [SAML 2.0 / OIDC]
|
||||
|
||||
## ZPA Architecture Design
|
||||
|
||||
### App Connector Placement
|
||||
|
||||
| Environment | Location | VM Count | Server Group |
|
||||
|---|---|---|---|
|
||||
| Primary DC | | 2 | |
|
||||
| DR Site | | 2 | |
|
||||
| AWS VPC | | 2 | |
|
||||
| Azure VNet | | 2 | |
|
||||
|
||||
### Application Segments
|
||||
|
||||
| Segment Name | Domains/IPs | TCP Ports | UDP Ports | Server Group | Browser Access |
|
||||
|---|---|---|---|---|---|
|
||||
| | | | | | |
|
||||
| | | | | | |
|
||||
|
||||
### Access Policy Matrix
|
||||
|
||||
| Policy Name | User Groups | App Segments | Posture Profile | Conditions | Action |
|
||||
|---|---|---|---|---|---|
|
||||
| | | | | | Allow |
|
||||
| | | | | | Allow |
|
||||
| Block Default | All | All | None | None | Deny |
|
||||
|
||||
### Device Posture Profiles
|
||||
|
||||
| Profile Name | OS | Min Version | Disk Encryption | AV/EDR Required | Domain Joined |
|
||||
|---|---|---|---|---|---|
|
||||
| Corporate Managed | Windows | 10 22H2+ | BitLocker | CrowdStrike | Yes |
|
||||
| Corporate Managed | macOS | 14.0+ | FileVault | CrowdStrike | No |
|
||||
| BYOD | Any | Current-1 | Any | Any | No |
|
||||
|
||||
## Migration Plan
|
||||
|
||||
### Wave 1: Low-Risk Web Applications (Weeks 1-2)
|
||||
- [ ] Applications: [list]
|
||||
- [ ] User groups: [list]
|
||||
- [ ] Success criteria: [define]
|
||||
- [ ] Rollback plan: [define]
|
||||
|
||||
### Wave 2: Business-Critical Web Apps (Weeks 3-5)
|
||||
- [ ] Applications: [list]
|
||||
- [ ] User groups: [list]
|
||||
- [ ] Success criteria: [define]
|
||||
- [ ] Rollback plan: [define]
|
||||
|
||||
### Wave 3: Non-Web TCP/UDP Applications (Weeks 6-8)
|
||||
- [ ] Applications: [list]
|
||||
- [ ] User groups: [list]
|
||||
- [ ] Success criteria: [define]
|
||||
- [ ] Rollback plan: [define]
|
||||
|
||||
### Wave 4: Legacy Applications (Weeks 9-12)
|
||||
- [ ] Applications: [list]
|
||||
- [ ] User groups: [list]
|
||||
- [ ] Success criteria: [define]
|
||||
- [ ] Rollback plan: [define]
|
||||
|
||||
## SIEM Integration
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| SIEM Platform | [Splunk / Sentinel / QRadar / Other] |
|
||||
| Log Streaming Method | [HTTPS / Syslog / Cloud NSS] |
|
||||
| Log Types | [User Activity / App Connector Status / Policy Violations] |
|
||||
| Retention Period | |
|
||||
| Alert Rules | |
|
||||
|
||||
## Testing Plan
|
||||
|
||||
### Functional Tests
|
||||
- [ ] User authentication via IdP
|
||||
- [ ] Application access per policy
|
||||
- [ ] Device posture enforcement
|
||||
- [ ] Browser Access for web apps
|
||||
- [ ] Failover between App Connectors
|
||||
- [ ] Client Connector auto-update
|
||||
|
||||
### Security Tests
|
||||
- [ ] Unauthorized user access denied
|
||||
- [ ] Non-compliant device blocked or restricted
|
||||
- [ ] No lateral movement between segments
|
||||
- [ ] Log events captured in SIEM
|
||||
- [ ] Incident response playbook tested
|
||||
|
||||
### Performance Tests
|
||||
- [ ] Application latency within SLA
|
||||
- [ ] Throughput meets requirements
|
||||
- [ ] Service Edge selection optimal for user locations
|
||||
|
||||
## Sign-Off
|
||||
|
||||
| Stakeholder | Role | Approval | Date |
|
||||
|---|---|---|---|
|
||||
| | Network Security | | |
|
||||
| | Identity Team | | |
|
||||
| | Application Owners | | |
|
||||
| | CISO / Security Lead | | |
|
||||
| | IT Operations | | |
|
||||
@@ -0,0 +1,83 @@
|
||||
# Standards and Frameworks Reference
|
||||
|
||||
## NIST SP 800-207: Zero Trust Architecture
|
||||
|
||||
### Core Tenets Applicable to ZTNA
|
||||
1. **All data sources and computing services are considered resources** - Every application behind ZPA is treated as a discrete resource requiring explicit access grants
|
||||
2. **All communication is secured regardless of network location** - ZPA encrypts all tunnels end-to-end regardless of whether users are on-premises or remote
|
||||
3. **Access to individual enterprise resources is granted on a per-session basis** - ZPA evaluates policy for each connection request rather than granting persistent network access
|
||||
4. **Access to resources is determined by dynamic policy** - ZPA policies incorporate identity, device posture, location, and behavioral signals
|
||||
5. **The enterprise monitors and measures the integrity and security posture of all owned and associated assets** - Device posture checks validate endpoint compliance before granting access
|
||||
6. **All resource authentication and authorization are dynamic and strictly enforced before access is allowed** - ZPA requires authentication through IdP and authorization through policy engine for every session
|
||||
|
||||
### NIST ZTA Deployment Models
|
||||
- **Enhanced Identity Governance**: ZPA implements this model by using identity as the primary decision factor combined with device trust signals
|
||||
- **Micro-Segmentation**: ZPA application segments function as software-defined microsegments at the application layer
|
||||
- **Software Defined Perimeters**: ZPA directly implements the SDP model with its broker-based architecture
|
||||
|
||||
### NIST SP 800-207A: Zero Trust Architecture Model for Cloud-Native Applications
|
||||
- Extends zero trust principles to multi-cloud environments
|
||||
- ZPA App Connectors can be deployed across AWS, Azure, GCP, and on-premises
|
||||
- Supports workload-to-workload zero trust with ZPA for workloads
|
||||
|
||||
## CISA Zero Trust Maturity Model v2.0
|
||||
|
||||
### Network Pillar
|
||||
| Maturity Level | Capability | ZPA Implementation |
|
||||
|---|---|---|
|
||||
| Traditional | Macro-segmentation with static rules | Legacy VPN replaced by ZPA |
|
||||
| Initial | Define network architecture with isolation | App Connectors isolate segments |
|
||||
| Advanced | Micro-perimeters with identity-based access | Per-app segments with IdP integration |
|
||||
| Optimal | Dynamic microsegmentation with continuous verification | Real-time posture + behavioral analytics |
|
||||
|
||||
### Identity Pillar
|
||||
| Maturity Level | Capability | ZPA Implementation |
|
||||
|---|---|---|
|
||||
| Traditional | Password-based, agency-managed | Basic IdP integration |
|
||||
| Initial | MFA for privileged users, federated identity | SAML/OIDC with IdP, SCIM provisioning |
|
||||
| Advanced | MFA for all users, phishing-resistant | Conditional access with posture checks |
|
||||
| Optimal | Continuous validation, risk-based authentication | ZPA + CrowdStrike/UEBA integration |
|
||||
|
||||
### Devices Pillar
|
||||
| Maturity Level | Capability | ZPA Implementation |
|
||||
|---|---|---|
|
||||
| Traditional | Limited device visibility | Manual device inventory |
|
||||
| Initial | Compliance enforcement for some devices | Basic posture profiles |
|
||||
| Advanced | Real-time device analytics | CrowdStrike ZTA score integration |
|
||||
| Optimal | Continuous diagnostics and mitigation | EDR-driven dynamic access decisions |
|
||||
|
||||
## CSA Software-Defined Perimeter Specification v2.0
|
||||
|
||||
### SDP Architecture Mapping to ZPA
|
||||
| SDP Component | ZPA Equivalent |
|
||||
|---|---|
|
||||
| SDP Controller | ZPA Service Edge + Policy Engine |
|
||||
| Initiating Host (IH) | Client Connector |
|
||||
| Accepting Host (AH) | App Connector |
|
||||
| SDP Gateway | ZPA Service Edge |
|
||||
|
||||
### SDP Deployment Models
|
||||
- **Client-to-Gateway**: Standard ZPA deployment (user to application via Service Edge)
|
||||
- **Client-to-Server**: ZPA Browser Access (direct browser connection through Service Edge)
|
||||
- **Server-to-Server**: ZPA Workload-to-Workload (App Connector to App Connector)
|
||||
- **Client-to-Server-to-Client**: Not directly supported in ZPA
|
||||
|
||||
## DoD Zero Trust Reference Architecture v2.0
|
||||
|
||||
### Pillar Alignment
|
||||
- ZPA maps to the **Network & Environment** pillar through application-layer microsegmentation
|
||||
- ZPA maps to the **User** pillar through IdP integration and continuous authentication
|
||||
- ZPA maps to the **Device** pillar through endpoint posture assessment
|
||||
- ZPA maps to the **Application & Workload** pillar through per-application access control
|
||||
- Visibility & Analytics pillar addressed through ZPA log streaming and analytics dashboards
|
||||
|
||||
## Compliance Mapping
|
||||
|
||||
| Regulation | Requirement | ZPA Capability |
|
||||
|---|---|---|
|
||||
| NIST 800-53 AC-4 | Information flow enforcement | Application segment policies |
|
||||
| NIST 800-53 AC-17 | Remote access | ZTNA replaces VPN |
|
||||
| PCI DSS 4.0 Req 1 | Network security controls | Microsegmentation per cardholder segment |
|
||||
| HIPAA 164.312(e) | Transmission security | End-to-end encrypted tunnels |
|
||||
| SOX Section 404 | Access controls over financial systems | Auditable per-session access logs |
|
||||
| FedRAMP | Continuous monitoring | ZPA FedRAMP Moderate authorized |
|
||||
@@ -0,0 +1,207 @@
|
||||
# ZTNA Implementation Workflows
|
||||
|
||||
## Workflow 1: Initial ZPA Deployment
|
||||
|
||||
```
|
||||
┌─────────────────┐
|
||||
│ Pre-Assessment │
|
||||
│ - Inventory apps │
|
||||
│ - Map user groups│
|
||||
│ - Classify data │
|
||||
└───────┬─────────┘
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ IdP Integration │
|
||||
│ - SAML/OIDC config │
|
||||
│ - SCIM provisioning │
|
||||
│ - MFA enrollment │
|
||||
│ - Test SSO flow │
|
||||
└───────┬─────────────┘
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ App Connector Deploy │
|
||||
│ - Provision VMs │
|
||||
│ - Generate enroll key│
|
||||
│ - Install + enroll │
|
||||
│ - Health validation │
|
||||
└───────┬─────────────┘
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ Application Segments │
|
||||
│ - Define apps by │
|
||||
│ FQDN/IP + ports │
|
||||
│ - Create seg groups │
|
||||
│ - Map to server grps │
|
||||
└───────┬─────────────┘
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ Access Policies │
|
||||
│ - User->App mapping │
|
||||
│ - Posture conditions │
|
||||
│ - Deny rules │
|
||||
│ - Priority ordering │
|
||||
└───────┬─────────────┘
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ Client Deployment │
|
||||
│ - Package connector │
|
||||
│ - MDM distribution │
|
||||
│ - Forwarding profile │
|
||||
│ - User acceptance │
|
||||
└───────┬─────────────┘
|
||||
v
|
||||
┌─────────────────────┐
|
||||
│ Validation & Monitor │
|
||||
│ - Access testing │
|
||||
│ - SIEM integration │
|
||||
│ - Dashboard setup │
|
||||
│ - Incident playbooks │
|
||||
└─────────────────────┘
|
||||
```
|
||||
|
||||
## Workflow 2: Access Request Evaluation (Runtime)
|
||||
|
||||
```
|
||||
User Request
|
||||
│
|
||||
v
|
||||
┌──────────────────┐ ┌──────────────────┐
|
||||
│ Client Connector │───>│ ZPA Service Edge │
|
||||
│ - Capture request │ │ - Receive tunnel │
|
||||
│ - Forward to edge │ │ - Identify user │
|
||||
└──────────────────┘ └────────┬─────────┘
|
||||
│
|
||||
┌────────────v────────────┐
|
||||
│ Authentication │
|
||||
│ - Redirect to IdP │
|
||||
│ - Validate SAML/OIDC │
|
||||
│ - Check MFA completion │
|
||||
└────────────┬────────────┘
|
||||
│
|
||||
┌────────────v────────────┐
|
||||
│ Authorization │
|
||||
│ - Match access policies │
|
||||
│ - Evaluate posture │
|
||||
│ - Check context signals │
|
||||
│ - Apply least privilege │
|
||||
└────────────┬────────────┘
|
||||
│
|
||||
┌────YES─────┴─────NO────┐
|
||||
v v
|
||||
┌──────────────┐ ┌──────────────┐
|
||||
│ Grant Access │ │ Deny Access │
|
||||
│ - Select App │ │ - Log denial │
|
||||
│ Connector │ │ - Alert SIEM │
|
||||
│ - Stitch tunnel│ │ - User notify │
|
||||
│ - Monitor │ └──────────────┘
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
## Workflow 3: VPN-to-ZTNA Migration
|
||||
|
||||
```
|
||||
Phase 1: Assessment (Weeks 1-2)
|
||||
├── Catalog all VPN-accessed applications
|
||||
├── Map user groups to applications
|
||||
├── Identify application dependencies
|
||||
├── Baseline VPN performance metrics
|
||||
└── Document compliance requirements
|
||||
|
||||
Phase 2: Parallel Deployment (Weeks 3-6)
|
||||
├── Deploy ZPA alongside existing VPN
|
||||
├── Configure App Connectors for pilot apps
|
||||
├── Create policies mirroring VPN ACLs
|
||||
├── Deploy Client Connector to pilot users
|
||||
└── Validate access and performance
|
||||
|
||||
Phase 3: Migration Waves (Weeks 7-16)
|
||||
├── Wave 1: Low-risk web applications
|
||||
├── Wave 2: Business-critical web apps
|
||||
├── Wave 3: Non-web TCP/UDP applications
|
||||
├── Wave 4: Legacy applications
|
||||
└── Each wave: test → validate → migrate → monitor
|
||||
|
||||
Phase 4: VPN Decommission (Weeks 17-20)
|
||||
├── Verify all applications accessible via ZPA
|
||||
├── Disable VPN for migrated user groups
|
||||
├── Monitor for access issues (2-week soak)
|
||||
├── Decommission VPN concentrators
|
||||
└── Update disaster recovery documentation
|
||||
```
|
||||
|
||||
## Workflow 4: Device Posture Enforcement
|
||||
|
||||
```
|
||||
┌───────────────────┐
|
||||
│ Device Connects │
|
||||
└───────┬───────────┘
|
||||
v
|
||||
┌───────────────────┐
|
||||
│ Posture Assessment │
|
||||
│ - OS version │
|
||||
│ - Patch level │
|
||||
│ - Disk encryption │
|
||||
│ - AV/EDR status │
|
||||
│ - Firewall enabled │
|
||||
│ - Domain joined │
|
||||
└───────┬───────────┘
|
||||
v
|
||||
┌───────────────────┐
|
||||
│ Posture Evaluation │
|
||||
│ Compare against │
|
||||
│ posture profiles │
|
||||
└───┬──────────┬────┘
|
||||
│ │
|
||||
PASS FAIL
|
||||
│ │
|
||||
v v
|
||||
┌────────┐ ┌──────────────────┐
|
||||
│ Full │ │ Restricted Access │
|
||||
│ Access │ │ - Browser only │
|
||||
└────────┘ │ - Limited apps │
|
||||
│ - Remediation msg │
|
||||
└──────────────────┘
|
||||
```
|
||||
|
||||
## Workflow 5: Incident Response with ZPA
|
||||
|
||||
```
|
||||
Alert Triggered (SIEM/SOAR)
|
||||
│
|
||||
v
|
||||
┌──────────────────┐
|
||||
│ 1. Triage │
|
||||
│ - Review ZPA logs │
|
||||
│ - Identify user │
|
||||
│ - Identify app │
|
||||
│ - Classify event │
|
||||
└───────┬──────────┘
|
||||
v
|
||||
┌──────────────────┐
|
||||
│ 2. Containment │
|
||||
│ - Revoke user │
|
||||
│ access in ZPA │
|
||||
│ - Isolate app │
|
||||
│ segment │
|
||||
│ - Block device │
|
||||
│ via posture │
|
||||
└───────┬──────────┘
|
||||
v
|
||||
┌──────────────────┐
|
||||
│ 3. Investigation │
|
||||
│ - Pull session │
|
||||
│ logs from ZPA │
|
||||
│ - Correlate with │
|
||||
│ IdP/EDR/SIEM │
|
||||
│ - Map lateral │
|
||||
│ movement │
|
||||
└───────┬──────────┘
|
||||
v
|
||||
┌──────────────────┐
|
||||
│ 4. Recovery │
|
||||
│ - Update policies │
|
||||
│ - Re-enable access│
|
||||
│ - Post-incident │
|
||||
│ review │
|
||||
└──────────────────┘
|
||||
```
|
||||
@@ -0,0 +1,459 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
ZTNA Deployment Readiness Assessment and ZPA Configuration Validator
|
||||
|
||||
This script performs pre-deployment checks for Zscaler Private Access (ZPA)
|
||||
implementation, validates existing configurations, and generates deployment
|
||||
readiness reports.
|
||||
"""
|
||||
|
||||
import json
|
||||
import csv
|
||||
import socket
|
||||
import ssl
|
||||
import subprocess
|
||||
import sys
|
||||
import ipaddress
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def check_dns_resolution(fqdn: str) -> dict:
|
||||
"""Validate DNS resolution for application FQDNs."""
|
||||
result = {"fqdn": fqdn, "resolved": False, "addresses": [], "error": None}
|
||||
try:
|
||||
addresses = socket.getaddrinfo(fqdn, None)
|
||||
result["resolved"] = True
|
||||
result["addresses"] = list(set(addr[4][0] for addr in addresses))
|
||||
except socket.gaierror as e:
|
||||
result["error"] = str(e)
|
||||
return result
|
||||
|
||||
|
||||
def check_port_connectivity(host: str, port: int, timeout: int = 5) -> dict:
|
||||
"""Test TCP connectivity to application endpoints."""
|
||||
result = {
|
||||
"host": host,
|
||||
"port": port,
|
||||
"reachable": False,
|
||||
"latency_ms": None,
|
||||
"error": None,
|
||||
}
|
||||
start = datetime.now()
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.settimeout(timeout)
|
||||
sock.connect((host, port))
|
||||
elapsed = (datetime.now() - start).total_seconds() * 1000
|
||||
result["reachable"] = True
|
||||
result["latency_ms"] = round(elapsed, 2)
|
||||
sock.close()
|
||||
except (socket.timeout, ConnectionRefusedError, OSError) as e:
|
||||
result["error"] = str(e)
|
||||
return result
|
||||
|
||||
|
||||
def check_tls_certificate(host: str, port: int = 443) -> dict:
|
||||
"""Validate TLS certificate for HTTPS applications."""
|
||||
result = {
|
||||
"host": host,
|
||||
"port": port,
|
||||
"valid": False,
|
||||
"issuer": None,
|
||||
"subject": None,
|
||||
"expiry": None,
|
||||
"days_remaining": None,
|
||||
"error": None,
|
||||
}
|
||||
try:
|
||||
context = ssl.create_default_context()
|
||||
with socket.create_connection((host, port), timeout=10) as sock:
|
||||
with context.wrap_socket(sock, server_hostname=host) as ssock:
|
||||
cert = ssock.getpeercert()
|
||||
result["valid"] = True
|
||||
result["issuer"] = dict(x[0] for x in cert.get("issuer", []))
|
||||
result["subject"] = dict(x[0] for x in cert.get("subject", []))
|
||||
expiry_str = cert.get("notAfter", "")
|
||||
if expiry_str:
|
||||
expiry = datetime.strptime(expiry_str, "%b %d %H:%M:%S %Y %Z")
|
||||
result["expiry"] = expiry.isoformat()
|
||||
result["days_remaining"] = (expiry - datetime.utcnow()).days
|
||||
except Exception as e:
|
||||
result["error"] = str(e)
|
||||
return result
|
||||
|
||||
|
||||
def validate_app_segment_config(config: dict) -> list:
|
||||
"""Validate application segment configuration against best practices."""
|
||||
issues = []
|
||||
|
||||
if not config.get("name"):
|
||||
issues.append({"severity": "critical", "message": "Application segment name is missing"})
|
||||
|
||||
domains = config.get("domains", [])
|
||||
ips = config.get("ip_addresses", [])
|
||||
if not domains and not ips:
|
||||
issues.append({
|
||||
"severity": "critical",
|
||||
"message": "No domains or IP addresses defined for segment"
|
||||
})
|
||||
|
||||
ports = config.get("tcp_ports", []) + config.get("udp_ports", [])
|
||||
if not ports:
|
||||
issues.append({"severity": "critical", "message": "No ports defined for segment"})
|
||||
|
||||
for port_range in config.get("tcp_ports", []):
|
||||
if "-" in str(port_range):
|
||||
start, end = port_range.split("-")
|
||||
if int(end) - int(start) > 100:
|
||||
issues.append({
|
||||
"severity": "warning",
|
||||
"message": f"Wide port range {port_range} violates least-privilege. Consider narrowing."
|
||||
})
|
||||
|
||||
if not config.get("server_group"):
|
||||
issues.append({
|
||||
"severity": "warning",
|
||||
"message": "No server group assigned. High availability not configured."
|
||||
})
|
||||
|
||||
for ip in ips:
|
||||
try:
|
||||
network = ipaddress.ip_network(ip, strict=False)
|
||||
if network.prefixlen < 24:
|
||||
issues.append({
|
||||
"severity": "warning",
|
||||
"message": f"Broad IP range {ip} (/{network.prefixlen}). Consider narrowing to specific hosts."
|
||||
})
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
if config.get("bypass_type") == "always":
|
||||
issues.append({
|
||||
"severity": "critical",
|
||||
"message": "Bypass is set to 'always'. Traffic will not be inspected."
|
||||
})
|
||||
|
||||
return issues
|
||||
|
||||
|
||||
def validate_access_policy(policy: dict) -> list:
|
||||
"""Validate access policy configuration."""
|
||||
issues = []
|
||||
|
||||
if not policy.get("name"):
|
||||
issues.append({"severity": "critical", "message": "Policy name is missing"})
|
||||
|
||||
if not policy.get("conditions"):
|
||||
issues.append({
|
||||
"severity": "critical",
|
||||
"message": "No conditions defined. Policy grants unrestricted access."
|
||||
})
|
||||
|
||||
conditions = policy.get("conditions", {})
|
||||
if not conditions.get("user_groups") and not conditions.get("users"):
|
||||
issues.append({
|
||||
"severity": "warning",
|
||||
"message": "No user or group conditions. Consider restricting by group."
|
||||
})
|
||||
|
||||
if not conditions.get("posture_profiles"):
|
||||
issues.append({
|
||||
"severity": "warning",
|
||||
"message": "No device posture profile attached. Unmanaged devices may access."
|
||||
})
|
||||
|
||||
if policy.get("action") == "allow" and not conditions.get("saml_attributes"):
|
||||
issues.append({
|
||||
"severity": "info",
|
||||
"message": "Consider adding SAML attribute conditions for finer-grained access."
|
||||
})
|
||||
|
||||
app_segments = policy.get("app_segments", [])
|
||||
if len(app_segments) > 20:
|
||||
issues.append({
|
||||
"severity": "warning",
|
||||
"message": f"Policy covers {len(app_segments)} segments. Consider splitting for manageability."
|
||||
})
|
||||
|
||||
return issues
|
||||
|
||||
|
||||
def generate_app_inventory_csv(apps: list, output_path: str) -> str:
|
||||
"""Generate a CSV inventory of applications for ZPA migration planning."""
|
||||
fieldnames = [
|
||||
"app_name", "fqdn", "ip_address", "port", "protocol",
|
||||
"user_groups", "criticality", "current_access_method",
|
||||
"migration_wave", "zpa_segment_name", "status"
|
||||
]
|
||||
with open(output_path, "w", newline="") as f:
|
||||
writer = csv.DictWriter(f, fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
for app in apps:
|
||||
writer.writerow({field: app.get(field, "") for field in fieldnames})
|
||||
return output_path
|
||||
|
||||
|
||||
def assess_deployment_readiness(config: dict) -> dict:
|
||||
"""Perform comprehensive deployment readiness assessment."""
|
||||
report = {
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"overall_status": "ready",
|
||||
"checks": [],
|
||||
"summary": {"critical": 0, "warning": 0, "info": 0, "passed": 0},
|
||||
}
|
||||
|
||||
# Check IdP configuration
|
||||
idp = config.get("identity_provider", {})
|
||||
if idp.get("type") in ["saml", "oidc"]:
|
||||
report["checks"].append({
|
||||
"category": "Identity Provider",
|
||||
"check": "IdP type configured",
|
||||
"status": "passed",
|
||||
"details": f"Type: {idp['type']}"
|
||||
})
|
||||
report["summary"]["passed"] += 1
|
||||
else:
|
||||
report["checks"].append({
|
||||
"category": "Identity Provider",
|
||||
"check": "IdP type configured",
|
||||
"status": "critical",
|
||||
"details": "No IdP integration configured"
|
||||
})
|
||||
report["summary"]["critical"] += 1
|
||||
|
||||
if idp.get("scim_enabled"):
|
||||
report["checks"].append({
|
||||
"category": "Identity Provider",
|
||||
"check": "SCIM provisioning enabled",
|
||||
"status": "passed",
|
||||
"details": "Automated user/group sync active"
|
||||
})
|
||||
report["summary"]["passed"] += 1
|
||||
else:
|
||||
report["checks"].append({
|
||||
"category": "Identity Provider",
|
||||
"check": "SCIM provisioning enabled",
|
||||
"status": "warning",
|
||||
"details": "Manual user management required without SCIM"
|
||||
})
|
||||
report["summary"]["warning"] += 1
|
||||
|
||||
# Check App Connectors
|
||||
connectors = config.get("app_connectors", [])
|
||||
if len(connectors) >= 2:
|
||||
report["checks"].append({
|
||||
"category": "App Connectors",
|
||||
"check": "High availability",
|
||||
"status": "passed",
|
||||
"details": f"{len(connectors)} connectors deployed"
|
||||
})
|
||||
report["summary"]["passed"] += 1
|
||||
elif len(connectors) == 1:
|
||||
report["checks"].append({
|
||||
"category": "App Connectors",
|
||||
"check": "High availability",
|
||||
"status": "warning",
|
||||
"details": "Single connector. Deploy at least 2 for HA."
|
||||
})
|
||||
report["summary"]["warning"] += 1
|
||||
else:
|
||||
report["checks"].append({
|
||||
"category": "App Connectors",
|
||||
"check": "High availability",
|
||||
"status": "critical",
|
||||
"details": "No App Connectors configured"
|
||||
})
|
||||
report["summary"]["critical"] += 1
|
||||
|
||||
# Check application segments
|
||||
segments = config.get("app_segments", [])
|
||||
for seg in segments:
|
||||
seg_issues = validate_app_segment_config(seg)
|
||||
for issue in seg_issues:
|
||||
report["checks"].append({
|
||||
"category": f"App Segment: {seg.get('name', 'unknown')}",
|
||||
"check": issue["message"],
|
||||
"status": issue["severity"],
|
||||
"details": ""
|
||||
})
|
||||
report["summary"][issue["severity"]] += 1
|
||||
if not seg_issues:
|
||||
report["summary"]["passed"] += 1
|
||||
|
||||
# Check access policies
|
||||
policies = config.get("access_policies", [])
|
||||
if not policies:
|
||||
report["checks"].append({
|
||||
"category": "Access Policies",
|
||||
"check": "Policies defined",
|
||||
"status": "critical",
|
||||
"details": "No access policies configured"
|
||||
})
|
||||
report["summary"]["critical"] += 1
|
||||
for pol in policies:
|
||||
pol_issues = validate_access_policy(pol)
|
||||
for issue in pol_issues:
|
||||
report["checks"].append({
|
||||
"category": f"Policy: {pol.get('name', 'unknown')}",
|
||||
"check": issue["message"],
|
||||
"status": issue["severity"],
|
||||
"details": ""
|
||||
})
|
||||
report["summary"][issue["severity"]] += 1
|
||||
if not pol_issues:
|
||||
report["summary"]["passed"] += 1
|
||||
|
||||
# Check SIEM integration
|
||||
siem = config.get("siem_integration", {})
|
||||
if siem.get("enabled"):
|
||||
report["checks"].append({
|
||||
"category": "Monitoring",
|
||||
"check": "SIEM integration",
|
||||
"status": "passed",
|
||||
"details": f"Streaming to {siem.get('type', 'unknown')}"
|
||||
})
|
||||
report["summary"]["passed"] += 1
|
||||
else:
|
||||
report["checks"].append({
|
||||
"category": "Monitoring",
|
||||
"check": "SIEM integration",
|
||||
"status": "warning",
|
||||
"details": "No SIEM integration. Access events not centrally monitored."
|
||||
})
|
||||
report["summary"]["warning"] += 1
|
||||
|
||||
if report["summary"]["critical"] > 0:
|
||||
report["overall_status"] = "not_ready"
|
||||
elif report["summary"]["warning"] > 3:
|
||||
report["overall_status"] = "ready_with_warnings"
|
||||
|
||||
return report
|
||||
|
||||
|
||||
def connectivity_scan(targets: list) -> list:
|
||||
"""Scan application endpoints for connectivity from App Connector perspective."""
|
||||
results = []
|
||||
for target in targets:
|
||||
host = target.get("host", "")
|
||||
ports = target.get("ports", [])
|
||||
|
||||
dns_result = check_dns_resolution(host) if not host.replace(".", "").isdigit() else None
|
||||
|
||||
for port in ports:
|
||||
conn_result = check_port_connectivity(host, port)
|
||||
tls_result = None
|
||||
if port == 443:
|
||||
tls_result = check_tls_certificate(host, port)
|
||||
|
||||
results.append({
|
||||
"host": host,
|
||||
"port": port,
|
||||
"dns": dns_result,
|
||||
"connectivity": conn_result,
|
||||
"tls": tls_result,
|
||||
})
|
||||
return results
|
||||
|
||||
|
||||
def generate_migration_plan(apps: list) -> dict:
|
||||
"""Generate a phased VPN-to-ZTNA migration plan."""
|
||||
waves = {
|
||||
"wave_1": {"name": "Low-risk Web Apps", "apps": [], "duration_weeks": 2},
|
||||
"wave_2": {"name": "Business-critical Web Apps", "apps": [], "duration_weeks": 3},
|
||||
"wave_3": {"name": "Non-web TCP/UDP Apps", "apps": [], "duration_weeks": 3},
|
||||
"wave_4": {"name": "Legacy Applications", "apps": [], "duration_weeks": 4},
|
||||
}
|
||||
|
||||
for app in apps:
|
||||
criticality = app.get("criticality", "medium").lower()
|
||||
protocol = app.get("protocol", "https").lower()
|
||||
legacy = app.get("is_legacy", False)
|
||||
|
||||
if legacy:
|
||||
waves["wave_4"]["apps"].append(app)
|
||||
elif protocol not in ["http", "https"]:
|
||||
waves["wave_3"]["apps"].append(app)
|
||||
elif criticality in ["high", "critical"]:
|
||||
waves["wave_2"]["apps"].append(app)
|
||||
else:
|
||||
waves["wave_1"]["apps"].append(app)
|
||||
|
||||
total_weeks = sum(w["duration_weeks"] for w in waves.values())
|
||||
return {
|
||||
"total_duration_weeks": total_weeks,
|
||||
"waves": waves,
|
||||
"generated": datetime.now().isoformat(),
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
"""Run the ZTNA deployment readiness assessment."""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="ZPA Deployment Readiness Assessment Tool"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--config", type=str, help="Path to ZPA configuration JSON file"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--scan", type=str, help="Path to targets JSON for connectivity scan"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--inventory", type=str, help="Path to app inventory JSON for CSV generation"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--migrate", type=str, help="Path to app list JSON for migration planning"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--output", type=str, default="report.json", help="Output file path"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.config:
|
||||
with open(args.config) as f:
|
||||
config = json.load(f)
|
||||
report = assess_deployment_readiness(config)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
print(f"Readiness report: {report['overall_status']}")
|
||||
print(f" Critical: {report['summary']['critical']}")
|
||||
print(f" Warnings: {report['summary']['warning']}")
|
||||
print(f" Passed: {report['summary']['passed']}")
|
||||
print(f"Report saved to {args.output}")
|
||||
|
||||
elif args.scan:
|
||||
with open(args.scan) as f:
|
||||
targets = json.load(f)
|
||||
results = connectivity_scan(targets)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(results, f, indent=2)
|
||||
reachable = sum(1 for r in results if r["connectivity"]["reachable"])
|
||||
print(f"Scan complete: {reachable}/{len(results)} endpoints reachable")
|
||||
print(f"Results saved to {args.output}")
|
||||
|
||||
elif args.inventory:
|
||||
with open(args.inventory) as f:
|
||||
apps = json.load(f)
|
||||
csv_path = args.output.replace(".json", ".csv")
|
||||
generate_app_inventory_csv(apps, csv_path)
|
||||
print(f"Inventory CSV saved to {csv_path}")
|
||||
|
||||
elif args.migrate:
|
||||
with open(args.migrate) as f:
|
||||
apps = json.load(f)
|
||||
plan = generate_migration_plan(apps)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(plan, f, indent=2)
|
||||
for wave_id, wave in plan["waves"].items():
|
||||
print(f" {wave_id}: {wave['name']} - {len(wave['apps'])} apps ({wave['duration_weeks']} weeks)")
|
||||
print(f"Migration plan saved to {args.output}")
|
||||
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user