init upload
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
.env
|
||||
client.ovpn
|
||||
.DS_Store
|
||||
@@ -0,0 +1,23 @@
|
||||
all:
|
||||
@echo "Usage: make server | make stop-server | make server-secret | make simple"
|
||||
|
||||
server:
|
||||
@cd server && docker compose up --build -d
|
||||
|
||||
stop-server:
|
||||
@cd server && docker compose down
|
||||
|
||||
clean:
|
||||
@cd server && docker compose down -v
|
||||
|
||||
server-secret:
|
||||
@cd server && printf 'Enter server secret: ' && read -r GS_SECRET && echo "GS_SECRET=$$GS_SECRET" > .env
|
||||
|
||||
ovpn:
|
||||
@docker cp gsocket-vpn:/vpn/client.ovpn . && echo 'client.ovpn saved!'
|
||||
|
||||
start:
|
||||
@cd client && sh gs-warp-simple.sh
|
||||
|
||||
stop:
|
||||
@sudo kill `cat /tmp/gswarp-ov.pid` `cat /tmp/gswarp-gs.pid` && sudo rm -f /tmp/gswarp-*.pid
|
||||
@@ -0,0 +1,108 @@
|
||||
# GS-Warp: A turnkey GSocket-tunneled VPN
|
||||
|
||||
## About
|
||||
|
||||
GS-Warp is a simple and straightforward implementation of the idea of tunneling [OpenVPN](https://openvpn.net/) traffic via [Global Socket](https://www.gsocket.io/) Relay Network (GSRN). This setup is especially suitable for installing the server side on a small VPS (Virtual Private Server) and allows you to:
|
||||
|
||||
- prevent potential eavesdroppers on your VPS traffic from knowing your real peer IP,
|
||||
- avoid provider-side blocking of your VPS,
|
||||
- staying protected in case of an (unlikely) event of compromising GSRN or GSocket encryption itself,
|
||||
- have the outgoing traffic server even behind NAT, as no external IP is required for GS-Warp to work.
|
||||
|
||||
## Dependencies
|
||||
|
||||
Server-side dependencies:
|
||||
|
||||
- full (real) root access to the server,
|
||||
- Docker (recommended),
|
||||
- OpenVPN (installed within the container),
|
||||
- GSocket (installed within the container),
|
||||
- Make (optional but recommended).
|
||||
|
||||
Client-side dependencies:
|
||||
|
||||
- any OpenVPN client,
|
||||
- GSocket,
|
||||
- Make (optional but recommended in case of using the "simple" client).
|
||||
|
||||
## Usage
|
||||
|
||||
### On the server
|
||||
|
||||
Assumes having Docker and Make. From the repo root:
|
||||
|
||||
1. Enter and save the GSocket secret: `make server-secret`
|
||||
2. Build (if necessary) and start the server: `make server`
|
||||
3. Export the `client.ovpn` file to the current directory: `make ovpn`
|
||||
4. Stop the server (without removing the data): `make stop-server`
|
||||
5. Stop the server and remove all data: `make clean`
|
||||
|
||||
### On the client ("simple" approach, Make-based)
|
||||
|
||||
1. Get the `client.ovpn` file from the server and put it into the `client` directory.
|
||||
2. Run `make start`, enter your GSocket server secret and then your sudo password (if necessary).
|
||||
3. To stop the client, run `make stop.`
|
||||
|
||||
### On the client (manual approach, POSIX)
|
||||
|
||||
1. Get the `client.ovpn` file from the server.
|
||||
2. Run these commands directly: `gs-netcat -D -s your_gsocket_secret -p 1194 && sudo openvpn --daemon gs-warp --config client.ovpn`
|
||||
3. To stop, first stop the OpenVPN process and then gs-netcat.
|
||||
|
||||
### On the client (manual approach, non-POSIX)
|
||||
|
||||
This is suitable for non-POSIX environments. You'll need any OpenVPN client and `gs-netcat` binary for your platform.
|
||||
|
||||
1. Get the `client.ovpn` file from the server and put it into your OpenVPN client's profile. Do not start the client yet.
|
||||
2. In a separate terminal window, run `gs-netcat -D -s your_gsocket_secret -p 1194`.
|
||||
3. Start the OpenVPN connection in the client.
|
||||
4. To stop, first stop the OpenVPN connection and then terminate the gs-netcat process.
|
||||
|
||||
More client options coming soon!
|
||||
|
||||
## FAQ
|
||||
|
||||
### What is the advantage of GS-Warp over a plain VPN on a VPS?
|
||||
|
||||
Potential eavesdroppers, including your own ISP, know that you're connecting to your VPS and can block/throttle this connection at will. Tunneling over GSRN hides the very fact of this connection, as well as provides an additional end-to-end encryption layer.
|
||||
|
||||
Additionally, a plain VPS requires an external IP for you to be able to connect directly. With GSRN, **both peers can be behind NAT** and this won't affect their connectivity in any way.
|
||||
|
||||
### What is the advantage of GS-Warp over plain GSRN tunneling with `gs-netcat`?
|
||||
|
||||
If you only need to have TCP connections tunneled, GS-Warp is an overkill indeed, and you can get away with setting up a SOCKS proxy like this (which even works within containers without special privileges):
|
||||
```
|
||||
# on the server side:
|
||||
gs-netcat -DlS -s [your_secret]
|
||||
|
||||
# on the client side:
|
||||
gs-netcat -D -p [your_socks_port] -s [your_secret]
|
||||
```
|
||||
|
||||
However, if you also need UDP or other IP traffic forwarded through your tunnel, you need to encapsulate it with a full VPN piped through the TCP channel established via `gs-netcat`. GS-Warp was created to facilitate just that.
|
||||
|
||||
### Can we use the GS-Warp server setup within existing containers?
|
||||
|
||||
Only if you have full root control over the host environment. Namely, you'll need to add `NET_ADMIN` and `NET_RAW` capabilities, `/dev/net/tun` device forwarding and `net.ipv4.ip_forward=1` sysctl setting.
|
||||
|
||||
### Why does GS-Warp use OpenVPN and not e.g. WireGuard or other modern alternatives?
|
||||
|
||||
Since all the end-to-end encryption and traffic masking heavy lifting is done by GSocket anyway, the choice of VPN package for IP traffic encapsulation became merely a matter of convenience. OpenVPN was selected because it has uniform configuration format across all platforms it's officially implemented on (desktop, embedded and mobile), which gives us the broadest compatibility range.
|
||||
|
||||
### I have e.g. an iPad where I can run OpenVPN but cannot run gs-netcat, what do I do?
|
||||
|
||||
Just decouple the client setup. Run gs-netcat on another device on your LAN (or even WAN) and then edit the IP in the `remote 127.0.0.1 1194` line of your `client.ovpn` config file to reflect the address of that device.
|
||||
|
||||
As a bonus, the traffic between your iPad and the node you run `gs-netcat` on will still be protected with OpenVPN encryption.
|
||||
|
||||
### What about Android?
|
||||
|
||||
On Android (at least on ARM64), you can freely run gs-netcat within Termux and then use the official OpenVPN Connect application to connect through it using the very same `client.ovpn` file. Just follow the guide above to run the correct gs-netcat command. Besides this, a dedicated Android helper application is being planned to make running a GSocket-based tunnel much easier for the average user.
|
||||
|
||||
**N.B.:** when running via Termux, don't forget to acquire the wakelock in the notification drawer for the OS to not suddenly suspend the gs-netcat process when idle.
|
||||
|
||||
## Credits
|
||||
|
||||
Created by Luxferre in 2026, released into the public domain with no warranties.
|
||||
|
||||
Thanks to Global Socket and OpenVPN projects for making this possible.
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
[ -z "$GS_SECRET" ] && GS_SECRET="$1"
|
||||
[ -z "$GS_SECRET" ] && printf 'Enter GSocket secret: ' && read -r GS_SECRET
|
||||
[ -z "$OVPNCFG" ] && OVPNCFG="$2"
|
||||
[ -z "$OVPNCFG" ] && OVPNCFG="client.ovpn"
|
||||
|
||||
GSPIDFILE='/tmp/gswarp-gs.pid'
|
||||
OVPIDFILE='/tmp/gswarp-ov.pid'
|
||||
|
||||
BEFORE_PIDS=$(pgrep -x gs-netcat 2>/dev/null)
|
||||
gs-netcat -D -s "$GS_SECRET" -p 1194
|
||||
sleep 0.5
|
||||
AFTER_PIDS=$(pgrep -x gs-netcat 2>/dev/null)
|
||||
|
||||
if [ -n "$BEFORE_PIDS" ]; then
|
||||
echo "$AFTER_PIDS" | grep -v -F -x "$BEFORE_PIDS" > "$GSPIDFILE"
|
||||
else
|
||||
echo "$AFTER_PIDS" > "$GSPIDFILE"
|
||||
fi
|
||||
|
||||
sudo openvpn --daemon gs-warp --config "$OVPNCFG" --writepid "$OVPIDFILE"
|
||||
|
||||
echo 'GS-Warp started'
|
||||
@@ -0,0 +1,26 @@
|
||||
FROM debian:trixie-slim
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install OpenVPN, OpenSSL, IPTables, GSocket and networking utilities
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
openvpn \
|
||||
openssl \
|
||||
iptables \
|
||||
iproute2 \
|
||||
curl \
|
||||
ca-certificates \
|
||||
procps \
|
||||
gsocket \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# FIX: Switch default iptables engine to legacy mode to bypass container nf_tables restriction
|
||||
RUN update-alternatives --set iptables /usr/sbin/iptables-legacy && \
|
||||
update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
|
||||
|
||||
WORKDIR /vpn
|
||||
|
||||
COPY entrypoint.sh /vpn/entrypoint.sh
|
||||
RUN chmod +x /vpn/entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/vpn/entrypoint.sh"]
|
||||
@@ -0,0 +1,22 @@
|
||||
services:
|
||||
gsocket-vpn:
|
||||
build: .
|
||||
container_name: gsocket-vpn
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- GS_SECRET=${GS_SECRET}
|
||||
dns:
|
||||
- 1.1.1.1
|
||||
- 8.8.8.8
|
||||
cap_add:
|
||||
- NET_ADMIN
|
||||
- NET_RAW
|
||||
devices:
|
||||
- /dev/net/tun:/dev/net/tun
|
||||
sysctls:
|
||||
- net.ipv4.ip_forward=1
|
||||
volumes:
|
||||
- vpn-data:/vpn
|
||||
|
||||
volumes:
|
||||
vpn-data:
|
||||
@@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if [ -z "$GS_SECRET" ]; then
|
||||
echo "[!] ERROR: GS_SECRET environment variable is missing."
|
||||
echo " Please start the container with -e GS_SECRET=\"your_secret_key\""
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure TUN device node exists in container namespace
|
||||
if [ ! -c /dev/net/tun ]; then
|
||||
mkdir -p /dev/net
|
||||
mknod /dev/net/tun c 10 200
|
||||
chmod 600 /dev/net/tun
|
||||
fi
|
||||
|
||||
# Force public DNS resolvers inside container for GSocket relay lookup
|
||||
echo "nameserver 1.1.1.1" > /etc/resolv.conf
|
||||
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
|
||||
|
||||
# 1. Generate Certificates & OpenVPN Configs (OpenSSL 3.x compliant)
|
||||
if [ ! -f /vpn/server.conf ]; then
|
||||
echo "[+] Generating OpenSSL 3.x compliant SSL/TLS Certificates..."
|
||||
|
||||
# A. Generate CA
|
||||
openssl req -x509 -newkey rsa:2048 -nodes \
|
||||
-keyout /vpn/ca.key -out /vpn/ca.crt -days 3650 \
|
||||
-subj "/CN=GSocket-CA" \
|
||||
-addext "basicConstraints=critical,CA:TRUE" \
|
||||
-addext "keyUsage=critical,keyCertSign,cRLSign" >/dev/null 2>&1
|
||||
|
||||
# B. Generate Server Cert
|
||||
cat <<EOF > /vpn/server_ext.cnf
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = serverAuth
|
||||
subjectAltName = DNS:gsocket, IP:127.0.0.1
|
||||
EOF
|
||||
|
||||
openssl req -newkey rsa:2048 -nodes -keyout /vpn/server.key -out /vpn/server.csr -subj "/CN=GSocket-Server" >/dev/null 2>&1
|
||||
openssl x509 -req -in /vpn/server.csr -CA /vpn/ca.crt -CAkey /vpn/ca.key -CAcreateserial \
|
||||
-out /vpn/server.crt -days 3650 -extfile /vpn/server_ext.cnf >/dev/null 2>&1
|
||||
|
||||
# C. Generate Client Cert
|
||||
cat <<EOF > /vpn/client_ext.cnf
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = digitalSignature
|
||||
extendedKeyUsage = clientAuth
|
||||
EOF
|
||||
|
||||
openssl req -newkey rsa:2048 -nodes -keyout /vpn/client.key -out /vpn/client.csr -subj "/CN=GSocket-Client" >/dev/null 2>&1
|
||||
openssl x509 -req -in /vpn/client.csr -CA /vpn/ca.crt -CAkey /vpn/ca.key -CAcreateserial \
|
||||
-out /vpn/client.crt -days 3650 -extfile /vpn/client_ext.cnf >/dev/null 2>&1
|
||||
|
||||
# D. Generate TLS-Crypt Key
|
||||
openvpn --genkey secret /vpn/tls-crypt.key
|
||||
|
||||
# E. OpenVPN Server Config (uses 'topology subnet' & 'redirect-gateway local')
|
||||
cat <<EOF > /vpn/server.conf
|
||||
dev tun
|
||||
topology subnet
|
||||
ca /vpn/ca.crt
|
||||
cert /vpn/server.crt
|
||||
key /vpn/server.key
|
||||
dh none
|
||||
ecdh-curve prime256v1
|
||||
tls-crypt /vpn/tls-crypt.key
|
||||
server 10.8.0.0 255.255.255.0
|
||||
push "redirect-gateway def1 local bypass-dhcp"
|
||||
push "dhcp-option DNS 1.1.1.1"
|
||||
push "dhcp-option DNS 8.8.8.8"
|
||||
keepalive 10 60
|
||||
cipher AES-256-GCM
|
||||
data-ciphers AES-256-GCM:AES-128-GCM
|
||||
persist-key
|
||||
persist-tun
|
||||
tun-mtu 1300
|
||||
mssfix 1200
|
||||
EOF
|
||||
|
||||
# F. Unified Client Config (Embedded relay routes via net_gateway)
|
||||
cat <<EOF > /vpn/client.ovpn
|
||||
client
|
||||
dev tun
|
||||
proto tcp-client
|
||||
remote 127.0.0.1 1194
|
||||
resolv-retry infinite
|
||||
nobind
|
||||
persist-key
|
||||
persist-tun
|
||||
remote-cert-tls server
|
||||
cipher AES-256-GCM
|
||||
tun-mtu 1300
|
||||
mssfix 1200
|
||||
|
||||
# Native OpenVPN routes to bypass GSocket relay nodes via physical default gateway
|
||||
route j.gs.thc.org 255.255.255.255 net_gateway
|
||||
route a.gs.thc.org 255.255.255.255 net_gateway
|
||||
route b.gs.thc.org 255.255.255.255 net_gateway
|
||||
route c.gs.thc.org 255.255.255.255 net_gateway
|
||||
route g.gs.thc.org 255.255.255.255 net_gateway
|
||||
|
||||
<ca>
|
||||
$(cat /vpn/ca.crt)
|
||||
</ca>
|
||||
<cert>
|
||||
$(cat /vpn/client.crt)
|
||||
</cert>
|
||||
<key>
|
||||
$(cat /vpn/client.key)
|
||||
</key>
|
||||
<tls-crypt>
|
||||
$(cat /vpn/tls-crypt.key)
|
||||
</tls-crypt>
|
||||
EOF
|
||||
|
||||
echo "[+] Client config generated at /vpn/client.ovpn"
|
||||
fi
|
||||
|
||||
# 2. Configure Networking & IPTables inside Container
|
||||
WAN_IF=$(ip route show default | awk '/default/ {print $5}' | head -n1)
|
||||
echo "[+] Container WAN Interface detected: $WAN_IF"
|
||||
|
||||
if [ "$(cat /proc/sys/net/ipv4/ip_forward 2>/dev/null)" = "1" ]; then
|
||||
echo "[+] IPv4 forwarding is active."
|
||||
else
|
||||
echo "[!] WARNING: IPv4 forwarding is not active in this container!"
|
||||
fi
|
||||
|
||||
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter 2>/dev/null || true
|
||||
echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter 2>/dev/null || true
|
||||
|
||||
iptables -F
|
||||
iptables -t nat -F
|
||||
|
||||
iptables -A INPUT -i tun+ -j ACCEPT
|
||||
iptables -A OUTPUT -o tun+ -j ACCEPT
|
||||
iptables -A FORWARD -i tun+ -j ACCEPT
|
||||
iptables -A FORWARD -o tun+ -j ACCEPT
|
||||
|
||||
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
|
||||
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1200
|
||||
|
||||
# 3. Start OpenVPN daemon
|
||||
echo "[+] Starting local OpenVPN daemon on 127.0.0.1:1194..."
|
||||
openvpn --config /vpn/server.conf \
|
||||
--proto tcp4-server \
|
||||
--local 127.0.0.1 \
|
||||
--lport 1194 &
|
||||
|
||||
sleep 2
|
||||
|
||||
# 4. Forward GSocket stream directly to 127.0.0.1:1194
|
||||
echo "[+] Starting gs-netcat port forwarder..."
|
||||
exec gs-netcat -s "$GS_SECRET" -l -d 127.0.0.1 -p 1194
|
||||
Reference in New Issue
Block a user