v1.0.1 probe

This commit is contained in:
2025-04-29 23:40:33 +02:00
parent 371b44422b
commit 56c57957c8
4 changed files with 152 additions and 42 deletions
+18
View File
@@ -0,0 +1,18 @@
BINARY_NAME=obsero-probe
all: build
build:
go build -o $(BINARY_NAME) ./cmd/obsero-probe
build-linux:
GOOS=linux GOARCH=amd64 go build -o $(BINARY_NAME)-linux ./cmd/obsero-probe
build-mac:
GOOS=darwin GOARCH=amd64 go build -o $(BINARY_NAME)-mac ./cmd/obsero-probe
build-arm:
GOOS=linux GOARCH=arm64 go build -o $(BINARY_NAME)-arm64 ./cmd/obsero-probe
clean:
rm -f $(BINARY_NAME)*
+25 -4
View File
@@ -1,20 +1,41 @@
package main package main
import ( import (
"flag"
"fmt" "fmt"
"os" "os"
"git.cryptolab.re/foudre/whitepaper_obsero/pkg/geo" "git.cryptolab.re/foudre/whitepaper_obsero/pkg/geo"
"git.cryptolab.re/foudre/whitepaper_obsero/pkg/probe" "git.cryptolab.re/foudre/whitepaper_obsero/pkg/probe"
"git.cryptolab.re/foudre/whitepaper_obsero/pkg/proof" "git.cryptolab.re/foudre/whitepaper_obsero/pkg/proof"
) )
func main() { func main() {
target := "https://example.com" target := flag.String("target", "https://example.com", "Target URL to probe")
output := flag.String("output", "proof_http_signed.json", "Output file name for proof JSON")
useIPFS := flag.Bool("ipfs", false, "Upload to IPFS after proof generation")
flag.Parse()
location := geo.GetGeoLocation() location := geo.GetGeoLocation()
result := probe.HttpPing(target) result := probe.HttpPing(*target)
observation := proof.BuildProof(result, location) observation := proof.BuildProof(result, location)
proof.SaveProof(observation, "proof_http_result.json") err := proof.SignProof(&observation)
fmt.Println("✅ Proof generated and saved.") if err != nil {
fmt.Println("❌ Failed to sign proof:", err)
os.Exit(1)
}
proof.SaveProof(observation, *output)
fmt.Println("✅ Signed proof saved to", *output)
if *useIPFS {
cid, err := proof.UploadToIPFS(*output)
if err != nil {
fmt.Println("❌ Failed to upload to IPFS:", err)
} else {
fmt.Println("📡 Uploaded to IPFS with CID:", cid)
}
}
} }
+49
View File
@@ -1,13 +1,34 @@
package proof package proof
import ( import (
"crypto/ecdsa"
"crypto/sha256"
"encoding/hex"
"encoding/json" "encoding/json"
"fmt"
"os" "os"
"github.com/ethereum/go-ethereum/crypto"
"git.cryptolab.re/foudre/whitepaper_obsero/pkg/geo" "git.cryptolab.re/foudre/whitepaper_obsero/pkg/geo"
"git.cryptolab.re/foudre/whitepaper_obsero/pkg/probe" "git.cryptolab.re/foudre/whitepaper_obsero/pkg/probe"
import (
...
shell "github.com/ipfs/go-ipfs-api"
...
) )
...
func UploadToIPFS(filepath string) (string, error) {
sh := shell.NewShell("localhost:5001")
cid, err := sh.AddNoPin(shell.NewShellFile(filepath))
if err != nil {
return "", err
}
return cid, nil
}
type Observation struct { type Observation struct {
Timestamp string `json:"timestamp"` Timestamp string `json:"timestamp"`
Target string `json:"target"` Target string `json:"target"`
@@ -17,6 +38,7 @@ type Observation struct {
Error string `json:"error_message"` Error string `json:"error_message"`
Observer ObserverInfo `json:"observer"` Observer ObserverInfo `json:"observer"`
Version string `json:"version"` Version string `json:"version"`
Proof ProofMeta `json:"proof"`
} }
type ObserverInfo struct { type ObserverInfo struct {
@@ -27,6 +49,11 @@ type ObserverInfo struct {
ProbeVersion string `json:"probe_version"` ProbeVersion string `json:"probe_version"`
} }
type ProofMeta struct {
Hash string `json:"hash"`
Signature string `json:"signature"`
}
func BuildProof(result probe.PingResult, loc geo.GeoInfo) Observation { func BuildProof(result probe.PingResult, loc geo.GeoInfo) Observation {
return Observation{ return Observation{
Timestamp: result.Timestamp, Timestamp: result.Timestamp,
@@ -50,3 +77,25 @@ func SaveProof(obs Observation, filename string) {
file, _ := json.MarshalIndent(obs, "", " ") file, _ := json.MarshalIndent(obs, "", " ")
_ = os.WriteFile(filename, file, 0644) _ = os.WriteFile(filename, file, 0644)
} }
func SignProof(obs *Observation) error {
// Replace with your own private key (for demo only)
privKeyHex := "4f3edf983ac636a65a842ce7c78d9aa706d3b113bce03738e0f7b6267d5bdc25"
privKey, err := crypto.HexToECDSA(privKeyHex)
if err != nil {
return err
}
// Hash relevant fields
data := fmt.Sprintf("%s|%s|%s|%d|%d", obs.Timestamp, obs.Target, obs.Status, obs.HTTPStatus, obs.LatencyMs)
hash := sha256.Sum256([]byte(data))
obs.Proof.Hash = hex.EncodeToString(hash[:])
sigBytes, err := crypto.Sign(hash[:], privKey)
if err != nil {
return err
}
obs.Proof.Signature = hex.EncodeToString(sigBytes)
return nil
}
+60 -38
View File
@@ -1,48 +1,57 @@
# 🛰️ Obsero Probe # 🛰️ Obsero Probe (Full)
Lightweight monitoring agent for generating Proof-of-Observability JSON files. Obsero Probe is a lightweight Go-based agent that generates cryptographically signed uptime proofs and can optionally upload them to IPFS.
This probe performs HTTP health checks, automatically geolocates itself, and exports signed observation files compliant with the Obsero specification. ---
## 🚀 Features
- HTTP ping with latency measurement
- Automatic geolocation of probe (city, region, country)
- SHA256 hashing of observation data
- EVM-compatible signature using Ethereum private key
- IPFS upload support (`--ipfs`)
- CLI support for target, output, and IPFS toggle
- Cross-platform Makefile for easy builds
--- ---
## ⚙️ Requirements ## ⚙️ Requirements
- Go 1.21+ - Go 1.21+
- Internet access (for geo lookup and ping) - Local IPFS node (optional, for `--ipfs`)
- Ethereum private key (test key included by default)
--- ---
## 🚀 Quick Start ## 📦 Quick Start
### 1. Clone & Enter ### 1. Install dependencies
```bash ```bash
cd probe cd probe
```
### 2. Install dependencies
```bash
go mod tidy go mod tidy
``` ```
### 3. Run the probe ### 2. Run a probe
```bash ```bash
go run ./cmd/obsero-probe go run ./cmd/obsero-probe --target https://example.com --output proof_http_signed.json --ipfs
``` ```
This will:
- Ping `https://example.com`
- Auto-detect country, city and region
- Output a file named `proof_http_result.json`
--- ---
## 📄 Output Format ## 🛠️ CLI Options
The output file is a valid Obsero proof: | Flag | Description |
|------------|------------------------------------|
| `--target` | URL to ping |
| `--output` | Output file name |
| `--ipfs` | Upload the proof to IPFS |
---
## 📄 Proof Format (simplified)
```json ```json
{ {
@@ -59,34 +68,47 @@ The output file is a valid Obsero proof:
"city": "Paris", "city": "Paris",
"probe_version": "0.1" "probe_version": "0.1"
}, },
"version": "0.1" "version": "0.1",
"proof": {
"hash": "ab13...cdef",
"signature": "0x..."
}
} }
``` ```
--- ---
## 📦 Next steps ## 📁 Project Structure
- Add CLI support (`--target`, `--output`)
- Add cryptographic signature of the proof
- Upload to IPFS
- Submit hash + CID on Base chain
---
## 📁 Structure
``` ```
probe/ probe/
├── cmd/ ├── cmd/
│ └── obsero-probe/ │ └── obsero-probe/main.go # CLI entrypoint
│ └── main.go # CLI entrypoint
├── pkg/ ├── pkg/
│ ├── geo/ # IP geolocation │ ├── geo/geo.go # Geolocation
│ ├── probe/ # HTTP ping logic │ ├── probe/ping.go # HTTP ping
│ └── proof/ # Proof struct + output │ └── proof/format.go # Build, sign and upload proof
├── go.mod ├── Makefile # Multi-platform build support
├── go.sum ├── go.mod / go.sum
```
---
## 🧱 Next Steps
- ✅ JSON signed and stored locally
- ✅ Upload to IPFS (`--ipfs`)
- 🔗 Submit `submitProof(hash, cid, timestamp)` to a smart contract on Base chain (coming soon)
---
## 🛠️ Makefile Usage
```bash
make build # Build for local platform
make build-linux # Build for Linux amd64
make build-mac # Build for macOS
make build-arm # Build for ARM64 (Raspberry Pi, etc.)
``` ```
--- ---