mirror of
https://github.com/go-i2p/go-gitlooseleaf.git
synced 2025-07-13 11:54:37 -04:00
Merge branch 'main' of github.com:go-i2p/go-gitlooseleaf
This commit is contained in:
129
README.md
129
README.md
@ -1,80 +1,87 @@
|
||||
# go-gitlooseleaf
|
||||
A soft-fork of gitea with support for running as a multi-protocol service. Just the mod and the CI files.
|
||||
|
||||
How it works:
|
||||
=============
|
||||
A soft-fork of Gitea that enables simultaneous multi-protocol access via standard TLS, I2P, and Tor onion services. This repository contains only the network interface modules and CI configuration needed to build custom Gitea binaries.
|
||||
|
||||
This uses GitHub CI to continuously build a version of Gitea that can simultaneously run as a regular TLS service, an I2P service, and a Tor onion service, based on the latest release of Gitea.
|
||||
We can do this without requiring a patch to the Gitea source code.
|
||||
This is because Gitea encapsulates its "Listening" and "Dialing" into functions, which can easily be substituted for alternative versions.
|
||||
For instance, the network listener is set up by a function, `graceful.GetListener() (net.Listener, error)` in the file `modules/graceful/server.go`.
|
||||
The default implementation of the `GetListener() (net.Listener, error)` function, `DefaultGetListener() (net.Listener, error)` is defined in the `modules/graceful/net_unix.go` for Unix-like systems and `modules/graceful/net_windows.go` for Windows-like systems.
|
||||
A developer who wishes to "Mod" gitea to listen on another kind of connection do so by creating a new file which implements a `GetListener() (net.Listener, error)` function using alternate listener implementations.
|
||||
## How It Works
|
||||
|
||||
On the client side, the same thing is possible because Go allows you to substitute the underlying transports used for the default HTTP Client.
|
||||
So, in the absence of overriding settings, we can configure it to use TLS, SAMv3 (for I2P), and the Tor SOCKS proxy to build HTTP connections using the appropriate transport for each service.
|
||||
This project leverages GitHub Actions to automatically build a modified version of Gitea that can simultaneously serve content over multiple protocols:
|
||||
- Standard HTTPS/TLS connections
|
||||
- I2P (Invisible Internet Project) network
|
||||
- Tor onion services
|
||||
|
||||
Finally, if you need to include additional libraries, run `go mod tidy` in the root of the gitea checkout to include them.
|
||||
The beauty of this approach is that it requires no changes to Gitea's core codebase, as Gitea intelligently encapsulates network operations through abstraction:
|
||||
|
||||
Here is a complete working example mod:
|
||||
1. **Network Listeners**: Gitea uses `graceful.GetListener()` (defined in `modules/graceful/server.go`) for all incoming connections
|
||||
2. **Network Clients**: Gitea's HTTP client connections can be configured with custom transport implementations
|
||||
|
||||
```Go
|
||||
// copy this file to modules/graceful/net_multi.go before building gitea
|
||||
package graceful
|
||||
We take advantage of these abstractions by replacing the default implementations with our multi-protocol versions during the build process.
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
## Implementation Details
|
||||
|
||||
"github.com/go-i2p/onramp"
|
||||
"github.com/cretz/bine/tor"
|
||||
)
|
||||
The network listener replacement works because Gitea's default `GetListener()` implementations (`DefaultGetListener()`) are defined in platform-specific files:
|
||||
- `modules/graceful/net_unix.go` for Unix-like systems
|
||||
- `modules/graceful/net_windows.go` for Windows
|
||||
|
||||
// Set up the I2P Garlic API
|
||||
var garlic, i2perr = onramp.NewGarlic("gitea-i2p", "127.0.0.1:7656", onramp.OPT_DEFAULTS)
|
||||
Our implementation introduces a `MultiGetListener()` function that handles TLS, I2P, and Tor connections using the `go-meta-listener` package, while still supporting Unix sockets for internal functions.
|
||||
|
||||
// Set up the Tor onion service
|
||||
var torInstance, torerr = tor.Start(nil, nil)
|
||||
var onion, onionerr = torInstance.Listen(nil, 80)
|
||||
Similarly, we replace the default HTTP client with a version that can route traffic through the appropriate network (TLS, I2P, or Tor) based on the destination.
|
||||
|
||||
// This implements the GetListener function for I2P. Note the exemption for Unix sockets.
|
||||
## Current Implementation
|
||||
|
||||
The current implementation in `net_mirror.go` uses:
|
||||
- `go-meta-listener/mirror` for listening on multiple protocols
|
||||
- Rate limiting through `go-i2p/go-limit`
|
||||
- Environment variables (`EMAIL`, `HOSTNAME`) for configuration
|
||||
|
||||
```go
|
||||
// This implements the GetListener function for TLS, I2P, and Onion
|
||||
func MultiGetListener(network, address string) (net.Listener, error) {
|
||||
// Add a deferral to say that we've tried to grab a listener
|
||||
defer GetManager().InformCleanup()
|
||||
switch network {
|
||||
case "unix", "unixpacket":
|
||||
// I2P isn't really a replacement for the stuff you use Unix sockets for and it's also not an anonymity risk, so treat them normally
|
||||
unixAddr, err := ResolveUnixAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetListenerUnixWrapper(network, unixAddr)
|
||||
default:
|
||||
return mirror.Listen("tcp", address, "./certs", true)
|
||||
}
|
||||
// Support for Unix sockets remains unchanged
|
||||
if network == "unix" || network == "unixpacket" {
|
||||
unixAddr, err := ResolveUnixAddr(network, address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetListenerUnixWrapper(network, unixAddr)
|
||||
}
|
||||
|
||||
// For TCP connections, create a multi-protocol mirror listener
|
||||
ml, err := mirrorListener.Listen(address, os.Getenv("EMAIL"), "./certs", true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Apply rate limiting
|
||||
return limitedlistener.NewLimitedListener(ml,
|
||||
limitedlistener.WithMaxConnections(500), // concurrent connections
|
||||
limitedlistener.WithRateLimit(24), // connections per second
|
||||
), nil
|
||||
}
|
||||
|
||||
// We use `init() to ensure that the appropriate Listeners and Dialers are correctly placed at runtime
|
||||
func init() {
|
||||
GetListener = MultiGetListener
|
||||
/*Dialer not shown here*/
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Caveats
|
||||
-------
|
||||
## Usage Caveats
|
||||
|
||||
Gitea makes a few other kinds of connections, besides `HTTP`, if instructed to do so in the config file.
|
||||
For instance, there is an SMTP client.
|
||||
Not all of these connections are automatically routed through the appropriate anonymity networks in this configuration.
|
||||
For I2P, you might need to use `127.0.0.1:7659/7660` for SMTP. For Tor, you would configure SOCKS proxy settings.
|
||||
Similarly, SSH client connections need additional configuration to properly route through these networks.
|
||||
Additional adjustments to the configuration can be made to also route these services across the appropriate networks but aren't fully documented here at this time.
|
||||
While the HTTP interface works seamlessly across all three protocols, other Gitea communication channels require additional configuration:
|
||||
|
||||
License
|
||||
-------
|
||||
1. **SMTP Client**: If configured, email connections from Gitea will need proper routing:
|
||||
- For I2P: Use local ports like `127.0.0.1:7659/7660`
|
||||
- For Tor: Configure appropriate SOCKS proxy settings
|
||||
|
||||
Both this mod and gitea are licensed under the MIT license.
|
||||
See LICENSE for net_multi*.go in this repository.
|
||||
LICENSE-gitea.md is a copy of the Gitea license from https://github.com/go-gitea/gitea
|
||||
2. **SSH Connections**: Git operations over SSH require additional configuration to properly route through anonymity networks. These settings depend on your specific deployment environment.
|
||||
|
||||
3. **Environment Variables**:
|
||||
- `EMAIL`: Used for TLS certificate generation (required for HTTPS)
|
||||
- `HOSTNAME`: Server hostname (defaults to local machine name if not set)
|
||||
|
||||
## Installation
|
||||
|
||||
You can:
|
||||
1. Download prebuilt binaries from the [releases page](https://github.com/go-i2p/go-gitlooseleaf/releases)
|
||||
2. Use the included `install.sh` script to set up a system service
|
||||
3. Build from source using the GitHub Actions workflows as a reference
|
||||
|
||||
## License
|
||||
|
||||
Both this modification and Gitea itself are licensed under the MIT license.
|
||||
- See [LICENSE](LICENSE) for this project's license
|
||||
- See [LICENSE-gitea.md](LICENSE-gitea.md) for the Gitea license from https://github.com/go-gitea/gitea
|
||||
|
Reference in New Issue
Block a user