Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nostr-rs-relay #366

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,7 @@ Install these other services at your leisure/preference:
* [Nextcloud](nextcloud#readme) - a collaborative file server
* [Nginx](nginx#readme) - a webserver configured with fast-cgi support for PHP scripts
* [Node-RED](nodered#readme) - a graphical event pipeline editor
* [Nostr-RS-Relay](nostr-rs-relay#readme) - a programmable Nostr relay
* [Ntfy-sh](ntfy-sh#readme) - a simple HTTP-based pub-sub notification service
* [Pairdrop](pairdrop#readme) - a webapp (PWA) to send files and messages peer to peer
* [Peertube](peertube#readme) - a decentralized and federated video platform
Expand Down
50 changes: 50 additions & 0 deletions nostr-rs-relay/.env-dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# The git repository to build from:
NOSTR_RS_RELAY_GIT_REPO=https://git.sr.ht/~gheartsfield/nostr-rs-relay.git
NOSTR_RS_RELAY_GIT_BRANCH=master

# The domain name for the nostr_rs_relay service:
NOSTR_RS_RELAY_TRAEFIK_HOST=nostr.example.com

# The name of this instance. If there is only one instance, use 'default'.
NOSTR_RS_RELAY_INSTANCE=

# Enter a logical one-word name for this instance:
NOSTR_RS_RELAY_NAME=nostr-rs-relay

# Enter a description for this nostr instance.
# You must enter all newlines with literal '\n'.
NOSTR_RS_RELAY_DESCRIPTION=A newly created nostr-rs-relay.\n\nCustomize this with your own info.

# Filter access by IP address source range (CIDR):
##Disallow all access: 0.0.0.0/32
##Allow all access: 0.0.0.0/0
NOSTR_RS_RELAY_IP_SOURCERANGE=0.0.0.0/0

# HTTP Basic Authentication:
# Use `make config` to fill this in properly, or set this to blank to disable.
NOSTR_RS_RELAY_HTTP_AUTH=

# OAUTH2
# Set to `true` to use OpenID/OAuth2 authentication via the
# traefik-forward-auth service in d.rymcg.tech.
# Using OpenID/OAuth2 will require login to access your app,
# but it will not affect what a successfully logged-in person can do in your
# app. If your app has built-in authentication and can check the user
# header that traefik-forward-auth sends, then your app can limit what the
# logged-in person can do in the app. But if your app can't check the user
# header, or if your app doesn't have built-in authentication at all, then
# any person with an account on your Gitea server can log into your app and
# have full access.
NOSTR_RS_RELAY_OAUTH2=
# In addition to Oauth2 authentication, you can configure basic authorization
# by entering which authorization group can log into your app. You create
# groups of email addresses in the `traefik` folder by running `make groups`.
NOSTR_RS_RELAY_OAUTH2_AUTHORIZED_GROUP=

# Mutual TLS (mTLS):
# Set true or false. If true, all clients must present a certificate signed by Step-CA:
NOSTR_RS_RELAY_MTLS_AUTH=false
# Enter a comma separated list of client domains allowed to connect via mTLS.
# Wildcards are allowed and encouraged on a per-app basis:
NOSTR_RS_RELAY_MTLS_AUTHORIZED_CERTS=*.clients.nostr.example.com

31 changes: 31 additions & 0 deletions nostr-rs-relay/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ROOT_DIR = ..
include ${ROOT_DIR}/_scripts/Makefile.projects
include ${ROOT_DIR}/_scripts/Makefile.instance

.PHONY: config-hook
config-hook:
#### This interactive configuration wizard creates the .env_{DOCKER_CONTEXT}_{INSTANCE} config file using .env-dist as the template:
@${BIN}/reconfigure_ask ${ENV_FILE} NOSTR_RS_RELAY_TRAEFIK_HOST "Enter the nostr domain name" nostr${INSTANCE_URL_SUFFIX}.${ROOT_DOMAIN}
@${BIN}/reconfigure ${ENV_FILE} NOSTR_RS_RELAY_INSTANCE=$${instance:-default}
@${BIN}/reconfigure_auth ${ENV_FILE} NOSTR_RS_RELAY
@${BIN}/reconfigure_ask ${ENV_FILE} NOSTR_RS_RELAY_NAME "Enter a logical one-word name for this Nostr instance."
@${BIN}/reconfigure_ask ${ENV_FILE} NOSTR_RS_RELAY_DESCRIPTION "Enter a description for this Nostr instance."
@echo ""

.PHONY: override-hook
override-hook:
#### This sets the override template variables for docker-compose.instance.yaml:
#### The template dynamically renders to docker-compose.override_{DOCKER_CONTEXT}_{INSTANCE}.yaml
#### These settings are used to automatically generate the service container labels, and traefik config, inside the template.
#### The variable arguments have three forms: `=` `=:` `=@`
#### name=VARIABLE_NAME # sets the template 'name' field to the value of VARIABLE_NAME found in the .env file
#### # (this hardcodes the value into docker-compose.override.yaml)
#### name=:VARIABLE_NAME # sets the template 'name' field to the literal string 'VARIABLE_NAME'
#### # (this hardcodes the string into docker-compose.override.yaml)
#### name=@VARIABLE_NAME # sets the template 'name' field to the literal string '${VARIABLE_NAME}'
#### # (used for regular docker-compose expansion of env vars by name.)
@${BIN}/docker_compose_override ${ENV_FILE} project=:nostr-rs-relay instance=@NOSTR_RS_RELAY_INSTANCE traefik_host=@NOSTR_RS_RELAY_TRAEFIK_HOST http_auth=NOSTR_RS_RELAY_HTTP_AUTH http_auth_var=@NOSTR_RS_RELAY_HTTP_AUTH ip_sourcerange=@NOSTR_RS_RELAY_IP_SOURCERANGE oauth2=NOSTR_RS_RELAY_OAUTH2 authorized_group=NOSTR_RS_RELAY_OAUTH2_AUTHORIZED_GROUP enable_mtls_auth=NOSTR_RS_RELAY_MTLS_AUTH mtls_authorized_certs=NOSTR_RS_RELAY_MTLS_AUTHORIZED_CERTS

.PHONY: shell
shell:
@make --no-print-directory docker-compose-shell SERVICE=nostr-rs-relay
13 changes: 13 additions & 0 deletions nostr-rs-relay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# nostr-rs-relay

[nostr-rs-relay](https://sr.ht/~gheartsfield/nostr-rs-relay/) is a
[Nostr](https://github.com/nostr-protocol/nostr) relay.


## Test

[Install golang]() and then install [nak](https://github.com/fiatjaf/nak)

```
go install github.com/fiatjaf/nak@latest
```
6 changes: 6 additions & 0 deletions nostr-rs-relay/config/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM debian:stable-slim
WORKDIR /template
RUN apt-get -y update && apt-get install -y openssl gettext
COPY template/* setup.sh ./
RUN chmod a+x setup.sh
CMD ["./setup.sh"]
8 changes: 8 additions & 0 deletions nostr-rs-relay/config/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

create_config() {
cat /template/config.toml | envsubst > /config/config.toml
echo "[ ! ] GENERATED CONFIG FILE ::: config.toml"
}

create_config
253 changes: 253 additions & 0 deletions nostr-rs-relay/config/template/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
# Nostr-rs-relay configuration

[info]
# The advertised URL for the Nostr websocket.
relay_url = "wss://${TRAEFIK_HOST}/"

# Relay information for clients. Put your unique server name here.
name = "${NAME}"

# Description
description = "${DESCRIPTION}"

# Administrative contact pubkey (32-byte hex, not npub)
#pubkey = "0c2d168a4ae8ca58c9f1ab237b5df682599c6c7ab74307ea8b05684b60405d41"

# Administrative contact URI
#contact = "mailto:[email protected]"

# Favicon location. Relative to the current directory. Assumes an
# ICO format.
#favicon = "favicon.ico"

# URL of Relay's icon.
#relay_icon = "https://example.test/img.png"

# Path to custom relay html page
#relay_page = "index.html"

[diagnostics]
# Enable tokio tracing (for use with tokio-console)
#tracing = false

[database]
# Database engine (sqlite/postgres). Defaults to sqlite.
# Support for postgres is currently experimental.
#engine = "sqlite"

# Directory for SQLite files. Defaults to the current directory. Can
# also be specified (and overriden) with the "--db dirname" command
# line option.
#data_directory = "."

# Use an in-memory database instead of 'nostr.db'.
# Requires sqlite engine.
# Caution; this will not survive a process restart!
#in_memory = false

# Database connection pool settings for subscribers:

# Minimum number of SQLite reader connections
#min_conn = 0

# Maximum number of SQLite reader connections. Recommend setting this
# to approx the number of cores.
#max_conn = 8

# Database connection string. Required for postgres; not used for
# sqlite.
#connection = "postgresql://postgres:nostr@localhost:7500/nostr"

# Optional database connection string for writing. Use this for
# postgres clusters where you want to separate reads and writes to
# different nodes. Ignore for single-database instances.
#connection_write = "postgresql://postgres:nostr@localhost:7500/nostr"

[logging]
# Directory to store log files. Log files roll over daily.
#folder_path = "./log"
#file_prefix = "nostr-relay"

[grpc]
# gRPC interfaces for externalized decisions and other extensions to
# functionality.
#
# Events can be authorized through an external service, by providing
# the URL below. In the event the server is not accessible, events
# will be permitted. The protobuf3 schema used is available in
# `proto/nauthz.proto`.
# event_admission_server = "http://[::1]:50051"

# If the event admission server denies writes
# in any case (excluding spam filtering).
# This is reflected in the relay information document.
# restricts_write = true

[network]
# Bind to this network address
address = "0.0.0.0"

# Listen on this port
port = 8080

# If present, read this HTTP header for logging client IP addresses.
# Examples for common proxies, cloudflare:
#remote_ip_header = "x-forwarded-for"
#remote_ip_header = "cf-connecting-ip"

# Websocket ping interval in seconds, defaults to 5 minutes
#ping_interval = 300

[options]
# Reject events that have timestamps greater than this many seconds in
# the future. Recommended to reject anything greater than 30 minutes
# from the current time, but the default is to allow any date.
reject_future_seconds = 1800

[limits]
# Limit events created per second, averaged over one minute. Must be
# an integer. If not set (or set to 0), there is no limit. Note:
# this is for the server as a whole, not per-connection.
#
# Limiting event creation is highly recommended if your relay is
# public!
#
#messages_per_sec = 5

# Limit client subscriptions created, averaged over one minute. Must
# be an integer. If not set (or set to 0), defaults to unlimited.
# Strongly recommended to set this to a low value such as 10 to ensure
# fair service.
#subscriptions_per_min = 0

# UNIMPLEMENTED...
# Limit how many concurrent database connections a client can have.
# This prevents a single client from starting too many expensive
# database queries. Must be an integer. If not set (or set to 0),
# defaults to unlimited (subject to subscription limits).
#db_conns_per_client = 0

# Limit blocking threads used for database connections. Defaults to 16.
#max_blocking_threads = 16

# Limit the maximum size of an EVENT message. Defaults to 128 KB.
# Set to 0 for unlimited.
#max_event_bytes = 131072

# Maximum WebSocket message in bytes. Defaults to 128 KB.
#max_ws_message_bytes = 131072

# Maximum WebSocket frame size in bytes. Defaults to 128 KB.
#max_ws_frame_bytes = 131072

# Broadcast buffer size, in number of events. This prevents slow
# readers from consuming memory.
#broadcast_buffer = 16384

# Event persistence buffer size, in number of events. This provides
# backpressure to senders if writes are slow.
#event_persist_buffer = 4096

# Event kind blacklist. Events with these kinds will be discarded.
#event_kind_blacklist = [
# 70202,
#]

# Event kind allowlist. Events other than these kinds will be discarded.
#event_kind_allowlist = [
# 0, 1, 2, 3, 7, 40, 41, 42, 43, 44, 30023,
#]

# Rejects imprecise requests (kind only and author only etc)
# This is a temperary measure to improve the adoption of outbox model
# Its recommended to have this enabled
limit_scrapers = false

[authorization]
# Pubkey addresses in this array are whitelisted for event publishing.
# Only valid events by these authors will be accepted, if the variable
# is set.
#pubkey_whitelist = [
# "35d26e4690cbe1a898af61cc3515661eb5fa763b57bd0b42e45099c8b32fd50f",
# "887645fef0ce0c3c1218d2f5d8e6132a19304cdc57cd20281d082f38cfea0072",
#]
# Enable NIP-42 authentication
#nip42_auth = false
# Send DMs (kind 4 and 44) and gift wraps (kind 1059) only to their authenticated recipients
#nip42_dms = false

[verified_users]
# NIP-05 verification of users. Can be "enabled" to require NIP-05
# metadata for event authors, "passive" to perform validation but
# never block publishing, or "disabled" to do nothing.
#mode = "disabled"

# Domain names that will be prevented from publishing events.
#domain_blacklist = ["wellorder.net"]

# Domain names that are allowed to publish events. If defined, only
# events NIP-05 verified authors at these domains are persisted.
#domain_whitelist = ["example.com"]

# Consider an pubkey "verified" if we have a successful validation
# from the NIP-05 domain within this amount of time. Note, if the
# domain provides a successful response that omits the account,
# verification is immediately revoked.
#verify_expiration = "1 week"

# How long to wait between verification attempts for a specific author.
#verify_update_frequency = "24 hours"

# How many consecutive failed checks before we give up on verifying
# this author.
#max_consecutive_failures = 20

[pay_to_relay]
# Enable pay to relay
#enabled = false

# Node interface to use
#processor = "ClnRest/LNBits"

# The cost to be admitted to relay
#admission_cost = 4200

# The cost in sats per post
#cost_per_event = 0

# Url of node api
#node_url = "<node url>"

# LNBits api secret
#api_secret = "<ln bits api>"

# Path to CLN rune
#rune_path = "<rune path>"

# Nostr direct message on signup
#direct_message=false

# Terms of service
#terms_message = """
#This service (and supporting services) are provided "as is", without warranty of any kind, express or implied.
#
#By using this service, you agree:
#* Not to engage in spam or abuse the relay service
#* Not to disseminate illegal content
#* That requests to delete content cannot be guaranteed
#* To use the service in compliance with all applicable laws
#* To grant necessary rights to your content for unlimited time
#* To be of legal age and have capacity to use this service
#* That the service may be terminated at any time without notice
#* That the content you publish may be removed at any time without notice
#* To have your IP address collected to detect abuse or misuse
#* To cooperate with the relay to combat abuse or misuse
#* You may be exposed to content that you might find triggering or distasteful
#* The relay operator is not liable for content produced by users of the relay
#"""

# Whether or not new sign ups should be allowed
#sign_ups = false

# optional if `direct_message=false`
#secret_key = "<nostr nsec>"
Loading