Avatar
jascha
2479739594ed5802a96703e5a870b515d986982474a71feae180e8ecffa302c6
Run Relayable.org #nostr relay Bitcoin Class of 2009 🧡 Founder of @npub1tpy5sj0wc4txn8fdx02y7lrq33yxmwcrupfgw9jxzunmf9ypfhhs837gzc Cybersecurity pro with head in Clouds. By day I also build massively scalable and redundant data center/cloud architectures⚡🫂💜 9367 9961 90C9 B785 889D 276E A61B 8390 B08D CD40

I just want to use the tag #Zungguzungguguzungguzeng

https://open.spotify.com/track/4czopM9AcLjrH4IunzRoBg

It's days like today I am glad I don't have an iPhone.

#onlyzaps

Another one from the #cybersecurity #patch collection.

Yesterday's weirdness is tomorrow's reason why.-- Hunter S. Thompson

#onlyzaps

For the first installment of #whosampledit ? ⚡

All the People - Cramp Your Style 1972

https://spotify.link/x3E5dfbJazb

#nostr #nostrmusic #music

I have this strange compulsion to Like #onlyzaps posts.

Zapifornication.

In what I do "downtime" is a four letter word. Everything I do has the goal of five nines.

#[0]

https://void.cat/d/2EYJ9NY3QQMebumWwUX63x.webp

1 bitcoin = 1 bitcoin, but also 1 bitcoin = one giant gun room 😀

Imagine the ammo room 🤣

Some crotch-pot cookin' 🩳💨

Ginger got her tag on, rollin dirty. #dogstr #dogs

Replying to Avatar jascha

Overview

--------

In order to have a resilient decentralized nostr network there needs to be a good distribution of relays. Avoiding the caveat of too many large (centralized) relays, many of unknown architecture and availability. It is not too difficult to run your own private relay at home or on an inexpensive cloud provider.

[Digital Ocean $200 Credit](https://m.do.co/c/e78d2c89afe3)

The following is based on the unofficial strfry docker repo: [https://hub.docker.com/r/cryptocartel/strfry](https://hub.docker.com/r/cryptocartel/strfry)

Install Requirements

--------------------

(In this example we're assuming your host is running Ubuntu 22.04 but should work with most Debian based OSs)

On your cloud server or home server be sure to [install Docker](https://docs.docker.com/engine/install/ubuntu/).

Now install docker-compose:

curl -SL https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

Make executable:

sudo chmod +x /usr/local/bin/docker-compose

### Point DNS to IP of Relay

In your DNS registrar or hosting control panel add an **A** record for `relay.yourdomain.com` to your instance public IP. You can alternatively use dynamic DNS if hosting from home. If using from home I recommend using a free CloudFlare account to proxy DNS to your home IP to obfuscate it. There are many videos and howtos on this.

Create docker-compose.yml

-------------------------

Make a _docker-compose.yml_ file with contents below:

services:

strfry-nostr-relay:

image: cryptocartel/strfry:latest

restart: unless-stopped

volumes:

- /local/path/to/strfry-data/etc:/etc/

- /local/path/to/strfry-data/strfry-db:/app/strfry-db

- /local/path/to/strfry-data/plugins:/app/plugins

ports:

- "7777:7777"

Add _whitelist.js_ Plugin to Lock Down Relay

--------------------------------------------

Add the following to you _plugins_ directory:

#!/usr/bin/env node

const whiteList = {

'003ba9b2c5bd8afeed41a4ce362a8b7fc3ab59c25b6a1359cae9093f296dac01': true,

};

const rl = require('readline').createInterface({

input: process.stdin,

output: process.stdout,

terminal: false

});

rl.on('line', (line) => {

let req = JSON.parse(line);

if (req.type === 'lookback') {

return; // do nothing

}

if (req.type !== 'new') {

console.error("unexpected request type"); // will appear in strfry logs

return;

}

let res = { id: req.event.id }; // must echo the event's id

if (whiteList[req.event.pubkey]) {

res.action = 'accept';

} else {

res.action = 'reject';

res.msg = 'blocked: not on white-list';

}

console.log(JSON.stringify(res));

});

Change the hex public key _(003ba9b2c5bd8afeed41a4ce362a8b7fc3ab59c25b6a1359cae9093f296dac01)_ to yours and add others you want to allow to use the relay.

Make it executable:

sudo chmod +x whitelist.js

Create your _strfry.conf_ in your /etc directory from above docker-compose.yml

##

## Default strfry config for cryptocartel/strfry Docker

##

# Directory that contains the strfry LMDB database (restart required)

db = "./strfry-db/"

dbParams {

# Maximum number of threads/processes that can simultaneously have LMDB transactions open (restart required)

maxreaders = 256

# Size of mmap() to use when loading LMDB (default is 10TB, does *not* correspond to disk-space used) (restart required)

mapsize = 10995116277760

}

relay {

# Interface to listen on. Use 0.0.0.0 to listen on all interfaces (restart required)

bind = "0.0.0.0"

# Port to open for the nostr websocket protocol (restart required)

port = 7777

# Set OS-limit on maximum number of open files/sockets (if 0, don't attempt to set) (restart required)

nofiles = 1000000

# HTTP header that contains the client's real IP, before reverse proxying (ie x-real-ip) (MUST be all lower-case)

realIpHeader = ""

info {

# NIP-11: Name of this server. Short/descriptive (< 30 characters)

name = "strfry docker test"

# NIP-11: Detailed information about relay, free-form

description = "This is a strfry instance."

# NIP-11: Administrative nostr pubkey, for contact purposes

pubkey = "unset"

# NIP-11: Alternative administrative contact (email, website, etc)

contact = "unset"

}

# Maximum accepted incoming websocket frame size (should be larger than max event and yesstr msg) (restart required)

maxWebsocketPayloadSize = 131072

# Websocket-level PING message frequency (should be less than any reverse proxy idle timeouts) (restart required)

autoPingSeconds = 55

# If TCP keep-alive should be enabled (detect dropped connections to upstream reverse proxy)

enableTcpKeepalive = false

# How much uninterrupted CPU time a REQ query should get during its DB scan

queryTimesliceBudgetMicroseconds = 10000

# Maximum records that can be returned per filter

maxFilterLimit = 500

# Maximum number of subscriptions (concurrent REQs) a connection can have open at any time

maxSubsPerConnection = 20

writePolicy {

# If non-empty, path to an executable script that implements the writePolicy plugin logic

plugin = "./plugins/whitelist.js"

# Number of seconds to search backwards for lookback events when starting the writePolicy plugin (0 for no lookback)

lookbackSeconds = 0

}

compression {

# Use permessage-deflate compression if supported by client. Reduces bandwidth, but slight increase in CPU (restart required)

enabled = true

# Maintain a sliding window buffer for each connection. Improves compression, but uses more memory (restart required)

slidingWindow = true

}

logging {

# Dump all incoming messages

dumpInAll = false

# Dump all incoming EVENT messages

dumpInEvents = false

# Dump all incoming REQ/CLOSE messages

dumpInReqs = false

# Log performance metrics for initial REQ database scans

dbScanPerf = false

}

numThreads {

# Ingester threads: route incoming requests, validate events/sigs (restart required)

ingester = 3

# reqWorker threads: Handle initial DB scan for events (restart required)

reqWorker = 3

# reqMonitor threads: Handle filtering of new events (restart required)

reqMonitor = 3

# yesstr threads: Experimental yesstr protocol (restart required)

yesstr = 1

}

}

events {

# Maximum size of normalised JSON, in bytes

maxEventSize = 65536

# Events newer than this will be rejected

rejectEventsNewerThanSeconds = 900

# Events older than this will be rejected

rejectEventsOlderThanSeconds = 94608000

# Ephemeral events older than this will be rejected

rejectEphemeralEventsOlderThanSeconds = 60

# Ephemeral events will be deleted from the DB when older than this

ephemeralEventsLifetimeSeconds = 300

# Maximum number of tags allowed

maxNumTags = 2000

# Maximum size for tag values, in bytes

maxTagValSize = 1024

}

Under the `info` section can add name, description, pubkey, and contact to fit your relay.

If using below nginx config you can change `bind` back to 127.0.0.1 to make it more secure. Change any other settings you feel confident you need to alter.

Start your container with `docker-compose` to test working from directory with the _docker-compose.yml_ file: `sudo docker-compose up`

This will start container in terminal. Once you are happy configuration is working can start as a daemon: `sudo docker-compose up -d`

Add Nginx Reverse Proxy and SSL

-------------------------------

Install nginx on your relay: `sudo apt-get update && sudo apt-get install nginx certbot python3-certbot-nginx`

Remove default config: `sudo rm -rf /etc/nginx/sites-available/default`

Create new default config: `sudo nano /etc/nginx/sites-available/default` Add new reverse proxy config:

server{

server_name relay.yourdomain.com;

location / {

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header Host $host;

proxy_pass http://127.0.0.1:7777;

proxy_http_version 1.1;

proxy_read_timeout 300s;

proxy_connect_timeout 300s;

proxy_send_timeout 300s;

send_timeout 300s;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";

}

}

Change `relay.yourdomain.com` to your DNS name.

Restart nginx: `sudo systemctl restart nginx`

### Add LetsEncrypt SSL Certificate

Use `certbot` to create new SSL and install it with nginx-plugin (replace with your DNS name): `sudo certbot --nginx -d relay.yourdomain.com`

Restart nginx again: `sudo systemctl restart nginx`

If no errors then good to go!

Testing and Usage

-----------------

You can now install something like [nostril](https://github.com/jb55/nostril) to test your relay. Just use a testing nostr account you add to whitelist.js to test with. Or add relay to your client.

nostril --envelope --sec --content "docker container is working and whitelisting!" | websocat ws://localhost:7777

Using Other strfry Commands

---------------------------

See container name or ID: `sudo docker ps`

Enter container to get bash access: `sudo docker exec -it /bin/bash`

This will show you have entered the running container. You can now run any strfry commands needed. See [strfry readme](https://github.com/hoytech/strfry#readme) for more.

bash-5.1# ./strfry --help

**Congrats you now have a working strfry nostr relay!**

By npub1y3uh89v5a4vq92t8q0j6su94zhvcdxpywjn3l6hpsr5welarqtrqj7yzhd  [@jascha](https://iris.to/jascha).

V4V lightning:crispactor61@walletofsatoshi.com

* * *

Follow me on [nostr](https://iris.to/jascha) Follow me on [Mastodon](https://citizenry.social/@jascha) Join Us [Citizenry.Technology](https://citizenry.technology/)

chrome plugin doing some odd behavior.

Open-Source Social Media

People have been trying to make more decentralized internet and social media experiences for a while, but it’s hard to compete with the network effects that the big centralized ones have established. A centralized server tends to be very efficient and self-reinforcing, and so centralized solutions get deployed, get the initial users, and thus entrench themselves for decades.

One of the ways to decentralize the internet is to normalize running a home server and make it easier to do so. As technology improves, basic server-grade computers have become more accessible, and a number of hardware and software solutions have come into existence that are geared towards a consumer server market. However, there are still long-term limitations on peoples’ interest or financial ability to run a server. The financial and bandwidth constraints are particularly problematic for potential users in developing countries.

On the other hand, some technologies enable more peer-to-peer information transfer. File-sharing, video calls, and things like that can allow people to connect to each other in high-bandwidth ways. Keet, for example, is far faster and higher resolution than Zoom for video chats involving modest amounts of people. A challenge with pure peer-to-peer models is that both users have to be online at the same time to coordinate.

A middle-ground method that seems to be beginning to work at scale is the idea of distributed servers or “relays”. In this model, not every user has to run a server, but individual servers are relatively easy to run, are financially incentivized to be run, and are therefore numerous enough that there is no way to control or censor the network. The result is a rather decentralized web of servers that connect to each other, and users that connect to them.

A good example of this is Nostr. It’s an open-source protocol that stands for “Notes and Other Stuff Transmitted by Relays”. For the first two years of its existence it was relatively unused, but in 2022 it started to get more traction. By the end of the year and into early 2023, thanks to efforts by Jack Dorsey and others, it started to gain some serious adoption.

I agree on the home server portion. By everyone running services at home or on dedicated servers of their own the centralized attack surface of current huge sites is nullified. Then is a matter of securing local resources based on exposure.

I've built an unofficial Docker container of Coracle I'm calling #[0] since the goal is to make a dedicated nostr Tor client with .onion relays. You can use this to run a local instance in a Docker container. I encourage everyone to run a client and relay if they have the know-how. Please test and any feedback appreciated!

https://hub.docker.com/r/relayable/coracle-clearnet

I'm working on a howto doc to cover running a full stack of nostr client (above) and strfry relay in containers. You can find the container and docs for strfry here:

https://hub.docker.com/r/cryptocartel/strfry