commit c37af441a9d57e6692b442109b922fb051994f1c Author: Raghav <1858838+quantumrag@users.noreply.github.com> Date: Wed Apr 15 02:28:47 2026 +0530 Add OpenVPN and cloudflared setup documentation and configs Co-Authored-By: Oz diff --git a/README.md b/README.md new file mode 100644 index 0000000..9221c16 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# OpenVPN via Cloudflare Tunnel (`vpn.bhatfamily.in`) + +This repository documents the VPN setup hosted on this machine. + +## What this provides +- OpenVPN server on this host +- Cloudflare Tunnel exposure via `vpn.bhatfamily.in` +- Client access using `cloudflared access tcp` + OpenVPN + +## Quick client connect +1. Ensure `cloudflared` and `openvpn` are installed on the client machine. +2. Use the provided client profile (`rbhat-client-cloudflared.ovpn`). +3. Update the profile remote to local forwarder: + - `remote 127.0.0.1 21194` +4. Start local forwarder: + ```bash + cloudflared access tcp --hostname vpn.bhatfamily.in --url localhost:21194 + ``` +5. In another terminal, start OpenVPN: + ```bash + sudo openvpn --config rbhat-client-cloudflared.ovpn + ``` +6. Confirm success via: + - `Initialization Sequence Completed` + +## Important +- `21194` is a **local client-side** port, not a public internet port on `vpn.bhatfamily.in`. +- If `cloudflared access tcp` fails with `address already in use`, choose another free local port and match it in the `.ovpn` `remote` line. + +## Full operational runbook +See `docs/operations.md` for: +- Service configuration details +- Firewall/NAT settings +- File paths and artifacts +- Verification and troubleshooting commands diff --git a/configs/cloudflared/config.yml b/configs/cloudflared/config.yml new file mode 100644 index 0000000..f41d5b9 --- /dev/null +++ b/configs/cloudflared/config.yml @@ -0,0 +1,14 @@ +tunnel: 6a2e99c2-ce2c-49a9-a3f2-8bf1ad3073b0 +credentials-file: /etc/cloudflared/6a2e99c2-ce2c-49a9-a3f2-8bf1ad3073b0.json + +ingress: + - hostname: web.bhatfamily.in + service: http://localhost:8080 + - hostname: ecom.bhatfamily.in + service: http://localhost:8081 + - hostname: ssh.bhatfamily.in + service: ssh://localhost:22 + - hostname: vpn.bhatfamily.in + service: tcp://localhost:1194 + - service: http_status:404 + diff --git a/configs/openvpn/server.conf b/configs/openvpn/server.conf new file mode 100644 index 0000000..08a1607 --- /dev/null +++ b/configs/openvpn/server.conf @@ -0,0 +1,27 @@ +port 1194 +proto tcp-server +dev tun +user nobody +group nogroup +persist-key +persist-tun +keepalive 10 120 +topology subnet +server 10.8.0.0 255.255.255.0 +ifconfig-pool-persist /var/log/openvpn/ipp.txt +push "redirect-gateway def1 bypass-dhcp" +push "dhcp-option DNS 1.1.1.1" +push "dhcp-option DNS 1.0.0.1" +ca /etc/openvpn/server/ca.crt +cert /etc/openvpn/server/server.crt +key /etc/openvpn/server/server.key +tls-crypt /etc/openvpn/server/tls-crypt.key +dh none +ecdh-curve prime256v1 +crl-verify /etc/openvpn/server/crl.pem +data-ciphers AES-256-GCM:AES-128-GCM +cipher AES-256-GCM +auth SHA256 +verb 3 +status /var/log/openvpn/openvpn-status.log +log-append /var/log/openvpn/openvpn.log diff --git a/configs/ufw/before.rules b/configs/ufw/before.rules new file mode 100644 index 0000000..b384dad --- /dev/null +++ b/configs/ufw/before.rules @@ -0,0 +1,80 @@ +*nat +:POSTROUTING ACCEPT [0:0] +-A POSTROUTING -s 10.8.0.0/24 -o wlp2s0 -j MASQUERADE +COMMIT + +# +# rules.before +# +# Rules that should be run before the ufw command line added rules. Custom +# rules should be added to one of these chains: +# ufw-before-input +# ufw-before-output +# ufw-before-forward +# + +# Don't delete these required lines, otherwise there will be errors +*filter +:ufw-before-input - [0:0] +:ufw-before-output - [0:0] +:ufw-before-forward - [0:0] +:ufw-not-local - [0:0] +# End required lines + + +# allow all on loopback +-A ufw-before-input -i lo -j ACCEPT +-A ufw-before-output -o lo -j ACCEPT + +# quickly process packets for which we already have a connection +-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT +-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + +# drop INVALID packets (logs these in loglevel medium and higher) +-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny +-A ufw-before-input -m conntrack --ctstate INVALID -j DROP + +# ok icmp codes for INPUT +-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT +-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT +-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT +-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT + +# ok icmp code for FORWARD +-A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT +-A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT +-A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT +-A ufw-before-forward -p icmp --icmp-type echo-request -j ACCEPT + +# allow dhcp client to work +-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT + +# +# ufw-not-local +# +-A ufw-before-input -j ufw-not-local + +# if LOCAL, RETURN +-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN + +# if MULTICAST, RETURN +-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN + +# if BROADCAST, RETURN +-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN + +# all other non-local packets are dropped +-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny +-A ufw-not-local -j DROP + +# allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above +# is uncommented) +-A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT + +# allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above +# is uncommented) +-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT + +# don't delete the 'COMMIT' line or these rules won't be processed +COMMIT diff --git a/configs/ufw/default.ufw b/configs/ufw/default.ufw new file mode 100644 index 0000000..ecec0ab --- /dev/null +++ b/configs/ufw/default.ufw @@ -0,0 +1,47 @@ +# /etc/default/ufw +# + +# Set to yes to apply rules to support IPv6 (no means only IPv6 on loopback +# accepted). You will need to 'disable' and then 'enable' the firewall for +# the changes to take affect. +IPV6=yes + +# Set the default input policy to ACCEPT, DROP, or REJECT. Please note that if +# you change this you will most likely want to adjust your rules. +DEFAULT_INPUT_POLICY="DROP" + +# Set the default output policy to ACCEPT, DROP, or REJECT. Please note that if +# you change this you will most likely want to adjust your rules. +DEFAULT_OUTPUT_POLICY="ACCEPT" + +# Set the default forward policy to ACCEPT, DROP or REJECT. Please note that +# if you change this you will most likely want to adjust your rules +DEFAULT_FORWARD_POLICY="ACCEPT" + +# Set the default application policy to ACCEPT, DROP, REJECT or SKIP. Please +# note that setting this to ACCEPT may be a security risk. See 'man ufw' for +# details +DEFAULT_APPLICATION_POLICY="SKIP" + +# By default, ufw only touches its own chains. Set this to 'yes' to have ufw +# manage the built-in chains too. Warning: setting this to 'yes' will break +# non-ufw managed firewall rules +MANAGE_BUILTINS=no + +# +# IPT backend +# +# only enable if using iptables backend +IPT_SYSCTL=/etc/ufw/sysctl.conf + +# Extra connection tracking modules to load. IPT_MODULES should typically be +# empty for new installations and modules added only as needed. See +# 'CONNECTION HELPERS' from 'man ufw-framework' for details. Complete list can +# be found in net/netfilter/Kconfig of your kernel source. Some common modules: +# nf_conntrack_irc, nf_nat_irc: DCC (Direct Client to Client) support +# nf_conntrack_netbios_ns: NetBIOS (samba) client support +# nf_conntrack_pptp, nf_nat_pptp: PPTP over stateful firewall/NAT +# nf_conntrack_ftp, nf_nat_ftp: active FTP support +# nf_conntrack_tftp, nf_nat_tftp: TFTP support (server side) +# nf_conntrack_sane: sane support +IPT_MODULES="" diff --git a/configs/ufw/sysctl.conf b/configs/ufw/sysctl.conf new file mode 100644 index 0000000..ab196be --- /dev/null +++ b/configs/ufw/sysctl.conf @@ -0,0 +1,41 @@ +# +# Configuration file for setting network variables. Please note these settings +# override /etc/sysctl.conf and /etc/sysctl.d. If you prefer to use +# /etc/sysctl.conf, please adjust IPT_SYSCTL in /etc/default/ufw. See +# Documentation/networking/ip-sysctl.txt in the kernel source code for more +# information. +# + +# Uncomment this to allow this host to route packets between interfaces +net/ipv4/ip_forward=1 +#net/ipv6/conf/default/forwarding=1 +#net/ipv6/conf/all/forwarding=1 + +# Disable ICMP redirects. ICMP redirects are rarely used but can be used in +# MITM (man-in-the-middle) attacks. Disabling ICMP may disrupt legitimate +# traffic to those sites. +net/ipv4/conf/all/accept_redirects=0 +net/ipv4/conf/default/accept_redirects=0 +net/ipv6/conf/all/accept_redirects=0 +net/ipv6/conf/default/accept_redirects=0 + +# Ignore bogus ICMP errors +net/ipv4/icmp_echo_ignore_broadcasts=1 +net/ipv4/icmp_ignore_bogus_error_responses=1 +net/ipv4/icmp_echo_ignore_all=0 + +# Don't log Martian Packets (impossible addresses) +# packets +net/ipv4/conf/all/log_martians=0 +net/ipv4/conf/default/log_martians=0 + +#net/ipv4/tcp_fin_timeout=30 +#net/ipv4/tcp_keepalive_intvl=1800 + +# Uncomment this to turn off ipv6 autoconfiguration +#net/ipv6/conf/default/autoconf=1 +#net/ipv6/conf/all/autoconf=1 + +# Uncomment this to enable ipv6 privacy addressing +#net/ipv6/conf/default/use_tempaddr=2 +#net/ipv6/conf/all/use_tempaddr=2 diff --git a/docs/operations.md b/docs/operations.md new file mode 100644 index 0000000..48ca15e --- /dev/null +++ b/docs/operations.md @@ -0,0 +1,102 @@ +# Operations Runbook: OpenVPN + Cloudflare Tunnel + +## Architecture +- OpenVPN server listens locally on TCP `1194` +- Cloudflare Tunnel ingress routes `vpn.bhatfamily.in` to `tcp://localhost:1194` +- Clients connect through local `cloudflared access tcp` forwarding, then OpenVPN to localhost + +## Service and Config Locations +- OpenVPN service: `openvpn-server@server` +- OpenVPN config: `/etc/openvpn/server/server.conf` +- PKI root: `/etc/openvpn/easy-rsa` +- Server cert/key files: `/etc/openvpn/server/` +- Cloudflared service: `cloudflared` +- Cloudflared config: `/etc/cloudflared/config.yml` +- Tunnel credentials: `/etc/cloudflared/6a2e99c2-ce2c-49a9-a3f2-8bf1ad3073b0.json` +- Tunnel ID: `6a2e99c2-ce2c-49a9-a3f2-8bf1ad3073b0` + +## OpenVPN Server Baseline +Expected key settings in `/etc/openvpn/server/server.conf`: +- `port 1194` +- `proto tcp-server` +- `dev tun` +- `server 10.8.0.0 255.255.255.0` +- `push "redirect-gateway def1 bypass-dhcp"` +- `push "dhcp-option DNS 1.1.1.1"` +- `push "dhcp-option DNS 1.0.0.1"` +- `tls-crypt /etc/openvpn/server/tls-crypt.key` +- `dh none` +- `ecdh-curve prime256v1` +- `data-ciphers AES-256-GCM:AES-128-GCM` +- `auth SHA256` + +## Cloudflared Ingress Baseline +Expected entries in `/etc/cloudflared/config.yml`: +- `vpn.bhatfamily.in -> tcp://localhost:1194` +- Existing routes: + - `web.bhatfamily.in -> http://localhost:8080` + - `ecom.bhatfamily.in -> http://localhost:8081` + - `ssh.bhatfamily.in -> ssh://localhost:22` + +## Firewall / Routing (UFW) +Expected system settings for VPN egress: +- `/etc/default/ufw` + - `DEFAULT_FORWARD_POLICY="ACCEPT"` +- `/etc/ufw/sysctl.conf` + - `net/ipv4/ip_forward=1` +- `/etc/ufw/before.rules` + - `-A POSTROUTING -s 10.8.0.0/24 -o wlp2s0 -j MASQUERADE` + +## Client Artifacts +- Generated profile: `/home/rbhat/rbhat-client-cloudflared.ovpn` +- Generated cert/key source: + - `/etc/openvpn/easy-rsa/pki/issued/rbhat-client.crt` + - `/etc/openvpn/easy-rsa/pki/private/rbhat-client.key` + +## Service Operations +Start/enable services: +```bash +sudo systemctl enable --now openvpn-server@server +sudo systemctl enable --now cloudflared +``` + +Stop/start OpenVPN only: +```bash +sudo systemctl stop openvpn-server@server +sudo systemctl start openvpn-server@server +``` + +Status checks: +```bash +systemctl is-enabled openvpn-server@server cloudflared +systemctl is-active openvpn-server@server cloudflared +sudo systemctl --no-pager status openvpn-server@server --lines=30 +sudo systemctl --no-pager status cloudflared --lines=30 +``` + +## Verification +Listener checks: +```bash +ss -tulpen | grep -E ':1194\b|:21194\b' +``` + +DNS checks: +```bash +dig +short vpn.bhatfamily.in CNAME +dig +short vpn.bhatfamily.in +``` + +OpenVPN server logs: +```bash +sudo journalctl --no-pager -u openvpn-server@server -n 120 +``` + +Cloudflared logs: +```bash +sudo journalctl --no-pager -u cloudflared -n 120 +``` + +## Troubleshooting Notes +- `cloudflared access tcp --url localhost:1194` may fail with `address already in use` if local OpenVPN server is already bound to `1194` on that machine. +- Use another local forwarder port (e.g. `21194`) and set OpenVPN client `remote 127.0.0.1 21194`. +- `vpn.bhatfamily.in:21194` is not meant to be publicly reachable; it is client-local forwarding endpoint semantics.