Files
go-i2p-testnet/lib/i2pd/config.go
Haris Khan eff93fa4fc Various changes
-adjusted config.go to be valid
-adjusted i2pd-node.dockerfile
2024-11-13 13:25:05 -05:00

574 lines
16 KiB
Go

package i2pd
import (
"bytes"
"context"
"fmt"
"gopkg.in/ini.v1"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"go-i2p-testnet/lib/utils"
)
// I2PDConfig represents the complete i2pd configuration
type I2PDConfig struct {
// Global options (before any section)
TunnelsConf string `ini:"tunconf"`
TunnelsDir string `ini:"tunnelsdir"`
CertsDir string `ini:"certsdir"`
Pidfile string `ini:"pidfile"`
Log string `ini:"log"`
Logfile string `ini:"logfile"`
Loglevel string `ini:"loglevel"`
Logclftime bool `ini:"logclftime"`
Daemon bool `ini:"daemon"`
Family string `ini:"family"`
Ifname string `ini:"ifname"`
Ifname4 string `ini:"ifname4"`
Ifname6 string `ini:"ifname6"`
Address4 string `ini:"address4"`
Address6 string `ini:"address6"`
Host string `ini:"host"`
Port int `ini:"port"`
IPv4 bool `ini:"ipv4"`
IPv6 bool `ini:"ipv6"`
SSU bool `ini:"ssu"`
Bandwidth string `ini:"bandwidth"`
Share int `ini:"share"`
Notransit bool `ini:"notransit"`
Floodfill bool `ini:"floodfill"`
Service bool `ini:"service"`
Datadir string `ini:"datadir"`
Netid int `ini:"netid"`
Nat bool `ini:"nat"`
ReservedRange bool `ini:"reservedrange"`
// Sections
NTCP2 NTCP2Config `ini:"ntcp2"`
SSU2 SSU2Config `ini:"ssu2"`
HTTP HTTPConfig `ini:"http"`
HTTPProxy HTTPProxyConfig `ini:"httpproxy"`
SocksProxy SocksProxyConfig `ini:"socksproxy"`
SAM SAMConfig `ini:"sam"`
BOB BOBConfig `ini:"bob"`
I2CP I2CPConfig `ini:"i2cp"`
I2PControl I2PControlConfig `ini:"i2pcontrol"`
Cryptography CryptographyConfig `ini:"cryptography"`
UPnP UPnPConfig `ini:"upnp"`
Meshnets MeshnetsConfig `ini:"meshnets"`
Reseed ReseedConfig `ini:"reseed"`
Addressbook AddressbookConfig `ini:"addressbook"`
Limits LimitsConfig `ini:"limits"`
Trust TrustConfig `ini:"trust"`
Persist PersistConfig `ini:"persist"`
CPUExt CPUExtConfig `ini:"cpuext"`
Nettime NettimeConfig `ini:"nettime"`
//LocalAddressbook LocalAddressbookConfig `ini:"localaddressbook"`
//Windows WindowsConfig `ini:"windows"`
//Unix UnixConfig `ini:"unix"`
}
// NTCP2 Section
type NTCP2Config struct {
Enabled bool `ini:"enabled"`
Published bool `ini:"published"`
Port int `ini:"port"`
}
// SSU2 Section
type SSU2Config struct {
Enabled bool `ini:"enabled"`
Published bool `ini:"published"`
Port int `ini:"port"`
}
// HTTP Section
type HTTPConfig struct {
Enabled bool `ini:"enabled"`
Address string `ini:"address"`
Port int `ini:"port"`
Webroot string `ini:"webroot"`
Auth bool `ini:"auth"`
User string `ini:"user"`
Pass string `ini:"pass"`
Lang string `ini:"lang"`
}
// HTTPProxy Section
type HTTPProxyConfig struct {
Enabled bool `ini:"enabled"`
Address string `ini:"address"`
Port int `ini:"port"`
Keys string `ini:"keys"`
AddressHelper bool `ini:"addresshelper"`
Outproxy string `ini:"outproxy"`
SignatureType int `ini:"signaturetype"`
InboundQuantity int `ini:"inbound.quantity"`
OutboundLength int `ini:"outbound.length"`
OutboundQuantity int `ini:"outbound.quantity"`
OutboundLengthVariance int `ini:"outbound.lengthVariance"`
I2CPLeaseSetType int `ini:"i2cp.leaseSetType"`
I2CPLeaseSetEncType string `ini:"i2cp.leaseSetEncType"`
}
// SocksProxy Section
type SocksProxyConfig struct {
Enabled bool `ini:"enabled"`
Address string `ini:"address"`
Port int `ini:"port"`
Keys string `ini:"keys"`
OutproxyEnabled bool `ini:"outproxy.enabled"`
Outproxy string `ini:"outproxy"`
OutproxyPort int `ini:"outproxyport"`
SignatureType int `ini:"signaturetype"`
InboundQuantity int `ini:"inbound.quantity"`
OutboundLength int `ini:"outbound.length"`
OutboundQuantity int `ini:"outbound.quantity"`
OutboundLengthVariance int `ini:"outbound.lengthVariance"`
I2CPLeaseSetType int `ini:"i2cp.leaseSetType"`
I2CPLeaseSetEncType string `ini:"i2cp.leaseSetEncType"`
}
// SAM Section
type SAMConfig struct {
Enabled bool `ini:"enabled"`
Address string `ini:"address"`
Port int `ini:"port"`
SingleThread bool `ini:"singlethread"`
}
// BOB Section
type BOBConfig struct {
Enabled bool `ini:"enabled"`
Address string `ini:"address"`
Port int `ini:"port"`
}
// I2CP Section
type I2CPConfig struct {
Enabled bool `ini:"enabled"`
Address string `ini:"address"`
Port int `ini:"port"`
SingleThread bool `ini:"singlethread"`
}
// I2PControl Section
type I2PControlConfig struct {
Enabled bool `ini:"enabled"`
Address string `ini:"address"`
Port int `ini:"port"`
Password string `ini:"password"`
Cert string `ini:"cert"`
Key string `ini:"key"`
}
// Cryptography Section
type CryptographyConfig struct {
Precomputation PrecomputationConfig `ini:"precomputation"`
// Add other cryptographic options here
}
// Precomputation Section
type PrecomputationConfig struct {
ElGamal bool `ini:"elgamal"`
}
// UPnP Section
type UPnPConfig struct {
Enabled bool `ini:"enabled"`
Name string `ini:"name"`
}
// Meshnets Section
type MeshnetsConfig struct {
Yggdrasil bool `ini:"yggdrasil"`
YggAddress string `ini:"yggaddress"`
}
// Reseed Section
type ReseedConfig struct {
Verify bool `ini:"verify"`
URLs string `ini:"urls"`
YggURLs string `ini:"yggurls"`
File string `ini:"file"`
ZipFile string `ini:"zipfile"`
Proxy string `ini:"proxy"`
Threshold int `ini:"threshold"`
}
// Addressbook Section
type AddressbookConfig struct {
DefaultURL string `ini:"defaulturl"`
Subscriptions string `ini:"subscriptions"`
HostsFile string `ini:"hostsfile"`
}
// Limits Section
type LimitsConfig struct {
TransitTunnels int `ini:"transittunnels"`
OpenFiles int `ini:"openfiles"`
CoreSize int `ini:"coresize"`
Zombies float64 `ini:"zombies"`
}
// Trust Section
type TrustConfig struct {
Enabled bool `ini:"enabled"`
Family string `ini:"family"`
Routers string `ini:"routers"`
Hidden bool `ini:"hidden"`
}
// TunnelConfig represents inbound or outbound tunnel configurations
type TunnelConfig struct {
Length int `ini:"length"`
Quantity int `ini:"quantity"`
}
// Persist Section
type PersistConfig struct {
Profiles bool `ini:"profiles"`
Addressbook bool `ini:"addressbook"`
}
// CPU Extensions Section
type CPUExtConfig struct {
AESNI bool `ini:"aesni"`
AVX bool `ini:"avx"`
Force bool `ini:"force"`
}
// Nettime Section
type NettimeConfig struct {
Enabled bool `ini:"enabled"`
NtpServers string `ini:"ntpservers"`
NtpSyncInterval int `ini:"ntpsyncinterval"`
}
func GenerateDefaultI2PDConfig() *I2PDConfig {
return &I2PDConfig{
// Global options (before any section)
TunnelsConf: "/var/lib/i2pd/tunnels.conf",
TunnelsDir: "/var/lib/i2pd/tunnels.d/",
CertsDir: "/var/lib/i2pd/certificates",
Pidfile: "/run/i2pd.pid",
Log: "stdout",
Logfile: "",
Loglevel: "debug",
Logclftime: false,
Daemon: false,
Family: "",
Ifname: "",
Ifname4: "",
Ifname6: "",
Address4: "",
Address6: "",
Host: "",
Port: 0, // Default is a random port
IPv4: true,
IPv6: true,
SSU: true,
Bandwidth: "L",
Share: 100,
Notransit: false,
Floodfill: true,
Service: false,
Datadir: "/var/lib/i2pd",
Netid: 2,
Nat: true,
// NTCP2 section
NTCP2: NTCP2Config{
Enabled: true,
Published: true,
Port: 0, // Uses global port option
},
// SSU2 section
SSU2: SSU2Config{
Enabled: true,
Published: true,
Port: 0, // Uses global port option or port + 1 if SSU is enabled
},
// HTTP section
HTTP: HTTPConfig{
Enabled: true,
Address: "127.0.0.1",
Port: 7070,
Webroot: "/",
Auth: false,
User: "",
Pass: "",
Lang: "english",
},
// HTTP Proxy section
HTTPProxy: HTTPProxyConfig{
Enabled: true,
Address: "127.0.0.1",
Port: 4444,
Keys: "",
AddressHelper: true,
Outproxy: "",
SignatureType: 7,
InboundQuantity: 5,
OutboundLength: 3,
OutboundQuantity: 5,
OutboundLengthVariance: 0,
I2CPLeaseSetType: 3,
I2CPLeaseSetEncType: "",
},
// SOCKS Proxy section
SocksProxy: SocksProxyConfig{
Enabled: true,
Address: "127.0.0.1",
Port: 4447,
Keys: "",
OutproxyEnabled: false,
Outproxy: "",
OutproxyPort: 0,
SignatureType: 7,
InboundQuantity: 5,
OutboundLength: 3,
OutboundQuantity: 5,
OutboundLengthVariance: 0,
I2CPLeaseSetType: 3,
I2CPLeaseSetEncType: "",
},
// SAM section
SAM: SAMConfig{
Enabled: true,
Address: "127.0.0.1",
Port: 7656,
SingleThread: true,
},
// BOB section
BOB: BOBConfig{
Enabled: false,
Address: "127.0.0.1",
Port: 2827,
},
// I2CP section
I2CP: I2CPConfig{
Enabled: false,
Address: "127.0.0.1",
Port: 7654,
SingleThread: true,
},
// I2PControl section
I2PControl: I2PControlConfig{
Enabled: false,
Address: "127.0.0.1",
Port: 7650,
Password: "itoopie",
Cert: "i2pcontrol.crt.pem",
Key: "i2pcontrol.key.pem",
},
// Cryptography section
Cryptography: CryptographyConfig{
Precomputation: PrecomputationConfig{
ElGamal: true,
},
// Initialize other cryptographic options as needed
},
// UPnP section
UPnP: UPnPConfig{
Enabled: false, // Disabled by default on non-Windows/Android platforms
Name: "I2Pd",
},
// Meshnets section
Meshnets: MeshnetsConfig{
Yggdrasil: false,
YggAddress: "",
},
// Reseed section
Reseed: ReseedConfig{
Verify: true,
URLs: "https://reseed.i2p-projekt.de/,https://i2p.mooo.com/netDb/,https://netdb.i2p2.no/",
YggURLs: "",
File: "",
ZipFile: "",
Proxy: "",
Threshold: 25,
},
// Addressbook section
Addressbook: AddressbookConfig{
DefaultURL: "http://reg.i2p/hosts.txt",
Subscriptions: "",
HostsFile: "hosts.txt",
},
// Limits section
Limits: LimitsConfig{
TransitTunnels: 10000, // As per default
OpenFiles: 0,
CoreSize: 0,
Zombies: 0.00,
},
// Trust section
Trust: TrustConfig{
Enabled: false,
Family: "",
Routers: "",
Hidden: false,
},
// Persist section
Persist: PersistConfig{
Profiles: true,
Addressbook: true,
},
// CPU Extensions section
CPUExt: CPUExtConfig{
AESNI: true,
AVX: true,
Force: false,
},
// Nettime section
Nettime: NettimeConfig{
Enabled: false,
NtpServers: "pool.ntp.org",
NtpSyncInterval: 72,
},
}
}
func GenerateRouterConfig(routerID int) (string, error) {
log.WithField("routerID", routerID).Debug("Starting i2pd router config generation")
// Initialize default configuration
config := GenerateDefaultI2PDConfig()
config.Netid = 5
config.ReservedRange = false
config.Nat = false
config.Floodfill = true
// Create an INI file from the struct
iniFile := ini.Empty()
err := iniFile.ReflectFrom(config)
if err != nil {
log.WithError(err).Error("Failed to reflect config struct to INI file")
return "", err
}
// Write INI file to a string
var buffer bytes.Buffer
_, err = iniFile.WriteTo(&buffer)
if err != nil {
log.WithError(err).Error("Failed to write INI file to buffer")
return "", err
}
configData := buffer.String()
log.WithFields(map[string]interface{}{
"routerID": routerID,
"config": configData,
}).Debug("i2pd router configuration generated successfully")
return configData, nil
}
func CopyConfigToVolume(cli *client.Client, ctx context.Context, volumeName string, configData string) error {
// Create a temporary container to copy data into the volume
log.WithField("volumeName", volumeName).Debug("Starting config copy to volume")
tempContainerConfig := &container.Config{
Image: "alpine",
Tty: false,
WorkingDir: "/var/lib/i2pd",
Cmd: []string{"sh", "-c", "mkdir -p /var/lib/i2pd && sleep 1d"},
}
hostConfig := &container.HostConfig{
Binds: []string{
fmt.Sprintf("%s:/var/lib/i2pd", volumeName),
},
}
log.WithFields(map[string]interface{}{
"image": tempContainerConfig.Image,
"volumeName": volumeName,
}).Debug("Creating temporary container")
resp, err := cli.ContainerCreate(ctx, tempContainerConfig, hostConfig, nil, nil, "")
if err != nil {
log.WithError(err).Error("Failed to create temporary container")
return fmt.Errorf("error creating temporary container: %v", err)
}
defer func() {
log.WithField("containerID", resp.ID).Debug("Removing temporary container")
removeOptions := container.RemoveOptions{Force: true}
err := cli.ContainerRemove(ctx, resp.ID, removeOptions)
if err != nil {
log.WithError(err).Error("Failed to remove temporary container")
}
}()
// Start the container
log.WithField("containerID", resp.ID).Debug("Starting temporary container")
startOptions := container.StartOptions{}
if err := cli.ContainerStart(ctx, resp.ID, startOptions); err != nil {
log.WithError(err).Error("Failed to start temporary container")
return fmt.Errorf("error starting temporary container: %v", err)
}
// Copy the configuration file into the container
log.Debug("Creating tar archive of config data")
tarReader, err := utils.CreateTarArchive("i2pd.conf", configData)
if err != nil {
log.WithError(err).Error("Failed to create tar archive")
return fmt.Errorf("error creating tar archive: %v", err)
}
// Copy to the container's volume-mounted directory
log.WithField("containerID", resp.ID).Debug("Copying config to container")
err = cli.CopyToContainer(ctx, resp.ID, "/var/lib/i2pd", tarReader, container.CopyToContainerOptions{})
if err != nil {
log.WithError(err).Error("Failed to copy config to container")
return fmt.Errorf("error copying to container: %v", err)
}
// Optionally, handle additional configuration files like local addressbook
/*
localAddrBookData := "your local addressbook content here"
tarReader, err = utils.CreateTarArchive("addressbook/local.csv", localAddrBookData)
if err != nil {
log.WithError(err).Error("Failed to create tar archive for local addressbook")
return fmt.Errorf("error creating tar archive for local addressbook: %v", err)
}
log.WithField("containerID", resp.ID).Debug("Copying local addressbook to container")
err = cli.CopyToContainer(ctx, resp.ID, "/var/lib/i2pd/addressbook", tarReader, container.CopyToContainerOptions{})
if err != nil {
log.WithError(err).Error("Failed to copy local addressbook to container")
return fmt.Errorf("error copying local addressbook to container: %v", err)
}
*/
// Stop the container
log.WithField("containerID", resp.ID).Debug("Stopping temporary container")
stopOptions := container.StopOptions{}
if err := cli.ContainerStop(ctx, resp.ID, stopOptions); err != nil {
log.WithError(err).Error("Failed to stop temporary container")
return fmt.Errorf("error stopping temporary container: %v", err)
}
log.Debug("Successfully copied config to volume")
return nil
}