expose-localhost


Nameexpose-localhost JSON
Version 0.8 PyPI version JSON
download
home_page
SummaryReverse proxy that creates a secure tunnel from public endpoint to locally running web service
upload_time2023-11-18 18:06:23
maintainer
docs_urlNone
author
requires_python>=3
licenseMIT License Copyright (c) 2021 Vignesh Rao Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords route53 certificate ec2 ngrok-alternative tunnel
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ![Python](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11-blue)

###### Platform Supported
![Generic badge](https://img.shields.io/badge/Platform-MacOS|Windows-1f425f.svg)

###### Repo Stats
[![GitHub](https://img.shields.io/github/license/thevickypedia/expose)][LICENSE]
[![GitHub repo size](https://img.shields.io/github/repo-size/thevickypedia/expose)][API_REPO]
[![GitHub code size](https://img.shields.io/github/languages/code-size/thevickypedia/expose)][API_REPO]

###### Deployments
[![doc](https://github.com/thevickypedia/expose/actions/workflows/pages/pages-build-deployment/badge.svg)][gha_pages]
[![pypi](https://github.com/thevickypedia/expose/actions/workflows/python-publish.yml/badge.svg)][gha_pypi]
[![markdown](https://github.com/thevickypedia/expose/actions/workflows/markdown-validation.yml/badge.svg)][gha_markdown]

[![Pypi-format](https://img.shields.io/pypi/format/expose-localhost)](https://pypi.org/project/expose-localhost/#files)
[![Pypi-status](https://img.shields.io/pypi/status/expose-localhost)](https://pypi.org/project/expose-localhost)
[![sourcerank](https://img.shields.io/librariesio/sourcerank/pypi/expose-localhost)](https://libraries.io/pypi/expose-localhost)

# Expose localhost using EC2
Reverse proxy that creates a secure tunnel from public endpoint to locally running web service

### Setup
#### Environment Variables:
Environment variables can be loaded from any `.env` file.

- **PORT**: Port number that has to be exposed (on which a localhost `service/app/api` is running)

<br>

<details>
<summary><strong>Optional env</strong></summary>

- **OPEN_PORT**: Boolean flag to enable `ingress` and `egress` on the specified port. Defaults to `False`
- **CHANNEL_TIMEOUT**: Timeout in seconds to wait for an incoming channel connection. Defaults to `100`
- **IMAGE_ID**: ID of any public AMI with an Ubuntu OS. Defaults to a region specific image ID.
- **INSTANCE_TYPE**: Instance type for tunneling. Defaults to `t2.nano`
- **AWS_ACCESS_KEY**: Access key to access AWS resources. Defaults to `~/.aws/config`
- **AWS_SECRET_KEY**: Secret key to access AWS resources. Defaults to `~/.aws/config`
- **AWS_REGION_NAME**: Region name where the instance should live. Defaults to `US-WEST-2`
- **KEY_PAIR**: Name for the ec2 key pair file. Defaults to `expose_localhost`
- **SECURITY_GROUP**: Name for the security group to allow port access. Defaults to `Expose Localhost`
- **SERVER_INFO**: Name for the JSON file to store the configuration info. Defaults to `server_info.json`
- **EMAIL_ADDRESS**: Email address to create the self-signed SSL and private key. Defaults to `USER@expose-localhost.com`
- **ORGANIZATION**: Organization name for the certificate. Defaults to the AWS endpoint.
- **HOSTED_ZONE**: Hosted zone name registered using `route53`. *Example: `mywebsite.com`*
- **SUBDOMAIN**: Sub-domain that has to be added for the domain name. *Example: `tunnel`*
</details>

<details>
<summary><strong>Latency</strong></summary>

`CHANNEL_TIMEOUT` can be adjusted to improve latency depending on the application's role.

**Network Latency**

Shorter timeouts can make your server more responsive to incoming connections but may also lead to false negatives if network latency is high.
If connections take longer to establish due to network conditions, a short timeout might reject valid connections prematurely.

**Connection Rate**

If your server expects a high rate of incoming connections, and you want to process them quickly, a shorter timeout can be beneficial.
However, it also means that your server needs to be able to process connections rapidly.

**Resource Usage**

Short timeouts can lead to a higher rate of repeated checks, which may consume more CPU resources on the server.
Ensure that your server has the capacity to handle frequent connection checks, if you are setting `CHANNEL_TIMEOUT` too low.
</details>

<details>
<summary><strong>Custom endpoint</strong></summary>

The public DNS names for EC2 instances are long and messy. To avoid that, an `A` record can be added to the `route53` hosted zone.

:warning: &nbsp; Requires an active hosted zone on `route53`.

:bulb: &nbsp; `SUBDOMAIN.HOSTED_ZONE` will be the endpoint to access the localhost from public internet.
</details>

<details>
<summary><strong>SSL certificate</strong></summary>

- Securing the tunnel requires the certificate chain and the key file.
- The certificate and key files should be in `pem` format stored in current working directory.
- File names should be stored as `key_file` and `cert_file` env var.
- No certs? No problem. `expose` will generate a self-signed certificate and a private key automatically.

:warning: &nbsp; Some web browsers might throw a warning and some might even block a self-signed certificate/private CA.

**Manually generate self-signed certificate**
> `openssl req -newkey rsa:2048 -sha256 -nodes -keyout private.pem -x509 -days 365 -out public.pem -subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=tunnel.example.com"`

**To verify the generated certificate**
> `openssl x509 -inform pem -in public.pem -noout -text`
</details>

### Usage
###### Installation
```shell
python3 -m pip install expose-localhost
```

###### Tunneling:
```python
import os

os.environ['env_file'] = 'custom'  # to load a custom .env file

import expose

# Instantiate object
tunnel = expose.Tunnel()

# Start tunneling
tunnel.start()

# set 'purge' flag to 'True' to reclaim AWS resources if configuration fails
# tunnel.start(purge=True)

# Stop tunneling - deletes all AWS resources acquired
tunnel.stop()
```

<br>

<details>
<summary><strong>Troubleshooting</strong></summary>

> If `E: Could not get lock /var/lib/dpkg/lock-frontend` occurs during startup, simply rerun the script with start command.

> This occurs when `apt` hasn't released the resources yet. A retry logic is in place to delete the lock file automatically.
> However, if any such issues persist, re-running `tunnel.start()` will simply re-configure the instance entirely.
</details>

<details>
<summary><strong>Limitations</strong></summary>

Currently `expose` cannot handle, tunneling multiple port numbers without modifying the following env vars in the `.env` file.
```shell
KEY_PAIR        # SSH connection to AWS ec2
KEY_FILE        # Private key filename for self signed SSL
CERT_FILE       # Public certificate filename for self signed SSL
SERVER_INFO     # Filename to dump JSON data with server configuration information
SECURITY_GROUP  # Ingress and egress firewall rules to control traffic allowed via VPC
```
</details>

## Coding Standards
Docstring format: [`Google`](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) <br>
Styling conventions: [`PEP 8`](https://www.python.org/dev/peps/pep-0008/) <br>
Clean code with pre-commit hooks: [`flake8`](https://flake8.pycqa.org/en/latest/) and 
[`isort`](https://pycqa.github.io/isort/)

## [Release Notes][release-notes]
**Requirement**
```shell
python -m pip install gitverse
```

**Usage**
```shell
gitverse-release reverse -f release_notes.rst -t 'Release Notes'
```

## Linting
`PreCommit` will ensure linting, and the doc creation are run on every commit.

**Requirement**
```shell
pip install sphinx==5.1.1 pre-commit recommonmark
```

**Usage**
```shell
pre-commit run --all-files
```

### Pypi Package
[![pypi-module](https://img.shields.io/badge/Software%20Repository-pypi-1f425f.svg)][pypi-read]

[https://pypi.org/project/expose-localhost/][pypi]

### Runbook
[![made-with-sphinx-doc](https://img.shields.io/badge/Code%20Docs-Sphinx-1f425f.svg)][sphinx-read]

[https://thevickypedia.github.io/expose/][docs]

## License & copyright

&copy; Vignesh Rao

Licensed under the [MIT License][LICENSE]

[LICENSE]: https://github.com/thevickypedia/expose/blob/main/LICENSE
[API_REPO]: https://api.github.com/repos/thevickypedia/expose
[pypi]: https://pypi.org/project/expose-localhost/
[pypi-read]: https://packaging.python.org/tutorials/packaging-projects/
[sphinx-read]: https://www.sphinx-doc.org/en/master/man/sphinx-autogen.html
[docs]: https://thevickypedia.github.io/expose/
[release-notes]: https://github.com/thevickypedia/expose/blob/main/release_notes.rst
[gha_pages]: https://github.com/thevickypedia/expose/actions/workflows/pages/pages-build-deployment
[gha_pypi]: https://github.com/thevickypedia/expose/actions/workflows/python-publish.yml
[gha_markdown]: https://github.com/thevickypedia/expose/actions/workflows/markdown-validation.yml

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "expose-localhost",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3",
    "maintainer_email": "",
    "keywords": "route53,certificate,ec2,ngrok-alternative,tunnel",
    "author": "",
    "author_email": "Vignesh Rao <svignesh1793@gmail.com>",
    "download_url": "",
    "platform": null,
    "description": "![Python](https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10%20%7C%203.11-blue)\n\n###### Platform Supported\n![Generic badge](https://img.shields.io/badge/Platform-MacOS|Windows-1f425f.svg)\n\n###### Repo Stats\n[![GitHub](https://img.shields.io/github/license/thevickypedia/expose)][LICENSE]\n[![GitHub repo size](https://img.shields.io/github/repo-size/thevickypedia/expose)][API_REPO]\n[![GitHub code size](https://img.shields.io/github/languages/code-size/thevickypedia/expose)][API_REPO]\n\n###### Deployments\n[![doc](https://github.com/thevickypedia/expose/actions/workflows/pages/pages-build-deployment/badge.svg)][gha_pages]\n[![pypi](https://github.com/thevickypedia/expose/actions/workflows/python-publish.yml/badge.svg)][gha_pypi]\n[![markdown](https://github.com/thevickypedia/expose/actions/workflows/markdown-validation.yml/badge.svg)][gha_markdown]\n\n[![Pypi-format](https://img.shields.io/pypi/format/expose-localhost)](https://pypi.org/project/expose-localhost/#files)\n[![Pypi-status](https://img.shields.io/pypi/status/expose-localhost)](https://pypi.org/project/expose-localhost)\n[![sourcerank](https://img.shields.io/librariesio/sourcerank/pypi/expose-localhost)](https://libraries.io/pypi/expose-localhost)\n\n# Expose localhost using EC2\nReverse proxy that creates a secure tunnel from public endpoint to locally running web service\n\n### Setup\n#### Environment Variables:\nEnvironment variables can be loaded from any `.env` file.\n\n- **PORT**: Port number that has to be exposed (on which a localhost `service/app/api` is running)\n\n<br>\n\n<details>\n<summary><strong>Optional env</strong></summary>\n\n- **OPEN_PORT**: Boolean flag to enable `ingress` and `egress` on the specified port. Defaults to `False`\n- **CHANNEL_TIMEOUT**: Timeout in seconds to wait for an incoming channel connection. Defaults to `100`\n- **IMAGE_ID**: ID of any public AMI with an Ubuntu OS. Defaults to a region specific image ID.\n- **INSTANCE_TYPE**: Instance type for tunneling. Defaults to `t2.nano`\n- **AWS_ACCESS_KEY**: Access key to access AWS resources. Defaults to `~/.aws/config`\n- **AWS_SECRET_KEY**: Secret key to access AWS resources. Defaults to `~/.aws/config`\n- **AWS_REGION_NAME**: Region name where the instance should live. Defaults to `US-WEST-2`\n- **KEY_PAIR**: Name for the ec2 key pair file. Defaults to `expose_localhost`\n- **SECURITY_GROUP**: Name for the security group to allow port access. Defaults to `Expose Localhost`\n- **SERVER_INFO**: Name for the JSON file to store the configuration info. Defaults to `server_info.json`\n- **EMAIL_ADDRESS**: Email address to create the self-signed SSL and private key. Defaults to `USER@expose-localhost.com`\n- **ORGANIZATION**: Organization name for the certificate. Defaults to the AWS endpoint.\n- **HOSTED_ZONE**: Hosted zone name registered using `route53`. *Example: `mywebsite.com`*\n- **SUBDOMAIN**: Sub-domain that has to be added for the domain name. *Example: `tunnel`*\n</details>\n\n<details>\n<summary><strong>Latency</strong></summary>\n\n`CHANNEL_TIMEOUT` can be adjusted to improve latency depending on the application's role.\n\n**Network Latency**\n\nShorter timeouts can make your server more responsive to incoming connections but may also lead to false negatives if network latency is high.\nIf connections take longer to establish due to network conditions, a short timeout might reject valid connections prematurely.\n\n**Connection Rate**\n\nIf your server expects a high rate of incoming connections, and you want to process them quickly, a shorter timeout can be beneficial.\nHowever, it also means that your server needs to be able to process connections rapidly.\n\n**Resource Usage**\n\nShort timeouts can lead to a higher rate of repeated checks, which may consume more CPU resources on the server.\nEnsure that your server has the capacity to handle frequent connection checks, if you are setting `CHANNEL_TIMEOUT` too low.\n</details>\n\n<details>\n<summary><strong>Custom endpoint</strong></summary>\n\nThe public DNS names for EC2 instances are long and messy. To avoid that, an `A` record can be added to the `route53` hosted zone.\n\n:warning: &nbsp; Requires an active hosted zone on `route53`.\n\n:bulb: &nbsp; `SUBDOMAIN.HOSTED_ZONE` will be the endpoint to access the localhost from public internet.\n</details>\n\n<details>\n<summary><strong>SSL certificate</strong></summary>\n\n- Securing the tunnel requires the certificate chain and the key file.\n- The certificate and key files should be in `pem` format stored in current working directory.\n- File names should be stored as `key_file` and `cert_file` env var.\n- No certs? No problem. `expose` will generate a self-signed certificate and a private key automatically.\n\n:warning: &nbsp; Some web browsers might throw a warning and some might even block a self-signed certificate/private CA.\n\n**Manually generate self-signed certificate**\n> `openssl req -newkey rsa:2048 -sha256 -nodes -keyout private.pem -x509 -days 365 -out public.pem -subj \"/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=tunnel.example.com\"`\n\n**To verify the generated certificate**\n> `openssl x509 -inform pem -in public.pem -noout -text`\n</details>\n\n### Usage\n###### Installation\n```shell\npython3 -m pip install expose-localhost\n```\n\n###### Tunneling:\n```python\nimport os\n\nos.environ['env_file'] = 'custom'  # to load a custom .env file\n\nimport expose\n\n# Instantiate object\ntunnel = expose.Tunnel()\n\n# Start tunneling\ntunnel.start()\n\n# set 'purge' flag to 'True' to reclaim AWS resources if configuration fails\n# tunnel.start(purge=True)\n\n# Stop tunneling - deletes all AWS resources acquired\ntunnel.stop()\n```\n\n<br>\n\n<details>\n<summary><strong>Troubleshooting</strong></summary>\n\n> If `E: Could not get lock /var/lib/dpkg/lock-frontend` occurs during startup, simply rerun the script with start command.\n\n> This occurs when `apt` hasn't released the resources yet. A retry logic is in place to delete the lock file automatically.\n> However, if any such issues persist, re-running `tunnel.start()` will simply re-configure the instance entirely.\n</details>\n\n<details>\n<summary><strong>Limitations</strong></summary>\n\nCurrently `expose` cannot handle, tunneling multiple port numbers without modifying the following env vars in the `.env` file.\n```shell\nKEY_PAIR        # SSH connection to AWS ec2\nKEY_FILE        # Private key filename for self signed SSL\nCERT_FILE       # Public certificate filename for self signed SSL\nSERVER_INFO     # Filename to dump JSON data with server configuration information\nSECURITY_GROUP  # Ingress and egress firewall rules to control traffic allowed via VPC\n```\n</details>\n\n## Coding Standards\nDocstring format: [`Google`](https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings) <br>\nStyling conventions: [`PEP 8`](https://www.python.org/dev/peps/pep-0008/) <br>\nClean code with pre-commit hooks: [`flake8`](https://flake8.pycqa.org/en/latest/) and \n[`isort`](https://pycqa.github.io/isort/)\n\n## [Release Notes][release-notes]\n**Requirement**\n```shell\npython -m pip install gitverse\n```\n\n**Usage**\n```shell\ngitverse-release reverse -f release_notes.rst -t 'Release Notes'\n```\n\n## Linting\n`PreCommit` will ensure linting, and the doc creation are run on every commit.\n\n**Requirement**\n```shell\npip install sphinx==5.1.1 pre-commit recommonmark\n```\n\n**Usage**\n```shell\npre-commit run --all-files\n```\n\n### Pypi Package\n[![pypi-module](https://img.shields.io/badge/Software%20Repository-pypi-1f425f.svg)][pypi-read]\n\n[https://pypi.org/project/expose-localhost/][pypi]\n\n### Runbook\n[![made-with-sphinx-doc](https://img.shields.io/badge/Code%20Docs-Sphinx-1f425f.svg)][sphinx-read]\n\n[https://thevickypedia.github.io/expose/][docs]\n\n## License & copyright\n\n&copy; Vignesh Rao\n\nLicensed under the [MIT License][LICENSE]\n\n[LICENSE]: https://github.com/thevickypedia/expose/blob/main/LICENSE\n[API_REPO]: https://api.github.com/repos/thevickypedia/expose\n[pypi]: https://pypi.org/project/expose-localhost/\n[pypi-read]: https://packaging.python.org/tutorials/packaging-projects/\n[sphinx-read]: https://www.sphinx-doc.org/en/master/man/sphinx-autogen.html\n[docs]: https://thevickypedia.github.io/expose/\n[release-notes]: https://github.com/thevickypedia/expose/blob/main/release_notes.rst\n[gha_pages]: https://github.com/thevickypedia/expose/actions/workflows/pages/pages-build-deployment\n[gha_pypi]: https://github.com/thevickypedia/expose/actions/workflows/python-publish.yml\n[gha_markdown]: https://github.com/thevickypedia/expose/actions/workflows/markdown-validation.yml\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2021 Vignesh Rao  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "Reverse proxy that creates a secure tunnel from public endpoint to locally running web service",
    "version": "0.8",
    "project_urls": {
        "Bug Tracker": "https://github.com/thevickypedia/expose/issues",
        "Docs": "https://thevickypedia.github.io/expose/",
        "Homepage": "https://github.com/thevickypedia/expose",
        "Release Notes": "https://github.com/thevickypedia/expose/blob/main/release_notes.rst",
        "Source": "https://github.com/thevickypedia/expose"
    },
    "split_keywords": [
        "route53",
        "certificate",
        "ec2",
        "ngrok-alternative",
        "tunnel"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fd56f6ec1888f63c784fcafbb99596d8026085b53294e0bf660d37e6d0765306",
                "md5": "138b1b667d5d8048e758c8d084d88b34",
                "sha256": "ea88bb827ed0fa31975030716b482f9f257654ab0096ac3fa92f917442a5d127"
            },
            "downloads": -1,
            "filename": "expose_localhost-0.8-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "138b1b667d5d8048e758c8d084d88b34",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3",
            "size": 27108,
            "upload_time": "2023-11-18T18:06:23",
            "upload_time_iso_8601": "2023-11-18T18:06:23.852558Z",
            "url": "https://files.pythonhosted.org/packages/fd/56/f6ec1888f63c784fcafbb99596d8026085b53294e0bf660d37e6d0765306/expose_localhost-0.8-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-18 18:06:23",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "thevickypedia",
    "github_project": "expose",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "expose-localhost"
}
        
Elapsed time: 0.15186s