mirror of
https://github.com/fosrl/gerbil.git
synced 2026-02-08 05:56:40 +00:00
Merge branch 'dev' of https://github.com/fosrl/gerbil into dev
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1 +1,3 @@
|
||||
gerbil
|
||||
.DS_Store
|
||||
bin/
|
||||
@@ -18,6 +18,8 @@ RUN CGO_ENABLED=0 GOOS=linux go build -o /gerbil
|
||||
# Start a new stage from scratch
|
||||
FROM ubuntu:22.04 AS runner
|
||||
|
||||
RUN apt-get update && apt-get install -y iptables iproute2 && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy the pre-built binary file from the previous stage and the entrypoint script
|
||||
COPY --from=builder /gerbil /usr/local/bin/
|
||||
COPY entrypoint.sh /
|
||||
|
||||
4
Makefile
4
Makefile
@@ -21,7 +21,11 @@ test:
|
||||
local:
|
||||
CGO_ENABLED=0 GOOS=linux go build -o gerbil
|
||||
|
||||
<<<<<<< HEAD
|
||||
go-build-release:
|
||||
=======
|
||||
release:
|
||||
>>>>>>> bab8630756f5b243feec8a9e8952086498808a11
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o bin/gerbil_linux_arm64
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o bin/gerbil_linux_amd64
|
||||
|
||||
|
||||
101
main.go
101
main.go
@@ -9,6 +9,7 @@ import (
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -188,12 +189,18 @@ func main() {
|
||||
wgconfig.PrivateKey = key.String()
|
||||
}
|
||||
} else {
|
||||
// loop until we get the config
|
||||
for wgconfig.PrivateKey == "" {
|
||||
logger.Info("Fetching remote config from %s", remoteConfigURL)
|
||||
wgconfig, err = loadRemoteConfig(remoteConfigURL, key, reachableAt)
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to load configuration: %v", err)
|
||||
logger.Error("Failed to load configuration: %v", err)
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
}
|
||||
wgconfig.PrivateKey = key.String()
|
||||
}
|
||||
}
|
||||
|
||||
wgClient, err = wgctrl.New()
|
||||
if err != nil {
|
||||
@@ -338,6 +345,10 @@ func ensureWireguardInterface(wgconfig WgConfig) error {
|
||||
return fmt.Errorf("failed to bring up interface: %v", err)
|
||||
}
|
||||
|
||||
if err := ensureMSSClamping(); err != nil {
|
||||
logger.Warn("Failed to ensure MSS clamping: %v", err)
|
||||
}
|
||||
|
||||
logger.Info("WireGuard interface %s created and configured", interfaceName)
|
||||
|
||||
return nil
|
||||
@@ -415,6 +426,94 @@ func ensureWireguardPeers(peers []Peer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ensureMSSClamping() error {
|
||||
// Calculate MSS value (MTU - 40 for IPv4 header (20) and TCP header (20))
|
||||
mssValue := mtuInt - 40
|
||||
|
||||
// Rules to be managed - just the chains, we'll construct the full command separately
|
||||
chains := []string{"INPUT", "OUTPUT", "FORWARD"}
|
||||
|
||||
// First, try to delete any existing rules
|
||||
for _, chain := range chains {
|
||||
deleteCmd := exec.Command("/usr/sbin/iptables",
|
||||
"-t", "mangle",
|
||||
"-D", chain,
|
||||
"-p", "tcp",
|
||||
"--tcp-flags", "SYN,RST", "SYN",
|
||||
"-j", "TCPMSS",
|
||||
"--set-mss", fmt.Sprintf("%d", mssValue))
|
||||
|
||||
logger.Info("Attempting to delete existing MSS clamping rule for chain %s", chain)
|
||||
|
||||
// Try deletion multiple times to handle multiple existing rules
|
||||
for i := 0; i < 3; i++ {
|
||||
out, err := deleteCmd.CombinedOutput()
|
||||
if err != nil {
|
||||
// Convert exit status 1 to string for better logging
|
||||
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||
logger.Debug("Deletion stopped for chain %s: %v (output: %s)",
|
||||
chain, exitErr.String(), string(out))
|
||||
}
|
||||
break // No more rules to delete
|
||||
}
|
||||
logger.Info("Deleted MSS clamping rule for chain %s (attempt %d)", chain, i+1)
|
||||
}
|
||||
}
|
||||
|
||||
// Then add the new rules
|
||||
var errors []error
|
||||
for _, chain := range chains {
|
||||
addCmd := exec.Command("/usr/sbin/iptables",
|
||||
"-t", "mangle",
|
||||
"-A", chain,
|
||||
"-p", "tcp",
|
||||
"--tcp-flags", "SYN,RST", "SYN",
|
||||
"-j", "TCPMSS",
|
||||
"--set-mss", fmt.Sprintf("%d", mssValue))
|
||||
|
||||
logger.Info("Adding MSS clamping rule for chain %s", chain)
|
||||
|
||||
if out, err := addCmd.CombinedOutput(); err != nil {
|
||||
errMsg := fmt.Sprintf("Failed to add MSS clamping rule for chain %s: %v (output: %s)",
|
||||
chain, err, string(out))
|
||||
logger.Error(errMsg)
|
||||
errors = append(errors, fmt.Errorf(errMsg))
|
||||
continue
|
||||
}
|
||||
|
||||
// Verify the rule was added
|
||||
checkCmd := exec.Command("/usr/sbin/iptables",
|
||||
"-t", "mangle",
|
||||
"-C", chain,
|
||||
"-p", "tcp",
|
||||
"--tcp-flags", "SYN,RST", "SYN",
|
||||
"-j", "TCPMSS",
|
||||
"--set-mss", fmt.Sprintf("%d", mssValue))
|
||||
|
||||
if out, err := checkCmd.CombinedOutput(); err != nil {
|
||||
errMsg := fmt.Sprintf("Rule verification failed for chain %s: %v (output: %s)",
|
||||
chain, err, string(out))
|
||||
logger.Error(errMsg)
|
||||
errors = append(errors, fmt.Errorf(errMsg))
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Info("Successfully added and verified MSS clamping rule for chain %s", chain)
|
||||
}
|
||||
|
||||
// If we encountered any errors, return them combined
|
||||
if len(errors) > 0 {
|
||||
var errMsgs []string
|
||||
for _, err := range errors {
|
||||
errMsgs = append(errMsgs, err.Error())
|
||||
}
|
||||
return fmt.Errorf("MSS clamping setup encountered errors:\n%s",
|
||||
strings.Join(errMsgs, "\n"))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func handlePeer(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.Method {
|
||||
case http.MethodPost:
|
||||
|
||||
Reference in New Issue
Block a user