Rename the project to ihasvpn

WGX shares its name with several other WireGuard tools, so the project
becomes ihasvpn, alongside ihasmail.

- Module github.com/Coffey-Labs/ihasvpn, command cmd/ihasvpn, image
  ghcr.io/coffey-labs/ihasvpn.
- Environment variables move from WGX_* to IHASVPN_*. The default database
  is ihasvpn.db, the nftables table is `ihasvpn`, metrics are ihasvpn_*, and
  the session cookie and theme key are renamed, so existing sessions end.
- The mark is the ihasmail cat peeking over the edge of a shield, drawn as
  a vector. docs/brand/generate.py builds the mark, mono mark, wordmarks,
  social card, favicons and app icons from that one drawing.
- The console takes ihasmail's palette: the ihasmail.org teal-navy for dark,
  its contrast-checked light tiers with the site's light accent, received
  traffic in the cat's orange and sent in teal. The wordmark weight and
  font stack follow ihasmail.org.
- Detail values wrap at spaces before breaking inside an address, so an
  IPv6 tunnel address no longer splits mid-number.
- The README history note about the earlier WGX installer is gone with the
  name it explained. Screenshots retaken.
This commit is contained in:
2026-09-12 23:48:36 -07:00
parent e807896806
commit 02e7993c87
74 changed files with 529 additions and 369 deletions
+5 -5
View File
@@ -12,7 +12,7 @@ import (
"strings"
)
// Rules describes the firewall WGX wants.
// Rules describes the firewall ihasvpn wants.
type Rules struct {
// Iface is the WireGuard interface name, e.g. wg0.
Iface string
@@ -31,7 +31,7 @@ type Rules struct {
// "the VPN connects but websites hang".
ClampMSS bool
// Table names the nftables table, so a host with its own rules never
// collides with ours. Defaults to "wgx".
// collides with ours. Defaults to "ihasvpn".
Table string
}
@@ -40,7 +40,7 @@ type Rules struct {
func Ruleset(r Rules) string {
table := r.Table
if table == "" {
table = "wgx"
table = "ihasvpn"
}
var b strings.Builder
fmt.Fprintf(&b, "table inet %s\n", table)
@@ -88,10 +88,10 @@ func Apply(ctx context.Context, r Rules) error {
return runNFT(ctx, Ruleset(r))
}
// Remove deletes the WGX table, ignoring the case where it is already gone.
// Remove deletes the ihasvpn table, ignoring the case where it is already gone.
func Remove(ctx context.Context, table string) error {
if table == "" {
table = "wgx"
table = "ihasvpn"
}
script := fmt.Sprintf("table inet %s\ndelete table inet %s\n", table, table)
return runNFT(ctx, script)
+1 -1
View File
@@ -17,7 +17,7 @@ func TestRuleset(t *testing.T) {
}
out := Ruleset(r)
for _, want := range []string{
"table inet wgx {",
"table inet ihasvpn {",
"udp dport 51820 accept",
`iifname "wg0" oifname "wg0" drop`,
`tcp option maxseg size set rt mtu`,
+2 -2
View File
@@ -7,7 +7,7 @@ import (
"strings"
)
// Sysctl is one kernel parameter and the value WGX wants for it.
// Sysctl is one kernel parameter and the value ihasvpn wants for it.
type Sysctl struct {
Key string
Value string
@@ -27,7 +27,7 @@ type Result struct {
Err string
}
// Wanted returns the sysctls WGX applies at startup, in order.
// Wanted returns the sysctls ihasvpn applies at startup, in order.
func Wanted(ipv6 bool) []Sysctl {
s := []Sysctl{
{Key: "net.ipv4.ip_forward", Value: "1", Required: true, Why: "peers cannot reach anything beyond the server without forwarding"},