{"id":25284710,"url":"https://github.com/ircama/aws-lambda-reverse-proxy","last_synced_at":"2025-10-27T19:31:29.363Z","repository":{"id":136958550,"uuid":"478124200","full_name":"Ircama/aws-lambda-reverse-proxy","owner":"Ircama","description":"A simple Python Reverse Proxy using AWS Lambda","archived":false,"fork":false,"pushed_at":"2024-09-09T14:23:41.000Z","size":47,"stargazers_count":20,"open_issues_count":1,"forks_count":8,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-09-09T17:30:58.885Z","etag":null,"topics":["aws","lambda","proxy","python","reverse-proxy"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ircama.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2022-04-05T12:44:23.000Z","updated_at":"2024-09-09T14:23:45.000Z","dependencies_parsed_at":"2023-10-05T09:55:27.529Z","dependency_job_id":null,"html_url":"https://github.com/Ircama/aws-lambda-reverse-proxy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ircama%2Faws-lambda-reverse-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ircama%2Faws-lambda-reverse-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ircama%2Faws-lambda-reverse-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ircama%2Faws-lambda-reverse-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ircama","download_url":"https://codeload.github.com/Ircama/aws-lambda-reverse-proxy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238550146,"owners_count":19490836,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","lambda","proxy","python","reverse-proxy"],"created_at":"2025-02-12T20:52:20.244Z","updated_at":"2025-10-27T19:31:24.059Z","avatar_url":"https://github.com/Ircama.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# aws-lambda-reverse-proxy\nA simple Python Reverse Proxy using AWS Lambda\n\n## Description\n\nThis program and related setup implements a simple http based request/response [reverse proxy application](https://en.wikipedia.org/wiki/Reverse_proxy) exposing to internet a default AWS auto-generated public fully functional https [endpoint](https://docs.aws.amazon.com/general/latest/gr/apigateway.html) that automatically uses the [lambda Function URL](https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html) certificate or the [Amazon API Gateway](https://aws.amazon.com/api-gateway/) certificate (or a custom one).\n\nThis reverse proxy application is able to inspect the received https request from the client (web browser) and to forward it to an http or https internet backend; in turn, when receiving the response from the backend, it is delivered to the client on the internet (e.g., web browser), which is unaware of the backend service IP address and related protocol, that can be HTTP or https with [self-signed SSL certificate](https://en.wikipedia.org/wiki/Self-signed_certificate), using the same port or a different one.\n\nThe http API endpoint includes a valid AWS certificate and allows HTTPS.\n\nFeatures:\n- configurable remote URL\n- [request/response](https://en.wikipedia.org/wiki/Request%E2%80%93response) mode\n- all standard http methods are supported (e.g., GET, POST, ..)\n- management of general connection and timeout errors of the backend site, including a splash page in case the remote backend is down\n- exposing a public [FQDN](https://en.wikipedia.org/wiki/Fully_qualified_domain_name) with valid SSL certificate provided by the Amazon Root CA\n- providing HTTS end-point with public FQDN to a non-secure HTTP backend (e.g., a computing resource), or to an HTTPS backend that uses a non-trusted self-signed SSL certificate\n- forwarding and integrating http headers and cookies between browser and backend\n- configurable filtered path (or paths) with simple warning page\n- allowing special `\u0026trace_connection=y` and `\u0026dump_request=y` debug queries (see below)\n- allowing up to 6 MB payload, with reference to the AWS Lambda quota (e.g., usable for small web pages and small-sized resources like icons, images, documents, etc.)\n\nLimitations:\n- the max response size must be within 6 MB\n- progressively streaming response payloads is not supported (only the request/response mode is allowed)\n\n### Tested architecture\n\nTested to integrate an always-free Oracle Cloud OCI computing resource.\n\n```mermaid\nflowchart TD;\n\nBrowser(Web browser)\n\nRproxy[\"AWS Reverse Proxy, exposing a fixed FQDN\nover HTTPS with valid SSL certificate\nprovided by the Amazon Root CA, port 443\"]\n\nOCI[\"Oracle Cloud Compute instance, exposing\na public IP address on a different port,\nwith self-signed certificate and no FQDN\"]\n\nBrowser \u003c==\u003e|internet| Rproxy \u003c==\u003e|internet| OCI\n```\n\n## Setup the needed AWS resources\n\n### Create a Python-based AWS Lambda function\n\n[AWS Lambda](https://aws.amazon.com/lambda/?nc2=h_ql_prod_fs_lbd) is a [serverless computing service](https://aws.amazon.com/getting-started/hands-on/run-serverless-code/?nc1=h_ls) included in the [free tier](https://aws.amazon.com/lambda/pricing/?loc=ft#Free_Tier) of Amazon Web Services (AWS), including one million free requests per month and 400000 GB-seconds of compute time per month.\n\n- AWS \u003e Lambda \u003e Functions \u003e Create function\n  - select \"Author from scratch\"\n  - Function name: rproxy\n  - Runtime: Python 3.11\n  - Architecture: x86_64\n  - Permissions: Create a new role with basic Lambda permissions\n\n- Press Create Function\n\n### Option 1 - Add a \"Function URL\" to the AWS Lambda function\n\nThe configuration of a [Function URL](https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html) is the preferred method, as does not imply the introduction of the fixed \"HTTP API Gateway\" timeout of 30 secs. Option 2 seems to better change long URLs. Both option can be concurrently active.\n\n- AWS \u003e Lambda \u003e Functions \u003e rproxy\n  - select \"Configuration\"\n  - select \"Function URL\"\n  - press \"Create function URL\"\n  - select \"Auth type\": \"NONE\"\n  - press \"SAVE\"\n  - read the \"Function URL\" (`https://\u003curl-id\u003e.lambda-url.\u003cregion\u003e.on.aws`) in the rproxy lambda function configuration\n  \n- Test this URL in another browser tab; you should get \"Hello from Lambda!\"\n\n- Add `/test` to the URL: `https://\u003curl-id\u003e.lambda-url.\u003cregion\u003e.on.aws/test`\n\n- You should still get \"Hello from Lambda!\" (this means that the Function URL works with all paths).\n\n### Option 2 - Link an HTTP API Gateway to trigger the AWS Lambda function\n\nAs alternative option to the usage of a \"Function URL\", an \"HTTP API Gateway\" can be created.\n\n[Amazon HTTP API Gateway](https://aws.amazon.com/api-gateway/?nc1=h_ls) provides a public HTTPS endpoint to the AWS Lambda function and automatically assigns a domain to the API, with a FQDN that uses a valid Amazon API Gateway certificate. It does not generate costs in case of limited number of small-sized requests per month (e.g., 4000 requests per month, with 512 KB each).\n\n- Press Add trigger\n\n- Select Api Gateway\n\n- Select \"Create an API\"\n  - Select \"HTTP API\"\n  - Security: Open\n\n- Press Add\n\n- Press \"rproxy-API\" in \"API Gateway: rproxy-API\"\n\n- Press \"Routes\"\n\n- Press Create\n\n- Route and method: `ANY` `/{proxy+}`\n\n- Notes on using the `ANY` `/{proxy+}` integration:\n  - https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html\n  - https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html\n  Note: this code requires Payload format version 2.0 (interpreted response format) for integration (might not work with version 1).\n\n- Press Create\n\n- Select \"ANY\" in \"`/rproxy`\" (not `/{proxy+}`)\n\n- Press Delete (and confirm).\n\n- You shoud have \n  ```\n  $default\n    /{proxy+}\n      ANY\n  ```\n\n- Press ANY\n\n- Press \"Attach integration\"\n\n- Select rproxy (your AWS Lambda function)\n\n- Press \"Attach integration\"\n\n- Notice:\n  Payload format version: 2.0\n  Timeout: 30000 msec\n\n- Press again \"API Gateway\" on the top.\n\n- Press \"rproxy-API\"\n\n- Select \"default\" (not $default)\n\n- Check that \"default\" is selected (not $default) and press \"Delete\". Confirm.\n  Note: if $default is missing, select \"Stages\" and add one named \"$default\", selecting \"Enable automatic deployment\". When done, you can remove the \"default\" Stage.\n\n- Press again \"API Gateway\" on the top.\n\n- Press \"rproxy-API\"\n\n- You should just have `\"$default\"\thttps://....execute-api....amazonaws.com/`\n\n- Test the URL in another browser tab; you should get \"Hello from Lambda!\"\n\n- Add `/test` to the URL: https://....execute-api....amazonaws.com/test\n\n- You should still get \"Hello from Lambda!\" (this means that the proxy gateway works with all paths).\n\n- Go back to AWS \u003e Lambda \u003e Functions \u003erproxy\n\n- Press Triggers (and do a refresh on this page)\n\n- You might have two API Gateway items:\n  ```\n  rproxy-API\n  API endpoint: https://https://....execute-api....amazonaws.com/{proxy+}\n  ```\n  and another one, with `arn:aws:execute-api.../*/*/rproxy`.\n\n- Remove the second one (select it and press Delete), so that only the `/{proxy+}` is configured.\n\n### Replace the default Python code with the reverse proxy\n\n- Go back to AWS \u003e Lambda \u003e Functions \u003erproxy\n\n- Select \"General configuration\". Configure the memory (e.g., 512 MB) and the timeout (e.g., 40 secs). Press Save.\n\n- Press \"Environment variables\".\n\n- Add `REMOTE_URL` and `FILTERED_PATH` (see below). For testing, use `REMOTE_URL=https://httpbin.org` and `FILTERED_PATH=/foobar|/baz`\n\n- Press Code.\n\n- Paste the code from this repo (replacing the default code).\n\n- Press \"Deploy\".\n\n- Select \"Runtime settings\" and press Edit.\n\n- Change the Handler: `lambda_function.proxy_handler`.\n\n- Press Save.\n\n### Test the configuration\n\n- Test again the page: `https://...`. You should get the https://httpbin.org home page.\n\n- Test `https://.../foobar`; you should get a \"Filtered URL.\" error (if using `FILTERED_PATH=/foobar`).\n\n- Test `https://.../baz`; you should get a \"Filtered URL.\" error (if using `FILTERED_PATH=/foobar|/baz`).\n\n- Test `https://.../cookies/set/:name/:value`; you should get the cookie named `:name:` set to `:value`.\n\n- Test `https://.../headers`; you should get the list of headers of your function, as obtained by https://httpbin.org/headers; included in the headers there should be `\"Cookie\": \":name=:value\",`\n\n- Test `https://.../headers?dump_request=y`; you should get the dump of the `event` and `context` variables of `proxy_handler()`.\n\n- Test `https://.../headers?trace_connection=y`; you should read tracing information in the CloudWatch Logs (e.g., `/usr/local/bin/aws logs tail /aws/lambda/rproxy  --follow`).\n\n- Try testing [other paths](https://stackoverflow.com/a/9770981/10598800).\n\nIn case of error, run `/usr/local/bin/aws logs tail /aws/lambda/rproxy --follow` and see the logs.\n\n## Installation of awscli\n\nInstallation of awscli on Unix (or [WSL](https://docs.microsoft.com/windows/wsl/about)) to trace the AWS Lambda function:\n\n```bash\n# Install awscli:\ncurl \"https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip\" -o \"awscliv2.zip\"\nunzip awscliv2.zip\nsudo ./aws/install\n/usr/local/bin/aws --version\n\n# Configure awscli:\n/usr/local/bin/aws configure\n```\n\n## Tracing\n\n(After installing `awscli`)\n\n```bash\n/usr/local/bin/aws logs tail /aws/lambda/\u003cfunction name\u003e --follow\n```\n\n## Needed environment variables\n\n`REMOTE_URL`: remote URL of the backend application (http or https). Example: https://httpbin.org\n\n`FILTERED_PATH`: (optional) path that needs to be filtered. A list of paths can be used, by separating each path with a pipe character (`|`). Example: `/foobar|/baz`.\n\n`NO_HEADERS`: (optional) when existing and set, do not forward headers.\n\nOptional parameters:\n\n- `GENERAL_ERROR`: title of the error message; default is \"AWS Lambda Error\"\n- `PAYLOAD_QUOTA`: max payload size; default is 5000000 bytes (size of the answer from the backend portal)\n- `REQUEST_TIMEOUT`: timeout to wait for the answer from the backend portal; default is 11.0 seconds\n- `APP_NAME`: application name; default is \"Sample Application\"\n- `FILTERED_URL_MSG`: filtered URL message; default is \"Filtered URL.\"\n\n## Special parameters\n\n- `\u0026trace_connection=y`: trace information to [CloudWatch log](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html); logs can be inspected via [`aws logs tail /aws/lambda/\u003cfunction name\u003e --follow`](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/logs/tail.html)\n- `\u0026dump_request=y`: dump the request, producing a page that describes the http request attributes (cookies, headers, path, query string, parameters, AWS context, etc.).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fircama%2Faws-lambda-reverse-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fircama%2Faws-lambda-reverse-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fircama%2Faws-lambda-reverse-proxy/lists"}