Skip to content

Instantly share code, notes, and snippets.

@GlitchWitch
Last active January 2, 2024 01:57
Show Gist options
  • Save GlitchWitch/207d18c8902fcb5e1c5f0e043f8e9101 to your computer and use it in GitHub Desktop.
Save GlitchWitch/207d18c8902fcb5e1c5f0e043f8e9101 to your computer and use it in GitHub Desktop.
Configure the server to act as a forwarder for port 80/443 While only allowing traffic from Cloudflare IPs

Purpose:

Helps facilitate the ability to run internet facing web apps on a homelab ($desinationip) without exposing the homelab's IP address and forcing the use of CloudFlare for incoming traffic. Tunnels both incoming web traffic and outgoing traffic. Uses public cloud VPS ($serverip) as the reverse proxy and VPN.

This setup should hide the homelab's IP even in the event of compromise, end-to-end encrypt all web traffic between CloudFlare and the homelab, and prevents the proxy server from being accessed directly.

Internet --> Cloudflare (80/443) --> Cloud Provider (cloudflare-reverse-proxy.sh) --> Homelab (port forward + nginx-proxy-manager)

Homelab (all traffic) --> Cloud Provider (OpenVPN on 4443) --> Internet

  • If Homelab's IP is discovered, it will only accept traffic from the proxy server, directed at a specific domain, and that traffic will only hit the web apps if it is properly encrypted from CloudFlare.
  • If the proxy's IP is discovered, it will only accept incoming connections from HomeLab's IP on port 4443 and a managment IP on port 22. Additonally traffic sent to 80/443 will only be forwarded to the homelab if it's from CloudFlare.
  • If the Homelab web app is pwnd, all outbound connections will be forced through the proxy, hiding the homelab's location.

Prerequisites:

  • Setup $serverip OpenVPN server on port 4443
  • Setup VM's running on $destinationip to connect to $serverip OpenVPN (ideally using pfsense with killswitch). This should prevent accidental IP disclosure.
  • Setup $destinationip port 80/443 forwarding to nginx-proxy-manager, only allow from $serverip
  • Setup $destinationip nginx-proxy-manager domains and only allow access from $serverip, import Cloudflare SSL origin certs.
  • Setup cloudflare domains and point to $serverip, enable proxying and "Full Strict SSL".
  • Run the script wget https://gist.githubusercontent.com/GlitchWitch/207d18c8902fcb5e1c5f0e043f8e9101/raw/862bf56e2fe02e09f3dec22a218824990bb18079/cloudflare-reverse-proxy.sh && bash cloudflare-reverse-proxy.sh desinationip managmentip && rm cloudflare-reverse-proxy.sh

This script should do the following assuming I didn't fuck it up:

  • Blocks all incoming SSH traffic on $serverip
  • Whitelists $managmentip to access SSH port on $serverip
  • Blocks all web (80/443) traffic on $serverip
  • Forwards all web traffic (80/443) on on $serverip to $destinationip only if received from cloudflare
  • Whitelist $destinationip to access OpenVPN on $serverip
# !/bin/bash
#
# Configure server to act as a reverse proxy for port 80/443 and only allow Cloudflare IPs
# Usage: bash cloudflare-reverse-proxy.sh destinationip managmentip
# Clear existing iptables
iptables -F
# Forward traffic from Cloudflare
for i in `curl https://www.cloudflare.com/ips-v4`; do
iptables -t nat -A PREROUTING -s $i -p tcp --dport 80 -j DNAT --to-destination $1:80;
done
for i in `curl https://www.cloudflare.com/ips-v4`; do
iptables -t nat -A PREROUTING -s $i -p tcp --dport 443 -j DNAT --to-destination $1:443;
done
# Block all other web traffic
iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 80 -j DROP
iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 443 -j DROP
# Block SSH Traffic not from our Managment IP
iptables -I INPUT -p tcp -s $2 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 22 -j DROP
# Allow access to OpenVPN
iptables -I INPUT -p tcp -s $1 --dport 4443 -j ACCEPT
iptables -A INPUT -p tcp -s 0.0.0.0/0 --dport 4443 -j DROP
iptables -I INPUT -p udp -s $1 --dport 4443 -j ACCEPT
iptables -A INPUT -p udp -s 0.0.0.0/0 --dport 4443 -j DROP
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.8.0.1/24 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables -A OUTPUT -o tun+ -j ACCEPT
# Enable IP Forwarding
sysctl net.ipv4.ip_forward=1
#iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -t nat -A POSTROUTING -p tcp --dport 80 -j MASQUERADE
iptables -t nat -A POSTROUTING -p tcp --dport 443 -j MASQUERADE
@JellyVPN
Copy link

JellyVPN commented Jan 2, 2024

Thank you for your response, I just need to convert this code to UFW
iptables -t nat -A PREROUTING -s $i -p tcp --dport 443 -j DNAT --to-destination $1:443;
can you help me, please?
also, I will check Tailscale, but I"m providing VPN in restricted countries and main IP of my server will be block less than 1 hour, the only thing I can do is hiding real IP, if you help me I will so much appreciate it
thanks a lot

@GlitchWitch
Copy link
Author

I'm not sure my hackey script is really the best thing to be emulating...

This might help you with the port forwarding from one IP to another using UFW: https://www.cyberciti.biz/faq/how-to-configure-ufw-to-forward-port-80443-to-internal-server-hosted-on-lan/

Also if you haven't heard of fly.io, based on the limited info I have about what you're working on I think it might be useful for some of your project's infrastructure.

@JellyVPN
Copy link

JellyVPN commented Jan 2, 2024

thank you, Dear @GlitchWitch, I appreciate it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment