Skip to content

Instantly share code, notes, and snippets.

@Semisol
Last active June 23, 2023 01:36
Show Gist options
  • Save Semisol/1715258b962cb130bdb62d47f349deb7 to your computer and use it in GitHub Desktop.
Save Semisol/1715258b962cb130bdb62d47f349deb7 to your computer and use it in GitHub Desktop.
udp-nostr test

steps

  1. generate your wireguard keypair and send your public key as a reply to this post or this gist
  2. input your address to the config file (that I will reply with)
  3. save the config file as wgnostr.conf
  4. install wireguard if you haven't already
  5. wg-quick up ./wgnostr.conf
  6. make a new directory, npm init and npm install nostr
  7. put udp-nostr.mjs there
  8. run node udp-nostr.mjs 127.0.0.1 5555 5556 wg:<name I gave you>

how to generate your wireguard keypair:

  1. wg genkey to generate your private key
  2. wg pubkey, copy-paste your private key and do Ctrl+D (EOF)
  3. outputted line is your public key

note

there is firewalling set up on the wireguard interface to prevent people from sending packets to each other and the configuration here also blocks all inbound packets not related to a connection initiated by you.

// npm i nostr
// node udp-nostr.mjs <destination host> <destination port> <listen port> <channel>
import nostr from 'nostr'
import dgram from 'dgram'
import crypto from 'crypto'
let argv = process.argv.slice(2)
let targetAddr = argv[0]
let targetPort = +argv[1]
let listenPort = +argv[2]
let channel = argv[3]
let priv = crypto.randomBytes(32).toString("hex")
let receivedSet = new Set()
let pk = nostr.getPublicKey(priv)
let pool = new nostr.RelayPool([
"wss://nostr-pub.semisol.dev"
])
console.log("Your identity is %s", pk)
pool.on('open', relay => {
console.log("Connected to relay %s", relay.url)
relay.subscribe("udp-nostr", { kinds: [23744], "#c": [channel] })
})
const server = dgram.createSocket('udp4')
server.on('error', (err) => {
console.error("Error:\n%s", err.stack)
server.close()
process.exit()
})
server.on('message', async (msg, rinfo) => {
let event = {
kind: 23744,
tags: [
["c", channel]
],
content: msg.toString("base64"),
created_at: Math.floor(Date.now() / 1000),
pubkey: pk
}
event.id = await nostr.calculateId(event)
event.sig = await nostr.signId(priv, event.id)
pool.send(["EVENT", event])
})
pool.on("event", (relay, sub, event) => {
let ts = Math.floor(Date.now() / 1000)
if (event.pubkey === pk) return
if (receivedSet.has(event.id)) return
if (event.created_at < ts - 3) {
console.log("dropped packet from %s: time too low", event.pubkey)
return
}
receivedSet.add(event.id)
setTimeout(() => {
receivedSet.delete(event.id)
}, 3000)
let data = Buffer.from(event.content, "base64")
server.send(data, targetPort, targetAddr)
})
server.on('listening', () => {
const address = server.address()
console.log(`Server listening on ${address.address}:${address.port}`)
})
server.bind(listenPort)
[Interface]
PrivateKey = <YOUR PRIVATE KEY>
ListenPort = 5555
Address = 10.4.0.2 # change this
PostUp = iptables -N wgnostr-filter
PostUp = iptables -I INPUT -i wgnostr -j wgnostr-filter
PostUp = iptables -I FORWARD -i wgnostr -j wgnostr-filter
PostUp = iptables -I FORWARD -o wgnostr -j wgnostr-filter
PostUp = iptables -I OUTPUT -o wgnostr -j wgnostr-filter
PostUp = iptables -A wgnostr-filter -m state --state ESTABLISHED,RELATED -j ACCEPT
PostUp = iptables -A wgnostr-filter -j REJECT
PostDown = iptables -D INPUT -i wgnostr -j wgnostr-filter
PostDown = iptables -D FORWARD -i wgnostr -j wgnostr-filter
PostDown = iptables -D FORWARD -o wgnostr -j wgnostr-filter
PostDown = iptables -D OUTPUT -o wgnostr -j wgnostr-filter
[Peer]
AllowedIPs = 10.4.0.1
PublicKey = aAS9Vftd9S3s4U0TBBUAlxXvaOHpSAewV86G+YufVEs=
Endpoint = 127.0.0.1:5556
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment