├── .gitignore ├── bin ├── restart_contrast_NET_service.bat ├── dotNet_agent_delayed_start.ps1 ├── add_my_ip_to_demo_security_group.sh ├── copy_ami_to_all_regions.sh ├── add_ingress_ports_to_demo_security_groups.sh ├── terminate_demo.sh ├── deregister_ami_across_regions.sh ├── TerminateRailsGoatInstances.ps1 ├── create_demo_security_groups.sh ├── win_2016_aws_network_fix.ps1 ├── CreateRailsGoatInstance.ps1 └── demo_contrast.sh └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | config_aws_creds.sh 2 | *.log -------------------------------------------------------------------------------- /bin/restart_contrast_NET_service.bat: -------------------------------------------------------------------------------- 1 | net stop "Contrast.NET Main Service" 2 | net start "Contrast.NET Main Service" -------------------------------------------------------------------------------- /bin/dotNet_agent_delayed_start.ps1: -------------------------------------------------------------------------------- 1 | Stop-Service -Name "Contrast.NET Main Service" 2 | Start-Sleep -s 60 3 | Start-Service -Name "Contrast.NET Main Service" -------------------------------------------------------------------------------- /bin/add_my_ip_to_demo_security_group.sh: -------------------------------------------------------------------------------- 1 | 2 | # Variables 3 | USAGE="Usage: $0 [your target AWS region] [your security group name]\n\nExample:\n$0 us-east-1 ContrastDemo-Sam-Spade" 4 | REGION_AWS=$1 5 | GROUP_NAME=$2 6 | HDE_PROFILE_NAME=contrast-hde 7 | 8 | if [[ $# -ne 1 ]]; then 9 | echo -e $USAGE 10 | exit 1 11 | fi 12 | 13 | # Add current IP to ContrastDemo security group 14 | CURRENT_IP=$(curl -s https://checkip.amazonaws.com) 15 | echo "Updating '${GROUP_NAME}' EC2 security group in region '${REGION_AWS}' to allow inbound access from ${CURRENT_IP} to port 3389..." 16 | ADD_IP_TO_DEMO_SG=$(aws --profile $HDE_PROFILE_NAME --region $REGION_AWS ec2 authorize-security-group-ingress --group-name $GROUP_NAME --protocol tcp --port 3389 --cidr $CURRENT_IP/32) 17 | -------------------------------------------------------------------------------- /bin/copy_ami_to_all_regions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Use this script to make Contrast Demo AMIs available to other AWS regions. 3 | # It uses the AMI name to know what to copy. 4 | 5 | # Variables 6 | VERSION=$1 7 | SOURCE_REGION=$2 8 | USAGE="Usage: $0 [source AMI name] [source region]\n\nExample:\n$0 hde-0.1.0 us-east-1" 9 | 10 | if [[ $# -ne 2 ]]; then 11 | echo -e $USAGE 12 | exit 1 13 | fi 14 | 15 | # Get the AMI ID of the latest HDE Golden Image 16 | AMI_ID="$(aws ec2 describe-images --filters "Name=name,Values=${VERSION}" --region=${SOURCE_REGION} | grep -o "ami-[a-zA-Z0-9_]*")" 17 | echo "Found matching AMI (${AMI_ID})..." 18 | 19 | # Copy AMI to all regions (except cn-north-1 cn-northwest-1 (China) where it's not allowed) 20 | # Old list of regions us-east-1 us-east-2 us-west-1 us-west-2 ap-northeast-1 ap-northeast-2 ap-south-1 ap-southeast-1 ap-southeast-2 ca-central-1 eu-central-1 eu-west-1 eu-west-2 eu-west-3 sa-east-1 21 | for REGION in us-east-1 us-east-2 us-west-1 us-west-2 ca-central-1 22 | do 23 | if [ $REGION != $SOURCE_REGION ]; then 24 | echo "Copying AMI named '${VERSION}' to '${REGION}' region..." 25 | aws ec2 copy-image --source-image $AMI_ID --source-region $SOURCE_REGION --region $REGION --name $VERSION 26 | fi 27 | done 28 | -------------------------------------------------------------------------------- /bin/add_ingress_ports_to_demo_security_groups.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Adds the specified TCP port number to the existing 'ContrastDemo' AWS security groups across all regions. 3 | # Includes AWS regions described here except ap-northeast-3: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html. 4 | 5 | # Variables 6 | USAGE="Usage: $0 [port number]\n\nExample:\n$0 8080" 7 | GROUP_NAME="ContrastDemo" 8 | PORT=$1 9 | # IP_PERMISSIONS="$("IpProtocol": "tcp", "FromPort": ${PORT}, "ToPort": ${PORT}, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}])" 10 | 11 | # Check if all expected arguments were provided 12 | if [[ $# -ne 1 ]]; then 13 | echo -e $USAGE 14 | exit 1 15 | fi 16 | 17 | # Add inbound security group rule across all regions except for China (cn-north-1 cn-northwest-1) where it's not allowed 18 | for REGION in us-east-1 us-east-2 us-west-1 us-west-2 ap-northeast-1 ap-northeast-2 ap-south-1 ap-southeast-1 ap-southeast-2 ca-central-1 eu-central-1 eu-west-1 eu-west-2 eu-west-3 sa-east-1 19 | do 20 | echo "Updating '${GROUP_NAME}' EC2 security group in region '${REGION}' to allow inbound access from port ${PORT}..." 21 | aws --region=$REGION ec2 authorize-security-group-ingress \ 22 | --group-name $GROUP_NAME \ 23 | --ip-permissions IpProtocol=tcp,FromPort=$PORT,ToPort=$PORT,IpRanges=' [{CidrIp=0.0.0.0/0}]',Ipv6Ranges=' [{CidrIpv6=::/0}]' 24 | done -------------------------------------------------------------------------------- /bin/terminate_demo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script will terminate the EC2 with the specified Instance ID 3 | 4 | #Variables 5 | USAGE="Usage: $0 [region] [instance ID]\n\nExample: $0 us-west-1 i-12345a1b2cdefg34h" 6 | REGION_AWS=$1 7 | INSTANCE_ID=$2 8 | HDE_PROFILE_NAME=contrast-hde 9 | 10 | # Check if all expected arguments were provided 11 | if [[ $# -ne 2 ]]; then 12 | echo -e $USAGE 13 | exit 1 14 | fi 15 | 16 | # Terminate the user-specified instance 17 | WINDOWS_INSTANCE_STATUS="$(aws --profile ${HDE_PROFILE_NAME} --region=${REGION_AWS} ec2 describe-instance-status --instance-id ${INSTANCE_ID} | grep "Code" | grep -Eo "[0-9]{1,2}" )" 18 | if [ $WINDOWS_INSTANCE_STATUS != 48 ]; then # EC2 status code of '48' means the instance is 'terminated' 19 | echo "Found instance with ID ${INSTANCE_ID}..." 20 | echo "Terminating Windows demo workstation instance ${INSTANCE_ID})..." 21 | aws --profile $HDE_PROFILE_NAME --region=$REGION_AWS ec2 terminate-instances --instance-ids $INSTANCE_ID 22 | else 23 | echo "The specified instance ${INSTANCE_ID} is already terminated or does not exist in region ${REGION_AWS}." 24 | fi 25 | 26 | # Find associated Linux instances used for Ruby demos 27 | # LINUX_INSTANCES="$(aws --profile $HDE_PROFILE_NAME --region=$REGION_AWS ec2 describe-instances --filter "Name=tag:Name,Values=Ruby-demo-for-${INSTANCE_ID}" | grep InstanceId | grep -o "i-[a-zA-Z0-9_]*")" 28 | # echo $LINUX_INSTANCES -------------------------------------------------------------------------------- /bin/deregister_ami_across_regions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script will deregister private AMIs with the inputted name across all AWS regions 3 | 4 | # Variables 5 | AMI_NAME=$1 6 | USAGE="Usage: $0 [target AMI name]\n\nExample:\n$0 hde-0.1.0" 7 | ANSWER=n 8 | 9 | if [[ $# -ne 1 ]]; then 10 | echo -e $USAGE 11 | exit 1 12 | fi 13 | 14 | echo "Are you sure you want to delete the AMI named ${AMI_NAME} from all AWS regions? [Y/n]?" 15 | read ANSWER 16 | if [ "${ANSWER}" = "Y" ] || [ "${ANSWER}" = "y" ]; then 17 | # Delete the AMI from all AWS regions 18 | for REGION in us-east-1 us-east-2 us-west-1 us-west-2 ap-northeast-1 ap-northeast-2 ap-south-1 ap-southeast-1 ap-southeast-2 ca-central-1 eu-central-1 eu-west-1 eu-west-2 eu-west-3 sa-east-1 19 | do 20 | # Get the AMI ID of the target AMI from its name 21 | AMI_ID="$(aws --region=${REGION} ec2 describe-images --filters "Name=platform,Values=windows" "Name=name,Values=${AMI_NAME}" --owner self | grep -o "ami-[a-zA-Z0-9_]*")" 22 | if [ -z $AMI_ID ]; then 23 | echo -e "\nERROR: No AMI found with the name ${AMI_NAME} in region ${REGION}." 24 | else 25 | echo -e "\nDeregisteing AMI ${AMI_ID} from ${REGION}..." 26 | aws --region=$REGION ec2 deregister-image --image-id $AMI_ID 27 | fi 28 | done 29 | elif [ "${ANSWER}" = "N" ] || [ "${ANSWER}" = "n" ]; then 30 | exit 0 31 | else 32 | echo -e "Invalid input. Please try again." 33 | exit 1 34 | fi -------------------------------------------------------------------------------- /bin/TerminateRailsGoatInstances.ps1: -------------------------------------------------------------------------------- 1 | # Set the access credentials for demo.person@contrastsecurity.com. 2 | # To set new credentials, use: Set-AWSCredential -AccessKey [access key] -SecretKey [secret key] -StoreAs DemoPerson 3 | Set-AWSCredential -ProfileName DemoPerson 4 | 5 | # Fix AWS Windows 2016 network issue 6 | # ./win_2016_aws_network_fix.ps1 7 | 8 | # Get the AWS region of this running instance 9 | $az = Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/placement/availability-zone 10 | $region = $az.Substring(0,$az.Length-1) 11 | 12 | # Get the instance ID of this running (Windows) instance 13 | $windows_instance_id = Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/instance-id 14 | $windows_instance_name = "Ruby-demo-for-" + $windows_instance_id 15 | 16 | # Get Linux instance(s) associated with this running (Windows) instance 17 | $linux_instances = (Get-EC2Instance -Region $region -Filter @{Name="tag:Name";Value=$windows_instance_name},@{Name="instance-state-name";Value="running"}).Instances 18 | For ($i=0; $i -lt $linux_instances.Length; $i++) { 19 | # If the found Linux instance is not already terminated, then terminate it. 20 | # $status = Get-EC2InstanceStatus -Region $region -InstanceId $linux_instances[$i].InstanceId 21 | # If ($status.InstanceState.Name -ne "terminated") { 22 | Remove-EC2Instance -Region $region -InstanceId $linux_instances[$i].InstanceId -Force 23 | Write-Host "Terminating Linux EC2 instance ("$linux_instances[$i].InstanceId")..." 24 | # } 25 | } 26 | Write-Host "`n" 27 | 28 | # Remove etc host file entries with hostname 'linux' 29 | If ($linux_instances.Length -gt 0) { 30 | $hosts_file = "C:\Windows\System32\drivers\etc\hosts" 31 | $cleaned_hosts_file = "C:\Contrast\temp\hosts.new" 32 | Get-Content $hosts_file | Where-Object {$_ -notmatch 'linux'} | Set-Content $cleaned_hosts_file -Force 33 | Copy-Item -Path $cleaned_hosts_file -Destination $hosts_file -Force 34 | Remove-Item $cleaned_hosts_file 35 | } -------------------------------------------------------------------------------- /bin/create_demo_security_groups.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Creates AWS EC2 security groups in the default VPC of all AWS regions with ingress rules suitable for Contrast Security demos. 3 | # Includes AWS regions described here except ap-northeast-3: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html. 4 | 5 | # Variables 6 | GROUP_NAME="ContrastDemo" 7 | 8 | for REGION in us-east-1 us-east-2 us-west-1 us-west-2 ap-northeast-1 ap-northeast-2 ap-south-1 ap-southeast-1 ap-southeast-2 ca-central-1 cn-north-1 cn-northwest-1 eu-central-1 eu-west-1 eu-west-2 eu-west-3 sa-east-1 9 | do 10 | echo "Creating '${GROUP_NAME}' EC2 security group in region '${REGION}'..." 11 | GROUP_ID="$(aws ec2 create-security-group --group-name ${GROUP_NAME} --description "Security group is appropriate inbound rules for Contrast demo workstation instances" --region=${REGION} | grep -o "sg-[a-zA-Z0-9_]*")" 12 | aws ec2 authorize-security-group-ingress \ 13 | --group-id ${GROUP_ID} \ 14 | --region=${REGION} \ 15 | --ip-permissions '[{"IpProtocol": "icmp", "FromPort": -1, "ToPort": -1, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 80, "ToPort": 80, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 8080, "ToPort": 8080, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 5000, "ToPort": 5000, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 7000, "ToPort": 7000, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 3389, "ToPort": 3389, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 6000, "ToPort": 6000, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 9000, "ToPort": 9000, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 90, "ToPort": 90, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 2000, "ToPort": 2000, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 8000, "ToPort": 8000, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 4000, "ToPort": 4000, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}, {"IpProtocol": "tcp", "FromPort": 3000, "ToPort": 3000, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}], {"IpProtocol": "tcp", "FromPort": 9001, "ToPort": 9001, "IpRanges": [{"CidrIp": "0.0.0.0/0"}], "Ipv6Ranges": [{"CidrIpv6": "::/0"}]}' 16 | done -------------------------------------------------------------------------------- /bin/win_2016_aws_network_fix.ps1: -------------------------------------------------------------------------------- 1 | # This script fixes a networking configuration issue with AWS Windows 2016 instances. 2 | # After running this script, users will be able to successfully query local instance metadata. 3 | # This script is kindly borrowed from https://gist.github.com/Gonzales/e000b7c2e72e13701c77431d3a2ffd73 4 | 5 | Add-Content 'c:\script.log' (date) 6 | 7 | # This fixes a bug in AWS startup script processing. 8 | 9 | # 169.254.169.254 is for metadata service 10 | # 169.254.169.250 is for KmsInstanceVpc1 11 | # 169.254.169.251 is for KmsInstanceVpc2 12 | $ipAddrs = @("169.254.169.254/32", "169.254.169.250/32", "169.254.169.251/32") 13 | 14 | $sleepTime = 1 15 | $count = 0 16 | 17 | # Retry logic for querying primary network interface and adding routes. 18 | while($true) 19 | { 20 | try 21 | { 22 | Add-Content 'c:\script.log' "Checking primary network interface" 23 | 24 | $ipConfigs = Get-NetIPConfiguration | Sort-Object -Property "InterfaceIndex" | select InterfaceIndex, IPv4DefaultGateway 25 | if(-not $ipConfigs -or $ipConfigs.Length -eq 0) 26 | { 27 | throw New-Object System.Exception("Failed to find the primary network interface") 28 | } 29 | $primaryIpConfig = $ipConfigs[0] 30 | $interfaceIndex = $primaryIpConfig.InterfaceIndex 31 | $defaultGateway = $primaryIpConfig.IPv4DefaultGateway.NextHop 32 | $interfaceMetric = 1 33 | 34 | Add-Content 'c:\script.log' "Primary network interface found. Adding routes now..." 35 | 36 | foreach ($ipAddr in $ipAddrs) 37 | { 38 | try 39 | { 40 | Remove-NetRoute -DestinationPrefix $ipAddr -PolicyStore ActiveStore -Confirm:$false -ErrorAction SilentlyContinue 41 | Remove-NetRoute -DestinationPrefix $ipAddr -PolicyStore PersistentStore -Confirm:$false -ErrorAction SilentlyContinue 42 | New-NetRoute -DestinationPrefix $ipAddr -InterfaceIndex $interfaceIndex ` 43 | -NextHop $defaultGateway -RouteMetric $interfaceMetric -ErrorAction Stop 44 | Add-Content 'c:\script.log' ("Successfully added the Route: {0}, gateway: {1}, NIC index: {2}, Metric: {3}" ` 45 | -f $ipAddr, $defaultGateway, $interfaceIndex, $interfaceMetric) 46 | } 47 | catch 48 | { 49 | Add-Content 'c:\script.log' ("Failed to add routes: {0}" -f $ipAddr) 50 | } 51 | } 52 | 53 | # Break if routes are added successfully. 54 | break 55 | } 56 | catch 57 | { 58 | Add-Content 'c:\script.log' ("Failed to add routes.. attempting it again {0}" -f $_.Exception.Message) 59 | } 60 | 61 | # It logs the status every 2 minutes. 62 | if (($count * $sleepTime) % 120 -eq 0) 63 | { 64 | Add-Content 'c:\script.log' "Message: Failed to add routes.. attempting it again" 65 | } 66 | 67 | Start-Sleep -seconds $sleepTime 68 | $count ++ 69 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Contrast Security Hosted Demo Environment 2 | This repo contains multiple scripts used to launch, manage, and use the Contrast Security Hosted Demo Environment. The demo environment is comprised of a "virtual developer workstation" and related services hosted in AWS, which enables demonstrations of Contrast's innovative application security monitoring and protection platform. 3 | 4 | The provided shell scripts are meant to be run from a Mac. The included PowerShell scripts are meant to be used from within the Windows "virtual developer workstation" for demonstration additional Contrast capabilities. 5 | 6 | # Script Descriptions and Details 7 | The `/bin` folder contains various scripts; below is more information about each one. 8 | 9 | ## Shell Scripts (for Mac users) 10 | ### add_ingress_ports_to_demo_security_groups.sh 11 | This script will add a new AWS security group inbound TCP rule for the user-specified port number.
12 | **Usage:** `./add_ingress_ports_to_demo_security_groups.sh [port number]` 13 | 14 | **Example:** 15 | `./add_ingress_ports_to_demo_security_groups.sh 8080` 16 |
17 | 18 | ### add_my_ip_to_demo_security_group.sh 19 | This script will add a new AWS security group inbound TCP rule 20 | for RDP (3389) using the current IP address for the specified region and security group.
21 | **Usage:** `./add_my_ip_to_demo_security_group.sh [your target AWS region] 22 | 23 | **Example:** 24 | `./add_my_ip_to_demo_security_group.sh us-east-1 ContrastDemo-Sam-Spade` 25 |
26 | 27 | ### copy_ami_to_all_regions.sh 28 | This script will copy a source AMI across all AWS regions. The source AMI is identified based on its name and source AWS region.
29 | **Usage:** `./copy_ami_to_all_regions.sh [source AMI name] [source region]` 30 | 31 | **Example:** 32 | `./copy_ami_to_all_regions.sh hde-0.1.0 us-east-1` 33 |
34 | 35 | ### create_demo_security_groups.sh 36 | This script will create a security group call `ContrastDemo` across all AWS regions.
37 | **Usage:** `./create_demo_security_groups.sh` 38 | 39 | ### demo_contrast.sh 40 | This script will launch a new Contrast demo "virtual developer workstation". It expects 5 input arguments: 41 | * Demo version/name of the latest demo EC2 AMI – you can specify default and that will automatically launch the latest AMI 42 | * Customer name or description, so your instance can be distinguished among your other demo instances 43 | * Your name, to help identify instances you’ve created 44 | * Your target AWS region, which should be closest to your geographic location (find your closest region at https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html) 45 | * Number of hours you need to keep the instance running – the instance will automatically terminate after the specified number of hours (if `0` is specified, then no auto-termination alarm will be set; if a value greater than `24` is specified, then the maximum allowed value of 24 will be set) 46 | 47 | **Usage:** `./demo_contrast.sh [demo version] [customer name or description] [your name] [your target AWS region] [hours to keep demo running]` 48 | 49 | **Example:** 50 | `./demo_contrast.sh default 'Johns Demo Instance' 'John Smith' us-west-1 2` 51 |
52 | 53 | ### deregister_ami_across_regions.sh 54 | This script will deregister AMIs across all AWS regions based on the specified AMI name. It is meant to be used to easily deregister obsolete Contrast demo workstation AMIs.
55 | **Usage:** `./deregister_ami_across_regions.sh [target AMI name]` 56 | 57 | **Example:** 58 | `./deregister_ami_across_regions.sh hde-0.1.0` 59 |
60 | 61 |

62 | ## PowerShell Scripts 63 | The following PowerShell scripts are designed to only be run from within a Contrast demo "virtual developer workstation". There are located in `C:\Contrast` within the demo workstation. 64 | 65 | ### CreateRailsGoatInstance.ps1 66 | This script will launch a Linux EC2 instance from within a Windows "virtual developer workstation" to support a Ruby RailsSGoat demonstration. The result is a Linux server in the same AWS VPC that is pre-configured to serve RailsGoat and connect to the Contrast TeamServer running on the Wndows workstation. This script will only allow for one running child Linux instance with RailsGoat that will automatically be terminated after 24 hours.
67 | **Usage:** `.\CreateRailsGoatInstance.ps1` 68 |
69 | 70 | ### dotNet_agent_delayed_start.ps1 71 | This script will wait for 120 seconds, then stop the Contrast .NET agent service and start it up again to ensure it is active and running.
72 | **Usage:** `.\dotNet_agent_delayed_start.ps1` 73 |
74 | 75 | ### TerminateRailsGoatInstances.ps1 76 | This script will terminate all Linux EC2 instances that are associated with the Windows "virtual developer workstation" from which it is run. If multiple Linux instances for RailsGoat were launched, this script will terminate all running instances.
77 | **Usage:** `.\TerminateRailsGoatInstances.ps1` 78 |
79 | 80 | ### win_2016_aws_network_fix.ps1 81 | This script is kindly borrowed from https://gist.github.com/Gonzales/e000b7c2e72e13701c77431d3a2ffd73. It fixes an issue with AWS Windows 2016 AMIs where it does not properly register routes to 169.254.169.254 by default, the AWS EC2 meta-data service to get information about a running instance from within an instance itself. This script is automatically run upon startup from the Contrast demo "virtual developer workstation" and should not need to be run again.
82 | **Usage:** `.\win_2016_aws_network_fix.ps1` 83 | -------------------------------------------------------------------------------- /bin/CreateRailsGoatInstance.ps1: -------------------------------------------------------------------------------- 1 | # Set the access credentials for demo.person@contrastsecurity.com. 2 | # To set new credentials, use: Set-AWSCredential -AccessKey [access key] -SecretKey [secret key] -StoreAs DemoPerson 3 | Set-AWSCredential -ProfileName DemoPerson 4 | 5 | # Fix AWS Windows 2016 network issue 6 | # ./win_2016_aws_network_fix.ps1 7 | 8 | # Define target Linux AMI by name 9 | $target_ami_name = "hde-linux-ruby-0.1.2" 10 | Write-Host $target_ami_name 11 | 12 | # Check to see if the instance is already running. 13 | <# 14 | $status = Get-EC2InstanceStatus -InstanceId $env:linux_instance_id 15 | if ($status.InstanceState.Name -eq "running") { 16 | Write-Host "Instance already running" 17 | $path = "http://" + $env:linux_instance_ip + ":5000" 18 | 19 | cmd /c start /min $path 20 | exit 21 | } 22 | #> 23 | 24 | <# 25 | Get the Host IP address (AWS Internal), to send to the Linux instance. 26 | The agents running on Linux instance will use it to connect to this Team Server. 27 | #> 28 | # $host_ip = (Get-NetIPConfiguration | ` 29 | # Where-Object { ` 30 | # $_.IPv4DefaultGateway -ne $null ` 31 | # -and ` 32 | # $_.NetAdapter.Status -ne "Disconnected" ` 33 | # } ` 34 | # ).IPv4Address.IPAddress 35 | 36 | # Get the internal (AWS internal) local IP address of this running instance to send to the new Linux instance. 37 | # The agents running on the Linux instance will use it to connect to the TeamServer on this host. 38 | $host_ip = Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/local-ipv4 39 | 40 | # Prepare User Data to send to the Linux machine. 41 | $bytes = [System.Text.Encoding]::Unicode.GetBytes($host_ip) 42 | $user_data = [Convert]::ToBase64String($bytes) 43 | 44 | # Get the AWS region of this running instance 45 | $az = Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/placement/availability-zone 46 | $region = $az.Substring(0,$az.Length-1) 47 | Write-Host "Current region is" $region 48 | 49 | # Get EC2 image ID 50 | $name_values = New-Object 'collections.generic.list[string]' 51 | $name_values.add($target_ami_name) 52 | $filter_name = New-Object Amazon.EC2.Model.Filter -Property @{Name = "name"; Values = $name_values} 53 | $target_image = Get-EC2Image -Filter $filter_name -Region $region 54 | 55 | # Get the Instance Id of this running instance 56 | $instance_id = Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/instance-id 57 | Write-Host "Instance ID is" $instance_id 58 | 59 | # Get the AWS public key used to launch this running instance 60 | # $public_key = Invoke-RestMethod -uri http://169.254.169.254/latest/meta-data/public-keys 61 | # $keyname = $public_key.Substring(2,$public_key.Length-2) 62 | If ($keyname.Length -lt 1) {$keyname="brian"} 63 | # Write-Host "Key is" $keyname 64 | 65 | # Setup tags for new Linux instance 66 | $tag_purpose = @{ Key="x-purpose"; Value="ruby demo" } 67 | $instance_name = "Ruby-demo-for-" + $instance_id 68 | $tag_name = @{ Key="Name"; Value=$instance_name } 69 | $tagspec = new-object Amazon.EC2.Model.TagSpecification 70 | $tagspec.ResourceType = "instance" 71 | $tagspec.Tags.Add($tag_purpose) 72 | $tagspec.Tags.Add($tag_name) 73 | 74 | # Check if Linux instance(s) associated with this running (Windows) instance already exist 75 | $running_linux_instances = (Get-EC2Instance -Region $region -Filter @{Name="tag:Name";Value=$instance_name},@{Name="instance-state-name";Value="running"}).Instances 76 | If ($running_linux_instances.Length -gt 0) { 77 | Write-Host "A child Linux instance called "$instance_name" already exists. You only need to run this script once." 78 | Write-Host "Please connect to http://linux:5000 to access RailsGoat.`n" 79 | 80 | # Open web browser to new Linux instance running RailsGoat 81 | $linux_instance_ip = $running_linux_instances[0].PrivateIpAddress 82 | $path = "http://" + $env:linux_instance_ip + ":5000" 83 | cmd /c start /min $path 84 | } Else { 85 | # Launch new Linux instance 86 | Write-Host "Launching new EC2 Linux instance for Ruby demo..." 87 | $instance = New-EC2Instance -Region $region -ImageId $target_image.ImageId -MinCount 1 -MaxCount 1 -KeyName $keyname -SecurityGroups "ContrastDemo" -InstanceType t2.medium -UserData $user_data -TagSpecification $tagspec 88 | 89 | # Get the new Linux instance ID and IP address via it's AWS reservation info 90 | $reservation = New-Object 'collections.generic.list[string]' 91 | $reservation.add($instance.ReservationId) 92 | 93 | $filter_reservation = New-Object Amazon.EC2.Model.Filter -Property @{Name = "reservation-id"; Values = $reservation} 94 | $instances = (Get-EC2Instance -Filter $filter_reservation -Region $region).Instances 95 | $instances[0] 96 | 97 | # Save new Linux instance ID and private IP address to environment variables 98 | $env:linux_instance_id = $instances[0].InstanceId 99 | $env:linux_instance_ip = $instances[0].PrivateIpAddress 100 | 101 | # Set unique name for the CloudWatch alarm 102 | $alarm_name="Auto-terminate " + $instances[0].InstanceId + " after 24 hours" 103 | 104 | # Set dimension for CloudWatch alarm 105 | $dimension = New-Object Amazon.CloudWatch.Model.dimension 106 | $dimension.set_Name("InstanceId") 107 | $dimension.set_Value($instances[0].InstanceId) 108 | 109 | # Set CloudWatch alarm action 110 | $alarm_action = "arn:aws:automate:" + $region + ":ec2:terminate" 111 | 112 | # Set CloudWatch alarm to automatically terminate the EC2 instance after 24 hours 113 | Write-CWMetricAlarm -AlarmName $alarm_name -AlarmDescription "Terminate instance after 24 hours" -MetricName "CPUUtilization" -Namespace "AWS/EC2" -Statistic "Average" -Period 900 -Threshold 0 -ComparisonOperator "GreaterThanThreshold" -EvaluationPeriods 96 -AlarmActions $alarm_action -Unit "Percent" -Dimensions $dimension 114 | 115 | # Update etc hosts file with the IP address. 116 | $hosts_file = "C:\Windows\System32\drivers\etc\hosts" 117 | $instances[0].PrivateIpAddress + " linux" | Add-Content -PassThru $hosts_file 118 | 119 | # Open web browser to new Linux instance running RailsGoat 120 | $path = "http://" + $env:linux_instance_ip + ":5000" 121 | cmd /c start /min $path 122 | 123 | Write-Host "Your Linux instance running Ruby RailsGoat should be available in about 5 minutes at" $path".`n" 124 | } -------------------------------------------------------------------------------- /bin/demo_contrast.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Launches Contrast Security SE virtual Windows developer workstation in AWS for demo purposes 4 | # This script is meant to be run on MacOS 5 | 6 | # Variables 7 | DEFAULT_DEMO_AMI="PlatformDemo-1.6.0" # This value should updated whenever a new AMI for the Contrast demo "golden image" is created 8 | USAGE="Usage: $0 [demo version] [customer name or description] [your name] [your target AWS region] [hours to keep demo running]\n\nExample:\n$0 default 'Acme Corp' 'Sam Spade' us-west-1 2" 9 | VERSION=$1 10 | CUSTOMER=$2 11 | CONTACT=$3 12 | REGION_AWS=$4 # For a list of AWS regions, look here: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Concepts.RegionsAndAvailabilityZones.html 13 | TTL=$5 14 | ALARM_PERIOD=900 # CloudWatch alarm period of 900 seconds (15 minutes) 15 | TTL_BUFFER=2 # Number of additional $ALARM_PERIOD duration buffers before automatic termination of demo instances 16 | TTL_PERIODS=0 17 | CREATION_TIMESTAMP="$(date '+%Y-%m-%d %H:%M:%S')" 18 | INSTANCE_TYPE=t3.xlarge 19 | HDE_PROFILE_NAME=contrast-hde 20 | NETSKOPE_IP_CIDR="163.116.128.0/17" 21 | PUBLIC_IP="" 22 | 23 | # Text Colors 24 | RED=$(tput setaf 1) 25 | GREEN=$(tput setaf 2) 26 | YELLOW=$(tput setaf 3) 27 | WHITE=$(tput setaf 7) 28 | GREY=$(tput setaf 8) 29 | RESET=$(tput sgr0) 30 | 31 | print_success() { 32 | echo -e "${GREEN}SUCCESS: $1${RESET}" 33 | } 34 | 35 | print_error() { 36 | echo -e "${RED}ERROR: $1${RESET}" 37 | } 38 | 39 | print_warning() { 40 | echo -e "${YELLOW}WARNING: $1${RESET}" 41 | } 42 | 43 | print_info() { 44 | echo -e "${WHITE}INFO: $1${RESET}" 45 | } 46 | 47 | print_normal() { 48 | echo -e "${WHITE}$1${RESET}" 49 | } 50 | 51 | print_debug() { 52 | echo -e "${GREY}DEBUG: $1${RESET}" 53 | } 54 | 55 | main() { 56 | # Check if AWS CLI is installed 57 | AWS_CLI_INSTALLED=$(command -v aws) 58 | if [[ -z $AWS_CLI_INSTALLED ]]; then 59 | print_error "AWS CLI is not installed. Aborting." 60 | exit 1 61 | else 62 | print_success "AWS CLI is installed." 63 | fi 64 | 65 | # Check if jq is installed 66 | JQ_INSTALLED=$(command -v jq) 67 | if [[ -z $JQ_INSTALLED ]]; then 68 | print_warning "jq is not installed." 69 | print_warning "jq will be required in the future and this will become an error." 70 | print_warning "Please install jq." 71 | else 72 | print_success "jq is installed." 73 | print_success "You are good to go for the future jq requirement." 74 | fi 75 | 76 | # Check if all expected arguments were provided 77 | if [[ $# -ne 5 ]]; then 78 | print_error "$USAGE" 79 | exit 1 80 | fi 81 | 82 | # Check if AWS CLI is installed and configured 83 | aws configure list-profiles | grep -q $HDE_PROFILE_NAME 84 | retVal=$? 85 | 86 | if [[ $retVal -ne 0 ]]; then 87 | print_normal "$HDE_PROFILE_NAME does not exist.." 88 | print_info "Please run 'aws configure sso --profile $HDE_PROFILE_NAME' to configure your AWS SSO profile." 89 | exit 1 90 | else 91 | print_info "$HDE_PROFILE_NAME already exists.." 92 | print_info "Logging out of $HDE_PROFILE_NAME profile.." 93 | aws sso logout --profile $HDE_PROFILE_NAME 94 | retVal=$? 95 | if [[ $retVal -ne 0 ]]; then 96 | print_error "Failed to logout of $HDE_PROFILE_NAME profile." 97 | exit 1 98 | else 99 | print_success "Successfully logged out of $HDE_PROFILE_NAME profile." 100 | print_info "Logging in to $HDE_PROFILE_NAME profile.." 101 | AWS_SSO_LOGIN=$(aws sso login --profile $HDE_PROFILE_NAME) 102 | print_info "$AWS_SSO_LOGIN" 103 | retVal=$? 104 | if [[ $retVal -ne 0 ]]; then 105 | print_error "Failed to login to $HDE_PROFILE_NAME profile." 106 | exit 1 107 | else 108 | print_success "Successfully logged in to $HDE_PROFILE_NAME profile." 109 | fi 110 | fi 111 | fi 112 | 113 | # Check if AWS CLI is able to connect to AWS 114 | IAM_IDENTITY=$(aws sts get-caller-identity --profile $HDE_PROFILE_NAME) 115 | if [[ $? -ne 0 ]]; then 116 | print_error "AWS CLI is not able to connect to AWS. Aborting." 117 | print_error "This could be caused by Netskope cert issues." 118 | exit 1 119 | else 120 | if [[ -z $IAM_IDENTITY ]]; then 121 | print_error "AWS CLI is not able to connect to AWS. Aborting." 122 | print_error "This could be caused by Netskope cert issues." 123 | exit 1 124 | else 125 | print_success "AWS CLI is able to connect to AWS." 126 | AWS_USER_ID=$(echo "$IAM_IDENTITY" | jq -r '.UserId') 127 | AWS_ACCOUNT_ID=$(echo "$IAM_IDENTITY" | jq -r '.Account') 128 | AWS_ARN=$(echo "$IAM_IDENTITY" | jq -r '.Arn') 129 | 130 | print_success "AWS CLI is able to connect to AWS." 131 | print_info "\tAWS User ID: $AWS_USER_ID" 132 | print_info "\tAWS Account ID: $AWS_ACCOUNT_ID" 133 | print_info "\tAWS ARN: $AWS_ARN" 134 | fi 135 | fi 136 | 137 | # Get the AMI ID of the latest HDE "Golden Image" 138 | if [[ $VERSION = default ]]; then 139 | VERSION=$DEFAULT_DEMO_AMI # This value should be set to the name of the latest Contrast demo AMI 140 | fi 141 | 142 | print_info "Launching Contrast demo instance..." 143 | print_info "\tCreation Time: ${CREATION_TIMESTAMP}" 144 | print_info "\tDemo Version: ${VERSION}" 145 | print_info "\tCustomer Name: ${CUSTOMER}" 146 | print_info "\tContact Name: ${CONTACT}" 147 | print_info "\tAWS Region: ${REGION_AWS}" 148 | print_info "\tTTL: ${TTL} hours" 149 | 150 | AMI_ID="$(aws --profile ${HDE_PROFILE_NAME} ec2 describe-images --filters "Name=name,Values=${VERSION}" --region=${REGION_AWS} | grep -o "ami-[a-zA-Z0-9_]*" | head -1)" 151 | if [[ ! -z $AMI_ID ]]; then 152 | print_success "Found matching AMI (${AMI_ID})..." 153 | else 154 | print_error "Could not find matching AMI named ${VERSION} in the ${REGION_AWS} region." 155 | exit 1 156 | fi 157 | 158 | # Create instance Name tag 159 | TAG_NAME="${CUSTOMER}-${CONTACT}" 160 | 161 | # Create log directory if it does not already exist 162 | if [[ ! -d "logs" ]]; then 163 | mkdir -p logs 164 | fi 165 | 166 | # Get Default VPC ID 167 | DEFAULT_VPC_ID=$(aws --profile $HDE_PROFILE_NAME --region "$REGION_AWS" ec2 describe-vpcs --filters "Name=is-default,Values=true" --query "Vpcs[0].VpcId" | grep -o "vpc-[a-zA-Z0-9_]*") 168 | 169 | # Define security group name 170 | GROUP_NAME=ContrastDemo-$(echo "$CONTACT" | tr " " "-") 171 | 172 | # Check if security group already exists 173 | DESCRIBE_SG=$(aws --profile $HDE_PROFILE_NAME --region "$REGION_AWS" ec2 describe-security-groups --filters "Name=group-name,Values=$GROUP_NAME" --query "SecurityGroups[0].GroupName") 174 | if [[ $DESCRIBE_SG ]] && [[ $DESCRIBE_SG != "null" ]]; then 175 | print_success "Found existing security group: ${DESCRIBE_SG}" 176 | else 177 | # Create a security group 178 | print_info "Security group: $GROUP_NAME not found. Creating..." 179 | CREATE_SG=$(aws --profile $HDE_PROFILE_NAME --region "$REGION_AWS" ec2 create-security-group --group-name "$GROUP_NAME" --description "$CONTACT" --vpc-id "$DEFAULT_VPC_ID") 180 | if [[ $? -ne 0 ]]; then 181 | print_error "Failed to create security group: $GROUP_NAME" 182 | exit 1 183 | else 184 | print_success "Successfully created security group: $GROUP_NAME" 185 | fi 186 | fi 187 | 188 | # Get current IP address 189 | CURRENT_IP=$(curl -s https://checkip.amazonaws.com) 190 | print_info "Current IP Address is: ${CURRENT_IP}" 191 | 192 | # Check if current IP address is in security group 193 | SG_IP=$(aws --profile $HDE_PROFILE_NAME \ 194 | --region "${REGION_AWS}" ec2 describe-security-groups \ 195 | --filters "Name=group-name,Values=$GROUP_NAME" "Name=ip-permission.from-port,Values=3389" "Name=ip-permission.to-port,Values=3389" "Name=ip-permission.cidr,Values=$CURRENT_IP/32" \ 196 | --query "SecurityGroups[0].IpPermissions[*].IpRanges[*].{CidrIp:CidrIp}") 197 | 198 | if [[ "$SG_IP" ]] && [[ "$SG_IP" != "null" ]]; then 199 | print_info "IP address: $CURRENT_IP already in security group: $GROUP_NAME" 200 | else 201 | # Add current IP to security group 202 | print_info "IP: $CURRENT_IP not in security group: $GROUP_NAME" 203 | print_info "Adding IP: $CURRENT_IP to security group: $GROUP_NAME" 204 | ADD_IP_TO_DEMO_SG=$(aws --profile $HDE_PROFILE_NAME --region "$REGION_AWS" ec2 authorize-security-group-ingress --group-name "$GROUP_NAME" --protocol tcp --port 3389 --cidr "${CURRENT_IP}/32") 205 | ADD_NETSKOPE_IP_TO_DEMO_SG=$(aws --profile $HDE_PROFILE_NAME --region "$REGION_AWS" ec2 authorize-security-group-ingress --group-name "$GROUP_NAME" --protocol tcp --port 3389 --cidr "${NETSKOPE_IP_CIDR}") 206 | 207 | fi 208 | 209 | # Launch the AWS EC2 instance 210 | LAUNCH_INSTANCE=$(aws --profile $HDE_PROFILE_NAME ec2 run-instances \ 211 | --image-id "$AMI_ID" \ 212 | --count 1 \ 213 | --instance-type $INSTANCE_TYPE \ 214 | --security-groups "$GROUP_NAME" \ 215 | --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${TAG_NAME}},{Key=Owner,Value=${CONTACT}},{Key=Demo-Version,Value=${VERSION}},{Key=x-purpose,Value='demo'},{Key=x-creation-timestamp,Value=${CREATION_TIMESTAMP}}]" \ 216 | --block-device-mapping "DeviceName=/dev/sda1,Ebs={DeleteOnTermination=true}" \ 217 | --region="$REGION_AWS" \ 218 | >"logs/demo_instance_${REGION_AWS}_${CREATION_TIMESTAMP}.log") 219 | 220 | if [[ $LAUNCH_INSTANCE ]]; then 221 | echo "Something went wrong, launching the EC2 instance failed! Please try again or contact the Contrast Sales Engineering team for assistance." 222 | exit 1 223 | fi 224 | 225 | # Get the Instance ID of the newly created instance 226 | INSTANCEID="$(aws --profile ${HDE_PROFILE_NAME} ec2 describe-instances --region="${REGION_AWS}" --filters "Name=tag:Name,Values=${TAG_NAME}" "Name=instance-state-name,Values=pending" | grep InstanceId | grep -o "i-[a-zA-Z0-9_]*")" 227 | 228 | if [[ ! -z $INSTANCEID ]]; then 229 | print_info "Launching Contrast virtual Windows developer workstation..." 230 | 231 | # Get public IP address of the newly created instance 232 | PUBLIC_IP="$(aws --profile ${HDE_PROFILE_NAME} ec2 describe-instances --region="${REGION_AWS}" --filters "Name=tag:Name,Values=${TAG_NAME}" "Name=instance-id,Values=${INSTANCEID}" | grep PublicIpAddress | grep -Eo "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}")" 233 | if [[ ! -z $PUBLIC_IP ]]; then 234 | print_info "Public IP address: ${PUBLIC_IP}" 235 | else 236 | print_error "Could not find public IP address for instance ${INSTANCEID}!" 237 | exit 1 238 | fi 239 | 240 | print_success "Successfully launched Contrast virtual Windows developer workstation!" 241 | print_success "\tInstanceID: ${INSTANCEID}" 242 | print_success "\tPublic IP: ${PUBLIC_IP}" 243 | print_info "Wait about 10 minutes, then open your remote desktop client and connect to ${PUBLIC_IP} as 'Administrator'." 244 | print_info "If you do not know the password, please ask your friendly neighborhood sales engineer." 245 | 246 | if [[ $TTL -gt 0 ]]; then 247 | # Check if the TTL value is greater than 24, and if so, then set it to the maximum alarm duration allowed by CloudWatch, which is 24 248 | if [[ $TTL -gt 23 ]]; then 249 | TTL=24 250 | TTL_PERIODS=$(expr $TTL \* 3600 / $ALARM_PERIOD) 251 | print_warning "The maximum allowed CloudWatch alarm duration is 24 hours. Resetting the auto-termination alarm to trigger after 24 hours." 252 | else 253 | TTL_PERIODS=$(expr "$TTL" \* 3600 / $ALARM_PERIOD + $TTL_BUFFER) 254 | fi 255 | # Set unique name for the CloudWatch alarm 256 | ALARM_NAME="Auto-terminate ${INSTANCEID} after ${TTL} hours" 257 | 258 | # Set CloudWatch alarm to automatically terminate the EC2 instance when the TTL expires 259 | TERMINATION_ALARM=$(aws --profile $HDE_PROFILE_NAME --region="${REGION_AWS}" cloudwatch put-metric-alarm \ 260 | --alarm-name "${ALARM_NAME}" \ 261 | --alarm-description "Terminate instance after ${TTL} hours" \ 262 | --namespace AWS/EC2 \ 263 | --metric-name CPUUtilization \ 264 | --unit Percent \ 265 | --statistic Average \ 266 | --period $ALARM_PERIOD \ 267 | --evaluation-periods "$TTL_PERIODS" \ 268 | --threshold 0 \ 269 | --comparison-operator GreaterThanOrEqualToThreshold \ 270 | --dimensions "Name=InstanceId,Value=${INSTANCEID}" \ 271 | --alarm-actions "arn:aws:automate:${REGION_AWS}:ec2:terminate") 272 | 273 | if [[ $TERMINATION_ALARM ]]; then 274 | aws --profile $HDE_PROFILE_NAME --region="${REGION_AWS}" ec2 terminate-instances --instance-ids "${INSTANCEID}" 275 | print_error "Something went wrong, setting the alarm to automatically terminate this instance failed! Please try again or contact the Contrast Sales Engineering team for assistance." 276 | exit 1 277 | else 278 | print_warning "Your workstation will automatically terminate after ${TTL} hour(s)." 279 | fi 280 | else 281 | # No alarm will be set and this instance will need to be auto-terminated 282 | print_error "*** PLEASE NOTE THAT THIS NEW INSTANCE WILL NOT BE AUTOMATICALLY TERMINATED ***" 283 | fi 284 | 285 | # Sleep 2 minutes and then check if the new instance is network accessible 286 | print_info "Now let's wait for 3 minutes and then check if the instance is ready..." 287 | sleep 180 288 | 289 | # Check if the new instance is publicly accessible every 10 seconds 290 | COUNTER=0 291 | while true; do 292 | NC_RESPONSE="$(nc -zv -G 1 "${PUBLIC_IP}" 3389 &>/dev/null && echo "Online" || echo "Offline")" 293 | if [[ "${NC_RESPONSE}" = "Online" ]]; then 294 | print_success "${NC_RESPONSE}" 295 | # If the instance is available, then launch Microsoft Remote Desktop to connect 296 | print_info "Opening Microsoft Remote Desktop session to your new virtual Windows developer workstation!" 297 | open -Fa /Applications/Microsoft\ Remote\ Desktop.app "rdp://full%20address=s:${PUBLIC_IP}&audiomode=i:0&disable%20themes=i:1&screen%20mode%20id=i:2&smart%20sizing=i:1&username=s:Administrator&session%20bpp=i:32&allow%20font%20smoothing=i:1&prompt%20for%20credentials%20on%20client=i:0&disable%20full%20window%20drag=i:1&autoreconnection%20enabled=i:1" 298 | # open -Fa /Applications/Microsoft\ Remote\ Desktop.app "rdp://full%20address=s:${PUBLIC_IP}&audiomode=i:0&disable%20themes=i:1&desktopwidth:i:${DESKTOP_WIDTH}&desktopheight:i:${DESKTOP_HEIGHT}&screen%20mode%20id=i:2&smart%20sizing=i:1&username=s:Administrator&session%20bpp=i:32&allow%20font%20smoothing=i:1&prompt%20for%20credentials%20on%20client=i:0&disable%20full%20window%20drag=i:1&autoreconnection%20enabled=i:1" 299 | break 300 | else 301 | print_warning "${NC_RESPONSE}" 302 | sleep 10 303 | COUNTER=$((COUNTER + 1)) 304 | if [[ $COUNTER -gt 30 ]]; then 305 | print_error "Something went wrong, the new instance is not network accessible! Please try again or contact the Contrast Sales Engineering team for assistance." 306 | exit 1 307 | fi 308 | fi 309 | done 310 | fi 311 | } 312 | 313 | main "$@" 314 | --------------------------------------------------------------------------------