- Go 95.9%
- Shell 2.8%
- Makefile 0.7%
- Batchfile 0.6%
- introduced `UOQ_CLIENT_AUTH_RETRIES` to override default retry attempts - added helper function `getAuthRetries` to handle env parsing and fallback - increased default `MaxAuthRetries` from 3 to 10 |
||
|---|---|---|
| .forgejo/workflows | ||
| init | ||
| internal | ||
| .editorconfig | ||
| .gitignore | ||
| .golangci.yml | ||
| .goreleaser.yml | ||
| go.mod | ||
| go.sum | ||
| integration_test.go | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| uoq.go | ||
uoq
uoq (UDP over QUIC, pronounced OOCK) is a simple proxy that tunnels UDP packets through QUIC datagrams. It's
designed to help bypass restrictive firewalls or multiplex UDP-based services on a single port (e.g., 443) using QUIC
SNI.
Installation
go install codeberg.org/vemilyus/uoq@latest
Usage
Server
The server listens for QUIC connections and forwards received datagrams to a target UDP address.
# Using self-signed certificates
uoq server -l 4433 -r 127.0.0.1:8080 --insecure
# Using your own certificates
uoq server -l 4433 -r 127.0.0.1:8080 --cert cert.pem --key key.pem
Client
The client listens for local UDP packets and forwards them to a uoq server via QUIC.
Note
To enable SNI (Server Name Indication), use the domain name of the remote host instead of its IP address in the
-rflag.
uoq client -l 8080 -r server.example.com:443
Use --insecure with the client if the server uses a self-signed certificate.
Routing for VPNs (e.g., WireGuard)
On Linux, macOS, and Windows, a specific route to the remote server via your default gateway is added
automatically. This ensures that the QUIC packets sent by the uoq client to the remote server are not routed back into
the VPN tunnel. You can disable this behavior with the --no-auto-route flag.
On other systems, or if you prefer a manual setup, you should add a permanent route to the remote host:
# Example (Linux/macOS)
ip route add server.example.com via <default-gateway>
Advanced Use Case: Caddy + layer4
You can use uoq behind Caddy with the layer4 module
to multiplex QUIC traffic on port 443. This allows you to run uoq alongside a web server on the same port by routing
based on the Server Name Indication (SNI).
execalso requires the exec module.
{
events {
on cert_obtained exec pkill -HUP uoq
# Example reload commands for other init systems:
# systemd: exec systemctl reload uoq-server
# OpenRC: exec rc-service uoq-server reload
# FreeBSD: exec service uoq_server reload
# launchd: exec launchctl kill HUP system/com.uoq.server
# Windows: exec nssm restart uoq-server
}
layer4 {
# Listen on UDP 443
udp/:443 {
@uoq quic sni uoq.example.com
route @uoq {
proxy udp/127.0.0.1:4433
}
}
}
}
uoq.example.com {
# to have Caddy handle the certificate (ACME, etc...)
}
example.com {
# reverse proxy to something else
}
In this setup, Caddy handles the UDP/443 listener and routes traffic for uoq.example.com to the uoq server listening
on 127.0.0.1:4433. The uoq server then handles the QUIC connection and forwards the datagrams to the final target.
The events block ensures that whenever Caddy obtains or renews a certificate, it signals all uoq processes with
SIGHUP to reload their certificates.
Caddy can also handle other services (like standard HTTPS) on the same port by matching different SNIs or protocols.
Features
- High performance via QUIC datagrams.
- Authentication via pre-shared secret.
- Automatic certificate reloading.
- Minimal overhead.
Init Systems
Configuration files for various init systems (systemd, OpenRC, FreeBSD rc, launchd, and Windows NSSM) can be found in the init directory.
License
BSD 3-Clause License. See LICENSE for details.