many new containers. work in progress

This commit is contained in:
Jeff Clement 2024-11-02 14:09:56 -06:00
parent f0f9f608cc
commit aed48ffdf8
Signed by: jeff
GPG key ID: 3BCB43A3F0E1D7DA
31 changed files with 1042 additions and 1 deletions

41
diy-tunnel/README.md Normal file
View file

@ -0,0 +1,41 @@
# DIY Tunnel
I **love** Cloudflare Tunnels and routinely use them to expose my self-hosted services to the Internet. However, there are a couple of limitations that make them less than ideal for some use-cases.
1. They work best with HTTP/HTTPS services. Other services like SSH / rando-TCP-service require the *clients* to run `cloudflared`. This prevents running public-facing non-HTTP services via. Cloudflare Tunnels.
2. Cloudflare is the *man-in-the-middle*. They manage the TLS certificates and, were they evil, they could inspect traffic.
This folder has some sample wireguard configuration to allow a cheap cloud-VPS to forward traffic through a wireguard tunnel to a private server.
* The VPS does not own/manage TLS certificates or any data.
* It supports any TCP services
* The connection is made from the private server to the public VPS, so only the VPS requires a static IP. The private server can hide behind a VPN and move networks with impunity.
* Through some network trickery, packets are forwarded from the VPS to the private server. The implication is that the private server sees the actual source IPs for the traffic which allows things like fail2ban to work appropriately.
Requirements:
1. One public facing machine (like a VPS) with a static IPv4 address
2. One private machine running your services
3. Wireguard installed on each (`apt install wireguard` for you Debian/Ubuntu folks)
Steps:
1. Generate keys for both the public and private server.
1. `wg genkey | tee privatekey | wg pubkey > publickey`
2. Copy `private/wg0.conf` to `/etc/wireguard/wg0.conf` on your private server.
* Update the ports `80,443` to be whatever ports you want to pass through.
* Add the private key for the public server, and the public key for the private server.
3. Copy `public/???/wg0.conf` to `/etc/wireguard/wg0.conf` on your public server.
* Update the ports `80,443` to be whatever ports you want to pass through.
* Add the private key for the private server, and the public key for the public server.
* Update the public IP for the public server (replace all 999.999.999.999) with your VPS IP
4. Start wireguard on each machine: `wg-quick wg0 up`
5. Enable wireguard on boot on each machine: `sudo systemctl enable wg-quick@wg0`
## Testing:
1. From public server, can ping private IP `ping 10.0.0.2`
2. From private server, can ping public IP `ping 10.0.0.1`
3. Run a webserver on the private server...
1. From public server: `curl http://10.0.0.2` should work
2. From workstation: `curl http://publicIP` should work
3. From the private server: `curl http://publicIP` should also work
That's about it.

View file

@ -0,0 +1 @@
`wg0.conf` should be deployed to `/etc/wireguard/wg0.conf` on the public facing (VPS) server.

View file

@ -0,0 +1,15 @@
[Interface]
Address = 10.0.0.1/24 # Private IP for the VPS in the VPN network
ListenPort = 51820 # Default WireGuard port
PrivateKey = ###PRIVATE KEY FOR PUBLIC SERVER####
# packet forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
# port forwarding (HTTP, HTTPS) - update port list as required
PreUp = iptables -t nat -A PREROUTING -i eth0 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 10.0.0.2
PostDown = iptables -t nat -D PREROUTING -i eth0 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 10.0.0.2
[Peer]
PublicKey = ###PUBLIC KEY FOR PRIVATE SERVER####
AllowedIPs = 10.0.0.2/32 # IP of the home server in VPN

View file

@ -0,0 +1 @@
Another nice option is instead of installing wireguard on the bare machine, we can fire it up within our existing `docker-compose.yml` and easily expose services from a set of docker containers.

View file

@ -0,0 +1,27 @@
services:
wireguard:
image: lscr.io/linuxserver/wireguard:latest
hostname: THEPRIVATESERVER
cap_add:
- NET_ADMIN
environment:
- TZ=America/Edmonton
volumes:
- ./wg0.conf:/config/wg_confs/wg0.conf
restart: always
sysctls:
- net.ipv4.ip_forward=1
caddy:
image: caddy:latest
restart: always
# this is the special sauce. This attaches this container to the
# network context of the wireguard container. Essentially this means
# that Caddy is listening on 10.0.0.2 now.
# If you have other containers exposing additional ports, do the same to them.
network_mode: service:wireguard
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile # Mount Caddyfile for configuration
- ./webroot:/srv/www # Mount local www directory to container
- ./data/caddy:/data/caddy # Persistent storage for certificates

View file

@ -0,0 +1,13 @@
[Interface]
Address = 10.0.0.2/24 # Private IP for the home server in the VPN network
PrivateKey = #### PRIVATE KEY OF PRIVATE SERVER ####
Table = 123
PreUp = ip rule add from 10.0.0.2 table 123 priority 1
PostDown = ip rule del from 10.0.0.2 table 123 priority 1
[Peer]
PublicKey = #### PUBLIC KEY OF PUBLIC SERVER ####
AllowedIPs = 0.0.0.0/0
Endpoint = 999.999.999.999:51820
PersistentKeepalive = 25

View file

@ -0,0 +1,3 @@
Copy `wg0.conf` to `/etc/wireguard/wg0.config`
This example is for wireguard running on the private server and forwarding traffic to local services AND docker services.

View file

@ -0,0 +1,46 @@
[Interface]
Address = 10.0.0.2/24 # Private IP for the home server in the VPN network
PrivateKey = #### PRIVATE KEY OF PRIVATE SERVER #####
Table = 123
# Enable IP forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
# loose reverse path forwarding validation
PostUp = sysctl -w net.ipv4.conf.wg0.rp_filter=2
# Mark new connections coming in through wg0
PreUp = iptables -t mangle -A PREROUTING -i wg0 -m state --state NEW -j CONNMARK --set-mark 1
PostDown = iptables -t mangle -D PREROUTING -i wg0 -m state --state NEW -j CONNMARK --set-mark 1
# Mark return packets to go out through WireGuard via policy routing
PreUp = iptables -t mangle -A PREROUTING ! -i wg0 -m connmark --mark 1 -j MARK --set-mark 1
PostDown = iptables -t mangle -D PREROUTING ! -i wg0 -m connmark --mark 1 -j MARK --set-mark 1
# Push marked connections back through wg0
PreUp = ip rule add fwmark 1 table 123 priority 456
PostDown = ip rule del fwmark 1 table 123 priority 456
# Route traffic to public IP to self to avoid it hitting the network
PreUp = iptables -t nat -A OUTPUT -d 999.999.999.999 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 127.0.0.1
PostDown = iptables -t nat -D OUTPUT -d 999.999.999.999 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 127.0.0.1
# ==== Firewall ===============================
# Allow our expected traffic
PreUp = iptables -A INPUT -i wg0 -p tcp -m multiport --dports 80,443 -j ACCEPT
PostDown = iptables -D INPUT -i wg0 -p tcp -m multiport --dports 80,443 -j ACCEPT
# And pings
PreUp = iptables -A INPUT -i wg0 -p icmp --icmp-type echo-request -j ACCEPT
PostDown = iptables -D INPUT -i wg0 -p icmp --icmp-type echo-request -j ACCEPT
# Block the rest
PreUp = iptables -A INPUT -i wg0 -j DROP
PostDown = iptables -D INPUT -i wg0 -j DROP
[Peer]
PublicKey = #### PUBLIC KEY OF PUBLIC SERVER #####
AllowedIPs = 0.0.0.0/0
Endpoint = 999.999.999.999:51820
PersistentKeepalive = 25

View file

@ -0,0 +1,3 @@
Copy `wg0.conf` to `/etc/wireguard/wg0.config`
This example works well for forwarding traffic to services running directly on the private server. If your services are running in Docker things get much more complicated because of how Docker handle networking. For that, see the `/public/docker` example.

View file

@ -0,0 +1,35 @@
[Interface]
Address = 10.0.0.2/24 # Private IP for the home server in the VPN network
PrivateKey = #### PRIVATE KEY OF PRIVATE SERVER #####
Table = 123
# Enable IP forwarding
PreUp = sysctl -w net.ipv4.ip_forward=1
# Return traffic through wireguard
PreUp = ip rule add from 10.0.0.2 table 123 priority 1
PostDown = ip rule del from 10.0.0.2 table 123 priority 1
# Route traffic to public IP to self to avoid it hitting the network
PreUp = iptables -t nat -A OUTPUT -d 999.999.999.999 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 127.0.0.1
PostDown = iptables -t nat -D OUTPUT -d 999.999.999.999 -p tcp -m multiport --dports 80,443 -j DNAT --to-destination 127.0.0.1
# ==== Firewall ===============================
# Allow our expected traffic
PreUp = iptables -A INPUT -i wg0 -p tcp -m multiport --dports 80,443 -j ACCEPT
PostDown = iptables -D INPUT -i wg0 -p tcp -m multiport --dports 80,443 -j ACCEPT
# And pings
PreUp = iptables -A INPUT -i wg0 -p icmp --icmp-type echo-request -j ACCEPT
PostDown = iptables -D INPUT -i wg0 -p icmp --icmp-type echo-request -j ACCEPT
# Block the rest
PreUp = iptables -A INPUT -i wg0 -j DROP
PostDown = iptables -D INPUT -i wg0 -j DROP
[Peer]
PublicKey = #### PUBLIC KEY OF PUBLIC SERVER #####
AllowedIPs = 0.0.0.0/0
Endpoint = 999.999.999.999:51820
PersistentKeepalive = 25