p2p

package
v0.0.0-...-c299779 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 2, 2024 License: GPL-3.0 Imports: 26 Imported by: 1

README

= p2p

A personal p2p network for your home.

== What is it?

A personal p2p network for your home. It connects all your computers together, and provides basic services like file sharing, and network management.

== How does it work?

This is a traditional p2p network. Each node is connected to peers, and exchanges messages to discover other nodes.

There is currently a command line client, and half a web client.

== How do I use it?

=== Install

    git clone https://gitlab.com/donomii/menu
    cd menu/p2p
    sh build.sh

=== Run

Warning: This program generates a lot of network traffic. It is not suitable for mobile devices, and/or any networks that charge by data volume. The author is never responsible, under any circumstances, for any charges you incur.

This program has not been reviewed by security professionals. It is not suitable for any use where security is important. Do not run this on your company network. The author is never responsible, under any circumstances, for any damage or security incidents.

    ./node --name "first node" --secret abcdefgh12345678

Important: The secret is the password for your network. Every node must use exactly the same secret password. You need to pick a long random string, and keep it secret. If you lose it, you will need to change all your nodes. You can use --generate-secret to generate a good random secret password.

    ./node --generate-secret
    Secret network phrase: b711380c37787aa4ba800fb9f78dbc824814f5f0f23e6580c2d127a181712fb3

Now you can start a node on another computer, and it will connect to the first node.

    ./node --name "second node" --secret abcdefgh12345678 --peer 192.168.0.3:9000

Replace 192.168.0.3 with the IP address of the first node. You can start as many nodes as you like on the same machine, and have them connect to each other. This is the easiest way to add services like filesharing.

    ./fileshare --share /tmp/files --name fileshare --peer 127.0.0.1:9000 --secret abcdefgh12345678

There are some other useful nodes you can run

    ./advertise --name advertise --secret abcdefgh12345678 --service-protocol http --service-port 8080 --service-name "My Web Server" --service-address 192.168.0.3

This will advertise a web server running on port 8080. You can use the --service-protocol to advertise other protocols, like ssh, or ftp.

The advertiser broadcasts your services to your local net, so you can find them easily, even if your computer switches IP address.

    ./p2p service "My Web Server"
        http://192.168.0.3:8080/

There is also a log monitor, which broadcasts your system logs to all your other nodes.

    ./logmon --name logmonitor --secret abcdefgh12345678

== Command line client

The command line client is a simple way to interact with the network.

    p2p nodes
      first node
      second node
      node 20

    p2p service "My Web Server"
      http://192.168.0.3:8080/

    p2p add 192.168.0.10:9000

== Web client

The web client is a work in progress. It is available at http://localhost:8999/, when running the main node (node.exe).

== Security

I have done my best with security, however I'm not a security professional. This is the most security without requiring the user to copy certificates between machines. This program expects to run on a trusted network, like your home network. Run it on the open internet at your own risk.

Even if the program is secure, I haven't taken any efforts to resist timing or trafic analysis or anything like that. At best, people won't be able to read your messages, but they will be able to see who you are talking to.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ExtraDebug bool = false
View Source
var GlobalDebug bool = false
View Source
var GlobalVerbose bool = false

Functions

func Debugf

func Debugf(format string, args ...interface{})

func DecodeRSAPublicKey

func DecodeRSAPublicKey(encodedKey string) *rsa.PublicKey

func DecryptWithPrivateKey

func DecryptWithPrivateKey(ciphertext []byte, privateKey *rsa.PrivateKey) []byte

func EncodeRSAPublicKey

func EncodeRSAPublicKey(pub *rsa.PublicKey) string

func EncryptWithPublicKey

func EncryptWithPublicKey(plaintext []byte, publicKey *rsa.PublicKey) []byte

func ExtraDebugf

func ExtraDebugf(format string, args ...interface{})

func GenerateSecretPhrase

func GenerateSecretPhrase() []byte

func KeyShortName

func KeyShortName(key []byte) string

func NodeShortName

func NodeShortName(node *Node) string

func PublicKeyToId

func PublicKeyToId(publicKey *rsa.PublicKey) string

func ShortName

func ShortName(node string) string

func VerifySignature

func VerifySignature(msg []byte, sign []byte, publicKey *rsa.PublicKey) bool

Types

type Announcement

type Announcement struct {
	Name      string
	KnownIps  []string
	LastSeen  time.Time
	PublicKey *rsa.PublicKey
	Peers     []string
}

type Config

type Config struct {
	Name             string
	PrivateKey       *rsa.PrivateKey
	PublicKey        *rsa.PublicKey
	KnownNodes       []string
	AnnounceInterval int
}

type Message

type Message struct {
	Id             string
	ReplyToId      string
	Type           string
	From           string
	To             string
	Content        []byte
	EncodedContent []byte
	Sign           []byte
	Hops           int
	Version        int
}

type Network

type Network struct {
	NodeName       string    // Display name of the node
	BindAddrPort   string    // Address and port to listen on
	ConnectedNodes *sync.Map // Map of connected nodes i.e. neighbours

	PrivateKey     *rsa.PrivateKey //This node's private key
	PublicKey      *rsa.PublicKey  //This node's public key
	SharedPassword []byte          //Shared password for private network.  All nodes must have the same password
	SharedKey      []byte          //Shared key for private network.  All nodes must have the same key (Pre-Shared Key)
	MsgCallbacks   *sync.Map       //Map of message types to callback functions

	Id                 string    //Id of this node, usually the public key
	Nodes              *sync.Map //All nodes that have been seen
	SeenMessages       *sync.Map //All message ids that have been seen, to prevent duplicates
	MessageCounter     int       //Number of messages sent
	DuplicateCounter   int       //Number of duplicate messages seen and dropped
	ForwardCounter     int       //Number of messages forwarded
	ReceivedCounter    int       //Number of messages received
	PossibleEndpoints  *sync.Map //All possible endpoints (ip:port) that have been seen
	AnnounceInterval   int       //How often to announce this node's existence on the network
	AutoPort           bool      //Whether to automatically increment the listening port number if the desired port is in use
	Services           *sync.Map //A collection of the currentknown services, as gathered from service announcements on the network
	MessageIdCallbacks *sync.Map //Handlers for message replies.  P2p works asynchronously, so every request has a callback id, and the reply contains that id
	Topology           *sync.Map //The current network topology, as gathered from topology announcements on the network
	Version            int       //The version of the p2p protocol
	MaxHops            int       //The maximum number of hops a message can take before being dropped
	TrustedKeys        []string  //List of trusted keys
	ConfigBaseDir      string    //The base directory for config files.  Leave unset for default(home directory/.p2p)

}

func NewNetwork

func NewNetwork(listenAddr string, sharedPassword, sharedKey []byte) (*Network, error)

func (*Network) AddEdge

func (p2pnet *Network) AddEdge(nodeId string, peers []string)

func (*Network) AddEndpoint

func (p2pnet *Network) AddEndpoint(endpoint string)

func (*Network) Announce

func (p2pnet *Network) Announce(myNodeName string, myBindport string)

func (*Network) Broadcast

func (p2pnet *Network) Broadcast(ty string, payload []byte) string

Broadcasts bytes to all nodes. The bytes are not examined or encrypted in any way

func (*Network) Connect

func (p2pnet *Network) Connect(addr string) error

func (*Network) ConnectNewEndpointsLoop

func (p2pnet *Network) ConnectNewEndpointsLoop()

func (*Network) Listen

func (p2pnet *Network) Listen()

func (*Network) LoadDefaultConfig

func (p2pnet *Network) LoadDefaultConfig(name string)

func (*Network) SaveDefaultConfig

func (p2pnet *Network) SaveDefaultConfig(name string)

func (*Network) SendMessage

func (p2pnet *Network) SendMessage(msg *Message) string

Send a message to a node, encrypting it with their public key, and routing it through the network

func (*Network) ServicesList

func (p2pnet *Network) ServicesList() []ServiceAnnouncement

func (*Network) Start

func (p2pnet *Network) Start()

type Node

type Node struct {
	Conn                net.Conn `json:"-"`
	PublicKey           *rsa.PublicKey
	AESKey              [32]byte
	SymmetricKeyReceive []byte       `json:"-"`
	SymmetricKeySend    []byte       `json:"-"`
	Buff                bufio.Reader `json:"-"`
	SeenIds             *sync.Map    //Attached to nodes(and thus connections, so we can route backwards)
	LastSeen            time.Time
	SendMutex           sync.Mutex //Mutex for sending messages

}

func (*Node) DisplayName

func (n *Node) DisplayName() string

func (*Node) Id

func (n *Node) Id() string

func (*Node) PublicKeyString

func (n *Node) PublicKeyString() string

type SearchResult

type SearchResult struct {
	Id     string // A uuid for later use
	Name   string // The name of the file
	Node   []byte // The public key of the node that has the file
	Sample string // A sample of the file
}

type ServiceAnnouncement

type ServiceAnnouncement struct {
	ServiceName     string
	ServiceAddress  string
	ServicePort     string
	ServiceProtocol string
	ServicePath     string
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL