diff --git a/.gitignore b/.gitignore index 4d3bfbf..645ba09 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,7 @@ server/docker/containers/ export/ # Any testing file -test* +*test # Ignore public and private keys p2prc.publicKey diff --git a/README.md b/README.md index 6a810ee..1a17640 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ > Fixing documentation to latest changes. If you have any questions setting up P2PRC either [create an issue](https://github.com/Akilan1999/p2p-rendering-computation/issues/new/choose) or send me an email (me AT akilan dot io). > Currently HEAD is always intended to stay on a working state. It is recommended to always use HEAD in your go.mod file. +> [!WARNING] +> The root node of P2PRC is down. We are working on creating a new root node with more stable performance. The new root node will be added on the 27th of November. +
diff --git a/cert.pem b/cert.pem
deleted file mode 100644
index f9a2028..0000000
--- a/cert.pem
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC9DCCAdygAwIBAgIQXOymZW4XLjqscy843BeeBzANBgkqhkiG9w0BAQsFADAS
-MRAwDgYDVQQKEwdBY21lIENvMB4XDTI0MTAyMDIxMjc1NloXDTI1MTAyMDIxMjc1
-NlowEjEQMA4GA1UEChMHQWNtZSBDbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
-AQoCggEBAMFErOjO5LYkiMev4Xma6DX7rmjcyQRau84IyOflajE7LFyUnEDxZJkE
-JU57mm06uOLr6XUytkFOFrgeCsWAbraiGhKDH5srBvvNAgah/8RgkIFXASDslEy5
-bI9RZZLe8jJP0cVGvgnZi6aZsDYZm9wlYSgY+9f9QddCb1NQ+/0mu9cluq6v/n3G
-q5PhXHt9CnHoYs8hJ+fbJATAogugvfh3zYbkrBUPY73hQ2/dwHy7mdfAieo6i3GR
-NP2/YQTHBwBqm6teOlBZ8VfQOyzU8czz1mhbD8GVh5CF/ZWE6tHxxjWG+B53VW/e
-yH0LlQQFttNn2bB58W9Bgfov5CBj/30CAwEAAaNGMEQwDgYDVR0PAQH/BAQDAgWg
-MBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwDwYDVR0RBAgwBocE
-TWH5GDANBgkqhkiG9w0BAQsFAAOCAQEAEs4zLQt9n1BLibCmoKwzYDSUK/KQQdcA
-8LREoTH6bD+TryzWSQ1zF+WZHbru9pGNO9gkEbmcYwziTVoPmFwblvoc/YoXFp2B
-fQiIAZ5+TMtEfdj6agW8+fz00eMKvo1HkbO3RhDj+KYxlED7DL4Tn/ESx7wKtPsX
-lSUBK4Chqmj3hB8OCIeDUoMwnCaA1plLfBgcFixtWyYEGv8gXgwrpVqXLfdnGCOI
-biFWeLMSXiqZOykJl6fJbOGjkmTsLSDHcyhV2x1+FHviDJYF4WckrkhSmBw+Pspz
-OT41o6uP/MFimbFAhCfcPRwHj1vMzfunKvb7UGPJPCWE5oWA7sWsQw==
------END CERTIFICATE-----
diff --git a/client/clientIPTable/AddCustomInformationToIPTable.go b/client/clientIPTable/AddCustomInformationToIPTable.go
index 56763b3..a6b8c4e 100644
--- a/client/clientIPTable/AddCustomInformationToIPTable.go
+++ b/client/clientIPTable/AddCustomInformationToIPTable.go
@@ -31,7 +31,7 @@ func AddCustomInformationToIPTable(text string) error {
if found {
table.WriteIpTable()
// update IPTable after modified entry
- UpdateIpTableListClient()
+ go UpdateIpTableListClient()
} else {
return errors.New("start server with p2prc -s as the server is currently not running")
}
diff --git a/client/clientIPTable/Iptable.go b/client/clientIPTable/Iptable.go
index d6da7e0..204bbf0 100644
--- a/client/clientIPTable/Iptable.go
+++ b/client/clientIPTable/Iptable.go
@@ -64,10 +64,11 @@ func UpdateIpTable(IpAddress string, serverPort string, wg *sync.WaitGroup) erro
}
}
- err = ipStruct.WriteIpTable()
- if err != nil {
- return err
- }
+ // Not required to update IP table as speed test updates the IP Table
+ //err = ipStruct.WriteIpTable()
+ //if err != nil {
+ // return err
+ //}
wg.Done()
diff --git a/config/config.go b/config/config.go
index 163a597..883638b 100644
--- a/config/config.go
+++ b/config/config.go
@@ -36,7 +36,8 @@ type Config struct {
PrivateKeyFile string
PemFile string
KeyFile string
- BareMetal string
+ BareMetal bool
+ UnsafeMode bool
CustomConfig interface{}
//NetworkInterface string
//NetworkInterfaceIPV6Index int
diff --git a/config/generate/generate.go b/config/generate/generate.go
index cdccc37..b926457 100644
--- a/config/generate/generate.go
+++ b/config/generate/generate.go
@@ -91,9 +91,10 @@ func SetDefaults(envName string, forceDefault bool, CustomConfig interface{}, No
}
// Generate Public and private keys and set path
- Defaults.PublicKeyFile = defaultPath + "p2prc.PublicKeyBareMetal"
+ Defaults.PublicKeyFile = defaultPath + "p2prc.publicKey"
Defaults.PrivateKeyFile = defaultPath + "p2prc.privateKey"
- Defaults.BareMetal = "False"
+ Defaults.BareMetal = false
+ Defaults.UnsafeMode = false
// Generate certificate files for SSL
err = GenerateCertificate()
diff --git a/key.pem b/key.pem
deleted file mode 100644
index 170c493..0000000
--- a/key.pem
+++ /dev/null
@@ -1,28 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDBRKzozuS2JIjH
-r+F5mug1+65o3MkEWrvOCMjn5WoxOyxclJxA8WSZBCVOe5ptOrji6+l1MrZBTha4
-HgrFgG62ohoSgx+bKwb7zQIGof/EYJCBVwEg7JRMuWyPUWWS3vIyT9HFRr4J2Yum
-mbA2GZvcJWEoGPvX/UHXQm9TUPv9JrvXJbqur/59xquT4Vx7fQpx6GLPISfn2yQE
-wKILoL34d82G5KwVD2O94UNv3cB8u5nXwInqOotxkTT9v2EExwcAapurXjpQWfFX
-0Dss1PHM89ZoWw/BlYeQhf2VhOrR8cY1hvged1Vv3sh9C5UEBbbTZ9mwefFvQYH6
-L+QgY/99AgMBAAECggEAag7BxFAk+j86QDqoRQ9Y9qbSowDl3tnbzcjMV1Vx3OpY
-AcYbqRfO2JmJz3PM3rwm0YAccRAPK+8qUIdL6e3804RJQndqVMBb6LorrnAf5ygG
-pLOWDvdEuoXWqR9F2j82MZ3Tw6p6hvU2yYn1RPrwqPJqSpLLQU/dXb87UEFUxyoQ
-7bNBNzsulZNd70JJtvmieXU1tf88EdiIxv/Ua9ZRepkkLDJlt3BwsGK+JdVhOhN2
-zUjhlQ4HrErdY6C0rEX7gKznSaThaZb6RYZOLqBfe5nG/uQjw+OfltLEz4nR5xn2
-2F07T0a5hP4WvCgNQRBzsXGYNumJEuSkcadEw8hEkQKBgQD2RAnUlnQ99xqvz3QK
-STptQcJOF07DQmEs6A8E7BHue/Z4+gYNtbyQ7NefDYBuGWOzUOXOJs6k//CCgcDe
-ZzmtRPs3Sro8AfK0FS09r/OpXL+LPJjhSJ+YEjoVzERSDCvVNshuIO92zlDPITg8
-J9ZsPzXrm+Yh1f5gvSgvmgJodwKBgQDI6FsH7mdjW3bp1tGnF/SzqOBMutyZp7/9
-b7dtJhZNwdi4765JVtLAXDei5kht7NzVlH7GJGcrIen5emKBRS6JjDlhFcFw669V
-biOiBrL/3Gu9irjLh2abSBE5r7GClelDLgmJ/JrpkRJRcBtfoPLsYIHtViNXz2CE
-w2yf3D+IqwKBgDV7l0r1Fe+zL7eI7WGif67kvicphrB/RQ10pHZkMozBnUiuvAvU
-MUykMzvWudKvbuitpAr+gJhzAS/GsDVc47jOp2RdtU58+dHEW5vvD5LzkqHRmj4r
-AIYNR1Iel6PeAtL+X88TFg6ORhyF0Wm3GSlPHQ27QOKOT/2Ady7HWsiHAoGAAZ2U
-tdCd9jeTEjhPAUf5CMTP4O4TvgySR6hxUihfP4rSglIzFZXkJfXX4LB3XqLr96+1
-AUTjq34fUolAZ4e14xdEktpI7u6GP2qeULw7DkGogCKwb7qMAa2nrc4S4FjyQj8J
-hpmIaV5oRk1fevphWbNA+DacHCWnwgmMQxDTVfcCgYAxbQQFyRJ1B+WJtvE66cqA
-T/DvgzevwqE4na+NNc6hApZt+kNoLODLUi6ikYimNzdtGnr4AIitvGR3J9qzFC+I
-+d2F1ioSV4fpVD7idYDVkncME+pXzzGweg91k8ucHqcdU1k70lYTokGgm3DyClcP
-76O6IS1URnFFXco9DGuDcA==
------END PRIVATE KEY-----
diff --git a/main.go b/main.go
index 3607d92..fb85b0f 100644
--- a/main.go
+++ b/main.go
@@ -1,11 +1,13 @@
package main
import (
- "log"
- "os"
+ "log"
+ "os"
+ "os/signal"
+ "syscall"
- "github.com/Akilan1999/p2p-rendering-computation/cmd"
- "github.com/urfave/cli/v2"
+ "github.com/Akilan1999/p2p-rendering-computation/cmd"
+ "github.com/urfave/cli/v2"
)
// VERSION specifies the version of the platform
@@ -16,16 +18,36 @@ var mode string
var OS, Pull_location, Run_script string
var List_servers, Ip_table bool
-func main() {
- app := cli.NewApp()
- app.Name = "p2p-rendering-computation"
- app.Usage = "p2p cli application to create and access VMs in other servers"
- app.Version = VERSION
- app.Flags = cmd.AppConfigFlags
- app.Action = cmd.CliAction
+// To be implemented later on
+func getFireSignalsChannel() chan os.Signal {
+
+ c := make(chan os.Signal, 1)
+ signal.Notify(c,
+ // https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html
+ syscall.SIGTERM, // "the normal way to politely ask a program to terminate"
+ syscall.SIGINT, // Ctrl+C
+ syscall.SIGQUIT, // Ctrl-\
+ syscall.SIGKILL, // "always fatal", "SIGKILL and SIGSTOP may not be caught by a program"
+ syscall.SIGHUP, // "terminal is disconnected"
+ )
+ return c
- err := app.Run(os.Args)
- if err != nil {
- log.Fatal(err)
- }
+}
+
+func exit() {
+ syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
+}
+
+func main() {
+ app := cli.NewApp()
+ app.Name = "p2p-rendering-computation"
+ app.Usage = "p2p cli application to create and access VMs in other servers"
+ app.Version = VERSION
+ app.Flags = cmd.AppConfigFlags
+ app.Action = cmd.CliAction
+
+ err := app.Run(os.Args)
+ if err != nil {
+ log.Fatal(err)
+ }
}
diff --git a/p2p/iptable.go b/p2p/iptable.go
index 372d88d..9cdf891 100644
--- a/p2p/iptable.go
+++ b/p2p/iptable.go
@@ -21,6 +21,7 @@ type IpAddresses struct {
type IpAddress struct {
Name string `json:"Name"`
+ MachineUsername string `json:"MachineUsername"`
Ipv4 string `json:"IPV4"`
Ipv6 string `json:"IPV6"`
Latency time.Duration `json:"Latency"`
@@ -31,6 +32,8 @@ type IpAddress struct {
NAT string `json:"NAT"`
EscapeImplementation string `json:"EscapeImplementation"`
ProxyServer string `json:"ProxyServer"`
+ UnSafeMode bool `json:"UnSafeMode"`
+ PublicKey string `json:"PublicKey"`
CustomInformation string `json:"CustomInformation"`
//CustomInformationKey []byte `json:"CustomInformationKey"`
}
diff --git a/p2p/speedtest.go b/p2p/speedtest.go
index 4957181..0468b07 100644
--- a/p2p/speedtest.go
+++ b/p2p/speedtest.go
@@ -1,5 +1,9 @@
package p2p
+import (
+ "github.com/Akilan1999/p2p-rendering-computation/config"
+)
+
// SpeedTest Runs a speed test and does updates IP tables accordingly
func (ip *IpAddresses) SpeedTest() error {
@@ -50,11 +54,26 @@ func (ip *IpAddresses) SpeedTest() error {
// SpeedTestUpdatedIPTable Called when ip tables from httpclient/server is also passed on
func (ip *IpAddresses) SpeedTestUpdatedIPTable() error {
+
+ Config, err := config.ConfigInit(nil, nil)
+ if err != nil {
+ return err
+ }
+
targets, err := ReadIpTable()
if err != nil {
return err
}
+ // Checks if baremetal mode and unsafe mode
+ // is enabled. If it is enabled it adds the
+ // the propagated public key to the list.
+
+ AddPublicKey := false
+ if Config.BareMetal && Config.UnsafeMode {
+ AddPublicKey = true
+ }
+
// To ensure struct has no duplicates IP addresses
//DoNotRead := targets
@@ -64,6 +83,16 @@ func (ip *IpAddresses) SpeedTestUpdatedIPTable() error {
//To ensure that there are no duplicate IP addresses
Exists := false
for k := range ip.IpAddress {
+ if AddPublicKey && ip.IpAddress[k].PublicKey != "" {
+ // This function call (AddAuthorisationKey) is inefficient but to be optimised later on.
+ // This is because when if the user is running on as unsafe mode the authorization file
+ // is opened from the SSH directory and then iterates through every single SSH entry
+ // to find out if the SSH entry exists or not. This will incur multiple CPU cycles
+ // for no reason. A better approach would be to have been to store the states on memory and only
+ // add when needed based on the memory location. This is something is to be discussed
+ // and look upon later on.
+ AddAuthorisationKey(ip.IpAddress[k].PublicKey)
+ }
// Checks if both the IPV4 addresses are the same or the IPV6 address is not
// an empty string and IPV6 address are the same
if (ip.IpAddress[k].Ipv4 == targets.IpAddress[i].Ipv4 && targets.IpAddress[i].NAT == "True") || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
diff --git a/p2p/ssh_autorisation.go b/p2p/ssh_autorisation.go
new file mode 100644
index 0000000..89b4a86
--- /dev/null
+++ b/p2p/ssh_autorisation.go
@@ -0,0 +1,123 @@
+// NOTE: Most of the code snippet was generated using ChatGPT
+// Prompt used: "generate go program to read and populate ssh authorization file"
+
+package p2p
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+)
+
+// GetAuthorizedKeysPath returns the path to the authorized_keys file
+func GetAuthorizedKeysPath() (string, error) {
+ homeDir, err := os.UserHomeDir()
+ if err != nil {
+ return "", fmt.Errorf("could not find home directory: %v", err)
+ }
+ return filepath.Join(homeDir, ".ssh", "authorized_keys"), nil
+}
+
+// ReadAuthorizedKeys reads and returns the current contents of the authorized_keys file as a map
+func ReadAuthorizedKeys(path string) (map[string]bool, error) {
+ file, err := os.Open(path)
+ if err != nil {
+ return nil, fmt.Errorf("could not open authorized_keys file: %v", err)
+ }
+ defer file.Close()
+
+ keys := make(map[string]bool)
+ scanner := bufio.NewScanner(file)
+ for scanner.Scan() {
+ line := strings.TrimSpace(scanner.Text())
+ // Skip empty lines and comments
+ if line != "" && !strings.HasPrefix(line, "#") {
+ keys[line] = true
+ }
+ }
+ if err := scanner.Err(); err != nil {
+ return nil, fmt.Errorf("error reading authorized_keys file: %v", err)
+ }
+ return keys, nil
+}
+
+// AddKeyToAuthorizedKeys adds a new key to the authorized_keys file if it doesn’t already exist
+func AddKeyToAuthorizedKeys(path, newKey string) error {
+ keys, err := ReadAuthorizedKeys(path)
+ if err != nil {
+ return err
+ }
+
+ // Check if the key already exists in the map
+ if keys[newKey] {
+ return errors.New("key already exists in authorized_keys")
+ }
+
+ // Append the new key
+ file, err := os.OpenFile(path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
+ if err != nil {
+ return fmt.Errorf("could not open authorized_keys file for writing: %v", err)
+ }
+ defer file.Close()
+
+ if _, err := file.WriteString(newKey + "\n"); err != nil {
+ return fmt.Errorf("could not write to authorized_keys file: %v", err)
+ }
+ return nil
+}
+
+func RemoveKeyFromAuthorizedKeys(path, keyToRemove string) error {
+ keys, err := ReadAuthorizedKeys(path)
+ if err != nil {
+ return err
+ }
+
+ // Check if the key exists in the map
+ if !keys[keyToRemove] {
+ return errors.New("key not found in authorized_keys")
+ }
+
+ // Delete the key from the map
+ delete(keys, keyToRemove)
+
+ // Write updated keys back to the authorized_keys file
+ file, err := os.OpenFile(path, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0600)
+ if err != nil {
+ return fmt.Errorf("could not open authorized_keys file for writing: %v", err)
+ }
+ defer file.Close()
+
+ for key := range keys {
+ if _, err := file.WriteString(key + "\n"); err != nil {
+ return fmt.Errorf("could not write to authorized_keys file: %v", err)
+ }
+ }
+
+ return nil
+}
+
+// AddAuthorisationKey Adds public key provided to the
+// authorization file so that nodes can SSH into
+// the
+func AddAuthorisationKey(PublicKey string) error {
+ path, err := GetAuthorizedKeysPath()
+ if err != nil {
+ return err
+ }
+
+ // Display existing keys
+ _, err = ReadAuthorizedKeys(path)
+ if err != nil {
+ return err
+ }
+
+ err = AddKeyToAuthorizedKeys(path, PublicKey)
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/server/server.go b/server/server.go
index 8140e48..0e56ed1 100644
--- a/server/server.go
+++ b/server/server.go
@@ -13,6 +13,7 @@ import (
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
+ "os/user"
"strconv"
"time"
)
@@ -69,13 +70,13 @@ func Server() (*gin.Engine, error) {
//Gets Ip Table from server node
r.POST("/IpTable", func(c *gin.Context) {
// Getting IPV4 address of client
- var ClientHost p2p.IpAddress
-
- if p2p.Ip4or6(c.ClientIP()) == "version 6" {
- ClientHost.Ipv6 = c.ClientIP()
- } else {
- ClientHost.Ipv4 = c.ClientIP()
- }
+ //var ClientHost p2p.IpAddress
+ //
+ //if p2p.Ip4or6(c.ClientIP()) == "version 6" {
+ // ClientHost.Ipv6 = c.ClientIP()
+ //} else {
+ // ClientHost.Ipv4 = c.ClientIP()
+ //}
// Variable to store IP table information
var IPTable p2p.IpAddresses
@@ -101,7 +102,7 @@ func Server() (*gin.Engine, error) {
json.Unmarshal(file, &IPTable)
//Add Client IP address to IPTable struct
- IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
+ //IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
// Runs speed test to return only servers in the IP table pingable
err = IPTable.SpeedTestUpdatedIPTable()
@@ -294,7 +295,7 @@ func Server() (*gin.Engine, error) {
ProxyIpAddr.ProxyServer = "False"
ProxyIpAddr.EscapeImplementation = "FRP"
- if config.BareMetal == "True" {
+ if config.BareMetal {
_, SSHPort, err := MapPort("22", "")
if err != nil {
return nil, err
@@ -303,9 +304,6 @@ func Server() (*gin.Engine, error) {
}
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
-
- // append the following to the ip table
- table.IpAddress = append(table.IpAddress, ProxyIpAddr)
// write information back to the IP Table
}
@@ -321,14 +319,34 @@ func Server() (*gin.Engine, error) {
ProxyIpAddr.ProxyServer = "True"
}
ProxyIpAddr.EscapeImplementation = ""
- if config.BareMetal == "True" {
+ if config.BareMetal {
ProxyIpAddr.BareMetalSSHPort = "22"
}
- table.IpAddress = append(table.IpAddress, ProxyIpAddr)
-
}
+ // Get machine username
+ currentUser, err := user.Current()
+ if err != nil {
+ return nil, err
+ }
+ // Add username p2prc binary is being run under
+ ProxyIpAddr.MachineUsername = currentUser.Username
+ ProxyIpAddr.UnSafeMode = config.UnsafeMode
+ // Adds the public key information to the IPTable
+ // improving transmission of IPTables without the
+ // entire public key is future work to be improved
+ // in the P2PRC protocol level (Improving by adding
+ // UDP with TCP reliability layer).
+ ProxyIpAddr.PublicKey, err = config.GetPublicKey()
+
+ if err != nil {
+ return nil, err
+ }
+
+ // append the following to the ip table
+ table.IpAddress = append(table.IpAddress, ProxyIpAddr)
+
// Writing results to the IPTable
err = table.WriteIpTable()
if err != nil {
@@ -406,11 +424,8 @@ func MapPort(port string, domainName string) (string, string, error) {
return "", "", err
}
- fmt.Println(domainName)
-
// Doing the proxy mapping for the domain name
if domainName != "" {
- fmt.Println("called --------------------------------")
fmt.Println("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4)
URL := "http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort + "/AddProxy?port=" + proxyPort + "&domain_name=" + domainName + "&ip_address=" + lowestLatencyIpAddress.Ipv4
//} else {
@@ -426,6 +441,7 @@ func MapPort(port string, domainName string) (string, string, error) {
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = "False"
ProxyIpAddr.EscapeImplementation = "FRP"
+
//ProxyIpAddr.CustomInformationKey = p2p.GenerateHashSHA256(config.IPTableKey)
} else {
return "", "", errors.New("proxy IP not found")