Scan IBM Cloud VPC Floating IPs and Classic IaaS for Open Ports
Perform a quick port scan on public IPs bound to your IBM Cloud account.
Overview
After getting dinged a few times by internal security scans I decided to write a script to scan all the servers in my IBM Cloud account for open ports. This python script will scan all the Floating IPs associated with your IBM Cloud account as well as the classic virtual and bare metal servers with public IPs. The script currently scans for SSH, RDP, Telnet, FTP, and SMTP but any port can be added to the scan list.
Prerequisites
- IBM Cloud API Key: This is used to authenticate with the IBM Cloud API. You can create an API key in the IBM Cloud console under Manage > Access (IAM) > API keys or using this link.
- python 3.10 or higher
- IBM Cloud CLI installed (optional: only used with the Code Engine deployment option)
Running the script locally
-
Export the IBM Cloud API Key: In order to run this script locally you will need to export the API key to the environment variable
IBMCLOUD_API_KEY
. You can do this by running the following command in your terminal:export IBMCLOUD_API_KEY=<your-api-key>
-
Install the required python packages: I include the
ibm_platform_services
library here so we can get back more verbose API exceptions in the event of an error.pip install SoftLayer ibm_vpc ibm_platform_services
-
Download the script: You can use the wget command provided or copy from the embedded gist below and save it to your local machine as
scan_ibmcloud.py
.wget -O scan_ibmcloud.py https://raw.githubusercontent.com/cloud-design-dev/ibmcloud-code-engine-demos/main/jobs/account-port-scan/port-scan-report.py
-
Invoke the script: The script will take a few minutes to run as it scans all the floating IPs and classic infrastructure servers in your account.
python scan_ibmcloud.py
-
Inspect the results: The scan results should provide output similar to the following:
$ python scan_ibmcloud.py Starting scan of floating IPs... Open ports on 169.x.y.zzz: [22] Open ports on 169.x.y.zzz: [3389] Scan complete. Starting scan on classic infrastructure virtual guests... Scan complete. Starting scan on classic infrastructure bare metals... Open ports on 169.x.y.zzz: [3389] Scan complete.
Automate the scan using Code Engine
If you want to automate this scan you can use IBM Cloud Code Engine to run the script on a schedule. Code Engine allows you to run your code in a serverless environment without having to manage the underlying infrastructure or any of the scaling, TLS, etc. The Code Engine project and resources can be created using the IBM Cloud Portal or the IBM Cloud CLI. I will outline the CLI method below.
CLI Method
-
Install the IBM Cloud CLI and required plugin: If you don’t have the IBM Cloud CLI installed you can download it from the IBM Cloud CLI page or use one of the pre-configured IBM Cloud Shell environments.
ibmcloud plugin install code-engine
-
Export API Key environment variable: The following variables will be used in the CLI commands below.
- IBMCLOUD_API_KEY: Your IBM Cloud API key.
- IBMCLOUD_REGION: The IBM Cloud region where the Code Engine project will be created. See here for a list of supported regions.
- IBMCLOUD_RESOURCE_GROUP: The resource group where the Code Engine project will be created.
export IBMCLOUD_API_KEY=<your-api-key> export IBMCLOUD_REGION=<region> export IBMCLOUD_RESOURCE_GROUP=<resource-group>
-
Login to the IBM Cloud CLI: Use the
-r
flag to target the region and the-g
flag for the Resource Group. The resource group must be set for the Code Engine plugin to work.ibmcloud login ibmcloud target -r "${IBMCLOUD_REGION}" -g "${IBMCLOUD_RESOURCE_GROUP}"
-
Create the Code Engine project: It is important to note that the project will take a few minutes to be created. Once the project is created the CLI will automatically switch to the project context. You can add tags to the project to help with organization and filtering using the
--tag
flag.ibmcloud ce project create --name scan-ibmcloud --tag supercooltag1 --tag supercooltag2
-
Create project secret: The only secret required for the the script to run is your
IBM Cloud API key
that is used to authenticate and scan the account.ibmcloud ce secret create --name ibmcloud-api-key --from-literal IBMCLOUD_API_KEY="${IBMCLOUD_API_KEY}"
-
Create a job configuration: With Code Engine we can run our jobs from existing containers or build from a source repository. In this case we will use a prebuilt container that I created and published to Docker hub
ibmcloud ce job create --name port-scan-job --image greyhoundforty/ibmportscanner:amd64latest --env-from-secret ibmcloud-api-key
-
Submit the job: The job will take a few minutes to run as it scans all the floating IPs and classic infrastructure servers in your account.
ibmcloud ce jobrun submit --job port-scan-job --name port-scan-job-initial-run
-
Inspect the results: Use the
logs -f -n
option to follow the logs for the jobrun in real time. The scan results should provide output similar to the following:ibmcloud ce jobrun logs -f -n port-scan-job-initial-run Getting logs for all instances of job run 'port-scan-job-initial-run'... Getting jobrun 'port-scan-job-initial-run'... Getting instances of jobrun 'port-scan-job-initial-run'... OK port-scan-job-initial-run-0-0/port-scan-job: Starting scan of floating IPs... port-scan-job-initial-run-0-0/port-scan-job: Open ports on 52.xx.yy.zz: [22] port-scan-job-initial-run-0-0/port-scan-job: VPC Floating IP Scan complete. port-scan-job-initial-run-0-0/port-scan-job: Starting scan on classic infrastructure virtual guests... port-scan-job-initial-run-0-0/port-scan-job: Open ports on 67.xx.yy.zz: [3389] port-scan-job-initial-run-0-0/port-scan-job: Classic Virtual Guests Scan complete. port-scan-job-initial-run-0-0/port-scan-job: Starting scan on classic infrastructure bare metals... port-scan-job-initial-run-0-0/port-scan-job: Classic Bare Metals Scan complete. Job run completed successfully.
-
Automate with Code Engine cron subscription: With Code Engine you can have your jobs and applications run on a schedule using the
Periodic Timer
subscription. The following command will create a subscription that runs the job every day at 8:30 AM CST. If the--time-zone
flag is not provided the default is UTC.ibmcloud ce sub cron create --name port-scan-job-cron --destination port-scan-job --destination-type job --schedule '30 08 * * *' --time-zone 'America/Chicago'