Built a Ngrok replacement
TL;DR (Not worth it)
I'm building an app that requires an authentication callback. You can't just use localhost. The internet can't route to it. I've usedNgrok before. I wasn't a fan of how the URL keeps changing when you use the Ngrok free tier. Also, there's a limit to Ngrok requests. So I thought to myself I should just build a Ngrok replacement.
What we needed is a reverse proxy server. This server would act as our local app while we develop. That server has a domain name that we could register as a callback url.
So I built a virtual machine in Azure, setup the routing, installed and configured Nginx. Then I stopped because I had to configure my home's network firewall to allow for traffic to stream via an ssh tunnel from laptop to the proxy server. That was way too much for me. I could do it, I've done it before. But I work a lot from other networks and don't have access to those routers and firewalls.
So I came back to Ngrok. Their software is an agent that doesn't require any networking setup. It's pretty cool and now I have a deepr understanding how convenient their product is to use.
Implementation
Wanted to share the code and how to do it here if you're interested in setting up a reverse proxy server.
# main.tf# We strongly recommend using the required_providers block to set the# Azure Provider source and version being usedterraform{required_providers{azurerm={source="hashicorp/azurerm"version="~>4.0.1"}}}provider"azurerm"{features{}}variableNGROK_ALT_UNAME{type=stringdescription="description"}variableNGROK_ALT_PWD{type=stringdefault=""description="description"}# Resource Groupresource"azurerm_resource_group""proxy"{name="ngrok-alt-rg"location="West Europe"}# Virtual Networkresource"azurerm_virtual_network""proxy"{name="ngrok-alt-vnet"address_space=["10.0.0.0/16"]location=azurerm_resource_group.proxy.locationresource_group_name=azurerm_resource_group.proxy.name}# Subnetresource"azurerm_subnet""proxy"{name="subnet1"resource_group_name=azurerm_resource_group.proxy.namevirtual_network_name=azurerm_virtual_network.proxy.nameaddress_prefixes=["10.0.1.0/24"]}# Public IPresource"azurerm_public_ip""proxy"{name="ngrok-alt-ip"location=azurerm_resource_group.proxy.locationresource_group_name=azurerm_resource_group.proxy.nameallocation_method="Static"}# Virtual Machineresource"azurerm_linux_virtual_machine""proxy"{name="ngrok-alt-vm"resource_group_name=azurerm_resource_group.proxy.namelocation=azurerm_resource_group.proxy.locationsize="Standard_B1s"admin_username=var.NGROK_ALT_UNAMEadmin_password=var.NGROK_ALT_PWD# Use a more secure method in production!network_interface_ids=[azurerm_network_interface.proxy.id,]os_disk{caching="ReadWrite"storage_account_type="Standard_LRS"}source_image_reference{publisher="Canonical"offer="UbuntuServer"sku="18.04-LTS"version="latest"}computer_name="ngrok-alt-vm"admin_ssh_key{username=var.NGROK_ALT_UNAMEpublic_key=file("~/.ssh/ngrok-key.pub")}}# Network Interfaceresource"azurerm_network_interface""proxy"{name="ngrok-alt-nic"location=azurerm_resource_group.proxy.locationresource_group_name=azurerm_resource_group.proxy.nameip_configuration{name="internal"subnet_id=azurerm_subnet.proxy.idprivate_ip_address_allocation="Dynamic"public_ip_address_id=azurerm_public_ip.proxy.id}}# Network Security Groupresource"azurerm_network_security_group""proxy"{name="ngrok-alt-nsg"location=azurerm_resource_group.proxy.locationresource_group_name=azurerm_resource_group.proxy.namesecurity_rule{name="AllowSSH"priority=1000direction="Inbound"access="Allow"protocol="Tcp"source_port_range="*"destination_port_range="22"source_address_prefix="*"destination_address_prefix="*"}}resource"azurerm_network_interface_security_group_association""proxy"{network_interface_id=azurerm_network_interface.proxy.idnetwork_security_group_id=azurerm_network_security_group.proxy.id}# DNS Zoneresource"azurerm_dns_zone""proxy"{name="yourdomain.com"resource_group_name=azurerm_resource_group.proxy.name}# A Recordresource"azurerm_dns_a_record""proxy"{name="tunnel"zone_name=azurerm_dns_zone.proxy.nameresource_group_name=azurerm_resource_group.proxy.namettl=300records=[azurerm_public_ip.proxy.ip_address]}
You'll need public a key at~/.ssh/ngrok-key.pub
and/.ssh/ngrok-key.pem
.
Set Env var for subscription:export ARM_SUBSCRIPTION_ID=00000000-xxxx-xxxx-xxxx-xxxxxxxxxxxx
terraform apply -var-file local.tfvars
To ssh you'll have to update the permission on the key. Or else ssh will determine the connection insecure and refuse the connection.
chmod 400 ~/.ssh/ngrok-key.pem
ssh -i ~/.ssh/ngrok-key.pem adminuser@[public-ip]
sudoapt updatesudoaptinstallnginx-y
sudovim /etc/nginx/sites-available/tunnel.yourdomain.com
Append the below configuration:
server{listen80;server_nametunnel.yourdomain.com;location/{proxy_passhttp://127.0.0.1:8080;proxy_set_headerHost$host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_headerX-Forwarded-Proto$scheme;}}
The below steps do:
- Link configuration
- Test configuration
- If test successful restart service
sudo ln-s /etc/nginx/sites-available/tunnel.yourdomain.com /etc/nginx/sites-enabled/sudonginx-tsudosystemctl restart nginx
The below setups an ssh tunnel. However, you'll also have to go to your router/firewall and open up your development port so this tunnel would work.ssh -R <azure-port>:localhost:<local-laptop-port> <laptop-username>@<laptop-public-ip-or-domain>
To make the tunnel more reliable setup withautossh.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse