Add OpenVPN and cloudflared setup documentation and configs
Co-Authored-By: Oz <oz-agent@warp.dev>
This commit is contained in:
35
README.md
Normal file
35
README.md
Normal file
@ -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
|
||||||
14
configs/cloudflared/config.yml
Normal file
14
configs/cloudflared/config.yml
Normal file
@ -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
|
||||||
|
|
||||||
27
configs/openvpn/server.conf
Normal file
27
configs/openvpn/server.conf
Normal file
@ -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
|
||||||
80
configs/ufw/before.rules
Normal file
80
configs/ufw/before.rules
Normal file
@ -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
|
||||||
47
configs/ufw/default.ufw
Normal file
47
configs/ufw/default.ufw
Normal file
@ -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=""
|
||||||
41
configs/ufw/sysctl.conf
Normal file
41
configs/ufw/sysctl.conf
Normal file
@ -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
|
||||||
102
docs/operations.md
Normal file
102
docs/operations.md
Normal file
@ -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.
|
||||||
Reference in New Issue
Block a user