Push what I have. Doesn't work unless you disable AppArmor right now.

This commit is contained in:
idk
2021-09-28 18:50:04 -04:00
commit 459fd77099
12 changed files with 571 additions and 0 deletions

21
Makefile Normal file
View File

@ -0,0 +1,21 @@
#export TOR_PT_MANAGED_TRANSPORT_VER=2.1
#export TOR_PT_STATE_LOCATION=$(PWD)
build: client/cmd/i2pclient server/cmd/i2pserver
clean:
rm -fv client/cmd/i2pclient server/cmd/i2pserver
client/cmd/i2pclient:
go build -o client/cmd/i2pclient ./client/cmd
server/cmd/i2pserver:
go build -o server/cmd/i2pserver ./server/cmd
serve:
tor -f torrc.d/torrc
install:
install -m755 client/cmd/i2pclient /usr/bin/i2pclient
install -m755 server/cmd/i2pserver /usr/bin/i2pserver

0
README.md Normal file
View File

BIN
client/cmd/i2pclient Executable file

Binary file not shown.

14
client/cmd/main.go Normal file
View File

@ -0,0 +1,14 @@
package main
import (
"log"
"os"
"i2pgit.org/idk/i2pt/client"
)
func main(){
log.Println("Starting I2P Pluggable Transport Client")
log.SetOutput(os.Stdout)
i2pconn.Main("i2ptclient","127.0.0.1:7656", "i2ptclient.i2pkeys")
}

147
client/i2pconn.go Normal file
View File

@ -0,0 +1,147 @@
// Dummy no-op pluggable transport client. Works only as a managed proxy.
//
// Usage (in torrc):
// UseBridges 1
// Bridge dummy X.X.X.X:YYYY
// ClientTransportPlugin dummy exec dummy-client
//
package i2pconn
import (
"io"
"net"
"os"
"os/signal"
"sync"
"syscall"
)
import (
"git.torproject.org/pluggable-transports/goptlib.git"
"github.com/eyedeekay/sam3/helper"
"github.com/eyedeekay/sam3"
)
var ptInfo pt.ClientInfo
var session *sam3.StreamSession
// When a connection handler starts, +1 is written to this channel; when it
// ends, -1 is written.
var handlerChan = make(chan int)
func copyLoop(a, b net.Conn) {
var wg sync.WaitGroup
wg.Add(2)
go func() {
io.Copy(b, a)
wg.Done()
}()
go func() {
io.Copy(a, b)
wg.Done()
}()
wg.Wait()
}
func handler(conn *pt.SocksConn) error {
handlerChan <- 1
defer func() {
handlerChan <- -1
}()
defer conn.Close()
remote, err := session.Dial("tcp", conn.Req.Target)
if err != nil {
conn.Reject()
return err
}
defer remote.Close()
err = conn.Grant(remote.RemoteAddr().(*net.TCPAddr))
if err != nil {
return err
}
copyLoop(conn, remote)
return nil
}
func acceptLoop(ln *pt.SocksListener) error {
defer ln.Close()
for {
conn, err := ln.AcceptSocks()
if err != nil {
if e, ok := err.(net.Error); ok && !e.Temporary() {
return err
}
continue
}
go handler(conn)
}
}
func Main(name, samaddr, keyspath string) {
var err error
session, err = sam.I2PStreamSession(name, samaddr, keyspath)
if err != nil {
os.Exit(1)
}
ptInfo, err = pt.ClientSetup([]string{"dummy"})
if err != nil {
os.Exit(1)
}
listeners := make([]net.Listener, 0)
for _, methodName := range ptInfo.MethodNames {
switch methodName {
case "dummy":
ln, err := pt.ListenSocks("tcp", "127.0.0.1:0")
if err != nil {
pt.CmethodError(methodName, err.Error())
break
}
go acceptLoop(ln)
pt.Cmethod(methodName, ln.Version(), ln.Addr())
listeners = append(listeners, ln)
default:
pt.CmethodError(methodName, "no such method")
}
}
pt.CmethodsDone()
var numHandlers int = 0
var sig os.Signal
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
// wait for first signal
sig = nil
for sig == nil {
select {
case n := <-handlerChan:
numHandlers += n
case sig = <-sigChan:
}
}
for _, ln := range listeners {
ln.Close()
}
if sig == syscall.SIGTERM {
return
}
// wait for second signal or no more handlers
sig = nil
for sig == nil && numHandlers != 0 {
select {
case n := <-handlerChan:
numHandlers += n
case sig = <-sigChan:
}
}
}

10
go.mod Normal file
View File

@ -0,0 +1,10 @@
module i2pgit.org/idk/i2pt
go 1.16
require (
git.torproject.org/pluggable-transports/goptlib.git v1.2.0
github.com/eyedeekay/sam3 v0.32.33-0.20210718190649-31b8d62f0461
)
replace github.com/eyedeekay/sam3 v0.32.33-0.20210718190649-31b8d62f0461 => ../../../github.com/eyedeekay/sam3

62
go.sum Normal file
View File

@ -0,0 +1,62 @@
git.torproject.org/pluggable-transports/goptlib.git v1.2.0 h1:0qRF7Dw5qXd0FtZkjWUiAh5GTutRtDGL4GXUDJ4qMHs=
git.torproject.org/pluggable-transports/goptlib.git v1.2.0/go.mod h1:4PBMl1dg7/3vMWSoWb46eGWlrxkUyn/CAJmxhDLAlDs=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eyedeekay/goSam v0.32.31-0.20210122211817-f97683379f23 h1:AHm/EzBilSQH+RFgEuslnlCpVQd88MQWx7KHW/VIQlc=
github.com/eyedeekay/goSam v0.32.31-0.20210122211817-f97683379f23/go.mod h1:UgJnih/LpotwKriwVPOEa6yPDM2NDdVrKfLtS5DOLPE=
github.com/eyedeekay/sam3 v0.32.32/go.mod h1:qRA9KIIVxbrHlkj+ZB+OoxFGFgdKeGp1vSgPw26eOVU=
github.com/eyedeekay/sam3 v0.32.33-0.20210718190649-31b8d62f0461 h1:i8nBcLYUADe7vJ9MaCq4MzHPtl6aKRbCLeKZc5vaQx4=
github.com/eyedeekay/sam3 v0.32.33-0.20210718190649-31b8d62f0461/go.mod h1:F4dHMuZ8McQsPedJdxITByRCO/krMv/a66ERA74Wa1w=
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
github.com/getlantern/errors v1.0.1/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
github.com/getlantern/go-socks5 v0.0.0-20171114193258-79d4dd3e2db5/go.mod h1:kGHRXch95rnGLHjER/GhhFiHvfnqNz7KqWD9kGfATHY=
github.com/getlantern/golog v0.0.0-20201105130739-9586b8bde3a9/go.mod h1:ZyIjgH/1wTCl+B+7yH1DqrWp6MPJqESmwmEQ89ZfhvA=
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
github.com/getlantern/netx v0.0.0-20190110220209-9912de6f94fd/go.mod h1:wKdY0ikOgzrWSeB9UyBVKPRhjXQ+vTb+BPeJuypUuNE=
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/renameio v1.0.0/go.mod h1:t/HQoYBZSsWSNK35C6CO/TpPLDVWvxOHboWUAweKUpk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/riobard/go-x25519 v0.0.0-20190716001027-10cc4d8d0b33/go.mod h1:BjmVxzAnkLeoEbqHEerI4eSw6ua+RaIB0S4jMV21RAs=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200410194907-79a7a3126eef/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
honnef.co/go/tools v0.0.1-2020.1.6/go.mod h1:pyyisuGw24ruLjrr1ddx39WE0y9OooInRzEYLhQB2YY=

69
main.go Normal file
View File

@ -0,0 +1,69 @@
package main
import (
"flag"
"log"
)
import "i2pgit.org/idk/i2pt/server"
import "i2pgit.org/idk/i2pt/client"
var (
keyPath = flag.String("listen-keys", "i2p-pt.i2pkeys", "Path to load and store I2P hidden service keys. Listening address is derived from these keys.")
keyBlind = flag.Bool("blind-keys", false, "Employ blinding strategy to prevent floodfills from discovering listening address.")
)
func clientOrServer() string {
client := false
server := false
args := flag.Args()
if len(args) == 0 {
return "client"
}
for _, arg := range args {
switch arg {
case "server":
if client {
return "both"
}
server = true
case "client":
if server {
return "both"
}
client = true
default:
log.Println("invalid argument:", arg, "ignoring")
}
}
if !client && !server {
return "client"
}
if client && server {
return "both"
}
if client {
return "client"
}
if server {
return "server"
}
return "client"
}
func main() {
flag.Parse()
runtype := clientOrServer()
log.Println("Running SAM PT of type:", runtype)
switch runtype {
case "client":
i2pclient.Main("i2ptclient","127.0.0.1:7656","i2ptclient")
case "server":
i2pclient.Main("i2ptserver","127.0.0.1:7656","i2ptserver")
case "both":
go i2pclient.Main("i2ptserver","127.0.0.1:7656","i2ptserver")
i2pclient.Main("i2ptclient","127.0.0.1:7656","i2ptclient")
default:
log.Fatal("Invalid configuration error. Exiting immediately.")
}
}

BIN
server/cmd/i2pserver Executable file

Binary file not shown.

38
server/cmd/main.go Normal file
View File

@ -0,0 +1,38 @@
package main
import (
"log"
"os"
"i2pgit.org/idk/i2pt/server"
)
import (
"time"
"math/rand"
)
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
func randSeq(n int) string {
b := make([]rune, n)
for i := range b {
b[i] = letters[rand.Intn(len(letters))]
}
return string(b)
}
func main(){
rand.Seed(time.Now().UnixNano())
// Open a file for logs.
logs, err := os.OpenFile("i2pt.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatalln("Failed to open log file")
}
defer logs.Close()
log.SetOutput(logs)
// log.SetOutput(os.Stdout)
i2plistener.Main("i2ptserver-"+randSeq(4),"127.0.0.1:7656", "/home/idk/i2ptserver.i2pkeys")
}

145
server/i2plistener.go Normal file
View File

@ -0,0 +1,145 @@
// I2P pluggable transport server. Works only as a managed proxy.
//
// Usage (in torrc):
// BridgeRelay 1
// ORPort 9001
// ExtORPort 6669
// ServerTransportPlugin i2p exec /usr/bin/i2ptserver
package i2plistener
import (
"io"
"io/ioutil"
"net"
"os"
"log"
"os/signal"
"sync"
"syscall"
)
import (
"git.torproject.org/pluggable-transports/goptlib.git"
"github.com/eyedeekay/sam3/helper"
"github.com/eyedeekay/sam3/i2pkeys"
)
type I2PAddr i2pkeys.I2PAddr
func (ia I2PAddr) Network() string {
return "i2p"
}
func (ia I2PAddr) String() string {
return i2pkeys.I2PAddr(ia).Base32()+":6669"
}
func wrapI2PAddr(i net.Addr) net.Addr {
var newaddr *I2PAddr
// newaddr = i.(*i2pkeys.I2PAddr)
newaddr = i.(*I2PAddr)
log.Println(newaddr.Network(), newaddr.String())
return newaddr
}
var ptInfo pt.ServerInfo
func copyLoop(a, b net.Conn) {
var wg sync.WaitGroup
wg.Add(2)
go func() {
io.Copy(b, a)
wg.Done()
}()
go func() {
io.Copy(a, b)
wg.Done()
}()
wg.Wait()
}
func handler(conn net.Conn) error {
defer conn.Close()
or, err := pt.DialOr(&ptInfo, conn.RemoteAddr().String(), "i2p")
if err != nil {
return err
}
defer or.Close()
copyLoop(conn, or)
return nil
}
func acceptLoop(ln net.Listener) error {
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
if e, ok := err.(net.Error); ok && e.Temporary() {
continue
}
return err
}
go handler(conn)
}
}
func Main(name, samaddr, keyspath string) {
var err error
log.Println("Starting I2P Pluggable Transport Service")
ptInfo, err = pt.ServerSetup(nil)
if err != nil {
log.Println("Error:", err.Error())
os.Exit(1)
}
log.Println("Pluggable Server Setup complete, binding:", ptInfo.Bindaddrs)
listeners := make([]net.Listener, 0)
for _, bindaddr := range ptInfo.Bindaddrs {
log.Println("Pluggable Server Binding Loop", bindaddr, bindaddr.MethodName)
switch bindaddr.MethodName {
case "i2p":
log.Println("Pluggable Server Binding I2P")
// ln, err := sam.NetListener(name, samaddr, keyspath)
ln, _ := sam.NetListener(name, samaddr, keyspath)
// if err != nil {
// log.Println("Binding error:", err.Error())
// pt.SmethodError(bindaddr.MethodName, err.Error())
// break
// }
log.Println("Pluggable Transport Addr:", ln.Addr().(*i2pkeys.I2PAddr).Base32())
go acceptLoop(ln)
pt.Smethod(bindaddr.MethodName, wrapI2PAddr(ln.Addr()))
listeners = append(listeners, ln)
default:
pt.SmethodError(bindaddr.MethodName, "no such method")
}
}
pt.SmethodsDone()
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGTERM)
if os.Getenv("TOR_PT_EXIT_ON_STDIN_CLOSE") == "1" {
// This environment variable means we should treat EOF on stdin
// just like SIGTERM: https://bugs.torproject.org/15435.
go func() {
io.Copy(ioutil.Discard, os.Stdin)
sigChan <- syscall.SIGTERM
}()
}
// wait for a signal
<-sigChan
// signal received, shut down
for _, ln := range listeners {
ln.Close()
}
}

65
torrc.d/torrc Normal file
View File

@ -0,0 +1,65 @@
#SocksPort 9050 # Default: Bind to localhost:9050 for local connections.
#SocksPort 192.168.0.1:9100 # Bind to this address:port too.
#SocksPolicy accept 192.168.0.0/16
#SocksPolicy reject *
#Log notice file /var/log/tor/notices.log
#Log debug file /var/log/tor/debug.log
#Log notice syslog
#Log debug stderr
#RunAsDaemon 1
#DataDirectory /var/lib/tor
#ControlPort 9051
#HashedControlPassword 16:872860B76453A77D60CA2BB8C1A7042072093276A3D701AD684053EC4C
#CookieAuthentication 1
#HiddenServiceDir /var/lib/tor/hidden_service/
#HiddenServicePort 80 127.0.0.1:80
#HiddenServiceDir /var/lib/tor/other_hidden_service/
#HiddenServicePort 80 127.0.0.1:80
#HiddenServicePort 22 127.0.0.1:22
#ORPort 9001
#ORPort 443 NoListen
#ORPort 127.0.0.1:9090 NoAdvertise
#Address noname.example.com
#OutboundBindAddress 10.0.0.5
#Nickname ididnteditheconfig
#RelayBandwidthRate 100 KB # Throttle traffic to 100KB/s (800Kbps)
#RelayBandwidthBurst 200 KB # But allow bursts up to 200KB/s (1600Kbps)
#AccountingMax 4 GB
#AccountingStart day 00:00
#AccountingStart month 3 15:00
#ContactInfo Random Person <nobody AT example dot com>
#ContactInfo 0xFFFFFFFF Random Person <nobody AT example dot com>
#DirPort 9030 # what port to advertise for directory connections
#DirPort 80 NoListen
#DirPort 127.0.0.1:9091 NoAdvertise
#DirPortFrontPage /etc/tor/tor-exit-notice.html
#MyFamily $keyid,$keyid,...
#ExitPolicy accept *:6660-6667,reject *:* # allow irc ports but no more
#ExitPolicy accept *:119 # accept nntp as well as default exit policy
#ExitPolicy reject *:* # no exits allowed
#BridgeRelay 1
PublishServerDescriptor 0
BridgeRelay 1
ORPort 9001 IPv6Only
ExtORPort 6669
ServerTransportPlugin i2p exec /usr/bin/i2pserver
DataDirectory /home/idk/go/src/i2pgit.org/idk/i2pt