Compare commits
95 Commits
v0.0.1
...
make-a-plu
Author | SHA1 | Date | |
---|---|---|---|
![]() |
accce088e6 | ||
![]() |
42beefd223 | ||
![]() |
12b71780a1 | ||
![]() |
b444857549 | ||
![]() |
2004e84df8 | ||
![]() |
7441572846 | ||
![]() |
93dd1b4e8d | ||
![]() |
398a6182af | ||
![]() |
d467b652ec | ||
![]() |
19c29cfdc6 | ||
![]() |
1548d1e36b | ||
![]() |
3e8ace902d | ||
![]() |
8afd6c6f28 | ||
![]() |
b94bd86d03 | ||
![]() |
7829962acd | ||
![]() |
299421e0fe | ||
a7c097d232 | |||
7282cb5fa0 | |||
2f8508ee92 | |||
b036b9e8f8 | |||
f36a500210 | |||
dbcf640320 | |||
08f2f9031d | |||
d40d687f6e | |||
b12bf1bf22 | |||
7bcc9344ec | |||
f84eb3ce70 | |||
f576588ec0 | |||
0ae229792c | |||
4e69e3d50b | |||
059a24d638 | |||
45071f0faa | |||
0791f1145b | |||
51c58d6407 | |||
0bf519a351 | |||
1eb8e6fb5c | |||
c4b8236446 | |||
162c6fb01a | |||
11c6b51be6 | |||
17712bf3ae | |||
7a438a29ed | |||
b0cd962ce9 | |||
92462d8986 | |||
8d1a4408ce | |||
179688d8c0 | |||
cb674587f6 | |||
dc0ec87635 | |||
4c86b4fd8a | |||
d48d8e217d | |||
0ac1d8ad65 | |||
c46fcb14f7 | |||
3ec7aace8a | |||
07b65bee1f | |||
1589518259 | |||
9fe7931202 | |||
8daf43276b | |||
2173a6a36e | |||
f9c992dcb2 | |||
fd9eae23eb | |||
![]() |
53eeba13a8 | ||
![]() |
e093175340 | ||
![]() |
81ea32f49c | ||
![]() |
731eaa0d11 | ||
![]() |
785a8f6b68 | ||
![]() |
7e2176986e | ||
![]() |
e630a6fe72 | ||
![]() |
352fdf2566 | ||
![]() |
d73ca116f8 | ||
![]() |
e506f38630 | ||
![]() |
4284b9ee04 | ||
![]() |
11d1479dcf | ||
![]() |
82b8f97ba4 | ||
![]() |
9ed8caaec3 | ||
![]() |
54edb1b12e | ||
![]() |
824441fa69 | ||
![]() |
da1beba872 | ||
![]() |
7c304110cd | ||
![]() |
0937e09acf | ||
![]() |
7a0bb222b9 | ||
![]() |
86a2b5f208 | ||
![]() |
2ef4aa08f9 | ||
![]() |
8b72c37a3b | ||
![]() |
2e55be1a20 | ||
![]() |
1b5e875113 | ||
![]() |
bca841c799 | ||
![]() |
c83775c361 | ||
![]() |
3aa32bcd7f | ||
![]() |
395aa73b17 | ||
![]() |
01153a9ee8 | ||
![]() |
eb0703485f | ||
![]() |
dac3888397 | ||
![]() |
83918dfff8 | ||
![]() |
54271fb852 | ||
![]() |
d5e81baf12 | ||
![]() |
8dfdb5b9d2 |
8
.dockerignore
Normal file
8
.dockerignore
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.idea
|
||||||
|
.git
|
||||||
|
.gitlab-ci.yml
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
# CI cache folder storing docker images
|
||||||
|
ci-exports
|
||||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
@@ -5,3 +5,5 @@
|
|||||||
i2pseeds.su3
|
i2pseeds.su3
|
||||||
*.pem
|
*.pem
|
||||||
onion.key
|
onion.key
|
||||||
|
tmp/
|
||||||
|
i2p-tools-*
|
||||||
|
106
.gitlab-ci.yml
Normal file
106
.gitlab-ci.yml
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
image: docker:19.03.12
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- docker_test
|
||||||
|
- docker_push
|
||||||
|
|
||||||
|
variables:
|
||||||
|
# When using dind service, we need to instruct docker to talk with
|
||||||
|
# the daemon started inside of the service. The daemon is available
|
||||||
|
# with a network connection instead of the default
|
||||||
|
# /var/run/docker.sock socket. Docker 19.03 does this automatically
|
||||||
|
# by setting the DOCKER_HOST in
|
||||||
|
# https://github.com/docker-library/docker/blob/d45051476babc297257df490d22cbd806f1b11e4/19.03/docker-entrypoint.sh#L23-L29
|
||||||
|
#
|
||||||
|
# The 'docker' hostname is the alias of the service container as described at
|
||||||
|
# https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services.
|
||||||
|
#
|
||||||
|
# Specify to Docker where to create the certificates, Docker will
|
||||||
|
# create them automatically on boot, and will create
|
||||||
|
# `/certs/client` that will be shared between the service and job
|
||||||
|
# container, thanks to volume mount from config.toml
|
||||||
|
DOCKER_TLS_CERTDIR: "/certs"
|
||||||
|
# Use TLS https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
|
||||||
|
DOCKER_HOST: tcp://docker:2376
|
||||||
|
|
||||||
|
services:
|
||||||
|
- docker:19.03.12-dind
|
||||||
|
|
||||||
|
.docker_cache:
|
||||||
|
cache:
|
||||||
|
# The same key should be used across branches
|
||||||
|
key: "$CI_COMMIT_REF_SLUG"
|
||||||
|
paths:
|
||||||
|
- ci-exports/*.tar
|
||||||
|
|
||||||
|
# Make sure we can build a docker image
|
||||||
|
# It's cached for later jobs
|
||||||
|
build_docker:
|
||||||
|
extends:
|
||||||
|
- .docker_cache
|
||||||
|
stage: docker_test
|
||||||
|
script:
|
||||||
|
# Try to load latest branch image from local tar or from registry
|
||||||
|
- docker load ci-exports/$CI_COMMIT_REF_SLUG.tar || docker pull $CI_REGISTRY_IMAGE:latest || true
|
||||||
|
- docker build --cache-from $CI_REGISTRY_IMAGE:latest --tag $CI_REGISTRY_IMAGE:latest .
|
||||||
|
- mkdir -p ci-exports/
|
||||||
|
- docker save $CI_REGISTRY_IMAGE:latest > ci-exports/$CI_COMMIT_REF_SLUG.tar
|
||||||
|
|
||||||
|
# Publishes the configured CI registry (by default that's gitlab's registry)
|
||||||
|
push_ci_registry:
|
||||||
|
extends:
|
||||||
|
- .docker_cache
|
||||||
|
stage: docker_push
|
||||||
|
cache:
|
||||||
|
policy: pull
|
||||||
|
before_script:
|
||||||
|
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||||
|
script:
|
||||||
|
- cat ci-exports/$CI_COMMIT_REF_SLUG.tar | docker load
|
||||||
|
- docker tag $CI_REGISTRY_IMAGE:latest $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||||
|
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||||
|
- docker push $CI_REGISTRY_IMAGE:latest
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
# Make sure to protect these tags!
|
||||||
|
- /^v(\d+\.){2,3}\d+$/
|
||||||
|
- /.+-release$/
|
||||||
|
variables:
|
||||||
|
- $CI_REGISTRY
|
||||||
|
- $CI_REGISTRY_USER
|
||||||
|
- $CI_REGISTRY_PASSWORD
|
||||||
|
- $CI_REGISTRY_IMAGE
|
||||||
|
|
||||||
|
# Publishes the cached image to docker
|
||||||
|
push_dockerhub_registry:
|
||||||
|
extends:
|
||||||
|
- .docker_cache
|
||||||
|
stage: docker_push
|
||||||
|
cache:
|
||||||
|
policy: pull
|
||||||
|
before_script:
|
||||||
|
- docker login -u $DOCKERHUB_REGISTRY_USER -p $DOCKERHUB_REGISTRY_PASSWORD $DOCKERHUB_REGISTRY
|
||||||
|
script:
|
||||||
|
- cat ci-exports/$CI_COMMIT_REF_SLUG.tar | docker load
|
||||||
|
- docker tag $CI_REGISTRY_IMAGE:latest $DOCKERHUB_REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||||
|
- docker tag $CI_REGISTRY_IMAGE:latest $DOCKERHUB_REGISTRY_IMAGE:latest
|
||||||
|
- docker push $DOCKERHUB_REGISTRY_IMAGE:$CI_COMMIT_TAG
|
||||||
|
- docker push $DOCKERHUB_REGISTRY_IMAGE:latest
|
||||||
|
# Push the readme to dockerhub
|
||||||
|
- >-
|
||||||
|
docker run -v $PWD:/workspace
|
||||||
|
-e DOCKERHUB_USERNAME="$DOCKERHUB_REGISTRY_USER"
|
||||||
|
-e DOCKERHUB_PASSWORD="$DOCKERHUB_REGISTRY_PASSWORD"
|
||||||
|
-e DOCKERHUB_REPOSITORY="$DOCKERHUB_REGISTRY_IMAGE"
|
||||||
|
-e README_FILEPATH='/workspace/README.md'
|
||||||
|
peterevans/dockerhub-description:2
|
||||||
|
only:
|
||||||
|
refs:
|
||||||
|
# Make sure to protect these tags!
|
||||||
|
- /^v(\d+\.){2,3}\d+$/
|
||||||
|
- /.+-release$/
|
||||||
|
variables:
|
||||||
|
- $DOCKERHUB_REGISTRY
|
||||||
|
- $DOCKERHUB_REGISTRY_USER
|
||||||
|
- $DOCKERHUB_REGISTRY_PASSWORD
|
||||||
|
- $DOCKERHUB_REGISTRY_IMAGE
|
@@ -31,4 +31,4 @@
|
|||||||
* numRi per su3 file: 75 --> 77
|
* numRi per su3 file: 75 --> 77
|
||||||
|
|
||||||
2016-01
|
2016-01
|
||||||
* fork from https://github.com/MDrollette/i2p-tools
|
* fork from https://i2pgit.org/idk/reseed-tools
|
||||||
|
14
Dockerfile
Normal file
14
Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
FROM debian:stable-backports
|
||||||
|
ARG I2P_GID=1000
|
||||||
|
ARG I2P_UID=1000
|
||||||
|
COPY . /var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools
|
||||||
|
WORKDIR /var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get dist-upgrade -y && \
|
||||||
|
apt-get install -y git golang-1.13-go make && \
|
||||||
|
mkdir -p /var/lib/i2p/i2p-config/reseed && \
|
||||||
|
chown -R $I2P_UID:$I2P_GID /var/lib/i2p && chmod -R o+rwx /var/lib/i2p
|
||||||
|
RUN /usr/lib/go-1.13/bin/go build -v -tags netgo -ldflags '-w -extldflags "-static"'
|
||||||
|
USER $I2P_UID
|
||||||
|
WORKDIR /var/lib/i2p/i2p-config/reseed
|
||||||
|
ENTRYPOINT [ "/var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools/entrypoint.sh" ]
|
149
Makefile
Normal file
149
Makefile
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
|
||||||
|
VERSION=0.0.6
|
||||||
|
APP=i2p-tools-1
|
||||||
|
USER_GH=eyedeekay
|
||||||
|
|
||||||
|
GOOS?=$(shell uname -s | tr A-Z a-z)
|
||||||
|
GOARCH?="amd64"
|
||||||
|
|
||||||
|
ARG=-v -tags netgo -ldflags '-w -extldflags "-static"'
|
||||||
|
|
||||||
|
#MIN_GO_VERSION=`ls /usr/lib/go-1.14 2>/dev/null >/dev/null && echo 1.14`
|
||||||
|
MIN_GO_VERSION?=1.15
|
||||||
|
|
||||||
|
I2P_UID=$(shell id -u i2psvc)
|
||||||
|
I2P_GID=$(shell id -g i2psvc)
|
||||||
|
|
||||||
|
WHOAMI=$(shell whoami)
|
||||||
|
|
||||||
|
echo:
|
||||||
|
@echo "type make version to do release $(APP) $(VERSION) $(GOOS) $(GOARCH) $(MIN_GO_VERSION) $(I2P_UID) $(I2P_GID)"
|
||||||
|
|
||||||
|
version:
|
||||||
|
cat README.md | gothub release -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(APP) -t v$(VERSION) -d -
|
||||||
|
|
||||||
|
edit:
|
||||||
|
cat README.md | gothub edit -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(APP) -t v$(VERSION) -d -
|
||||||
|
|
||||||
|
upload: binary tar
|
||||||
|
gothub upload -s $(GITHUB_TOKEN) -u $(USER_GH) -r $(APP) -t v$(VERSION) -f ../i2p-tools.tar.xz -n "i2p-tools.tar.xz"
|
||||||
|
|
||||||
|
build: gofmt
|
||||||
|
/usr/lib/go-$(MIN_GO_VERSION)/bin/go build $(ARG) -o i2p-tools-$(GOOS)-$(GOARCH)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm i2p-tools-* *.key *.i2pKeys *.crt *.crl *.pem tmp -rf
|
||||||
|
|
||||||
|
binary:
|
||||||
|
GOOS=darwin GOARCH=amd64 make build
|
||||||
|
GOOS=linux GOARCH=386 make build
|
||||||
|
GOOS=linux GOARCH=amd64 make build
|
||||||
|
GOOS=linux GOARCH=arm make build
|
||||||
|
GOOS=linux GOARCH=arm64 make build
|
||||||
|
GOOS=openbsd GOARCH=amd64 make build
|
||||||
|
GOOS=freebsd GOARCH=386 make build
|
||||||
|
GOOS=freebsd GOARCH=amd64 make build
|
||||||
|
|
||||||
|
tar:
|
||||||
|
tar --exclude="./.git" --exclude="./tmp" -cvf ../i2p-tools.tar.xz .
|
||||||
|
|
||||||
|
install:
|
||||||
|
install -m755 i2p-tools-$(GOOS)-$(GOARCH) /usr/local/bin/i2p-tools
|
||||||
|
install -m755 etc/init.d/reseed /etc/init.d/reseed
|
||||||
|
|
||||||
|
### You shouldn't need to use these now that the go mod require rule is fixed,
|
||||||
|
## but I'm leaving them in here because it made it easier to test that both
|
||||||
|
## versions behaved the same way. -idk
|
||||||
|
|
||||||
|
build-fork:
|
||||||
|
/usr/lib/go-$(MIN_GO_VERSION)/bin/go build -o i2p-tools-idk
|
||||||
|
|
||||||
|
build-unfork:
|
||||||
|
/usr/lib/go-$(MIN_GO_VERSION)/bin/go build -o i2p-tools-md
|
||||||
|
|
||||||
|
fork:
|
||||||
|
sed -i 's|idk/reseed-tools|idk/reseed-tools|g' main.go cmd/*.go reseed/*.go su3/*.go
|
||||||
|
make gofmt build-fork
|
||||||
|
|
||||||
|
unfork:
|
||||||
|
sed -i 's|idk/reseed-tools|idk/reseed-tools|g' main.go cmd/*.go reseed/*.go su3/*.go
|
||||||
|
sed -i 's|RTradeLtd/i2p-tools-1|idk/reseed-tools|g' main.go cmd/*.go reseed/*.go su3/*.go
|
||||||
|
make gofmt build-unfork
|
||||||
|
|
||||||
|
gofmt:
|
||||||
|
gofmt -w main.go cmd/*.go reseed/*.go su3/*.go
|
||||||
|
|
||||||
|
try:
|
||||||
|
mkdir -p tmp && \
|
||||||
|
cd tmp && \
|
||||||
|
../i2p-tools-$(GOOS)-$(GOARCH) reseed --signer=you@mail.i2p --netdb=/home/idk/.i2p/netDb --tlsHost=your-domain.tld --onion --p2p --i2p --littleboss=start
|
||||||
|
|
||||||
|
stop:
|
||||||
|
mkdir -p tmp && \
|
||||||
|
cd tmp && \
|
||||||
|
../i2p-tools-$(GOOS)-$(GOARCH) reseed --signer=you@mail.i2p --netdb=/home/idk/.i2p/netDb --tlsHost=your-domain.tld --onion --p2p --i2p --littleboss=stop
|
||||||
|
|
||||||
|
docker:
|
||||||
|
docker build -t eyedeekay/reseed .
|
||||||
|
|
||||||
|
docker-push: docker
|
||||||
|
docker push --disable-content-trust false eyedeekay/reseed:$(VERSION)
|
||||||
|
|
||||||
|
users:
|
||||||
|
docker run --rm eyedeekay/reseed cat /etc/passwd
|
||||||
|
|
||||||
|
docker-ls:
|
||||||
|
docker run --rm \
|
||||||
|
--user $(I2P_UID) \
|
||||||
|
--group-add $(I2P_GID) \
|
||||||
|
--name reseed \
|
||||||
|
--publish 8443:8443 \
|
||||||
|
--volume /var/lib/i2p/i2p-config/netDb:/var/lib/i2p/i2p-config/netDb \
|
||||||
|
eyedeekay/reseed ls /var/lib/i2p/i2p-config -lah
|
||||||
|
|
||||||
|
docker-server:
|
||||||
|
docker run -itd \
|
||||||
|
--name reseed \
|
||||||
|
--user $(I2P_UID) \
|
||||||
|
--group-add $(I2P_GID) \
|
||||||
|
--publish 8443:8443 \
|
||||||
|
--restart=always \
|
||||||
|
--volume /var/lib/i2p/i2p-config/netDb:/var/lib/i2p/i2p-config/netDb:z \
|
||||||
|
--volume reseed-keyss:/var/lib/i2p/i2p-config/reseed \
|
||||||
|
eyedeekay/reseed \
|
||||||
|
--signer=hankhill19580@gmail.com
|
||||||
|
docker logs -f reseed
|
||||||
|
|
||||||
|
docker-run:
|
||||||
|
docker run -itd \
|
||||||
|
--name reseed \
|
||||||
|
--user $(I2P_UID) \
|
||||||
|
--group-add $(I2P_GID) \
|
||||||
|
--publish 8443:8443 \
|
||||||
|
--volume /var/lib/i2p/i2p-config/netDb:/var/lib/i2p/i2p-config/netDb:z \
|
||||||
|
--volume reseed-keys:/var/lib/i2p/i2p-config/reseed \
|
||||||
|
eyedeekay/reseed \
|
||||||
|
--signer=hankhill19580@gmail.com
|
||||||
|
|
||||||
|
docker-homerun:
|
||||||
|
docker run -itd \
|
||||||
|
--name reseed \
|
||||||
|
--user 1000 \
|
||||||
|
--group-add 1000 \
|
||||||
|
--publish 8443:8443 \
|
||||||
|
--volume $(HOME)/i2p/netDb:/var/lib/i2p/i2p-config/netDb:z \
|
||||||
|
--volume reseed-keys:/var/lib/i2p/i2p-config/reseed:z \
|
||||||
|
eyedeekay/reseed \
|
||||||
|
--signer=hankhill19580@gmail.com
|
||||||
|
|
||||||
|
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/jre/
|
||||||
|
export CGO_CFLAGS=-I/usr/lib/jvm/java-8-openjdk-amd64/include/ -I/usr/lib/jvm/java-8-openjdk-amd64/include/linux/
|
||||||
|
|
||||||
|
gojava:
|
||||||
|
go get -u -v github.com/sridharv/gojava
|
||||||
|
cp -v ~/go/bin/gojava ./gojava
|
||||||
|
|
||||||
|
jar: gojava
|
||||||
|
echo $(JAVA_HOME)
|
||||||
|
./gojava -v -o reseed.jar -s . build ./reseed
|
||||||
|
|
95
README.md
95
README.md
@@ -1,29 +1,88 @@
|
|||||||
I2P Reseed Tools
|
I2P Reseed Tools
|
||||||
==================
|
==================
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
If you have go installed you can download, build, and install this tool with `go get`
|
If you have go installed you can download, build, and install this tool with `go get`
|
||||||
|
|
||||||
```
|
```
|
||||||
go get github.com/MDrollette/i2p-tools
|
go get i2pgit.org/idk/reseed-tools
|
||||||
i2p-tools -h
|
reseed-tools -h
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
### Docker!
|
||||||
|
|
||||||
|
To make it easier to deploy reseeds, it is possible to run this software as a
|
||||||
|
Docker image. Because the software requires access to a network database to host
|
||||||
|
a reseed, you will need to mount the netDb as a volume inside your docker
|
||||||
|
container to provide access to it, and you will need to run it as the same user
|
||||||
|
and group inside the container as I2P.
|
||||||
|
|
||||||
|
When you run a reseed under Docker in this fashion, it will automatically
|
||||||
|
generate a self-signed certificate for your reseed server in a Docker volume
|
||||||
|
mamed reseed-keys. *Back up this directory*, if it is lost it is impossible
|
||||||
|
to reproduce.
|
||||||
|
|
||||||
|
Please note that Docker is not currently compatible with .onion reseeds unless
|
||||||
|
you pass the --network=host tag.
|
||||||
|
|
||||||
|
#### If I2P is running as your user, do this:
|
||||||
|
|
||||||
|
docker run -itd \
|
||||||
|
--name reseed \
|
||||||
|
--publish 443:8443 \
|
||||||
|
--restart always \
|
||||||
|
--volume $HOME/.i2p/netDb:$HOME/.i2p/netDb:z \
|
||||||
|
--volume reseed-keys:/var/lib/i2p/i2p-config/reseed \
|
||||||
|
eyedeekay/reseed \
|
||||||
|
--signer $YOUR_EMAIL_HERE
|
||||||
|
|
||||||
|
#### If I2P is running as another user, do this:
|
||||||
|
|
||||||
|
docker run -itd \
|
||||||
|
--name reseed \
|
||||||
|
--user $(I2P_UID) \
|
||||||
|
--group-add $(I2P_GID) \
|
||||||
|
--publish 443:8443 \
|
||||||
|
--restart always \
|
||||||
|
--volume /PATH/TO/USER/I2P/HERE/netDb:/var/lib/i2p/i2p-config/netDb:z \
|
||||||
|
--volume reseed-keys:/var/lib/i2p/i2p-config/reseed \
|
||||||
|
eyedeekay/reseed \
|
||||||
|
--signer $YOUR_EMAIL_HERE
|
||||||
|
|
||||||
|
#### **Debian/Ubuntu and Docker**
|
||||||
|
|
||||||
|
In many cases I2P will be running as the Debian system user ```i2psvc```. This
|
||||||
|
is the case for all installs where Debian's Advanced Packaging Tool(apt) was
|
||||||
|
used to peform the task. If you used ```apt-get install``` this command will
|
||||||
|
work for you. In that case, just copy-and-paste:
|
||||||
|
|
||||||
|
docker run -itd \
|
||||||
|
--name reseed \
|
||||||
|
--user $(id -u i2psvc) \
|
||||||
|
--group-add $(id -g i2psvc) \
|
||||||
|
--publish 443:8443 \
|
||||||
|
--restart always \
|
||||||
|
--volume /var/lib/i2p/i2p-config/netDb:/var/lib/i2p/i2p-config/netDb:z \
|
||||||
|
--volume reseed-keys:/var/lib/i2p/i2p-config/reseed \
|
||||||
|
eyedeekay/reseed \
|
||||||
|
--signer $YOUR_EMAIL_HERE
|
||||||
|
|
||||||
### Locally behind a webserver (reverse proxy setup), preferred:
|
### Locally behind a webserver (reverse proxy setup), preferred:
|
||||||
|
|
||||||
```
|
```
|
||||||
i2p-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --port=8443 --ip=127.0.0.1 --trustProxy
|
reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --port=8443 --ip=127.0.0.1 --trustProxy
|
||||||
```
|
```
|
||||||
|
|
||||||
### Without a webserver, standalone with TLS support
|
### Without a webserver, standalone with TLS support
|
||||||
|
|
||||||
```
|
```
|
||||||
i2p-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --tlsHost=your-domain.tld
|
reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --tlsHost=your-domain.tld
|
||||||
```
|
```
|
||||||
|
|
||||||
If this is your first time running a reseed server (ie. you don't have any existing keys),
|
If this is your first time running a reseed server (ie. you don't have any existing keys),
|
||||||
@@ -38,61 +97,61 @@ http://j7xszhsjy7orrnbdys7yykrssv5imkn4eid7n5ikcnxuhpaaw6cq.b32.i2p/
|
|||||||
|
|
||||||
also a short guide and complete tech info.
|
also a short guide and complete tech info.
|
||||||
|
|
||||||
## Experimental, currently only available from eyedeekay/i2p-tools-1 fork
|
## Experimental, currently only available from idk/reseed-tools fork
|
||||||
|
|
||||||
Requires ```go mod``` and at least go 1.13. To build the eyedeekay/i2p-tools-1
|
Requires ```go mod``` and at least go 1.13. To build the idk/reseed-tools
|
||||||
fork, from anywhere:
|
fork, from anywhere:
|
||||||
|
|
||||||
git clone https://github.com/eyedeekay/i2p-tools-1
|
git clone https://i2pgit.org/idk/reseed-tools
|
||||||
cd i2p-tools-1
|
cd reseed-tools
|
||||||
make build
|
make build
|
||||||
|
|
||||||
### Without a webserver, standalone, self-supervising(Automatic restarts)
|
### Without a webserver, standalone, self-supervising(Automatic restarts)
|
||||||
|
|
||||||
```
|
```
|
||||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --restart=start
|
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --littleboss=start
|
||||||
```
|
```
|
||||||
|
|
||||||
### Without a webserver, standalone, automatic OnionV3 with TLS support
|
### Without a webserver, standalone, automatic OnionV3 with TLS support
|
||||||
|
|
||||||
```
|
```
|
||||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion
|
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --i2p --p2p
|
||||||
```
|
```
|
||||||
|
|
||||||
### Without a webserver, standalone, serve P2P with LibP2P
|
### Without a webserver, standalone, serve P2P with LibP2P
|
||||||
|
|
||||||
```
|
```
|
||||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --p2p
|
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --p2p
|
||||||
```
|
```
|
||||||
|
|
||||||
### Without a webserver, standalone, upload a single signed .su3 to github
|
### Without a webserver, standalone, upload a single signed .su3 to github
|
||||||
|
|
||||||
* This one isn't working yet, look for it by ~Monday.
|
* This one isn't working yet, I'll get to it eventually, I've got a cooler idea now.
|
||||||
|
|
||||||
```
|
```
|
||||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --github --ghrepo=i2p-tools-1 --ghuser=eyedeekay
|
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --github --ghrepo=reseed-tools --ghuser=eyedeekay
|
||||||
```
|
```
|
||||||
|
|
||||||
### Without a webserver, standalone, in-network reseed
|
### Without a webserver, standalone, in-network reseed
|
||||||
|
|
||||||
```
|
```
|
||||||
./i2p-tools-1 reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --i2p
|
./reseed-tools reseed --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --i2p
|
||||||
```
|
```
|
||||||
|
|
||||||
### Without a webserver, standalone, Regular TLS, OnionV3 with TLS
|
### Without a webserver, standalone, Regular TLS, OnionV3 with TLS
|
||||||
|
|
||||||
```
|
```
|
||||||
./i2p-tools-1 reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion
|
./reseed-tools reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion
|
||||||
```
|
```
|
||||||
|
|
||||||
### Without a webserver, standalone, Regular TLS, OnionV3 with TLS, and LibP2P
|
### Without a webserver, standalone, Regular TLS, OnionV3 with TLS, and LibP2P
|
||||||
|
|
||||||
```
|
```
|
||||||
./i2p-tools-1 reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --p2p
|
./reseed-tools reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --p2p
|
||||||
```
|
```
|
||||||
|
|
||||||
### Without a webserver, standalone, Regular TLS, OnionV3 with TLS, I2P In-Network reseed, and LibP2P, self-supervising
|
### Without a webserver, standalone, Regular TLS, OnionV3 with TLS, I2P In-Network reseed, and LibP2P, self-supervising
|
||||||
|
|
||||||
```
|
```
|
||||||
./i2p-tools-1 reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --p2p --restart=start
|
./reseed-tools reseed --tlsHost=your-domain.tld --signer=you@mail.i2p --netdb=/home/i2p/.i2p/netDb --onion --p2p --littleboss=start
|
||||||
```
|
```
|
@@ -3,7 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/codegangsta/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewKeygenCommand() cli.Command {
|
func NewKeygenCommand() cli.Command {
|
||||||
|
193
cmd/reseed.go
193
cmd/reseed.go
@@ -2,6 +2,7 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
//"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@@ -11,16 +12,16 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"crawshaw.io/littleboss"
|
//"crawshaw.io/littleboss"
|
||||||
"github.com/MDrollette/i2p-tools/reseed"
|
|
||||||
"github.com/RTradeLtd/go-garlic-tcp-transport/common"
|
|
||||||
"github.com/codegangsta/cli"
|
|
||||||
"github.com/cretz/bine/tor"
|
"github.com/cretz/bine/tor"
|
||||||
"github.com/cretz/bine/torutil"
|
"github.com/cretz/bine/torutil"
|
||||||
"github.com/cretz/bine/torutil/ed25519"
|
"github.com/cretz/bine/torutil/ed25519"
|
||||||
|
"github.com/eyedeekay/sam3"
|
||||||
"github.com/eyedeekay/sam3/i2pkeys"
|
"github.com/eyedeekay/sam3/i2pkeys"
|
||||||
"github.com/libp2p/go-libp2p"
|
"github.com/libp2p/go-libp2p"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
"i2pgit.org/idk/reseed-tools/reseed"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewReseedCommand() cli.Command {
|
func NewReseedCommand() cli.Command {
|
||||||
@@ -118,31 +119,84 @@ func NewReseedCommand() cli.Command {
|
|||||||
Name: "i2p",
|
Name: "i2p",
|
||||||
Usage: "Listen for reseed request inside the I2P network",
|
Usage: "Listen for reseed request inside the I2P network",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "yes",
|
||||||
|
Usage: "Automatically answer 'yes' to self-signed SSL generation",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "samaddr",
|
Name: "samaddr",
|
||||||
Value: "127.0.0.1:7656",
|
Value: "127.0.0.1:7656",
|
||||||
Usage: "Use this SAM address to set up I2P connections for in-network reseed",
|
Usage: "Use this SAM address to set up I2P connections for in-network reseed",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "restart",
|
Name: "littleboss",
|
||||||
Value: "start",
|
Value: "start",
|
||||||
Usage: "Start in self-supervising mode",
|
Usage: "Self-Supervise this application",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "acme",
|
||||||
|
Usage: "Automatically generate a TLS certificate with the ACME protocol, defaults to Let's Encrypt",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "acmeserver",
|
||||||
|
Value: "https://acme-staging-v02.api.letsencrypt.org/directory",
|
||||||
|
Usage: "Use this server to issue a certificate with the ACME protocol",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reseedMain(c *cli.Context) {
|
func CreateEepServiceKey(c *cli.Context) (i2pkeys.I2PKeys, error) {
|
||||||
lb := littleboss.New("reseed")
|
sam, err := sam3.NewSAM(c.String("samaddr"))
|
||||||
restart := c.String("restart")
|
if err != nil {
|
||||||
lb.Command("restart", &restart)
|
return i2pkeys.I2PKeys{}, err
|
||||||
lb.Run(func(ctx context.Context) {
|
}
|
||||||
reseedAction(c)
|
defer sam.Close()
|
||||||
})
|
k, err := sam.NewKeys()
|
||||||
|
if err != nil {
|
||||||
|
return i2pkeys.I2PKeys{}, err
|
||||||
|
}
|
||||||
|
return k, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadKeys(keysPath string, c *cli.Context) (i2pkeys.I2PKeys, error) {
|
||||||
|
if _, err := os.Stat(keysPath); os.IsNotExist(err) {
|
||||||
|
keys, err := CreateEepServiceKey(c)
|
||||||
|
if err != nil {
|
||||||
|
return i2pkeys.I2PKeys{}, err
|
||||||
|
}
|
||||||
|
file, err := os.Create(keysPath)
|
||||||
|
defer file.Close()
|
||||||
|
if err != nil {
|
||||||
|
return i2pkeys.I2PKeys{}, err
|
||||||
|
}
|
||||||
|
err = i2pkeys.StoreKeysIncompat(keys, file)
|
||||||
|
if err != nil {
|
||||||
|
return i2pkeys.I2PKeys{}, err
|
||||||
|
}
|
||||||
|
return keys, nil
|
||||||
|
} else if err == nil {
|
||||||
|
file, err := os.Open(keysPath)
|
||||||
|
defer file.Close()
|
||||||
|
if err != nil {
|
||||||
|
return i2pkeys.I2PKeys{}, err
|
||||||
|
}
|
||||||
|
keys, err := i2pkeys.LoadKeysIncompat(file)
|
||||||
|
if err != nil {
|
||||||
|
return i2pkeys.I2PKeys{}, err
|
||||||
|
}
|
||||||
|
return keys, nil
|
||||||
|
} else {
|
||||||
|
return i2pkeys.I2PKeys{}, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reseedAction(c *cli.Context) {
|
func reseedAction(c *cli.Context) {
|
||||||
// validate flags
|
// validate flags
|
||||||
|
if c.String("littleboss") != "start" {
|
||||||
|
log.Println("--littleboss", c.String("littleboss"))
|
||||||
|
return
|
||||||
|
}
|
||||||
netdbDir := c.String("netdb")
|
netdbDir := c.String("netdb")
|
||||||
if netdbDir == "" {
|
if netdbDir == "" {
|
||||||
fmt.Println("--netdb is required")
|
fmt.Println("--netdb is required")
|
||||||
@@ -163,28 +217,67 @@ func reseedAction(c *cli.Context) {
|
|||||||
var i2pTlsCert, i2pTlsKey string
|
var i2pTlsCert, i2pTlsKey string
|
||||||
var i2pkey i2pkeys.I2PKeys
|
var i2pkey i2pkeys.I2PKeys
|
||||||
|
|
||||||
|
if tlsHost != "" {
|
||||||
|
onionTlsHost = tlsHost
|
||||||
|
i2pTlsHost = tlsHost
|
||||||
|
tlsKey = c.String("tlsKey")
|
||||||
|
// if no key is specified, default to the host.pem in the current dir
|
||||||
|
if tlsKey == "" {
|
||||||
|
tlsKey = tlsHost + ".pem"
|
||||||
|
onionTlsKey = tlsHost + ".pem"
|
||||||
|
i2pTlsKey = tlsHost + ".pem"
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsCert = c.String("tlsCert")
|
||||||
|
// if no certificate is specified, default to the host.crt in the current dir
|
||||||
|
if tlsCert == "" {
|
||||||
|
tlsCert = tlsHost + ".crt"
|
||||||
|
onionTlsCert = tlsHost + ".crt"
|
||||||
|
i2pTlsCert = tlsHost + ".crt"
|
||||||
|
}
|
||||||
|
|
||||||
|
// prompt to create tls keys if they don't exist?
|
||||||
|
auto := c.Bool("yes")
|
||||||
|
// use ACME?
|
||||||
|
acme := c.Bool("acme")
|
||||||
|
if acme {
|
||||||
|
acmeserver := c.String("acmeserver")
|
||||||
|
err := checkUseAcmeCert(tlsHost, signerID, acmeserver, &tlsCert, &tlsKey, auto)
|
||||||
|
if nil != err {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := checkOrNewTLSCert(tlsHost, &tlsCert, &tlsKey, auto)
|
||||||
|
if nil != err {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if c.Bool("i2p") {
|
if c.Bool("i2p") {
|
||||||
var err error
|
var err error
|
||||||
i2pkey, err = i2phelpers.LoadKeys("i2pkeys")
|
i2pkey, err = LoadKeys("reseed.i2pkeys", c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
i2pTlsHost = i2pkey.Addr().Base32()
|
if i2pTlsHost == "" {
|
||||||
|
i2pTlsHost = i2pkey.Addr().Base32()
|
||||||
|
}
|
||||||
if i2pTlsHost != "" {
|
if i2pTlsHost != "" {
|
||||||
i2pTlsKey = c.String("tlsKey")
|
|
||||||
// if no key is specified, default to the host.pem in the current dir
|
// if no key is specified, default to the host.pem in the current dir
|
||||||
if i2pTlsKey == "" {
|
if i2pTlsKey == "" {
|
||||||
i2pTlsKey = i2pTlsHost + ".pem"
|
i2pTlsKey = i2pTlsHost + ".pem"
|
||||||
}
|
}
|
||||||
|
|
||||||
i2pTlsCert = c.String("tlsCert")
|
|
||||||
// if no certificate is specified, default to the host.crt in the current dir
|
// if no certificate is specified, default to the host.crt in the current dir
|
||||||
if i2pTlsCert == "" {
|
if i2pTlsCert == "" {
|
||||||
i2pTlsCert = i2pTlsHost + ".crt"
|
i2pTlsCert = i2pTlsHost + ".crt"
|
||||||
}
|
}
|
||||||
|
|
||||||
// prompt to create tls keys if they don't exist?
|
// prompt to create tls keys if they don't exist?
|
||||||
err := checkOrNewTLSCert(i2pTlsHost, &i2pTlsCert, &i2pTlsKey)
|
auto := c.Bool("yes")
|
||||||
|
err := checkOrNewTLSCert(i2pTlsHost, &i2pTlsCert, &i2pTlsKey, auto)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
@@ -206,52 +299,33 @@ func reseedAction(c *cli.Context) {
|
|||||||
}
|
}
|
||||||
ok = []byte(key.PrivateKey())
|
ok = []byte(key.PrivateKey())
|
||||||
}
|
}
|
||||||
onionTlsHost = torutil.OnionServiceIDFromPrivateKey(ed25519.PrivateKey(ok)) + ".onion"
|
if onionTlsHost == "" {
|
||||||
|
onionTlsHost = torutil.OnionServiceIDFromPrivateKey(ed25519.PrivateKey(ok)) + ".onion"
|
||||||
|
}
|
||||||
err = ioutil.WriteFile(c.String("onionKey"), ok, 0644)
|
err = ioutil.WriteFile(c.String("onionKey"), ok, 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalln(err.Error())
|
log.Fatalln(err.Error())
|
||||||
}
|
}
|
||||||
if onionTlsHost != "" {
|
if onionTlsHost != "" {
|
||||||
onionTlsKey = c.String("tlsKey")
|
|
||||||
// if no key is specified, default to the host.pem in the current dir
|
// if no key is specified, default to the host.pem in the current dir
|
||||||
if onionTlsKey == "" {
|
if onionTlsKey == "" {
|
||||||
onionTlsKey = onionTlsHost + ".pem"
|
onionTlsKey = onionTlsHost + ".pem"
|
||||||
}
|
}
|
||||||
|
|
||||||
onionTlsCert = c.String("tlsCert")
|
|
||||||
// if no certificate is specified, default to the host.crt in the current dir
|
// if no certificate is specified, default to the host.crt in the current dir
|
||||||
if onionTlsCert == "" {
|
if onionTlsCert == "" {
|
||||||
onionTlsCert = onionTlsHost + ".crt"
|
onionTlsCert = onionTlsHost + ".crt"
|
||||||
}
|
}
|
||||||
|
|
||||||
// prompt to create tls keys if they don't exist?
|
// prompt to create tls keys if they don't exist?
|
||||||
err := checkOrNewTLSCert(onionTlsHost, &onionTlsCert, &onionTlsKey)
|
auto := c.Bool("yes")
|
||||||
|
err := checkOrNewTLSCert(onionTlsHost, &onionTlsCert, &onionTlsKey, auto)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if tlsHost != "" {
|
|
||||||
tlsKey = c.String("tlsKey")
|
|
||||||
// if no key is specified, default to the host.pem in the current dir
|
|
||||||
if tlsKey == "" {
|
|
||||||
tlsKey = tlsHost + ".pem"
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsCert = c.String("tlsCert")
|
|
||||||
// if no certificate is specified, default to the host.crt in the current dir
|
|
||||||
if tlsCert == "" {
|
|
||||||
tlsCert = tlsHost + ".crt"
|
|
||||||
}
|
|
||||||
|
|
||||||
// prompt to create tls keys if they don't exist?
|
|
||||||
err := checkOrNewTLSCert(tlsHost, &tlsCert, &tlsKey)
|
|
||||||
if nil != err {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
reloadIntvl, err := time.ParseDuration(c.String("interval"))
|
reloadIntvl, err := time.ParseDuration(c.String("interval"))
|
||||||
if nil != err {
|
if nil != err {
|
||||||
fmt.Printf("'%s' is not a valid time interval.\n", reloadIntvl)
|
fmt.Printf("'%s' is not a valid time interval.\n", reloadIntvl)
|
||||||
@@ -265,7 +339,8 @@ func reseedAction(c *cli.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load our signing privKey
|
// load our signing privKey
|
||||||
privKey, err := getOrNewSigningCert(&signerKey, signerID)
|
auto := c.Bool("yes")
|
||||||
|
privKey, err := getOrNewSigningCert(&signerKey, signerID, auto)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
@@ -317,7 +392,7 @@ func reseedAction(c *cli.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reseedHTTPS(c *cli.Context, tlsCert, tlsKey string, reseeder reseed.Reseeder) {
|
func reseedHTTPS(c *cli.Context, tlsCert, tlsKey string, reseeder *reseed.ReseederImpl) {
|
||||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||||
server.Reseeder = reseeder
|
server.Reseeder = reseeder
|
||||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||||
@@ -346,7 +421,7 @@ func reseedHTTPS(c *cli.Context, tlsCert, tlsKey string, reseeder reseed.Reseede
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reseedHTTP(c *cli.Context, reseeder reseed.Reseeder) {
|
func reseedHTTP(c *cli.Context, reseeder *reseed.ReseederImpl) {
|
||||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||||
server.Reseeder = reseeder
|
server.Reseeder = reseeder
|
||||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||||
@@ -383,7 +458,7 @@ func makeRandomHost(port int) (host.Host, error) {
|
|||||||
return host, nil
|
return host, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func reseedP2P(c *cli.Context, reseeder reseed.Reseeder) {
|
func reseedP2P(c *cli.Context, reseeder *reseed.ReseederImpl) {
|
||||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||||
server.Reseeder = reseeder
|
server.Reseeder = reseeder
|
||||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||||
@@ -421,7 +496,7 @@ func reseedP2P(c *cli.Context, reseeder reseed.Reseeder) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func reseedOnion(c *cli.Context, onionTlsCert, onionTlsKey string, reseeder reseed.Reseeder) {
|
func reseedOnion(c *cli.Context, onionTlsCert, onionTlsKey string, reseeder *reseed.ReseederImpl) {
|
||||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||||
server.Reseeder = reseeder
|
server.Reseeder = reseeder
|
||||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||||
@@ -496,7 +571,7 @@ func reseedOnion(c *cli.Context, onionTlsCert, onionTlsKey string, reseeder rese
|
|||||||
log.Printf("Onion server started on %s\n", server.Addr)
|
log.Printf("Onion server started on %s\n", server.Addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func reseedI2P(c *cli.Context, i2pTlsCert, i2pTlsKey string, i2pIdentKey i2pkeys.I2PKeys, reseeder reseed.Reseeder) {
|
func reseedI2P(c *cli.Context, i2pTlsCert, i2pTlsKey string, i2pIdentKey i2pkeys.I2PKeys, reseeder *reseed.ReseederImpl) {
|
||||||
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
server := reseed.NewServer(c.String("prefix"), c.Bool("trustProxy"))
|
||||||
server.Reseeder = reseeder
|
server.Reseeder = reseeder
|
||||||
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
server.Addr = net.JoinHostPort(c.String("ip"), c.String("port"))
|
||||||
@@ -524,26 +599,16 @@ func reseedI2P(c *cli.Context, i2pTlsCert, i2pTlsKey string, i2pIdentKey i2pkeys
|
|||||||
log.Fatalln(err.Error())
|
log.Fatalln(err.Error())
|
||||||
}
|
}
|
||||||
port += 1
|
port += 1
|
||||||
if _, err := os.Stat(c.String("onionKey")); err == nil {
|
if i2pTlsCert != "" && i2pTlsKey != "" {
|
||||||
//ok, err := ioutil.ReadFile(c.String("onionKey"))
|
if err := server.ListenAndServeI2PTLS(c.String("samaddr"), i2pIdentKey, i2pTlsCert, i2pTlsKey); err != nil {
|
||||||
if err != nil {
|
log.Fatalln(err)
|
||||||
log.Fatalln(err.Error())
|
|
||||||
} else {
|
|
||||||
if i2pTlsCert != "" && i2pTlsKey != "" {
|
|
||||||
if err := server.ListenAndServeI2PTLS(c.String("samaddr"), i2pIdentKey, i2pTlsCert, i2pTlsKey); err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := server.ListenAndServeI2P(c.String("samaddr"), i2pIdentKey); err != nil {
|
|
||||||
log.Fatalln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if os.IsNotExist(err) {
|
} else {
|
||||||
if err := server.ListenAndServeI2P(c.String("samaddr"), i2pIdentKey); err != nil {
|
if err := server.ListenAndServeI2P(c.String("samaddr"), i2pIdentKey); err != nil {
|
||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Onion server started on %s\n", server.Addr)
|
log.Printf("Onion server started on %s\n", server.Addr)
|
||||||
}
|
}
|
||||||
|
218
cmd/utils.go
218
cmd/utils.go
@@ -2,10 +2,12 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"crypto"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/rsa"
|
"crypto/rsa"
|
||||||
|
"crypto/tls"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
@@ -16,8 +18,15 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/MDrollette/i2p-tools/reseed"
|
"i2pgit.org/idk/reseed-tools/reseed"
|
||||||
"github.com/MDrollette/i2p-tools/su3"
|
"i2pgit.org/idk/reseed-tools/su3"
|
||||||
|
|
||||||
|
"github.com/go-acme/lego/v4/certcrypto"
|
||||||
|
"github.com/go-acme/lego/v4/certificate"
|
||||||
|
"github.com/go-acme/lego/v4/challenge/http01"
|
||||||
|
"github.com/go-acme/lego/v4/challenge/tlsalpn01"
|
||||||
|
"github.com/go-acme/lego/v4/lego"
|
||||||
|
"github.com/go-acme/lego/v4/registration"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadPrivateKey(path string) (*rsa.PrivateKey, error) {
|
func loadPrivateKey(path string) (*rsa.PrivateKey, error) {
|
||||||
@@ -35,18 +44,38 @@ func loadPrivateKey(path string) (*rsa.PrivateKey, error) {
|
|||||||
return privKey, nil
|
return privKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Taken directly from the lego example, since we need very minimal support
|
||||||
|
// https://go-acme.github.io/lego/usage/library/
|
||||||
|
type MyUser struct {
|
||||||
|
Email string
|
||||||
|
Registration *registration.Resource
|
||||||
|
key crypto.PrivateKey
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u *MyUser) GetEmail() string {
|
||||||
|
return u.Email
|
||||||
|
}
|
||||||
|
func (u MyUser) GetRegistration() *registration.Resource {
|
||||||
|
return u.Registration
|
||||||
|
}
|
||||||
|
func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
|
||||||
|
return u.key
|
||||||
|
}
|
||||||
|
|
||||||
func signerFile(signerID string) string {
|
func signerFile(signerID string) string {
|
||||||
return strings.Replace(signerID, "@", "_at_", 1)
|
return strings.Replace(signerID, "@", "_at_", 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOrNewSigningCert(signerKey *string, signerID string) (*rsa.PrivateKey, error) {
|
func getOrNewSigningCert(signerKey *string, signerID string, auto bool) (*rsa.PrivateKey, error) {
|
||||||
if _, err := os.Stat(*signerKey); nil != err {
|
if _, err := os.Stat(*signerKey); nil != err {
|
||||||
fmt.Printf("Unable to read signing key '%s'\n", *signerKey)
|
fmt.Printf("Unable to read signing key '%s'\n", *signerKey)
|
||||||
fmt.Printf("Would you like to generate a new signing key for %s? (y or n): ", signerID)
|
if !auto {
|
||||||
reader := bufio.NewReader(os.Stdin)
|
fmt.Printf("Would you like to generate a new signing key for %s? (y or n): ", signerID)
|
||||||
input, _ := reader.ReadString('\n')
|
reader := bufio.NewReader(os.Stdin)
|
||||||
if []byte(input)[0] != 'y' {
|
input, _ := reader.ReadString('\n')
|
||||||
return nil, fmt.Errorf("A signing key is required")
|
if []byte(input)[0] != 'y' {
|
||||||
|
return nil, fmt.Errorf("A signing key is required")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := createSigningCertificate(signerID); nil != err {
|
if err := createSigningCertificate(signerID); nil != err {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -58,7 +87,7 @@ func getOrNewSigningCert(signerKey *string, signerID string) (*rsa.PrivateKey, e
|
|||||||
return loadPrivateKey(*signerKey)
|
return loadPrivateKey(*signerKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkOrNewTLSCert(tlsHost string, tlsCert, tlsKey *string) error {
|
func checkUseAcmeCert(tlsHost, signer, cadirurl string, tlsCert, tlsKey *string, auto bool) error {
|
||||||
_, certErr := os.Stat(*tlsCert)
|
_, certErr := os.Stat(*tlsCert)
|
||||||
_, keyErr := os.Stat(*tlsKey)
|
_, keyErr := os.Stat(*tlsKey)
|
||||||
if certErr != nil || keyErr != nil {
|
if certErr != nil || keyErr != nil {
|
||||||
@@ -69,13 +98,174 @@ func checkOrNewTLSCert(tlsHost string, tlsCert, tlsKey *string) error {
|
|||||||
fmt.Printf("Unable to read TLS key '%s'\n", *tlsKey)
|
fmt.Printf("Unable to read TLS key '%s'\n", *tlsKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("Would you like to generate a new self-signed certificate for '%s'? (y or n): ", tlsHost)
|
if !auto {
|
||||||
reader := bufio.NewReader(os.Stdin)
|
fmt.Printf("Would you like to generate a new certificate with Let's Encrypt or a custom ACME server? '%s'? (y or n): ", tlsHost)
|
||||||
input, _ := reader.ReadString('\n')
|
reader := bufio.NewReader(os.Stdin)
|
||||||
if []byte(input)[0] != 'y' {
|
input, _ := reader.ReadString('\n')
|
||||||
fmt.Println("Continuing without TLS")
|
if []byte(input)[0] != 'y' {
|
||||||
|
fmt.Println("Continuing without TLS")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TLSConfig := &tls.Config{}
|
||||||
|
TLSConfig.NextProtos = []string{"http/1.1"}
|
||||||
|
TLSConfig.Certificates = make([]tls.Certificate, 1)
|
||||||
|
var err error
|
||||||
|
TLSConfig.Certificates[0], err = tls.LoadX509KeyPair(*tlsCert, *tlsKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if time.Now().Sub(TLSConfig.Certificates[0].Leaf.NotAfter) < (time.Hour * 48) {
|
||||||
|
ecder, err := ioutil.ReadFile(tlsHost + signer + ".acme.key")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
privateKey, err := x509.ParseECPrivateKey(ecder)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user := MyUser{
|
||||||
|
Email: signer,
|
||||||
|
key: privateKey,
|
||||||
|
}
|
||||||
|
config := lego.NewConfig(&user)
|
||||||
|
config.CADirURL = cadirurl
|
||||||
|
config.Certificate.KeyType = certcrypto.RSA2048
|
||||||
|
client, err := lego.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
renewAcmeIssuedCert(client, user, tlsHost, tlsCert, tlsKey)
|
||||||
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ecder, err := x509.MarshalECPrivateKey(privateKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
filename := tlsHost + signer + ".acme.key"
|
||||||
|
keypem, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer keypem.Close()
|
||||||
|
err = pem.Encode(keypem, &pem.Block{Type: "EC PRIVATE KEY", Bytes: ecder})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user := MyUser{
|
||||||
|
Email: signer,
|
||||||
|
key: privateKey,
|
||||||
|
}
|
||||||
|
config := lego.NewConfig(&user)
|
||||||
|
config.CADirURL = cadirurl
|
||||||
|
config.Certificate.KeyType = certcrypto.RSA2048
|
||||||
|
client, err := lego.NewClient(config)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return newAcmeIssuedCert(client, user, tlsHost, tlsCert, tlsKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func renewAcmeIssuedCert(client *lego.Client, user MyUser, tlsHost string, tlsCert, tlsKey *string) error {
|
||||||
|
var err error
|
||||||
|
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "8000"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "8443"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// New users will need to register
|
||||||
|
if user.Registration, err = client.Registration.QueryRegistration(); err != nil {
|
||||||
|
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user.Registration = reg
|
||||||
|
}
|
||||||
|
resource, err := client.Certificate.Get(tlsHost, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
certificates, err := client.Certificate.Renew(*resource, true, false, "")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ioutil.WriteFile(tlsHost+".pem", certificates.PrivateKey, 0600)
|
||||||
|
ioutil.WriteFile(tlsHost+".crt", certificates.Certificate, 0600)
|
||||||
|
// ioutil.WriteFile(tlsHost+".crl", certificates.PrivateKey, 0600)
|
||||||
|
*tlsCert = tlsHost + ".crt"
|
||||||
|
*tlsKey = tlsHost + ".pem"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newAcmeIssuedCert(client *lego.Client, user MyUser, tlsHost string, tlsCert, tlsKey *string) error {
|
||||||
|
var err error
|
||||||
|
err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "8000"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "8443"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// New users will need to register
|
||||||
|
if user.Registration, err = client.Registration.QueryRegistration(); err != nil {
|
||||||
|
reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
user.Registration = reg
|
||||||
|
}
|
||||||
|
|
||||||
|
request := certificate.ObtainRequest{
|
||||||
|
Domains: []string{tlsHost},
|
||||||
|
Bundle: true,
|
||||||
|
}
|
||||||
|
certificates, err := client.Certificate.Obtain(request)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ioutil.WriteFile(tlsHost+".pem", certificates.PrivateKey, 0600)
|
||||||
|
ioutil.WriteFile(tlsHost+".crt", certificates.Certificate, 0600)
|
||||||
|
// ioutil.WriteFile(tlsHost+".crl", certificates.PrivateKey, 0600)
|
||||||
|
*tlsCert = tlsHost + ".crt"
|
||||||
|
*tlsKey = tlsHost + ".pem"
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkOrNewTLSCert(tlsHost string, tlsCert, tlsKey *string, auto bool) error {
|
||||||
|
_, certErr := os.Stat(*tlsCert)
|
||||||
|
_, keyErr := os.Stat(*tlsKey)
|
||||||
|
if certErr != nil || keyErr != nil {
|
||||||
|
if certErr != nil {
|
||||||
|
fmt.Printf("Unable to read TLS certificate '%s'\n", *tlsCert)
|
||||||
|
}
|
||||||
|
if keyErr != nil {
|
||||||
|
fmt.Printf("Unable to read TLS key '%s'\n", *tlsKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !auto {
|
||||||
|
fmt.Printf("Would you like to generate a new self-signed certificate for '%s'? (y or n): ", tlsHost)
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
input, _ := reader.ReadString('\n')
|
||||||
|
if []byte(input)[0] != 'y' {
|
||||||
|
fmt.Println("Continuing without TLS")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := createTLSCertificate(tlsHost); nil != err {
|
if err := createTLSCertificate(tlsHost); nil != err {
|
||||||
return err
|
return err
|
||||||
|
@@ -4,9 +4,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
"github.com/MDrollette/i2p-tools/reseed"
|
"github.com/urfave/cli"
|
||||||
"github.com/MDrollette/i2p-tools/su3"
|
"i2pgit.org/idk/reseed-tools/reseed"
|
||||||
"github.com/codegangsta/cli"
|
"i2pgit.org/idk/reseed-tools/su3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewSu3VerifyCommand() cli.Command {
|
func NewSu3VerifyCommand() cli.Command {
|
||||||
|
BIN
content/images/reseed.png
Normal file
BIN
content/images/reseed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 198 KiB |
18
content/lang/en/homepage.md
Normal file
18
content/lang/en/homepage.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
You have found an I2P Reseed
|
||||||
|
============================
|
||||||
|
|
||||||
|
Maybe it was by accident, or maybe you visited the URL because you saw it in the software somewhere. While we've got
|
||||||
|
your attention, we're going to take this opportunity to tell you a little about what we do here. I2P is a peer-to-peer
|
||||||
|
network which uses "Garlic Routing" to maintain privacy. Reseed nodes help you get connected to I2P for the first time,
|
||||||
|
and even though you should only have to use them once in a great while, they are very important services.
|
||||||
|
|
||||||
|
[To learn more about I2P, visit the project website](https://geti2p.net)
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
|
[](https://geti2p.net)
|
||||||
|
|
||||||
|
- [Learn more about reseeds here:](https://geti2p.net/en/docs/reseed)
|
||||||
|
- [Learn how to run a reseed here:](https://geti2p.net/en/get-involved/guides/reseed)
|
||||||
|
- [Read the reseed server code and learn about more reseed options here:](https://i2pgit.org/idk/reseed-tools)
|
||||||
|
|
||||||
|
### Here on purpose? Here's a one-time link to a reseed bundle for you.
|
0
content/script.js
Normal file
0
content/script.js
Normal file
37
content/style.css
Normal file
37
content/style.css
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
body {
|
||||||
|
font-family: monospace;
|
||||||
|
text-align: justify;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: blue;
|
||||||
|
text-decoration: underline;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1em;
|
||||||
|
font-family: serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-button:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link-button:active {
|
||||||
|
color:red;
|
||||||
|
}
|
5
entrypoint.sh
Executable file
5
entrypoint.sh
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#! /usr/bin/env sh
|
||||||
|
|
||||||
|
cp -r /var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools/content ./content
|
||||||
|
|
||||||
|
/var/lib/i2p/go/src/i2pgit.org/idk/reseed-tools/reseed-tools reseed --yes=true --netdb=/var/lib/i2p/i2p-config/netDb $@
|
80
etc/init.d/reseed
Normal file
80
etc/init.d/reseed
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: samcatd
|
||||||
|
# Required-Start: $local_fs $network $named $time $syslog
|
||||||
|
# Required-Stop: $local_fs $network $named $time $syslog
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Description: <DESCRIPTION>
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
SCRIPT='/usr/local/bin/i2p-tools'
|
||||||
|
RUNAS=i2psvc
|
||||||
|
NETDBDIR=/var/lib/i2p/i2p-config/netDb
|
||||||
|
RUNDIR=/var/lib/i2p/i2p-config/reseed
|
||||||
|
SIGNER=you@mail.i2p
|
||||||
|
MORE_OPTIONS=""
|
||||||
|
if [ -f /etc/default/reseed ]; then
|
||||||
|
source /etc/default/reseed
|
||||||
|
fi
|
||||||
|
RUNOPTS=" reseed --signer=$SIGNER --netdb=$NETDBDIR $MORE_OPTIONS "
|
||||||
|
|
||||||
|
rundir(){
|
||||||
|
if [ !-d $RUNDIR ]; then
|
||||||
|
install -d -oi2psvc -m2770 $RUNDIR
|
||||||
|
fi
|
||||||
|
cd $RUNDIR
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
rundir
|
||||||
|
su - $RUNAS $SCRIPT $RUNOPTS --restart=start
|
||||||
|
}
|
||||||
|
|
||||||
|
stop() {
|
||||||
|
rundir
|
||||||
|
su - $RUNAS $SCRIPT $RUNOPTS --restart=stop
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
rundir
|
||||||
|
su - $RUNAS $SCRIPT $RUNOPTS --restart=restart
|
||||||
|
}
|
||||||
|
|
||||||
|
status() {
|
||||||
|
rundir
|
||||||
|
su - $RUNAS $SCRIPT $RUNOPTS --restart=status
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstall() {
|
||||||
|
echo -n "Are you really sure you want to uninstall this service? That cannot be undone. [yes|No] "
|
||||||
|
local SURE
|
||||||
|
read SURE
|
||||||
|
if [ "$SURE" = "yes" ]; then
|
||||||
|
stop
|
||||||
|
rm -f "$PIDFILE"
|
||||||
|
echo "Notice: log file is not be removed: '$LOGFILE'" >&2
|
||||||
|
update-rc.d -f reseed remove
|
||||||
|
rm -fv "$0"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
start)
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status
|
||||||
|
;;
|
||||||
|
uninstall)
|
||||||
|
uninstall
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
restart
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 {start|stop|restart|uninstall}"
|
||||||
|
esac
|
30
go.mod
30
go.mod
@@ -1,23 +1,19 @@
|
|||||||
module github.com/eyedeekay/i2p-tools-1
|
module i2pgit.org/idk/reseed-tools
|
||||||
|
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
crawshaw.io/littleboss v0.0.0-20190317185602-8957d0aedcce
|
|
||||||
github.com/MDrollette/i2p-tools v0.0.0
|
|
||||||
github.com/codegangsta/cli v1.22.1
|
|
||||||
github.com/cretz/bine v0.1.0
|
github.com/cretz/bine v0.1.0
|
||||||
github.com/gomodule/redigo v2.0.0+incompatible // indirect
|
github.com/eyedeekay/sam3 v0.32.32
|
||||||
github.com/gorilla/handlers v1.4.2
|
github.com/go-acme/lego/v4 v4.3.1
|
||||||
github.com/hashicorp/golang-lru v0.5.3 // indirect
|
github.com/gorilla/handlers v1.5.1
|
||||||
github.com/justinas/alice v0.0.0-20171023064455-03f45bd4b7da
|
github.com/justinas/alice v1.2.0
|
||||||
github.com/stretchr/testify v1.4.0 // indirect
|
github.com/libp2p/go-libp2p v0.13.0
|
||||||
github.com/throttled/throttled v2.2.4+incompatible
|
github.com/libp2p/go-libp2p-core v0.8.0
|
||||||
golang.org/x/crypto v0.0.0-20191029031824-8986dd9e96cf // indirect
|
github.com/libp2p/go-libp2p-gostream v0.3.1
|
||||||
golang.org/x/net v0.0.0-20191101175033-0deb6923b6d9 // indirect
|
github.com/libp2p/go-libp2p-http v0.2.0
|
||||||
gopkg.in/throttled/throttled.v2 v2.2.4 // indirect
|
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
|
||||||
|
golang.org/x/text v0.3.5
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/MDrollette/i2p-tools v0.0.0 => ./
|
|
||||||
|
|
||||||
replace github.com/codegangsta/cli v1.22.1 => github.com/urfave/cli v1.22.1
|
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
* incorporate libp2p(ipfs) listener from RTradeLtd/i2p-tools-1 master
|
* incorporate libp2p(ipfs) listener from RTradeLtd/i2p-tools-1 master
|
||||||
* in-network(I2P) reseeds in case there's a point to that.
|
* in-network(I2P) reseeds in case there's a point to that.
|
||||||
* self-supervising reseed service, if it crashes it will restart itself
|
* self-supervising reseed service, if it crashes it will restart itself
|
||||||
|
* add an initscript
|
||||||
|
|
||||||
2019-06-27
|
2019-06-27
|
||||||
* automatically configuring Tor Onionv3 Server
|
* automatically configuring Tor Onionv3 Server
|
||||||
@@ -40,4 +41,4 @@
|
|||||||
* numRi per su3 file: 75 --> 77
|
* numRi per su3 file: 75 --> 77
|
||||||
|
|
||||||
2016-01
|
2016-01
|
||||||
* fork from https://github.com/MDrollette/i2p-tools
|
* fork from https://i2pgit.org/idk/reseed-tools
|
||||||
|
4
main.go
4
main.go
@@ -4,8 +4,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/MDrollette/i2p-tools/cmd"
|
"github.com/urfave/cli"
|
||||||
"github.com/codegangsta/cli"
|
"i2pgit.org/idk/reseed-tools/cmd"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
132
reseed/homepage.go
Normal file
132
reseed/homepage.go
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
package reseed
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"gitlab.com/golang-commonmark/markdown"
|
||||||
|
"golang.org/x/text/language"
|
||||||
|
)
|
||||||
|
|
||||||
|
var SupportedLanguages = []language.Tag{
|
||||||
|
language.English,
|
||||||
|
}
|
||||||
|
var CachedLanguagePages = map[string]string{}
|
||||||
|
var CachedDataPages = map[string][]byte{}
|
||||||
|
|
||||||
|
var BaseContentPath, ContentPathError = ContentPath()
|
||||||
|
|
||||||
|
var matcher = language.NewMatcher(SupportedLanguages)
|
||||||
|
|
||||||
|
var header = []byte(`<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>This is an I2P Reseed Server</title>
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<script src="script.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>`)
|
||||||
|
var footer = []byte(` </body>
|
||||||
|
</html>`)
|
||||||
|
|
||||||
|
var md = markdown.New(markdown.XHTMLOutput(true), markdown.HTML(true))
|
||||||
|
|
||||||
|
func ContentPath() (string, error) {
|
||||||
|
exPath, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
//exPath := filepath.Dir(ex)
|
||||||
|
if _, err := os.Stat(filepath.Join(exPath, "content")); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Join(exPath, "content"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv *Server) HandleARealBrowser(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if ContentPathError != nil {
|
||||||
|
http.Error(w, "403 Forbidden", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lang, _ := r.Cookie("lang")
|
||||||
|
accept := r.Header.Get("Accept-Language")
|
||||||
|
tag, _ := language.MatchStrings(matcher, lang.String(), accept)
|
||||||
|
base, _ := tag.Base()
|
||||||
|
|
||||||
|
switch r.URL.Path {
|
||||||
|
case "/style.css":
|
||||||
|
w.Header().Set("Content-Type", "text/css")
|
||||||
|
HandleAFile(w, "", "style.css")
|
||||||
|
case "/script.js":
|
||||||
|
w.Header().Set("Content-Type", "text/javascript")
|
||||||
|
HandleAFile(w, "", "script.js")
|
||||||
|
default:
|
||||||
|
image := strings.Replace(r.URL.Path, "/", "", -1)
|
||||||
|
if strings.HasPrefix(image, "images") {
|
||||||
|
w.Header().Set("Content-Type", "image/png")
|
||||||
|
HandleAFile(w, "images", strings.TrimPrefix(strings.TrimPrefix(r.URL.Path, "/"), "images"))
|
||||||
|
} else {
|
||||||
|
w.Header().Set("Content-Type", "text/html")
|
||||||
|
w.Write([]byte(header))
|
||||||
|
HandleALocalizedFile(w, base.String())
|
||||||
|
w.Write([]byte(`<ul><li><form method="post" action="/i2pseeds" class="inline">
|
||||||
|
<input type="hidden" name="onetime" value="` + srv.Acceptable() + `">
|
||||||
|
<button type="submit" name="submit_param" value="submit_value" class="link-button">
|
||||||
|
Bundle
|
||||||
|
</button>
|
||||||
|
</form></li></ul>`))
|
||||||
|
w.Write([]byte(footer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleAFile(w http.ResponseWriter, dirPath, file string) {
|
||||||
|
file = filepath.Join(dirPath, file)
|
||||||
|
if _, prs := CachedDataPages[file]; prs == false {
|
||||||
|
path := filepath.Join(BaseContentPath, file)
|
||||||
|
f, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
w.Write([]byte("Oops! Something went wrong handling your language. Please file a bug at https://i2pgit.org/idk/reseed-tools\n\t" + err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
CachedDataPages[file] = f
|
||||||
|
w.Write([]byte(CachedDataPages[file]))
|
||||||
|
} else {
|
||||||
|
w.Write(CachedDataPages[file])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleALocalizedFile(w http.ResponseWriter, dirPath string) {
|
||||||
|
if _, prs := CachedLanguagePages[dirPath]; prs == false {
|
||||||
|
dir := filepath.Join(BaseContentPath, "lang", dirPath)
|
||||||
|
files, err := ioutil.ReadDir(dir)
|
||||||
|
if err != nil {
|
||||||
|
w.Write([]byte("Oops! Something went wrong handling your language. Please file a bug at https://i2pgit.org/idk/reseed-tools\n\t" + err.Error()))
|
||||||
|
}
|
||||||
|
var f []byte
|
||||||
|
for _, file := range files {
|
||||||
|
if !strings.HasSuffix(file.Name(), ".md") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
trimmedName := strings.TrimSuffix(file.Name(), ".md")
|
||||||
|
path := filepath.Join(dir, file.Name())
|
||||||
|
b, err := ioutil.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
w.Write([]byte("Oops! Something went wrong handling your language. Please file a bug at https://i2pgit.org/idk/reseed-tools\n\t" + err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f = append(f, []byte(`<div id="`+trimmedName+`">`)...)
|
||||||
|
f = append(f, []byte(md.RenderToString(b))...)
|
||||||
|
f = append(f, []byte(`</div>`)...)
|
||||||
|
|
||||||
|
}
|
||||||
|
CachedLanguagePages[dirPath] = string(f)
|
||||||
|
w.Write([]byte(CachedLanguagePages[dirPath]))
|
||||||
|
} else {
|
||||||
|
w.Write([]byte(CachedLanguagePages[dirPath]))
|
||||||
|
}
|
||||||
|
}
|
@@ -3,6 +3,7 @@ package reseed
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
@@ -20,8 +21,8 @@ import (
|
|||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
gostream "github.com/libp2p/go-libp2p-gostream"
|
gostream "github.com/libp2p/go-libp2p-gostream"
|
||||||
p2phttp "github.com/libp2p/go-libp2p-http"
|
p2phttp "github.com/libp2p/go-libp2p-http"
|
||||||
"github.com/throttled/throttled"
|
throttled "github.com/throttled/throttled/v2"
|
||||||
"github.com/throttled/throttled/store"
|
"github.com/throttled/throttled/v2/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -34,9 +35,10 @@ type Server struct {
|
|||||||
I2PSession *sam3.StreamSession
|
I2PSession *sam3.StreamSession
|
||||||
I2PListener *sam3.StreamListener
|
I2PListener *sam3.StreamListener
|
||||||
I2PKeys i2pkeys.I2PKeys
|
I2PKeys i2pkeys.I2PKeys
|
||||||
Reseeder Reseeder
|
Reseeder *ReseederImpl
|
||||||
Blacklist *Blacklist
|
Blacklist *Blacklist
|
||||||
OnionListener *tor.OnionService
|
OnionListener *tor.OnionService
|
||||||
|
acceptables map[string]time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServer(prefix string, trustProxy bool) *Server {
|
func NewServer(prefix string, trustProxy bool) *Server {
|
||||||
@@ -65,6 +67,7 @@ func NewServer(prefix string, trustProxy bool) *Server {
|
|||||||
server := Server{Server: h, Reseeder: nil}
|
server := Server{Server: h, Reseeder: nil}
|
||||||
|
|
||||||
th := throttled.RateLimit(throttled.PerHour(4), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(200000))
|
th := throttled.RateLimit(throttled.PerHour(4), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(200000))
|
||||||
|
thw := throttled.RateLimit(throttled.PerHour(30), &throttled.VaryBy{RemoteAddr: true}, store.NewMemStore(200000))
|
||||||
|
|
||||||
middlewareChain := alice.New()
|
middlewareChain := alice.New()
|
||||||
if trustProxy {
|
if trustProxy {
|
||||||
@@ -79,13 +82,85 @@ func NewServer(prefix string, trustProxy bool) *Server {
|
|||||||
})
|
})
|
||||||
|
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
mux.Handle("/", middlewareChain.Append(disableKeepAliveMiddleware, loggingMiddleware).Then(errorHandler))
|
mux.Handle("/", middlewareChain.Append(disableKeepAliveMiddleware, loggingMiddleware, thw.Throttle, server.browsingMiddleware).Then(errorHandler))
|
||||||
mux.Handle(prefix+"/i2pseeds.su3", middlewareChain.Append(disableKeepAliveMiddleware, loggingMiddleware, verifyMiddleware, th.Throttle).Then(http.HandlerFunc(server.reseedHandler)))
|
mux.Handle(prefix+"/i2pseeds.su3", middlewareChain.Append(disableKeepAliveMiddleware, loggingMiddleware, verifyMiddleware, th.Throttle).Then(http.HandlerFunc(server.reseedHandler)))
|
||||||
server.Handler = mux
|
server.Handler = mux
|
||||||
|
|
||||||
return &server
|
return &server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See use of crypto/rand on:
|
||||||
|
// https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go
|
||||||
|
const (
|
||||||
|
letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" // 52 possibilities
|
||||||
|
letterIdxBits = 6 // 6 bits to represent 64 possibilities / indexes
|
||||||
|
letterIdxMask = 1<<letterIdxBits - 1 // All 1-bits, as many as letterIdxBits
|
||||||
|
)
|
||||||
|
|
||||||
|
func SecureRandomAlphaString() string {
|
||||||
|
length := 16
|
||||||
|
result := make([]byte, length)
|
||||||
|
bufferSize := int(float64(length) * 1.3)
|
||||||
|
for i, j, randomBytes := 0, 0, []byte{}; i < length; j++ {
|
||||||
|
if j%bufferSize == 0 {
|
||||||
|
randomBytes = SecureRandomBytes(bufferSize)
|
||||||
|
}
|
||||||
|
if idx := int(randomBytes[j%length] & letterIdxMask); idx < len(letterBytes) {
|
||||||
|
result[i] = letterBytes[idx]
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecureRandomBytes returns the requested number of bytes using crypto/rand
|
||||||
|
func SecureRandomBytes(length int) []byte {
|
||||||
|
var randomBytes = make([]byte, length)
|
||||||
|
_, err := rand.Read(randomBytes)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("Unable to generate random bytes")
|
||||||
|
}
|
||||||
|
return randomBytes
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
func (srv *Server) Acceptable() string {
|
||||||
|
if srv.acceptables == nil {
|
||||||
|
srv.acceptables = make(map[string]time.Time)
|
||||||
|
}
|
||||||
|
if len(srv.acceptables) > 50 {
|
||||||
|
for val := range srv.acceptables {
|
||||||
|
srv.CheckAcceptable(val)
|
||||||
|
}
|
||||||
|
for val := range srv.acceptables {
|
||||||
|
if len(srv.acceptables) < 50 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
delete(srv.acceptables, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
acceptme := SecureRandomAlphaString()
|
||||||
|
srv.acceptables[acceptme] = time.Now()
|
||||||
|
return acceptme
|
||||||
|
}
|
||||||
|
|
||||||
|
func (srv *Server) CheckAcceptable(val string) bool {
|
||||||
|
if srv.acceptables == nil {
|
||||||
|
srv.acceptables = make(map[string]time.Time)
|
||||||
|
}
|
||||||
|
if timeout, ok := srv.acceptables[val]; ok {
|
||||||
|
checktime := time.Now().Sub(timeout)
|
||||||
|
if checktime > (4 * time.Minute) {
|
||||||
|
delete(srv.acceptables, val)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
delete(srv.acceptables, val)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (srv *Server) ListenAndServe() error {
|
func (srv *Server) ListenAndServe() error {
|
||||||
addr := srv.Addr
|
addr := srv.Addr
|
||||||
if addr == "" {
|
if addr == "" {
|
||||||
@@ -245,7 +320,7 @@ func (srv *Server) ListenAndServeI2P(samaddr string, I2PKeys i2pkeys.I2PKeys) er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("I2P server started on http://%v.onion\n", srv.OnionListener.ID)
|
log.Printf("I2P server started on http://%v.b32.i2p\n", srv.I2PListener.Addr().(i2pkeys.I2PAddr).Base32())
|
||||||
return srv.Serve(srv.I2PListener)
|
return srv.Serve(srv.I2PListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +366,20 @@ func loggingMiddleware(next http.Handler) http.Handler {
|
|||||||
return handlers.CombinedLoggingHandler(os.Stdout, next)
|
return handlers.CombinedLoggingHandler(os.Stdout, next)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (srv *Server) browsingMiddleware(next http.Handler) http.Handler {
|
||||||
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if srv.CheckAcceptable(r.FormValue("onetime")) {
|
||||||
|
srv.reseedHandler(w, r)
|
||||||
|
}
|
||||||
|
if i2pUserAgent != r.UserAgent() {
|
||||||
|
srv.HandleARealBrowser(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
next.ServeHTTP(w, r)
|
||||||
|
}
|
||||||
|
return http.HandlerFunc(fn)
|
||||||
|
}
|
||||||
|
|
||||||
func verifyMiddleware(next http.Handler) http.Handler {
|
func verifyMiddleware(next http.Handler) http.Handler {
|
||||||
fn := func(w http.ResponseWriter, r *http.Request) {
|
fn := func(w http.ResponseWriter, r *http.Request) {
|
||||||
if i2pUserAgent != r.UserAgent() {
|
if i2pUserAgent != r.UserAgent() {
|
||||||
|
@@ -15,7 +15,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/MDrollette/i2p-tools/su3"
|
"i2pgit.org/idk/reseed-tools/su3"
|
||||||
)
|
)
|
||||||
|
|
||||||
type routerInfo struct {
|
type routerInfo struct {
|
||||||
@@ -33,13 +33,13 @@ func (p Peer) Hash() int {
|
|||||||
return int(crc32.ChecksumIEEE(c))
|
return int(crc32.ChecksumIEEE(c))
|
||||||
}
|
}
|
||||||
|
|
||||||
type Reseeder interface {
|
/*type Reseeder interface {
|
||||||
// get an su3 file (bytes) for a peer
|
// get an su3 file (bytes) for a peer
|
||||||
PeerSu3Bytes(peer Peer) ([]byte, error)
|
PeerSu3Bytes(peer Peer) ([]byte, error)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
type ReseederImpl struct {
|
type ReseederImpl struct {
|
||||||
netdb NetDbProvider
|
netdb *LocalNetDbImpl
|
||||||
su3s chan [][]byte
|
su3s chan [][]byte
|
||||||
|
|
||||||
SigningKey *rsa.PrivateKey
|
SigningKey *rsa.PrivateKey
|
||||||
@@ -49,7 +49,7 @@ type ReseederImpl struct {
|
|||||||
NumSu3 int
|
NumSu3 int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewReseeder(netdb NetDbProvider) *ReseederImpl {
|
func NewReseeder(netdb *LocalNetDbImpl) *ReseederImpl {
|
||||||
return &ReseederImpl{
|
return &ReseederImpl{
|
||||||
netdb: netdb,
|
netdb: netdb,
|
||||||
su3s: make(chan [][]byte),
|
su3s: make(chan [][]byte),
|
||||||
@@ -224,10 +224,10 @@ func (rs *ReseederImpl) createSu3(seeds []routerInfo) (*su3.File, error) {
|
|||||||
return su3File, nil
|
return su3File, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type NetDbProvider interface {
|
/*type NetDbProvider interface {
|
||||||
// Get all router infos
|
// Get all router infos
|
||||||
RouterInfos() ([]routerInfo, error)
|
RouterInfos() ([]routerInfo, error)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
type LocalNetDbImpl struct {
|
type LocalNetDbImpl struct {
|
||||||
Path string
|
Path string
|
||||||
|
Reference in New Issue
Block a user