Skip to content

Commit

Permalink
enh: add bot authorization token, use cloudflare custom domain with W…
Browse files Browse the repository at this point in the history
…AF (#20)

* enh: add bot authorization token, use cloudflare custom domain with WAF

* fix: lint
  • Loading branch information
notdodo authored Sep 22, 2024
1 parent df00b7c commit 7fd968a
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 8 deletions.
2 changes: 2 additions & 0 deletions pulumi/Pulumi.production.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ config:
environment: production
project: erfiume
aws:region: eu-west-1
erfiume:telegram-authorization-token:
secure: AAABAAtA6vkP45ayorXzotOCFcQKQoeCjsLAFRG06Dr/DY1k3XbPLCdwAhiXtIh8T8b7rH0E/Ct9IrnvHbvJb7WyvTW4EG/92at/kVy8jBhjSp9uZ++Z3vCOI8rid2eP
erfiume:telegram-bot-token:
secure: AAABAPwvcC722Zh0BGmJZ73kUE7l0G9DDM40Q34uSQWJciCW9YdzWiqgzO/UvouqD7IGD6/O3q/KCnfphKeUQVC5L/89r+pjKOiAZSR0
2 changes: 2 additions & 0 deletions pulumi/Pulumi.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -268,5 +268,7 @@ config:
aws:secretKey: test
aws:skipCredentialsValidation: "true"
aws:skipRequestingAccountId: "true"
erfiume:telegram-authorization-token:
secure: AAABANBm/MQpNhcald3hBBL7UPUAhiYz5jxH+zeC4suyb48OpZcrnZHIhKl3qcPMRqjKtmdLGVoit/Cs+GVrfDprpQ2S4g1c7aujoehK2WTHuJwkznfqRzjyEXMxRd45
erfiume:telegram-bot-token:
secure: AAABAJCtZcMcH6RjMHY80HjCxKpVe2pLIHvj6g/v9efhMAZIg3HiNYmofthrZhjrSnkSMKzSrVcoqpvOgMUvV+zsZ1GUonnFmBYZ/VvA
60 changes: 57 additions & 3 deletions pulumi/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""An AWS Python Pulumi program"""

import pulumi
import pulumi_cloudflare
from pulumi_aws import (
apigatewayv2,
cloudwatch,
Expand All @@ -19,6 +20,7 @@
SYNC_MINUTES_RATE_NORMAL = 24 * 60 # Once a day
SYNC_MINUTES_RATE_EMERGENCY = 20
EMERGENCY = False
CUSTOM_DOMAIN_NAME = "erfiume.thedodo.xyz"

stazioni_table = dynamodb.Table(
f"{RESOURCES_PREFIX}-stazioni",
Expand Down Expand Up @@ -146,7 +148,7 @@
"ENVIRONMENT": pulumi.get_stack(),
},
},
memory_size=1024,
memory_size=768,
timeout=50,
)

Expand All @@ -164,7 +166,7 @@
"ENVIRONMENT": pulumi.get_stack(),
},
},
memory_size=1024,
memory_size=768,
timeout=10,
)

Expand Down Expand Up @@ -237,11 +239,21 @@
)

if pulumi.get_stack() == "production":
gw_domain_name = apigatewayv2.DomainName(
f"{RESOURCES_PREFIX}-bot",
domain_name=CUSTOM_DOMAIN_NAME,
domain_name_configuration=apigatewayv2.DomainNameDomainNameConfigurationArgs(
certificate_arn="arn:aws:acm:eu-west-1:841162699174:certificate/109ca827-8d70-4e11-8995-0b3dbdbd0510",
endpoint_type="REGIONAL",
security_policy="TLS_1_2",
),
)
bot_webhook_gw = apigatewayv2.Api(
f"{RESOURCES_PREFIX}-webhook",
protocol_type="HTTP",
route_key="POST /erfiume_bot",
target=bot_lambda.arn,
disable_execute_api_endpoint=True,
)
lambda_.Permission(
f"{RESOURCES_PREFIX}-lambda-bot-api-gateway",
Expand All @@ -250,9 +262,51 @@
principal="apigateway.amazonaws.com",
source_arn=bot_webhook_gw.execution_arn.apply(lambda arn: f"{arn}/*/*"),
)
gw_api_mapping = apigatewayv2.ApiMapping(
f"{RESOURCES_PREFIX}-bot-domain-mapping",
api_id=bot_webhook_gw.id,
domain_name=gw_domain_name.domain_name,
stage="$default",
)

pulumi_cloudflare.Record(
f"{RESOURCES_PREFIX}-api-gw-cname",
name="erfiume",
type="CNAME",
zone_id="cec5bf01afed114303a536c264a1f394",
proxied=True,
content=gw_domain_name.domain_name_configuration.target_domain_name,
)

telegram_authorization_token = pulumi.Config().require_secret(
"telegram-authorization-token"
)
pulumi_cloudflare.Ruleset(
f"{RESOURCES_PREFIX}-waf",
zone_id="cec5bf01afed114303a536c264a1f394",
name="erfiume-bot-check-authorization-header",
description="erfiume_bot Block Invalid Authorization Header",
kind="zone",
phase="http_request_firewall_custom",
rules=[
pulumi_cloudflare.RulesetRuleArgs(
action="block",
expression="(cf.client.bot)",
enabled=True,
),
pulumi_cloudflare.RulesetRuleArgs(
action="block",
expression=telegram_authorization_token.apply(
lambda header: f'(all(http.request.headers["x-telegram-bot-api-secret-token"][*] ne "{header}") and http.host eq "{CUSTOM_DOMAIN_NAME}")' # noqa: E501
),
enabled=True,
),
],
)

Webhook(
f"{RESOURCES_PREFIX}-apigateway-registration",
token=pulumi.Config().require_secret("telegram-bot-token"),
url=bot_webhook_gw.api_endpoint.apply(lambda url: f"{url}/erfiume_bot"),
authorization_token=telegram_authorization_token,
url=f"https://{CUSTOM_DOMAIN_NAME}/erfiume_bot",
)
18 changes: 17 additions & 1 deletion pulumi/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pulumi/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ package-mode = false
python = "^3.12"
pulumi-aws = "^6.52.0"
pulumi-command = "^1.0.1"
pulumi-cloudflare = "^5.39.0"

[tool.poetry.group.dev.dependencies]
awscli-local = "^0.22.0"
Expand Down
23 changes: 19 additions & 4 deletions pulumi/telegram_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@ class _TelegramWebhookProvider(ResourceProvider):
def create(self, props: dict[str, Any]) -> CreateResult:
webhook_url = props["url"]
token = props["token"]
secret_token = props["authorization_token"]
response = requests.post(
f"https://api.telegram.org/bot{token}/setWebhook",
json={"url": webhook_url},
json={
"url": webhook_url,
"secret_token": secret_token,
},
timeout=10,
)
if response.status_code != requests.codes.OK:
raise requests.RequestException(response.text)
return CreateResult(id_="-", outs={})
return CreateResult(id_="-")


class Webhook(Resource):
Expand All @@ -34,8 +38,19 @@ class Webhook(Resource):
"""

def __init__(
self, name: str, token: str | pulumi.Output[str], url: str | pulumi.Output[str]
self,
name: str,
token: str | pulumi.Output[str],
url: str | pulumi.Output[str],
authorization_token: str | pulumi.Output[str] | None = None,
) -> None:
super().__init__(
_TelegramWebhookProvider(), name, {"token": token, "url": url}, None
_TelegramWebhookProvider(),
name,
{
"token": token,
"url": url,
"authorization_token": authorization_token,
},
None,
)

0 comments on commit 7fd968a

Please sign in to comment.