A soft-fork of Gitea with built-in support for running as an I2P (Invisible Internet Project) service. This project provides network implementation files and CI configuration to build Gitea with I2P support.
Go-Gittisane enables you to run the Gitea git server with anonymity features through the I2P network. All HTTP traffic - both incoming requests to your Gitea instance and outgoing requests from it - are routed through I2P, providing privacy and censorship resistance.
Go-Gittisane leverages Gitea’s modular network architecture to replace the standard TCP/IP networking with I2P connectivity:
Network Module Substitution: Gitea encapsulates its network operations in the graceful
package. By providing alternative implementations of key functions like GetListener()
, we can redirect all network traffic through I2P.
net_anon.go
, which uses the github.com/go-i2p/onramp
library to establish I2P connectivity. This file:
GetListener
function that returns I2P listenersnet_anon_unix.go
and net_anon_windows.go
.This repository contains a GitHub Actions workflow that:
The core networking modification looks like this:
// This file gets copied to modules/graceful/net_anon.go during build
package graceful
import (
"net"
"net/http"
"github.com/go-i2p/onramp"
)
// Set up I2P connectivity
var garlic, i2perr = onramp.NewGarlic("gitea-anon", "127.0.0.1:7656", onramp.OPT_DEFAULTS)
// Custom implementation of GetListener for I2P
func I2PGetListener(network, address string) (net.Listener, error) {
defer GetManager().InformCleanup()
switch network {
case "tcp", "tcp4", "tcp6", "i2p", "i2pt":
return garlic.Listen()
case "unix", "unixpacket":
// Unix sockets handled normally
unixAddr, err := ResolveUnixAddr(network, address)
if err != nil {
return nil, err
}
return GetListenerUnixWrapper(network, unixAddr)
default:
return nil, net.UnknownNetworkError(network)
}
}
// Initialize everything at runtime
func init() {
if i2perr != nil {
panic(i2perr)
}
GetListener = I2PGetListener
httpClient := &http.Client{
Transport: &http.Transport{
Dial: garlic.Dial,
},
}
http.DefaultClient = httpClient
http.DefaultTransport = httpClient.Transport
}
While HTTP traffic is anonymized, other types of connections might not be:
These limitations can be addressed with additional configuration but are beyond the scope of the default implementation.
Both this modification and Gitea are licensed under the MIT license.
Contributions are welcome! Please feel free to submit a Pull Request.