26 Commits

Author SHA1 Message Date
idk
8da5f98b0c bulk release update 2022-04-01 19:06:27 -04:00
idk
416399e78f bulk release update 2022-04-01 17:39:27 -04:00
idk
80cde5f300 switch to wget-ds to download su3 files 2022-03-29 01:42:56 -04:00
idk
3413faf5c9 comment out shellservice copy line it's not required anymore 2022-03-25 23:19:31 -04:00
idk
eb5d4f5cce expand go-i2pd stup just slightly to trigger yet another runner build 2022-02-14 01:04:04 -05:00
idk
60d2f906d2 add i2pd.go stub, trying to see if a non-retry CI build uses the correct domain 2022-02-14 00:52:14 -05:00
idk
fac4d0147f Adds an arbitrary line to the readme to trigger the gitlab runner 2022-02-13 02:24:16 -05:00
idk
c2d32d78f0 <div><p> around reseed server status paragraph 2022-02-07 12:00:15 -05:00
idk
e95797eca1 Only display ping stats from the current date 2022-02-07 11:46:44 -05:00
idk
2db015addb Adds the ability to monitor other reseed servers from the reseed server 2022-02-05 11:43:20 -05:00
idk
d8289a4834 eliminate some superfluous logging 2022-02-04 19:29:50 -05:00
idk
59431496db Adds the ability to monitor other reseed servers from the reseed server 2022-02-04 18:57:31 -05:00
idk
7fefd783b2 trim newlines from default keynames 2022-01-31 19:33:44 -05:00
idk
69ef8a0344 limit poster width 2022-01-05 12:27:59 -05:00
idk
f74f7f8c98 fix status in initscript, add --background to initscript 2022-01-05 12:22:42 -05:00
idk
421bba5f03 poster on readme 2022-01-05 12:18:58 -05:00
idk
7689fb1321 poster on readme 2022-01-05 12:18:45 -05:00
idk
04c94cd2ba changelog and version 2021-12-16 14:44:34 -05:00
idk
64b79e0f82 include license in the plugin package 2021-12-16 14:42:23 -05:00
idk
5e5c9c0d2f Allow configuration of the signer email with a file 2021-12-14 22:44:52 -05:00
idk
3088a5b6d0 Allow configuration of the signer email with a file 2021-12-14 22:26:47 -05:00
idk
3859e539c5 fail when signer==you@mail.i2p 2021-12-14 22:12:05 -05:00
idk
6249b3f41e bump, update changelog, re-release 2021-12-14 19:13:57 -05:00
idk
8ed93440a4 Add index 2021-12-14 17:45:07 -05:00
idk
bd4f7d746d Re-enable autostart but delay it by 24hrs. For some reason permissions are not set correctly if autostart isn't set 2021-12-14 17:23:55 -05:00
idk
d7bf080c43 version bump 2021-12-14 16:24:34 -05:00
16 changed files with 251 additions and 23 deletions

View File

@ -1,3 +1,12 @@
2021-12-16
* app.Version = "0.2.11"
* include license file in plugin
2021-12-14
* app.Version = "0.2.10"
* restart changelog
* fix websiteURL in plugin.config
2019-04-21
* app.Version = "0.1.7"
* enabling TLS 1.3 *only*

View File

@ -1,9 +1,11 @@
VERSION=0.2.8
VERSION=0.2.13
APP=reseed-tools
USER_GH=eyedeekay
CGO_ENABLED=0
export CGO_ENABLED=0
PLUGIN_PORT=7671
export PLUGIN_PORT=7671
GOOS?=$(shell uname -s | tr A-Z a-z)
GOARCH?="amd64"
@ -262,7 +264,7 @@ upload-su3s:
GOOS=windows GOARCH=386 make upload-single-su3
download-single-su3:
wget -N -c "https://github.com/eyedeekay/reseed-tools/releases/download/v$(VERSION)/reseed-tools-$(GOOS)-$(GOARCH).su3"
wget-ds "https://github.com/eyedeekay/reseed-tools/releases/download/v$(VERSION)/reseed-tools-$(GOOS)-$(GOARCH).su3"
upload-single-deb:
gothub upload -R -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(APP) -t v$(VERSION) -f reseed-tools_$(VERSION)-1_amd64.deb -l "`sha256sum reseed-tools_$(VERSION)-1_amd64.deb`" -n "reseed-tools_$(VERSION)-1_amd64.deb"
@ -276,25 +278,32 @@ upload-single-su3:
tmp/content:
mkdir -p tmp
cp -rv content tmp/content
echo "you@mail.i2p" > tmp/signer
tmp/lib:
mkdir -p tmp/lib
cp "$(HOME)/Workspace/GIT_WORK/i2p.i2p/build/shellservice.jar" tmp/lib/shellservice.jar
# cp "$(HOME)/build/shellservice.jar" tmp/lib/shellservice.jar
su3s: tmp/content tmp/lib
tmp/LICENSE:
cp LICENSE.md tmp/LICENSE
SIGNER_DIR=$(HOME)/i2p-go-keys/
su3s: tmp/content tmp/lib tmp/LICENSE
i2p.plugin.native -name=reseed-tools-$(GOOS)-$(GOARCH) \
-signer=hankhill19580@gmail.com \
-signer-dir=$(SIGNER_DIR) \
-version "$(VERSION)" \
-author=hankhill19580@gmail.com \
-autostart=false \
-autostart=true \
-clientname=reseed-tools-$(GOOS)-$(GOARCH) \
-command="reseed-tools-$(GOOS)-$(GOARCH) reseed --yes --signer=you@mail.i2p --netdb=\$$CONFIG/netDb" \
-command="reseed-tools-$(GOOS)-$(GOARCH) reseed --yes --signer=\$$PLUGIN/signer --port=$(PLUGIN_PORT)" \
-consolename="Reseed Tools" \
-consoleurl="https://127.0.0.1:8443" \
-consoleurl="https://127.0.0.1:$(PLUGIN_PORT)" \
-updateurl="http://idk.i2p/reseed-tools/reseed-tools-$(GOOS)-$(GOARCH).su3" \
-website="http://idk.i2p/reseed-tools/" \
-icondata="content/images/reseed-icon.png" \
-delaystart="3" \
-delaystart="1" \
-desc="`cat description-pak`" \
-exename=reseed-tools-$(GOOS)-$(GOARCH) \
-targetos="$(GOOS)" \

View File

@ -1,6 +1,8 @@
I2P Reseed Tools
==================
![Reseed Tools Poster](content/images/reseed.png)
This tool provides a secure and efficient reseed server for the I2P network.
There are several utility commands to create, sign, and validate SU3 files.
Please note that this requires at least Go version 1.13, and uses Go Modules.
@ -34,6 +36,14 @@ and via the github mirror at https://github.com/eyedeekay/reseed-tools/releases.
These can be installed by adding them on the
[http://127.0.0.1:7657/configplugins](http://127.0.0.1:7657/configplugins).
After installing the plugin, you should immediately edit the `$PLUGIN/signer`
file in order to set your `--signer` email, which is used to name your keys.
You can find the `$PLUGIN` directory in your I2P config directory, which is
usually `$HOME/.i2p` on Unixes.
This will allow the developers to contact you if your reseed has issues
and will authenticate your reseed to the I2P routers that use it.
- darwin/amd64: [http://idk.i2p/reseed-tools/reseed-tools-darwin-amd64.su3](http://idk.i2p/reseed-tools/reseed-tools-darwin-amd64.su3)
- darwin/arm64: [http://idk.i2p/reseed-tools/reseed-tools-darwin-arm64.su3](http://idk.i2p/reseed-tools/reseed-tools-darwin-arm64.su3)
- linux/386: [http://idk.i2p/reseed-tools/reseed-tools-linux-386.su3](http://idk.i2p/reseed-tools/reseed-tools-linux-386.su3)
@ -65,7 +75,12 @@ Debian users who are running I2P as a system service must also run the
the I2P service's netDb directory. On Debian and Ubuntu, that user is `i2psvc`
and the netDb directory is: `/var/lib/i2p/i2p-config/netDb`.
##### Systemd Service
##### Service Integration
Support for running as a system service as part of the reseed package
is new. PR's that improve integration are welcome.
###### Systemd Service
A systemd service is provided which should work with the I2P Debian package
when reseed-tools is installed in `/usr/bin/reseed-tools`. If you install with
@ -83,7 +98,7 @@ this you should edit the `/etc/systemd/system/reseed.d/reseed.service`.
- To reload the systemd services: `sudo systemctl daemon-reload`
- To view the status/logs: `sudo journalctl -u reseed.service`
##### SysV Service
###### SysV Service
An initscript is also provided. The initscript, unlike the systemd service,
cannot schedule itself to restart. You should restart the service roughly once

12
cmd/i2pd.go Normal file
View File

@ -0,0 +1,12 @@
//go:build i2pd
// +build i2pd
package cmd
import (
i2pd "github.com/eyedeekay/go-i2pd/goi2pd"
)
func InitializeI2PD() func() {
return i2pd.InitI2PSAM(nil)
}

View File

@ -2,6 +2,8 @@ package cmd
import (
"context"
"strings"
//"flag"
"fmt"
"io/ioutil"
@ -30,11 +32,11 @@ func getDefaultSigner() string {
if intentionalsigner == "" {
adminsigner := os.Getenv("MAILTO")
if adminsigner != "" {
return adminsigner
return strings.Replace(adminsigner, "\n", "", -1)
}
return ""
}
return intentionalsigner
return strings.Replace(intentionalsigner, "\n", "", -1)
}
func getHostName() string {
@ -42,7 +44,7 @@ func getHostName() string {
if hostname == "" {
hostname, _ = os.Hostname()
}
return hostname
return strings.Replace(hostname, "\n", "", -1)
}
func NewReseedCommand() cli.Command {
@ -214,6 +216,16 @@ func LoadKeys(keysPath string, c *cli.Context) (i2pkeys.I2PKeys, error) {
}
}
// fileExists checks if a file exists and is not a directory before we
// try using it to prevent further errors.
func fileExists(filename string) bool {
info, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
}
return !info.IsDir()
}
func reseedAction(c *cli.Context) {
netdbDir := c.String("netdb")
if netdbDir == "" {
@ -222,10 +234,22 @@ func reseedAction(c *cli.Context) {
}
signerID := c.String("signer")
if signerID == "" {
if signerID == "" || signerID == "you@mail.i2p" {
fmt.Println("--signer is required")
return
}
if !strings.Contains(signerID, "@") {
if !fileExists(signerID) {
fmt.Println("--signer must be an email address or a file containing an email address.")
return
}
bytes, err := ioutil.ReadFile(signerID)
if err != nil {
fmt.Println("--signer must be an email address or a file containing an email address.")
return
}
signerID = string(bytes)
}
var tlsCert, tlsKey string
tlsHost := c.String("tlsHost")

View File

@ -347,6 +347,10 @@ func createSigningCertificate(signerID string) error {
}
func createTLSCertificate(host string) error {
return CreateTLSCertificate(host)
}
func CreateTLSCertificate(host string) error {
fmt.Println("Generating TLS keys. This may take a minute...")
priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
if err != nil {

View File

@ -70,3 +70,8 @@ img {
.link-button:active {
color:red;
}
figure > img {
max-width: 35%;
display: inline;
}

View File

@ -1,2 +1 @@
Reseed tools is a self-contained, easy-to-configure I2P reseed service
which can be run on any OS.
Reseed tools is a self-contained, easy-to-configure I2P reseed service which can be run on any OS.

View File

@ -19,15 +19,15 @@ fi
RUNOPTS=" reseed --yes=true --netdb=$NETDBDIR $MORE_OPTIONS "
start() {
start-stop-daemon --user $RUNAS --chuid $RUNAS --exec $SCRIPT --chdir $RUNDIR --make-pidfile --pidfile $RUNDIR/reseed.pid --start -- $RUNOPTS
start-stop-daemon --background --user $RUNAS --chuid $RUNAS --exec $SCRIPT --chdir $RUNDIR --make-pidfile --pidfile $RUNDIR/reseed.pid --start -- $RUNOPTS
}
stop() {
start-stop-daemon --user $RUNAS --exec $SCRIPT --chdir $RUNDIR --remove-pidfile --pidfile $RUNDIR/reseed.pid --stop
start-stop-daemon --background --user $RUNAS --exec $SCRIPT --chdir $RUNDIR --remove-pidfile --pidfile $RUNDIR/reseed.pid --stop
}
status() {
start-stop-daemon --user $RUNAS --exec $SCRIPT --chdir $RUNDIR --remove-pidfile --pidfile $RUNDIR/reseed.pid --status
start-stop-daemon --background --user $RUNAS --exec $SCRIPT --chdir $RUNDIR --pidfile $RUNDIR/reseed.pid --status
}
restart() {

3
go.mod
View File

@ -16,6 +16,7 @@ require (
github.com/throttled/throttled/v2 v2.7.1
github.com/urfave/cli v1.22.5
gitlab.com/golang-commonmark/markdown v0.0.0-20191127184510-91b5b3c99c19
github.com/eyedeekay/go-i2pd v0.0.0-20220213070306-9807541b2dfc
golang.org/x/text v0.3.5
)
@ -26,3 +27,5 @@ replace github.com/libp2p/go-libp2p-core => github.com/libp2p/go-libp2p-core v0.
replace github.com/libp2p/go-libp2p-gostream => github.com/libp2p/go-libp2p-gostream v0.3.1
replace github.com/libp2p/go-libp2p-http => github.com/libp2p/go-libp2p-http v0.2.0
replace github.com/eyedeekay/go-i2pd v0.0.0-20220213070306-9807541b2dfc => ./go-i2pd

2
go.sum
View File

@ -137,6 +137,8 @@ github.com/eyedeekay/go-fpw v0.0.0-20200512022837-c8b4dcdc74d4/go.mod h1:RyCx7Ku
github.com/eyedeekay/go-i2cp v0.0.0-20190716135428-6d41bed718b0 h1:rnn9OlD/3+tATEZNuiMR1C84O5CX8bZL2qqgttprKrw=
github.com/eyedeekay/go-i2cp v0.0.0-20190716135428-6d41bed718b0/go.mod h1:+P0fIhkqIYjo7exMJRTlSteRMbRyHbiBiKw+YlPWk+c=
github.com/eyedeekay/go-i2pcontrol v0.0.0-20200110011336-510cca77e350/go.mod h1:bhIQsVpbNNXMtcoZ9UF4hLQleOjaCgKGXiRRhNc8TOA=
github.com/eyedeekay/i2pd v0.3.0-1stbinrelease.0.20210702172028-5d01ee95810a h1:dALePX8FUwdy71vN77GMEc/B1Otu5dRGkDlb7maULfQ=
github.com/eyedeekay/i2pd v0.3.0-1stbinrelease.0.20210702172028-5d01ee95810a/go.mod h1:4qJhWn+yNrWRbqFHhU8kl7JgbcW1hm3PMgvlPlxO3gg=
github.com/eyedeekay/ramp v0.0.0-20190429201811-305b382042ab/go.mod h1:h7mvUAMgZ/rtRDUOkvKTK+8LnDMeUhJSoa5EPdB51fc=
github.com/eyedeekay/sam3 v0.32.2/go.mod h1:Y3igFVzN4ybqkkpfUWULGhw7WRp8lieq0ORXbLBbcZM=
github.com/eyedeekay/sam3 v0.32.32 h1:9Ea1Ere5O8Clx8zYxKnvhrWy7R96Q4FvxlPskYf8VW0=

View File

@ -6,6 +6,9 @@
</head>
<body>
<h1 id="i2p-reseed-tools">I2P Reseed Tools</h1>
<figure>
<img src="content/images/reseed.png" alt="" /><figcaption>Reseed Tools Poster</figcaption>
</figure>
<p>This tool provides a secure and efficient reseed server for the I2P network. There are several utility commands to create, sign, and validate SU3 files. Please note that this requires at least Go version 1.13, and uses Go Modules.</p>
<p>Standard reseeds are distributed with the I2P packages. To get your reseed included, apply on <a href="http://zzz.i2p">zzz.i2p</a>.</p>
<h2 id="dependencies">Dependencies</h2>
@ -16,6 +19,8 @@
<p>Reseed-tools can be run as a user, as a freestanding service, or be installed as an I2P Plugin. It will attempt to configure itself automatically. You should make sure to set the <code>--signer</code> flag or the <code>RESEED_EMAIL</code> environment variable to configure your signing keys/contact info.</p>
<h4 id="plugin-install-urls">Plugin install URLs</h4>
<p>Plugin releases are available inside of i2p at http://idk.i2p/reseed-tools/ and via the github mirror at https://github.com/eyedeekay/reseed-tools/releases. These can be installed by adding them on the <a href="http://127.0.0.1:7657/configplugins">http://127.0.0.1:7657/configplugins</a>.</p>
<p>After installing the plugin, you should immediately edit the <code>$PLUGIN/signer</code> file in order to set your <code>--signer</code> email, which is used to name your keys. You can find the <code>$PLUGIN</code> directory in your I2P config directory, which is usually <code>$HOME/.i2p</code> on Unixes.</p>
<p>This will allow the developers to contact you if your reseed has issues and will authenticate your reseed to the I2P routers that use it.</p>
<ul>
<li>darwin/amd64: <a href="http://idk.i2p/reseed-tools/reseed-tools-darwin-amd64.su3">http://idk.i2p/reseed-tools/reseed-tools-darwin-amd64.su3</a></li>
<li>darwin/arm64: <a href="http://idk.i2p/reseed-tools/reseed-tools-darwin-arm64.su3">http://idk.i2p/reseed-tools/reseed-tools-darwin-arm64.su3</a></li>

View File

@ -19,7 +19,7 @@ func main() {
app := cli.NewApp()
app.Name = "reseed-tools"
app.Version = "0.2.8"
app.Version = "0.2.9"
app.Usage = "I2P tools and reseed server"
app.Author = "eyedeekay"
app.Email = "hankhill19580@gmail.com"

View File

@ -91,6 +91,14 @@ func (srv *Server) HandleARealBrowser(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(image, "images") {
w.Header().Set("Content-Type", "image/png")
HandleAFile(w, "images", strings.TrimPrefix(strings.TrimPrefix(r.URL.Path, "/"), "images"))
} else if strings.HasPrefix(image, "ping") {
PingEverybody()
http.Redirect(w, r, "/readout", http.StatusFound)
} else if strings.HasPrefix(image, "readout") {
w.Header().Set("Content-Type", "text/html")
w.Write([]byte(header))
ReadOut(w)
w.Write([]byte(footer))
} else {
w.Header().Set("Content-Type", "text/html")
w.Write([]byte(header))
@ -101,6 +109,7 @@ func (srv *Server) HandleARealBrowser(w http.ResponseWriter, r *http.Request) {
Reseed
</button>
</form></li></ul>`))
ReadOut(w)
w.Write([]byte(footer))
}
}
@ -108,7 +117,7 @@ func (srv *Server) HandleARealBrowser(w http.ResponseWriter, r *http.Request) {
func HandleAFile(w http.ResponseWriter, dirPath, file string) {
file = filepath.Join(dirPath, file)
if _, prs := CachedDataPages[file]; prs == false {
if _, prs := CachedDataPages[file]; !prs {
path := filepath.Join(BaseContentPath, file)
f, err := ioutil.ReadFile(path)
if err != nil {
@ -123,7 +132,7 @@ func HandleAFile(w http.ResponseWriter, dirPath, file string) {
}
func HandleALocalizedFile(w http.ResponseWriter, dirPath string) {
if _, prs := CachedLanguagePages[dirPath]; prs == false {
if _, prs := CachedLanguagePages[dirPath]; !prs {
dir := filepath.Join(BaseContentPath, "lang", dirPath)
files, err := ioutil.ReadDir(dir)
if err != nil {

123
reseed/ping.go Normal file
View File

@ -0,0 +1,123 @@
package reseed
import (
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"path/filepath"
"strings"
"time"
)
// Ping requests an `.su3` from another reseed server and return true if
// the reseed server is alive If the reseed server is not alive, returns
// false and the status of the request as an error
func Ping(url string) (bool, error) {
if strings.HasSuffix(url, "i2pseeds.su3") {
url = url + "i2pseeds.su3"
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return false, err
}
req.Header.Set("User-Agent", i2pUserAgent)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return false, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return false, fmt.Errorf("%s", resp.Status)
}
return true, nil
}
func PingWriteContent(url string) error {
date := time.Now().Format("2006-01-02")
path := strings.Replace(url, "http://", "", 1)
path = strings.Replace(path, "https://", "", 1)
path = strings.Replace(path, "/", "", -1)
path = filepath.Join(BaseContentPath, path+"-"+date+".ping")
if _, err := os.Stat(path); err != nil {
result, err := Ping(url)
if result {
log.Printf("Ping: %s OK", url)
err := ioutil.WriteFile(path, []byte("Alive: Status OK"), 0644)
return err
} else {
log.Printf("Ping: %s %s", url, err)
err := ioutil.WriteFile(path, []byte("Dead: "+err.Error()), 0644)
return err
}
}
return nil
}
//TODO: make this a configuration option
var AllReseeds = []string{
"https://banana.incognet.io/",
"https://i2p.novg.net/",
"https://i2pseed.creativecowpat.net:8443/",
"https://reseed.diva.exchange/",
"https://reseed.i2pgit.org/",
"https://reseed.memcpy.io/",
"https://reseed.onion.im/",
"https://reseed2.i2p.net/",
}
func PingEverybody() []string {
var nonerrs []string
for _, url := range AllReseeds {
err := PingWriteContent(url)
if err == nil {
nonerrs = append(nonerrs, url)
} else {
nonerrs = append(nonerrs, err.Error()+"-"+url)
}
}
return nonerrs
}
// Get a list of all files ending in ping in the BaseContentPath
func GetPingFiles() ([]string, error) {
var files []string
date := time.Now().Format("2006-01-02")
err := filepath.Walk(BaseContentPath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if strings.HasSuffix(path, ".ping") && strings.Contains(path, date) {
files = append(files, path)
}
return nil
})
if len(files) == 0 {
return nil, fmt.Errorf("No ping files found")
}
return files, err
}
func ReadOut(w http.ResponseWriter) {
pinglist, err := GetPingFiles()
if err == nil {
fmt.Fprintf(w, "<h3>Reseed Server Statuses</h3>")
fmt.Fprintf(w, "<div><p>This feature is experimental and may not always provide accurate results.</p></div>")
fmt.Fprintf(w, "</div><p><ul>")
for _, file := range pinglist {
ping, err := ioutil.ReadFile(file)
host := strings.Replace(file, ".ping", "", 1)
host = filepath.Base(host)
if err == nil {
fmt.Fprintf(w, "<li><strong>%s</strong> - %s</li>\n", host, ping)
} else {
fmt.Fprintf(w, "<li><strong>%s</strong> - No ping file found</li>\n", host)
}
}
fmt.Fprintf(w, "</ul></p></div>")
} else {
fmt.Fprintf(w, "<h4>No ping files found, check back later for reseed stats</h4>")
}
}

View File

@ -34,8 +34,16 @@ func SignerFilename(signer string) string {
}
func NewTLSCertificate(host string, priv *ecdsa.PrivateKey) ([]byte, error) {
return NewTLSCertificateAltNames(priv, host)
}
func NewTLSCertificateAltNames(priv *ecdsa.PrivateKey, hosts ...string) ([]byte, error) {
notBefore := time.Now()
notAfter := notBefore.Add(5 * 365 * 24 * time.Hour)
host := ""
if len(hosts) > 0 {
host = hosts[0]
}
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
@ -61,9 +69,10 @@ func NewTLSCertificate(host string, priv *ecdsa.PrivateKey) ([]byte, error) {
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
IsCA: true,
DNSNames: hosts[1:],
}
hosts := strings.Split(host, ",")
hosts = strings.Split(host, ",")
for _, h := range hosts {
if ip := net.ParseIP(h); ip != nil {
template.IPAddresses = append(template.IPAddresses, ip)