Automating IP Blocking on Cloudflare with a Slack Bot
In the world of web security, time is of the essence. Manually blocking suspicious IP addresses on Cloudflare via the UI can be a tedious process.
In this blog, I’ll show you how to set up a Slack bot that seamlessly integrates with Cloudflare, giving you the power to block suspicious IPs with a command.
Prerequisites:
Before diving into the setup process, ensure you have the following in place:
- Cloudflare Account:
- An active Cloudflare account with a domain already configured.
2. Cloudflare API Credentials:
- Obtain the API key for authentication in the Slack bot.
3. Slack Workspace:
- A Slack workspace where you have the necessary permissions to create a new Slack app.
4. Slack App Token:
- Generate a Slack app and obtain the app token. This token will enable the bot to interact with your Slack workspace.
5. Ngrok:
- Recommended for testing: Ngrok to expose your local development server to the internet. This is useful for testing Slack slash commands.
With these prerequisites in place, you’ll be ready to set up your Slack bot for seamless integration with Cloudflare.
Let’s move on to the step-by-step guide!
Assuming you already have a Cloudflare account, our next move is to generate API credentials directly. It’s important to note that the Global API key, which was the previous method of authorization for Cloudflare API interactions, has now been replaced by API tokens. Whenever possible, it is recommended to use API tokens instead of the Global API key.
- To proceed, visit https://dash.cloudflare.com/profile/api-tokens and follow these steps:
- Click on “Create Token.”
- Choose the option to “Create Custom Token.”
You might wonder why we specifically selected for “Account Firewall Access Rules Edit.” This selection is made because we’ll be creating a IP Access rule on account level which will be applicable to all zones within that account.
Copy the token and save it for later!
Cloudflare’s API Documentation: https://developers.cloudflare.com/api/operations/ip-access-rules-for-an-account-create-an-ip-access-rule
2. Assuming you’ve already created a workspace on Slack, let’s now focus on the steps to create a Slack Bot. Follow these simple instructions:
- Open https://api.slack.com/apps.
- Click on “Create New App.”
- Choose “From scratch.”
- Provide a name for your app, select the workspace, and click “Create App.”
- Click on the “OAuth & Permissions” button and then select “Scopes”
Under the “Bot Token Scopes” section, click on “Add an OAuth Scope” and add the scopes shown in the screenshot below:
- Proceed to “Install to Workspace” and click “Allow” to generate an OAuth token.
3. The next step is to create a dedicated folder named ‘cloudflare-bot’ and include the following essential files:
.env: This file is used to store sensitive information and configuration settings, such as API tokens (SLACK_TOKEN
and CLOUDFLARE_BEARER_TOKEN
), and Cloudflare API URL (CLOUDFLARE_URL
). It helps in keeping sensitive data separate from the code for security reasons.
SLACK_TOKEN=<Copy & paste the “OAuth Token”>
CLOUDFLARE_BEARER_TOKEN=<token>
CLOUDFLARE_URL=https://api.cloudflare.com/client/v4/accounts/<account-id>/firewall/access_rules/rules
bot.py: It includes code for blocking IP addresses on Cloudflare based on Slack commands. The Flask web application (app
) listens for incoming requests, processes them, and interacts with both Slack and Cloudflare using the specified tokens and URLs.
import requests
from slack_sdk import WebClient
from flask import Flask, request, Response
from pathlib import Path
from dotenv import load_dotenv
import logging
env_path = Path("cloudflare-bot") / ".env"
load_dotenv(dotenv_path=env_path)
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(levelname)s - %(message)s",
filename="app.log",
)
app = Flask(__name__)
client = WebClient(token=os.environ["SLACK_TOKEN"])
bearer_token = os.environ.get("CLOUDFLARE_BEARER_TOKEN")
cloudflare_url = os.environ.get("CLOUDFLARE_URL")
def block_ip(ip):
headers = {
"Authorization": f'Bearer {bearer_token}',
"Content-Type": "application/json",
}
data = {
"configuration": {"target": "ip", "value": ip},
"mode": "block",
"notes": "Blocked by Slack BOT",
}
try:
response = requests.post(cloudflare_url, json=data, headers=headers)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
logging.error(f"Error while blocking IP {ip}: {e}")
return {}
@app.route('/block-ip', methods=['POST'])
def block_ip_command():
data = request.form
channel_id = data.get('channel_id')
ip_to_block = data.get('text')
response = block_ip(ip_to_block)
if response.get('success'):
message = f"IP address {ip_to_block} has been successfully blocked by Groot."
else:
message = f"Failed to block IP address {ip_to_block}."
client.chat_postMessage(
channel=channel_id, text=message)
return Response(), 200
# Run the Flask app
if __name__ == "__main__":
app.run(debug=True)
Next, execute the code, and you’ll observe a web server running at http://127.0.0.1:5000/. To make this accessible publicly, we’ll utilize NGROK. Run the command ‘ngrok http 5000’ in NGROK, and you’ll obtain a public address.
4. Proceed to ‘Slash Commands,’ and follow the steps to create a new command, as illustrated in the screenshot below. Add the NGROK URL to the requested URL field, specifying it as ‘’https://86ef-3-109-91-41.ngrok-free.app/block-ip”.
5. We can create the channel in Slack and adding our app to it as demonstrated in the screenshot below.
For instance, use the command ‘/block-ip 192.168.1.10’ to initiate the blocking process and observe the response to verify its success.
To confirm the results, visit the Cloudflare UI. You’ll notice that the specified IP is now successfully blocked at the account level.
Considerations:
- There are alternative methods available for making a Flask app public besides using ngrok. Explore various options to find the one that best suits your requirements.
- Once you’ve achieved this setup, the possibilities extend beyond the basics. Utilize Cloudflare APIs to create a versatile bot capable of performing actions such as cache purging, blocking specific user-agents, and more.
I invite you to share your thoughts and insights about this blog post in the comments section below. Your feedback is valuable, and I’m eager to hear about your experiences and any innovative approaches you may have explored. If you have questions feel free to reach out to me on my socials available at https://adiintify.com/.