mirror of
https://github.com/KusakabeShi/EtherGuard-VPN.git
synced 2024-12-25 15:28:48 +01:00
fastgen static config, update readme
This commit is contained in:
parent
d555963227
commit
17fe0cdae3
@ -82,8 +82,6 @@ VPN起來以後,自己手動加ip也行
|
||||
$ ./etherguard-go -mode gencfg -cfgmode super -config example_config/super_mode/gensuper.yaml
|
||||
```
|
||||
|
||||
|
||||
|
||||
把一個super,2個edge分別搬去三台機器
|
||||
或是2台機器,super和edge可以是同一台
|
||||
|
||||
|
@ -154,7 +154,7 @@ type Peer struct {
|
||||
|
||||
LastPacketReceivedAdd1Sec atomic.Value // *time.Time
|
||||
|
||||
SingleWayLatency float64
|
||||
SingleWayLatency atomic.Value
|
||||
stopping sync.WaitGroup // routines pending stop
|
||||
|
||||
ID mtypes.Vertex
|
||||
@ -245,7 +245,7 @@ func (device *Device) NewPeer(pk NoisePublicKey, id mtypes.Vertex, isSuper bool,
|
||||
peer.cookieGenerator.Init(pk)
|
||||
peer.device = device
|
||||
peer.endpoint_trylist = NewEndpoint_trylist(peer, mtypes.S2TD(device.EdgeConfig.DynamicRoute.PeerAliveTimeout))
|
||||
peer.SingleWayLatency = mtypes.Infinity
|
||||
peer.SingleWayLatency.Store(mtypes.Infinity)
|
||||
peer.queue.outbound = newAutodrainingOutboundQueue(device)
|
||||
peer.queue.inbound = newAutodrainingInboundQueue(device)
|
||||
peer.queue.staged = make(chan *QueueOutboundElement, QueueStagedSize)
|
||||
|
@ -470,39 +470,76 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||
packet_type = elem.Type
|
||||
|
||||
if device.IsSuperNode {
|
||||
switch dst_nodeID {
|
||||
case mtypes.NodeID_AllPeer:
|
||||
if packet_type.IsControl_Edge2Super() {
|
||||
should_process = true
|
||||
} else {
|
||||
device.log.Errorf("received unsupported packet_type %v from %v %v", packet_type, src_nodeID, peer.endpoint.DstToString())
|
||||
goto skip
|
||||
}
|
||||
switch dst_nodeID {
|
||||
case mtypes.NodeID_SuperNode:
|
||||
should_process = true
|
||||
default:
|
||||
device.log.Errorf("Invalid dst_nodeID received. Check your code for bug")
|
||||
device.log.Errorf("received invalid dst_nodeID %v from %v %v", dst_nodeID, src_nodeID, peer.endpoint.DstToString())
|
||||
goto skip
|
||||
}
|
||||
} else {
|
||||
// Set should_receive and should_process
|
||||
if packet_type.IsNormal() {
|
||||
switch dst_nodeID {
|
||||
case mtypes.NodeID_Boardcast:
|
||||
case device.ID:
|
||||
should_receive = true
|
||||
should_transfer = true
|
||||
case mtypes.NodeID_SuperNode:
|
||||
case mtypes.NodeID_Broadcast:
|
||||
should_receive = true
|
||||
case mtypes.NodeID_AllPeer:
|
||||
should_receive = true
|
||||
}
|
||||
}
|
||||
if packet_type.IsControl_Edge2Edge() {
|
||||
switch dst_nodeID {
|
||||
case device.ID:
|
||||
should_process = true
|
||||
case mtypes.NodeID_Broadcast:
|
||||
should_process = true
|
||||
case mtypes.NodeID_AllPeer:
|
||||
packet := elem.packet[path.EgHeaderLen:] //true packet
|
||||
if device.CheckNoDup(packet) {
|
||||
should_process = true
|
||||
}
|
||||
}
|
||||
if packet_type.IsControl_Super2Edge() {
|
||||
if peer.ID == mtypes.NodeID_SuperNode {
|
||||
switch dst_nodeID {
|
||||
case device.ID:
|
||||
should_process = true
|
||||
case mtypes.NodeID_SuperNode:
|
||||
should_process = true
|
||||
}
|
||||
|
||||
} else {
|
||||
device.log.Errorf("received ServerUpdate packet from non supernode %v %v", src_nodeID, peer.endpoint.DstToString())
|
||||
goto skip
|
||||
}
|
||||
}
|
||||
|
||||
// Set should_transfer
|
||||
switch dst_nodeID {
|
||||
case mtypes.NodeID_Broadcast:
|
||||
should_transfer = true
|
||||
case mtypes.NodeID_AllPeer:
|
||||
packet := elem.packet[path.EgHeaderLen:] //packet body
|
||||
if device.CheckNoDup(packet) {
|
||||
should_transfer = true
|
||||
} else {
|
||||
should_process = false
|
||||
should_transfer = false
|
||||
if device.LogLevel.LogTransit {
|
||||
fmt.Printf("Transit: Duplicate packet received from %d through %d , src_nodeID = %d . Dropeed.\n", peer.ID, device.ID, src_nodeID)
|
||||
fmt.Printf("Transit: Duplicate packet received from %d through %d , src_nodeID = %d . Dropped.\n", peer.ID, device.ID, src_nodeID)
|
||||
}
|
||||
goto skip
|
||||
}
|
||||
case device.ID:
|
||||
if packet_type == path.NormalPacket {
|
||||
should_receive = true
|
||||
} else {
|
||||
should_process = true
|
||||
}
|
||||
should_transfer = false
|
||||
case mtypes.NodeID_SuperNode:
|
||||
should_transfer = false
|
||||
case mtypes.NodeID_Invalid:
|
||||
should_transfer = false
|
||||
default:
|
||||
if device.graph.Next(device.ID, dst_nodeID) != mtypes.NodeID_Invalid {
|
||||
should_transfer = true
|
||||
@ -517,7 +554,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||
device.log.Verbosef("TTL is 0 %v", dst_nodeID)
|
||||
} else {
|
||||
EgHeader.SetTTL(l2ttl - 1)
|
||||
if dst_nodeID == mtypes.NodeID_Boardcast { //Regular transfer algorithm
|
||||
if dst_nodeID == mtypes.NodeID_Broadcast { //Regular transfer algorithm
|
||||
device.TransitBoardcastPacket(src_nodeID, peer.ID, elem.Type, elem.packet, MessageTransportOffsetContent)
|
||||
} else if dst_nodeID == mtypes.NodeID_AllPeer { // Control Message will try send to every know node regardless the connectivity
|
||||
skip_list := make(map[mtypes.Vertex]bool)
|
||||
@ -534,7 +571,7 @@ func (peer *Peer) RoutineSequentialReceiver() {
|
||||
if device.LogLevel.LogTransit {
|
||||
fmt.Printf("Transit: Transfer packet from %d through %d to %d\n", peer.ID, device.ID, peer_out.ID)
|
||||
}
|
||||
device.SendPacket(peer_out, elem.Type, elem.packet, MessageTransportOffsetContent)
|
||||
go device.SendPacket(peer_out, elem.Type, elem.packet, MessageTransportOffsetContent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -309,17 +309,20 @@ func (device *Device) server_process_Pong(peer *Peer, content mtypes.PongMsg) er
|
||||
|
||||
func (device *Device) process_ping(peer *Peer, content mtypes.PingMsg) error {
|
||||
Timediff := device.graph.GetCurrentTime().Sub(content.Time).Seconds()
|
||||
peer.SingleWayLatency = Timediff
|
||||
NewTimediff := peer.SingleWayLatency.Load().(float64)
|
||||
DR := NewTimediff * device.EdgeConfig.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance
|
||||
NewTimediff = NewTimediff*DR + Timediff*(1-DR)
|
||||
peer.SingleWayLatency.Store(NewTimediff)
|
||||
|
||||
PongMSG := mtypes.PongMsg{
|
||||
Src_nodeID: content.Src_nodeID,
|
||||
Dst_nodeID: device.ID,
|
||||
Timediff: Timediff,
|
||||
Timediff: NewTimediff,
|
||||
TimeToAlive: device.EdgeConfig.DynamicRoute.PeerAliveTimeout,
|
||||
AdditionalCost: device.EdgeConfig.DynamicRoute.AdditionalCost,
|
||||
}
|
||||
if device.EdgeConfig.DynamicRoute.P2P.UseP2P && time.Now().After(device.graph.NhTableExpire) {
|
||||
device.graph.UpdateLatency(content.Src_nodeID, device.ID, PongMSG.Timediff, device.EdgeConfig.DynamicRoute.PeerAliveTimeout, device.EdgeConfig.DynamicRoute.AdditionalCost, true, false)
|
||||
device.graph.UpdateLatencyMulti([]mtypes.PongMsg{PongMSG}, true, false)
|
||||
}
|
||||
body, err := mtypes.GetByte(&PongMSG)
|
||||
if err != nil {
|
||||
@ -887,7 +890,7 @@ func (device *Device) RoutinePostPeerInfo(startchan <-chan struct{}) {
|
||||
RequestID: 0,
|
||||
Src_nodeID: device.ID,
|
||||
Dst_nodeID: id,
|
||||
Timediff: peer.SingleWayLatency,
|
||||
Timediff: peer.SingleWayLatency.Load().(float64),
|
||||
TimeToAlive: time.Since(*peer.LastPacketReceivedAdd1Sec.Load().(*time.Time)).Seconds() + device.EdgeConfig.DynamicRoute.PeerAliveTimeout,
|
||||
}
|
||||
pongs = append(pongs, pong)
|
||||
@ -989,7 +992,7 @@ func (device *Device) RoutineSpreadAllMyNeighbor() {
|
||||
timeout := mtypes.S2TD(device.EdgeConfig.DynamicRoute.P2P.SendPeerInterval)
|
||||
for {
|
||||
device.process_RequestPeerMsg(mtypes.QueryPeerMsg{
|
||||
Request_ID: uint32(mtypes.NodeID_Boardcast),
|
||||
Request_ID: uint32(mtypes.NodeID_Broadcast),
|
||||
})
|
||||
time.Sleep(timeout)
|
||||
}
|
||||
|
@ -256,9 +256,9 @@ func (device *Device) RoutineReadFromTUN() {
|
||||
dstMacAddr := tap.GetDstMacAddr(elem.packet[path.EgHeaderLen:])
|
||||
// lookup peer
|
||||
if tap.IsNotUnicast(dstMacAddr) {
|
||||
dst_nodeID = mtypes.NodeID_Boardcast
|
||||
dst_nodeID = mtypes.NodeID_Broadcast
|
||||
} else if val, ok := device.l2fib.Load(dstMacAddr); !ok { //Lookup failed
|
||||
dst_nodeID = mtypes.NodeID_Boardcast
|
||||
dst_nodeID = mtypes.NodeID_Broadcast
|
||||
} else {
|
||||
dst_nodeID = val.(*IdAndTime).ID
|
||||
}
|
||||
@ -275,7 +275,7 @@ func (device *Device) RoutineReadFromTUN() {
|
||||
continue
|
||||
}
|
||||
|
||||
if dst_nodeID != mtypes.NodeID_Boardcast {
|
||||
if dst_nodeID != mtypes.NodeID_Broadcast {
|
||||
var peer *Peer
|
||||
next_id := device.graph.Next(device.ID, dst_nodeID)
|
||||
if next_id != mtypes.NodeID_Invalid {
|
||||
|
@ -3,7 +3,7 @@ Interface:
|
||||
Name: tap1
|
||||
VPPIFaceID: 1
|
||||
VPPBridgeID: 4242
|
||||
MacAddrPrefix: 8E:AA:C8:4B
|
||||
MacAddrPrefix: DA:21:10:81
|
||||
IPv4CIDR: 192.168.76.0/24
|
||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||
IPv6LLPrefix: fe80::a3df:0/112
|
||||
@ -12,17 +12,17 @@ Interface:
|
||||
SendAddr: 127.0.0.1:5001
|
||||
L2HeaderMode: kbdbg
|
||||
NodeID: 1
|
||||
NodeName: Node1
|
||||
NodeName: EgNet1
|
||||
PostScript: ""
|
||||
DefaultTTL: 200
|
||||
L2FIBTimeout: 3600
|
||||
PrivKey: Fe9Q6K5L6xTVbx/zFc07tnQuo+pkeyrhfoTQ3BF5GRM=
|
||||
PrivKey: LFFQqPBQ84x2AQ9BCI+0wG8nr+Y6yXHqhXkMCb4HCmg=
|
||||
ListenPort: 3001
|
||||
LogLevel:
|
||||
LogLevel: error
|
||||
LogTransit: true
|
||||
LogControl: true
|
||||
LogNormal: true
|
||||
LogControl: true
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
DynamicRoute:
|
||||
@ -100,8 +100,8 @@ NextHopTable:
|
||||
ResetConnInterval: 86400
|
||||
Peers:
|
||||
- NodeID: 2
|
||||
PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
|
||||
PSKey: kWDwCaC11UvYjfiXBMwYpR6Pujo1vaVW8JTusp1Kkrw=
|
||||
PubKey: 0r2o9Hb36gYVgD3VSKCH18MVOZw0BvzcJ6TOTo6Cc1g=
|
||||
PSKey: lFq67qp9LXL3PtlEJ3SGg3c/6++Ljy2I8i/k0Xcibvk=
|
||||
EndPoint: 127.0.0.1:3002
|
||||
PersistentKeepalive: 30
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
||||
Name: tap1
|
||||
VPPIFaceID: 1
|
||||
VPPBridgeID: 4242
|
||||
MacAddrPrefix: 8E:AA:C8:4B
|
||||
MacAddrPrefix: DA:21:10:81
|
||||
IPv4CIDR: 192.168.76.0/24
|
||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||
IPv6LLPrefix: fe80::a3df:0/112
|
||||
@ -12,17 +12,17 @@ Interface:
|
||||
SendAddr: 127.0.0.1:5001
|
||||
L2HeaderMode: kbdbg
|
||||
NodeID: 2
|
||||
NodeName: Node2
|
||||
NodeName: EgNet2
|
||||
PostScript: ""
|
||||
DefaultTTL: 200
|
||||
L2FIBTimeout: 3600
|
||||
PrivKey: WaeR98bFhy0rxw7unsaTo7aR2RmySo9l185IZqPWl1c=
|
||||
PrivKey: M8SxYCTHCPES/yPqcKP4mr+AoMAx9sgUmk64FCJIv6k=
|
||||
ListenPort: 3002
|
||||
LogLevel:
|
||||
LogLevel: error
|
||||
LogTransit: true
|
||||
LogControl: true
|
||||
LogNormal: true
|
||||
LogControl: true
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
DynamicRoute:
|
||||
@ -100,20 +100,20 @@ NextHopTable:
|
||||
ResetConnInterval: 86400
|
||||
Peers:
|
||||
- NodeID: 1
|
||||
PubKey: iDhQA9pgL01Gb0MrPzbiV80P4Uv3+uY/s+wNTQye0Qo=
|
||||
PSKey: kWDwCaC11UvYjfiXBMwYpR6Pujo1vaVW8JTusp1Kkrw=
|
||||
PubKey: fnc7bfFTf7B23hwtARPpX14tCeZwNfDhGCJctBpMfA8=
|
||||
PSKey: lFq67qp9LXL3PtlEJ3SGg3c/6++Ljy2I8i/k0Xcibvk=
|
||||
EndPoint: 127.0.0.1:3001
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
||||
- NodeID: 3
|
||||
PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
|
||||
PSKey: f2/34zUTLx8RP9cYisESoQlxz55oGZlTemqxv25VVa8=
|
||||
PubKey: ymNpm430tiph3rMSVnQzDAxmK9+3jdcRFi6e96xmQUI=
|
||||
PSKey: Y86PZY1ldgoyzPJxEqei5Vg5zlzkJkoO77LJfxV8alE=
|
||||
EndPoint: 127.0.0.1:3003
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
||||
- NodeID: 4
|
||||
PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
|
||||
PSKey: zkG1ywPqS4MiGofuWmxHHBs8YBlnYd04B4T9IhkbXYM=
|
||||
PubKey: 9YSIkihv/+aeukOaWwsR9EKvO1DM9+5kN53a/osTpmA=
|
||||
PSKey: QHyrrls0KT2dvBKtoWkZvq5NQ+Xyjm0YgbMUzCCRw34=
|
||||
EndPoint: 127.0.0.1:3004
|
||||
PersistentKeepalive: 30
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
||||
Name: tap1
|
||||
VPPIFaceID: 1
|
||||
VPPBridgeID: 4242
|
||||
MacAddrPrefix: 8E:AA:C8:4B
|
||||
MacAddrPrefix: DA:21:10:81
|
||||
IPv4CIDR: 192.168.76.0/24
|
||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||
IPv6LLPrefix: fe80::a3df:0/112
|
||||
@ -12,17 +12,17 @@ Interface:
|
||||
SendAddr: 127.0.0.1:5001
|
||||
L2HeaderMode: kbdbg
|
||||
NodeID: 3
|
||||
NodeName: Node3
|
||||
NodeName: EgNet3
|
||||
PostScript: ""
|
||||
DefaultTTL: 200
|
||||
L2FIBTimeout: 3600
|
||||
PrivKey: vNUFWbZXySk2dTl5R9UEG73p+4IQmywvC1uQStf0vao=
|
||||
PrivKey: cTO/GUSYHoj5mKczCyQu/ckPiDMEygkUbXcY3RafGEE=
|
||||
ListenPort: 3003
|
||||
LogLevel:
|
||||
LogLevel: error
|
||||
LogTransit: true
|
||||
LogControl: true
|
||||
LogNormal: true
|
||||
LogControl: true
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
DynamicRoute:
|
||||
@ -99,21 +99,21 @@ NextHopTable:
|
||||
5: 4
|
||||
ResetConnInterval: 86400
|
||||
Peers:
|
||||
- NodeID: 5
|
||||
PubKey: AarP7cL6TVmFyHRZLXuxFGr5uQghsp57ydsJdj+lGzs=
|
||||
PSKey: +TU8Zi8dr/UBqNyW/MYMgJiqkLnRbHW4ExQYQ2eNEag=
|
||||
EndPoint: 127.0.0.1:3005
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
||||
- NodeID: 2
|
||||
PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
|
||||
PSKey: f2/34zUTLx8RP9cYisESoQlxz55oGZlTemqxv25VVa8=
|
||||
PubKey: 0r2o9Hb36gYVgD3VSKCH18MVOZw0BvzcJ6TOTo6Cc1g=
|
||||
PSKey: Y86PZY1ldgoyzPJxEqei5Vg5zlzkJkoO77LJfxV8alE=
|
||||
EndPoint: 127.0.0.1:3002
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
||||
- NodeID: 4
|
||||
PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
|
||||
PSKey: 8HN+PBGDKmBFCDlWIyNUFFYS4X6ONGXI32AIKXSnUqU=
|
||||
PubKey: 9YSIkihv/+aeukOaWwsR9EKvO1DM9+5kN53a/osTpmA=
|
||||
PSKey: SQyLomXDeknBIFezUKardOviAmNS+YZ1XTvZtYVlOtE=
|
||||
EndPoint: 127.0.0.1:3004
|
||||
PersistentKeepalive: 30
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
||||
- NodeID: 5
|
||||
PubKey: x66hOjYXoZjL1FI3OVtf/CWittsnvmezKV6sW0v5FXQ=
|
||||
PSKey: ChWBQurfGNZE5xIlhi9EUvZrQPBvkFsfrPaD6tyqSYg=
|
||||
EndPoint: 127.0.0.1:3005
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
||||
Name: tap1
|
||||
VPPIFaceID: 1
|
||||
VPPBridgeID: 4242
|
||||
MacAddrPrefix: 8E:AA:C8:4B
|
||||
MacAddrPrefix: DA:21:10:81
|
||||
IPv4CIDR: 192.168.76.0/24
|
||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||
IPv6LLPrefix: fe80::a3df:0/112
|
||||
@ -12,17 +12,17 @@ Interface:
|
||||
SendAddr: 127.0.0.1:5001
|
||||
L2HeaderMode: kbdbg
|
||||
NodeID: 4
|
||||
NodeName: Node4
|
||||
NodeName: EgNet4
|
||||
PostScript: ""
|
||||
DefaultTTL: 200
|
||||
L2FIBTimeout: 3600
|
||||
PrivKey: sn0BUwyNxfmgePYi6O6a8pFDKiLaCz6jk3ws+covRTA=
|
||||
PrivKey: ai9XXdezwamYHf7EvzmLGlMp7mUg+hZwoqLefzwHWVM=
|
||||
ListenPort: 3004
|
||||
LogLevel:
|
||||
LogLevel: error
|
||||
LogTransit: true
|
||||
LogControl: true
|
||||
LogNormal: true
|
||||
LogControl: true
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
DynamicRoute:
|
||||
@ -100,20 +100,20 @@ NextHopTable:
|
||||
ResetConnInterval: 86400
|
||||
Peers:
|
||||
- NodeID: 2
|
||||
PubKey: MC8dHNj8u/RrK9iL6ln+AaGZWkMrDl+8aUoyxbsBZC4=
|
||||
PSKey: zkG1ywPqS4MiGofuWmxHHBs8YBlnYd04B4T9IhkbXYM=
|
||||
PubKey: 0r2o9Hb36gYVgD3VSKCH18MVOZw0BvzcJ6TOTo6Cc1g=
|
||||
PSKey: QHyrrls0KT2dvBKtoWkZvq5NQ+Xyjm0YgbMUzCCRw34=
|
||||
EndPoint: 127.0.0.1:3002
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
||||
- NodeID: 3
|
||||
PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
|
||||
PSKey: 8HN+PBGDKmBFCDlWIyNUFFYS4X6ONGXI32AIKXSnUqU=
|
||||
PubKey: ymNpm430tiph3rMSVnQzDAxmK9+3jdcRFi6e96xmQUI=
|
||||
PSKey: SQyLomXDeknBIFezUKardOviAmNS+YZ1XTvZtYVlOtE=
|
||||
EndPoint: 127.0.0.1:3003
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
||||
- NodeID: 6
|
||||
PubKey: GH6ra6xhDezskkJrr/DXPi93vtmhi96DFBJ3s8U20EA=
|
||||
PSKey: f50pI53AQ6RoTGEnTSjl5YJhuMS/xiJjwtPuiP0xMUM=
|
||||
PubKey: f6kHXq3qPLocdM0CZEkoumOHevrabzqOBFG5vg9cjDc=
|
||||
PSKey: crsb9pbTY/Bei7TugjPNtg4dVKVzjwC/A6AjlSVoqbQ=
|
||||
EndPoint: 127.0.0.1:3006
|
||||
PersistentKeepalive: 30
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
||||
Name: tap1
|
||||
VPPIFaceID: 1
|
||||
VPPBridgeID: 4242
|
||||
MacAddrPrefix: 8E:AA:C8:4B
|
||||
MacAddrPrefix: DA:21:10:81
|
||||
IPv4CIDR: 192.168.76.0/24
|
||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||
IPv6LLPrefix: fe80::a3df:0/112
|
||||
@ -12,17 +12,17 @@ Interface:
|
||||
SendAddr: 127.0.0.1:5001
|
||||
L2HeaderMode: kbdbg
|
||||
NodeID: 5
|
||||
NodeName: Node5
|
||||
NodeName: EgNet5
|
||||
PostScript: ""
|
||||
DefaultTTL: 200
|
||||
L2FIBTimeout: 3600
|
||||
PrivKey: Blk9f1+NiC2fVCZpUBG34G9hrcLThemk/1Zd/dET6AA=
|
||||
PrivKey: hBNK6Wu/Cl2MOXVA/F8yZsqIQ5eeIYCKPJeLu7i/190=
|
||||
ListenPort: 3005
|
||||
LogLevel:
|
||||
LogLevel: error
|
||||
LogTransit: true
|
||||
LogControl: true
|
||||
LogNormal: true
|
||||
LogControl: true
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
DynamicRoute:
|
||||
@ -100,8 +100,8 @@ NextHopTable:
|
||||
ResetConnInterval: 86400
|
||||
Peers:
|
||||
- NodeID: 3
|
||||
PubKey: 1vg9bSyqjDL8oUdqpKXn/RR96cjTHPCBga0vaw86WzU=
|
||||
PSKey: +TU8Zi8dr/UBqNyW/MYMgJiqkLnRbHW4ExQYQ2eNEag=
|
||||
PubKey: ymNpm430tiph3rMSVnQzDAxmK9+3jdcRFi6e96xmQUI=
|
||||
PSKey: ChWBQurfGNZE5xIlhi9EUvZrQPBvkFsfrPaD6tyqSYg=
|
||||
EndPoint: 127.0.0.1:3003
|
||||
PersistentKeepalive: 30
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
@ -3,7 +3,7 @@ Interface:
|
||||
Name: tap1
|
||||
VPPIFaceID: 1
|
||||
VPPBridgeID: 4242
|
||||
MacAddrPrefix: 8E:AA:C8:4B
|
||||
MacAddrPrefix: DA:21:10:81
|
||||
IPv4CIDR: 192.168.76.0/24
|
||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||
IPv6LLPrefix: fe80::a3df:0/112
|
||||
@ -12,17 +12,17 @@ Interface:
|
||||
SendAddr: 127.0.0.1:5001
|
||||
L2HeaderMode: kbdbg
|
||||
NodeID: 6
|
||||
NodeName: Node6
|
||||
NodeName: EgNet6
|
||||
PostScript: ""
|
||||
DefaultTTL: 200
|
||||
L2FIBTimeout: 3600
|
||||
PrivKey: h03OJ1d8cVGF8TemiWWTla7RCIMtInhUnjs2CBb8AT8=
|
||||
PrivKey: ao6wfUYOG3FBYYPlb+VtXk2ZiK6j/6ac75Y9VuKd2Vs=
|
||||
ListenPort: 3006
|
||||
LogLevel:
|
||||
LogLevel: error
|
||||
LogTransit: true
|
||||
LogControl: true
|
||||
LogNormal: true
|
||||
LogControl: true
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
DynamicRoute:
|
||||
@ -100,8 +100,8 @@ NextHopTable:
|
||||
ResetConnInterval: 86400
|
||||
Peers:
|
||||
- NodeID: 4
|
||||
PubKey: WkBYMUcQwWwUlDYh7uLu4YefiH1yXb3Tkf3wGEtE6HY=
|
||||
PSKey: f50pI53AQ6RoTGEnTSjl5YJhuMS/xiJjwtPuiP0xMUM=
|
||||
PubKey: 9YSIkihv/+aeukOaWwsR9EKvO1DM9+5kN53a/osTpmA=
|
||||
PSKey: crsb9pbTY/Bei7TugjPNtg4dVKVzjwC/A6AjlSVoqbQ=
|
||||
EndPoint: 127.0.0.1:3004
|
||||
PersistentKeepalive: 30
|
||||
PersistentKeepalive: 0
|
||||
Static: true
|
@ -1,84 +1,105 @@
|
||||
# Etherguard
|
||||
[English](README.md)
|
||||
|
||||
Static Mode的[範例配置檔](./)的說明文件
|
||||
[English](README.md) | [中文](#)
|
||||
|
||||
## Static Mode
|
||||
|
||||
沒有自動選路,沒有握手伺服器
|
||||
類似原本的wireguard,一切都要提前配置好
|
||||
設定檔裡面的`NextHopTable`部分,只有此模式會生效
|
||||
|
||||
十分類似原本的wireguard,一切都要提前配置好
|
||||
|
||||
但是除了peer以外,還要額外配置轉發表,所有人共用一份轉發表
|
||||
|
||||
設定檔裡面的`nexthoptable`部分,只有此模式會生效
|
||||
|
||||
這個模式下,不存在任何的Control Message,斷線偵測甚麼的也不會有
|
||||
這個模式下,不存在任何的Control Message,斷線偵測什麼的也不會有
|
||||
請務必保持提前定義好的拓樸。不然如果存在中轉,中轉節點斷了,部分連線就會中斷
|
||||
|
||||
## Quick Start
|
||||
首先,按照需求修改`genstatic.yaml`
|
||||
|
||||
```yaml
|
||||
Config output dir: /tmp/eg_gen_static # 設定檔輸出位置
|
||||
ConfigTemplate for edge node: "" # 設定檔Template
|
||||
Network name: "EgNet"
|
||||
Edge Node:
|
||||
MacAddress prefix: "" # 留空隨機產生
|
||||
IPv4 range: 192.168.76.0/24 # 順帶一提,IP的部分可以直接省略沒關係
|
||||
IPv6 range: fd95:71cb:a3df:e586::/64 # 這個欄位唯一的目的只是在啟動以後,調用ip命令,幫tap接口加個ip
|
||||
IPv6 LL range: fe80::a3df:0/112 # 和VPN本身運作完全無關
|
||||
Edge Nodes: # 所有的節點相關設定
|
||||
1:
|
||||
Endpoint(optional): 127.0.0.1:3001
|
||||
2:
|
||||
Endpoint(optional): 127.0.0.1:3002
|
||||
3:
|
||||
Endpoint(optional): 127.0.0.1:3003
|
||||
4:
|
||||
Endpoint(optional): 127.0.0.1:3004
|
||||
5:
|
||||
Endpoint(optional): 127.0.0.1:3005
|
||||
6:
|
||||
Endpoint(optional): 127.0.0.1:3006
|
||||
Distance matrix for all nodes: |- # 左邊是起點,上面是終點,Inf代表此二節點不相連 ,數值代表相連。數值大小代表通過成本(通常是延遲)
|
||||
X 1 2 3 4 5 6
|
||||
1 0 1.0 Inf Inf Inf Inf
|
||||
2 1.0 0 1.0 1.0 Inf Inf
|
||||
3 Inf 1.0 0 1 1.0 Inf
|
||||
4 Inf 1.0 1.0 0 Inf 1.0
|
||||
5 Inf Inf 1.0 Inf 1.0 Inf
|
||||
6 Inf Inf Inf 1.0 Inf 1.0
|
||||
```
|
||||
接著執行這個,就會生成所需設定檔了。
|
||||
```
|
||||
./etherguard-go -mode gencfg -cfgmode static -config example_config/static_mode/genstatic.yaml
|
||||
```
|
||||
|
||||
把這些設定檔不捨去對應節點,然後再執行
|
||||
```
|
||||
./etherguard-go -config [設定檔位置] -mode edge
|
||||
```
|
||||
就可以了
|
||||
|
||||
確認運作以後,可以關閉不必要的log增加性能
|
||||
|
||||
## Documentation
|
||||
|
||||
Static Mode的說明文件
|
||||
|
||||
這份[範例配置檔](./)的網路拓樸如圖所示
|
||||
|
||||
!["Topology"](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/static_mode/Example_static.png)
|
||||
|
||||
發出封包時,會設定起始ID=自己的Node ID,終點ID則是看Dst Mac Address。
|
||||
如果Dst MacAddr是廣播地址,或是不在自己的對應表裡面,就會設定終點=Boardcast
|
||||
如果Dst MacAddr是廣播地址,或是不在自己的對應表裡面,就會設定終點=Broadcast
|
||||
|
||||
收到封包的時候,如果`dst==自己ID`,就會收下,不轉給任何人。
|
||||
同時還會看它的 Src Mac Address 和 Src NodeID ,並加入對應表
|
||||
這樣下次傳給他就可以直接傳給目標,而不用廣播給全節點了
|
||||
|
||||
所以設定檔中的轉發表如下表。格式是yaml的巢狀dictionary
|
||||
轉發/發送封包時,直接查詢 `NhTable[起點][終點]=下一跳`
|
||||
轉發/發送封包時,直接查詢`NhTable`
|
||||
就知道下面一個封包要轉給誰了
|
||||
|
||||
NextHopTable 是長這樣的資料結構,`NhTable[起點][終點]=下一跳`
|
||||
|
||||
```yaml
|
||||
nexthoptable:
|
||||
NextHopTable:
|
||||
1:
|
||||
2: 2
|
||||
3: 2
|
||||
4: 2
|
||||
5: 2
|
||||
6: 2
|
||||
2:
|
||||
1: 1
|
||||
3: 3
|
||||
4: 4
|
||||
5: 3
|
||||
6: 4
|
||||
|
||||
3:
|
||||
1: 2
|
||||
2: 2
|
||||
4: 4
|
||||
5: 5
|
||||
6: 4
|
||||
4:
|
||||
1: 2
|
||||
2: 2
|
||||
3: 3
|
||||
5: 3
|
||||
6: 6
|
||||
5:
|
||||
1: 3
|
||||
2: 3
|
||||
3: 3
|
||||
4: 3
|
||||
6: 3
|
||||
6:
|
||||
1: 4
|
||||
2: 4
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
```
|
||||
|
||||
### Boardcast
|
||||
比較特別的是`終點ID=Boardcast`的情況。
|
||||
### Broadcast
|
||||
比較特別的是`終點ID=Broadcast`的情況。
|
||||
|
||||
假設今天的狀況:我是4號,我收到`起點ID = 1,終點ID=boardcast`的封包
|
||||
假設今天的狀況:我是4號,我收到`起點ID = 1,終點ID=Broadcast`的封包
|
||||
我應該只轉給6號就好,而不會轉給3號。
|
||||
因為3號會收到來自2號的封包,自己就不用重複遞送了
|
||||
|
||||
因此我有設計,如果`終點ID = Boardcast`,就會檢查Src到自己的所有鄰居,會不會經過自己
|
||||
因此我有設計,如果`終點ID = Broadcast`,就會檢查Src到自己的所有鄰居,會不會經過自己
|
||||
**1 -> 6** 會經過自己: [1 2 4 6]
|
||||
**1 -> 3** 不會: [1 2 3]
|
||||
2號是封包來源跳過檢查
|
||||
@ -94,189 +115,97 @@ nexthoptable:
|
||||
|
||||
```
|
||||
X 1 2 3 4 5 6
|
||||
1 0 0.5 Inf Inf Inf Inf
|
||||
2 0.5 0 0.5 0.5 Inf Inf
|
||||
3 Inf 0.5 0 0.5 0.5 Inf
|
||||
4 Inf 0.5 0.5 0 Inf 0.5
|
||||
5 Inf Inf 0.5 Inf 0 Inf
|
||||
6 Inf Inf Inf 0.5 Inf 0
|
||||
1 0 1.0 Inf Inf Inf Inf
|
||||
2 1.0 0 1.0 1.0 Inf Inf
|
||||
3 Inf 1.0 0 1 1.0 Inf
|
||||
4 Inf 1.0 1.0 0 Inf 1.0
|
||||
5 Inf Inf 1.0 Inf 1.0 Inf
|
||||
6 Inf Inf Inf 1.0 Inf 1.0
|
||||
```
|
||||
|
||||
之後用這個指令就能輸出用Floyd Warshall算好的轉發表了,填入設定檔即可
|
||||
```
|
||||
./etherguard-go -config example_config/static_mode/path.txt -mode slove
|
||||
|
||||
NextHopTable:
|
||||
1:
|
||||
2: 2
|
||||
3: 2
|
||||
4: 2
|
||||
5: 2
|
||||
6: 2
|
||||
2:
|
||||
1: 1
|
||||
3: 3
|
||||
4: 4
|
||||
5: 3
|
||||
6: 4
|
||||
3:
|
||||
1: 2
|
||||
2: 2
|
||||
4: 4
|
||||
5: 5
|
||||
6: 4
|
||||
4:
|
||||
1: 2
|
||||
2: 2
|
||||
3: 3
|
||||
5: 3
|
||||
6: 6
|
||||
5:
|
||||
1: 3
|
||||
2: 3
|
||||
3: 3
|
||||
4: 3
|
||||
6: 3
|
||||
6:
|
||||
1: 4
|
||||
2: 4
|
||||
3: 4
|
||||
4: 4
|
||||
5: 4
|
||||
```
|
||||
### EdgeNode Config Parameter
|
||||
|
||||
程式還會額外輸出一些資訊,像是路徑表。
|
||||
會標示所有的起點終點組合的封包路徑,還有行經距離
|
||||
```
|
||||
Human readable:
|
||||
src dist path
|
||||
1 -> 2 0.500000 [1 2]
|
||||
1 -> 3 1.000000 [1 2 3]
|
||||
1 -> 4 1.000000 [1 2 4]
|
||||
1 -> 5 1.500000 [1 2 3 5]
|
||||
1 -> 6 1.500000 [1 2 4 6]
|
||||
2 -> 1 0.500000 [2 1]
|
||||
2 -> 3 0.500000 [2 3]
|
||||
2 -> 4 0.500000 [2 4]
|
||||
2 -> 5 1.000000 [2 3 5]
|
||||
2 -> 6 1.000000 [2 4 6]
|
||||
3 -> 1 1.000000 [3 2 1]
|
||||
3 -> 2 0.500000 [3 2]
|
||||
3 -> 4 0.500000 [3 4]
|
||||
3 -> 5 0.500000 [3 5]
|
||||
3 -> 6 1.000000 [3 4 6]
|
||||
4 -> 1 1.000000 [4 2 1]
|
||||
4 -> 2 0.500000 [4 2]
|
||||
4 -> 3 0.500000 [4 3]
|
||||
4 -> 5 1.000000 [4 3 5]
|
||||
4 -> 6 0.500000 [4 6]
|
||||
5 -> 1 1.500000 [5 3 2 1]
|
||||
5 -> 2 1.000000 [5 3 2]
|
||||
5 -> 3 0.500000 [5 3]
|
||||
5 -> 4 1.000000 [5 3 4]
|
||||
5 -> 6 1.500000 [5 3 4 6]
|
||||
6 -> 1 1.500000 [6 4 2 1]
|
||||
6 -> 2 1.000000 [6 4 2]
|
||||
6 -> 3 1.000000 [6 4 3]
|
||||
6 -> 4 0.500000 [6 4]
|
||||
6 -> 5 1.500000 [6 4 3 5]
|
||||
```
|
||||
Key | Description
|
||||
-------------- |:-----
|
||||
[Interface](#Interface)| 接口相關設定。VPN有兩端,一端是VPN網路,另一端則是本地接口
|
||||
NodeID | 節點ID。節點之間辨識身分用的,同一網路內節點ID不能重複
|
||||
NodeName | 節點名稱
|
||||
PostScript | 初始化完畢之後要跑的腳本
|
||||
DefaultTTL | TTL,etherguard層使用,和乙太層不共通
|
||||
L2FIBTimeout | MacAddr-> NodeID 查找表的 timeout(秒) ,類似ARP table
|
||||
PrivKey | 私鑰,和wireguard規格一樣
|
||||
ListenPort | 監聽的udp埠
|
||||
[LogLevel](#LogLevel)| 紀錄log
|
||||
[DynamicRoute](../super_mode/README_zh.md#DynamicRoute) | 動態路由相關設定,Static模式用不到
|
||||
NextHopTable | 轉發表, 下一跳 = `NhTable[起點][終點]`
|
||||
ResetConnInterval | 如果對方是動態ip就要用這個。每隔一段時間就會重置連線,重新解析域名
|
||||
[Peers](#Peers) | 鄰居節點,和wireguard相同
|
||||
|
||||
有些設定檔對應某些運作模式,這邊針對共同部分的設定做說明
|
||||
<a name="Interface"></a>Interface | Description
|
||||
---------------|:-----
|
||||
[IType](#IType)| 接口類型,意味著從VPN網路收到的封包要丟去哪邊
|
||||
Name | 裝置名稱
|
||||
VPPIFaceID | VPP 的 interface ID。同一個VPP runtime內不能重複
|
||||
VPPBridgeID | VPP 的網橋ID。不使用VPP網橋功能的話填0
|
||||
MacAddrPrefix | MAC地址前綴。真正的 MAC 地址=[前綴]:[NodeID]
|
||||
IPv4CIDR | 啟動以後,調用ip命令,幫tap接口加個ip。僅限tap有效
|
||||
IPv4CIDR | 啟動以後,調用ip命令,幫tap接口加個ip。僅限tap有效
|
||||
IPv6LLPrefix | 啟動以後,調用ip命令,幫tap接口加個ip。僅限tap有效
|
||||
MTU | 裝置MTU,僅限`tap` , `vpp` 模式有效
|
||||
RecvAddr | listen地址,收到的東西丟去 VPN 網路。僅限`*sock`生效
|
||||
SendAddr | 連線地址,VPN網路收到的東西丟去這個地址。僅限`*sock`生效
|
||||
[L2HeaderMode](#L2HeaderMode) | 僅限 `stdio` 生效。debug用途,有三種模式
|
||||
|
||||
### Edge config
|
||||
<a name="IType"></a>IType | Description
|
||||
-----------|:-----
|
||||
dummy | 收到的封包直接丟棄,但幫忙轉發。作為中繼節點,本身不加入網路使用
|
||||
stdio | 收到的封包丟stdout,stdin進來的資料丟入vpn網路,debug用途<br>需要參數: `MacAddrPrefix` && `L2HeaderMode`
|
||||
udpsock | 收到的封包丟去一個udp socket<br>需要參數: `RecvAddr` && `SendAddr`
|
||||
tcpsock | 收到的封包丟去一個tcp socket<br>需要參數: `RecvAddr` \|\| `SendAddr`
|
||||
unixsock | 收到的封包丟去一個unix socket(SOCK_STREAM 模式)<br>需要參數: `RecvAddr` \|\| `SendAddr`
|
||||
udpsock | 收到的封包丟去一個unix socket(SOCK_DGRAM 模式)<br>需要參數: `RecvAddr` \|\| `SendAddr`
|
||||
udpsock | 收到的封包丟去一個unix socket(SOCK_SEQPACKET 模式)<br>需要參數: `RecvAddr` \|\| `SendAddr`
|
||||
fd | 收到的封包丟去一個特定的file descriptor<br>需要參數: 無. 但是使用環境變數 `EG_FD_RX` && `EG_FD_TX` 來指定
|
||||
vpp | 使用libmemif使vpp加入VPN網路<br>需要參數: `Name` && `VPPIFaceID` && `VPPBridgeID` && `MacAddrPrefix` && `MTU`
|
||||
tap | Linux的tap設備。讓linux加入VPN網路<br>需要參數: `Name` && `MacAddrPrefix` && `MTU`<br>可選參數:`IPv4CIDR` , `IPv6CIDR` , `IPv6LLPrefix`
|
||||
|
||||
1. `interface`
|
||||
1. `itype`: 裝置類型,意味著從VPN網路收到的封包要丟去哪個硬體
|
||||
1. `dummy`: 收到的封包直接丟棄,也不發出任何封包。作為中繼節點使用
|
||||
2. `stdio`: 收到的封包丟stdout,stdin進來的資料丟入vpn網路
|
||||
需要參數: `macaddrprefix`,`l2headermode`
|
||||
3. `udpsock`: 把VPN網路收到的layer2封包讀寫去一個udp socket.
|
||||
Paramaters: `recvaddr`,`sendaddr`
|
||||
3. `tcpsock`: 把VPN網路收到的layer2封包讀寫去一個tcp socket.
|
||||
Paramaters: `recvaddr`,`sendaddr`
|
||||
3. `unixsock`: 把VPN網路收到的layer2封包讀寫去一個unix socket(SOCK_STREAM 模式).
|
||||
Paramaters: `recvaddr`,`sendaddr`
|
||||
3. `unixgramsock`: 把VPN網路收到的layer2封包讀寫去一個unix socket(SOCK_DGRAM 模式).
|
||||
Paramaters: `recvaddr`,`sendaddr`
|
||||
3. `unixpacketsock`: 把VPN網路收到的layer2封包讀寫去一個unix socket(SOCK_SEQPACKET 模式).
|
||||
Paramaters: `recvaddr`,`sendaddr`
|
||||
3. `fd`: 把VPN網路收到的layer2封包讀寫去一個特定的file descriptor.
|
||||
Paramaters: 無. 但是使用環境變數 `EG_FD_RX` 和 `EG_FD_TX` 來指定
|
||||
4. `vpp`: 使用libmemif使vpp加入VPN網路
|
||||
需要參數: `name`,`vppifaceid`,`vppbridgeid`,`macaddrprefix`,`mtu`
|
||||
5. `tap`: Linux的tap設備。讓linux加入VPN網路
|
||||
需要參數: `name`,`macaddrprefix`,`mtu`
|
||||
2. `name` : 裝置名稱
|
||||
3. `vppifaceid`: VPP 的 interface ID。一個VPP runtime內不能重複
|
||||
4. `vppbridgeid`: VPP 的網橋ID。不使用VPP網橋功能的話填0
|
||||
5. `macaddrprefix`: MAC地址前綴。真正的 MAC 地址=[前綴]:[NodeID]。
|
||||
如果這邊填了完整6格長度,就忽略`NodeID`
|
||||
6. `recvaddr`: 僅限`XXXsock`生效。listen地址,收到的東西丟去 VPN 網路
|
||||
7. `sendaddr`: 僅限`XXXsock`生效。連線地址,VPN網路收到的東西丟去這個地址
|
||||
8. `l2headermode`: 僅限 `stdio` 生效。debug用途,有三種模式:
|
||||
1. `nochg`: 從 VPN 網路收到什麼,就往tap裝置發送什麼。不對封包作任何更動
|
||||
2. `kbdbg`: 鍵盤bebug模式。搭配 `stdio` 模式,讓我 debug 用
|
||||
因為前 12 byte 會用來做選路判斷,但是只是要debug,構造完整的封包就不是很方便
|
||||
這個模式下,如果輸入b2content,就會幫你把b轉換成`FF:FF:FF:FF:FF:FF`, `2` 轉換成 `AA:BB:CC:DD:EE:02` 。封包內容變成 `b"0xffffffffffffaabbccddee02content"`。
|
||||
用鍵盤就能輕鬆產生L2 header,查看選路的行為
|
||||
3. `noL2`: 拔掉L2 Header的模式。
|
||||
但是本VPN會查詢L2用作選路,所以會變成一律廣播
|
||||
2. `nodeid`: 節點ID。節點之間辨識身分用的,同一網路內節點ID不能重複
|
||||
3. `postscript`: etherguard初始化完畢之後要跑的腳本.
|
||||
3. `nodename`: 節點名稱
|
||||
4. `defaultttl`: 預設ttl(etherguard層使用,和乙太層不共通)
|
||||
5. `l2fibtimeout`: MacAddr-> NodeID 查找表的 timeout(秒)
|
||||
5. `privkey`: 私鑰,和wireguard規格一樣
|
||||
5. `listenport`: 監聽的udp埠
|
||||
6. `loglevel`: 紀錄log
|
||||
1. `loglevel`: wireguard原本的log紀錄器的loglevel。
|
||||
有`debug`,`error`,`slient`三種程度
|
||||
2. `logtransit`: 轉送封包,也就是起點/終點都不是自己的封包的log
|
||||
3. `logcontrol`: Control Message的log
|
||||
4. `lognormal`: 收發普通封包,起點是自己or終點是自己的log
|
||||
5. `logntp`: NTP 同步時鐘相關的log
|
||||
7. `dynamicroute`: 動態路由相關的設定。時間類設定單位都是秒
|
||||
1. `sendpinginterval`: 發送Ping訊息的間隔
|
||||
2. `dupchecktimeout`: 重複封包檢查的timeout。完全相同的封包收第二次會被丟棄
|
||||
1. `peeralivetimeout`: 每次收到封包就重置,超過時間沒收到就標記該peer離線
|
||||
3. `conntimeout`: 檢查peer離線的間格,如果標記離線,就切換下一個endpoint(supernode可能傳了多個endpoint過來)
|
||||
4. `savenewpeers`: 是否把下載來的鄰居資訊存到本地設定檔裡面
|
||||
5. `supernode`: 參見[Super模式](example_config/super_mode/README_zh.md)
|
||||
6. `p2p` 參見 [P2P模式](example_config/p2p_mode/README_zh.md)
|
||||
7. `ntpconfig`: NTP 相關的設定
|
||||
1. `usentp`: 是否使用ntp同步時鐘
|
||||
2. `maxserveruse`: 一次對多連線幾個NTP伺服器
|
||||
第一次會全部連一遍測延遲,之後每次都取延遲前n低的來用
|
||||
3. `synctimeinterval`: 多久同步一次
|
||||
4. `ntptimeout`: 多久算是超時
|
||||
5. `servers`: NTP伺服器列表
|
||||
8. `nexthoptable`: 轉發表。只有Static模式會用到,參見 [Static模式](example_config/super_mode/README_zh.md)
|
||||
9. `resetconninterval`: 如果對方是動態ip就要用這個。每隔一段時間就會重新解析domain。
|
||||
10. `peers`: 和wireguard一樣的peer資訊
|
||||
1. `nodeid`: 對方的節點ID
|
||||
2. `pubkey`: 對方的公鑰
|
||||
3. `pskey`: 對方的預共享金鑰。但是目前沒用(因為不能設定自己的),之後會加
|
||||
4. `endpoint`: 對方的連線地址。如果roaming會覆寫設定檔
|
||||
5. `static`: 設定成true的話,每隔`resetconninterval`秒就會重新解析一次domain,與此同時也不會被roaming覆寫
|
||||
<a name="L2HeaderMode"></a>L2HeaderMode | Description
|
||||
---------------|:-----
|
||||
nochg | 收到的封包丟stdout,stdin進來的資料丟入vpn網路,不對封包作任何更動
|
||||
kbdbg | 前 12byte 會用來做選路判斷<br>但是stdio模式下,使用鍵盤輸入一個Ethernet frame不太方便<br>此模式讓我快速產生Ethernet frame,debug更方便<br>`b`轉換成`FF:FF:FF:FF:FF:FF`<br>`2`轉換成 `AA:BB:CC:DD:EE:02`<br>輸入`b2aaaaa`就會變成`b"0xffffffffffffaabbccddee02aaaaa"`
|
||||
noL2 | 讀取時拔掉L2 Header的模式<br>寫入時時一律使用廣播MacAddress
|
||||
|
||||
### Super config
|
||||
<a name="LogLevel"></a>LogLevel | Description
|
||||
------------|:-----
|
||||
LogLevel | wireguard原本的log紀錄器的loglevel<br>接受參數: `debug`,`error`,`slient`
|
||||
LogTransit | 轉送封包,也就是起點/終點都不是自己的封包的log
|
||||
LogNormal | 收發普通封包,起點是自己or終點是自己的log
|
||||
LogControl | Control Message的log
|
||||
LogInternal | 一些內部事件的log
|
||||
LogNTP | NTP 同步時鐘相關的log
|
||||
|
||||
參見 [example_config/super_mode/README_zh.md](example_config/super_mode/README_zh.md)
|
||||
|
||||
### Quick start
|
||||
<a name="Peers"></a>Peers | Description
|
||||
--------------------|:-----
|
||||
NodeID | 對方的節點ID
|
||||
PubKey | 對方的公鑰
|
||||
PSKey | 對方的預共享金鑰
|
||||
EndPoint | 對方的連線地址。如果漫遊,而且`Static=false`會覆寫設定檔
|
||||
PersistentKeepalive | wireguard的PersistentKeepalive參數
|
||||
Static | 關閉漫遊功能,每隔`ResetConnInterval`秒,重置回初始ip
|
||||
|
||||
#### Run example config
|
||||
|
||||
在**不同terminal**分別執行以下命令
|
||||
|
||||
```
|
||||
./etherguard-go -config example_config/super_mode/n1.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/n2.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/n3.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/n4.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/n5.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/n6.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/EgNet_edge1.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/EgNet_edge2.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/EgNet_edge3.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/EgNet_edge4.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/EgNet_edge5.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/EgNet_edge6.yaml -mode edge
|
||||
```
|
||||
|
||||
因為本範例配置是stdio的kbdbg模式,stdin會讀入VPN網路
|
||||
@ -284,12 +213,7 @@ src dist path
|
||||
```
|
||||
b1message
|
||||
```
|
||||
因為`l2headermode`是`kbdbg`,所以b1會被轉換成 12byte 的layer 2 header,b是廣播地址`FF:FF:FF:FF:FF:FF`,1是普通地址`AA:BB:CC:DD:EE:01`,message是後面的payload,然後再丟入VPN
|
||||
因為`L2HeaderMode`是`kbdbg`,所以b1會被轉換成 12byte 的layer 2 header,b是廣播地址`FF:FF:FF:FF:FF:FF`,1是普通地址`AA:BB:CC:DD:EE:01`,message是後面的payload,然後再丟入VPN
|
||||
此時應該要能夠在另一個視窗上看見字串b1message。前12byte被轉換回來了
|
||||
|
||||
#### Run your own etherguard
|
||||
|
||||
要正式使用,請將itype改成`tap`,並且修改各節點的公鑰私鑰和連線地址
|
||||
再關閉不必要的log增加性能,最後部屬到不同節點即可
|
||||
|
||||
## 下一篇: [Super Mode的運作](../super_mode/README_zh.md)
|
@ -1,6 +1,6 @@
|
||||
Config output dir: /tmp/eg_gen_static
|
||||
ConfigTemplate for edge node: "n1.yaml"
|
||||
Network name: "Node"
|
||||
ConfigTemplate for edge node: "" # "EgNet_edge1.yaml"
|
||||
Network name: "EgNet"
|
||||
Edge Node:
|
||||
MacAddress prefix: ""
|
||||
IPv4 range: 192.168.76.0/24
|
||||
@ -9,27 +9,21 @@ Edge Node:
|
||||
Edge Nodes:
|
||||
1:
|
||||
Endpoint(optional): 127.0.0.1:3001
|
||||
PersistentKeepalive: 30
|
||||
2:
|
||||
Endpoint(optional): 127.0.0.1:3002
|
||||
PersistentKeepalive: 30
|
||||
3:
|
||||
Endpoint(optional): 127.0.0.1:3003
|
||||
PersistentKeepalive: 30
|
||||
4:
|
||||
Endpoint(optional): 127.0.0.1:3004
|
||||
PersistentKeepalive: 30
|
||||
5:
|
||||
Endpoint(optional): 127.0.0.1:3005
|
||||
PersistentKeepalive: 30
|
||||
6:
|
||||
Endpoint(optional): 127.0.0.1:3006
|
||||
PersistentKeepalive: 30
|
||||
Distance matrix for all nodes: |-
|
||||
X 1 2 3 4 5 6
|
||||
1 0 1 Inf Inf Inf Inf
|
||||
2 1 0 1 1 Inf Inf
|
||||
3 Inf 1 0 1 1 Inf
|
||||
4 Inf 1 1 0 Inf 1
|
||||
5 Inf Inf 1 Inf 0 Inf
|
||||
6 Inf Inf Inf 1 Inf 0
|
||||
1 0 1.0 Inf Inf Inf Inf
|
||||
2 1.0 0 1.0 1.0 Inf Inf
|
||||
3 Inf 1.0 0 1 1.0 Inf
|
||||
4 Inf 1.0 1.0 0 Inf 1.0
|
||||
5 Inf Inf 1.0 Inf 1.0 Inf
|
||||
6 Inf Inf Inf 1.0 Inf 1.0
|
Binary file not shown.
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 43 KiB |
BIN
example_config/super_mode/EGS08.png
Normal file
BIN
example_config/super_mode/EGS08.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
@ -1,28 +1,28 @@
|
||||
Interface:
|
||||
IType: stdio
|
||||
Name: tap1
|
||||
Name: Node001
|
||||
VPPIFaceID: 1
|
||||
VPPBridgeID: 4242
|
||||
MacAddrPrefix: AA:BB:CC:DD
|
||||
IPv4CIDR: ""
|
||||
IPv6CIDR: ""
|
||||
IPv6LLPrefix: ""
|
||||
MacAddrPrefix: CE:51:BA:B4
|
||||
IPv4CIDR: 192.168.76.0/24
|
||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||
IPv6LLPrefix: fe80::a3df:0/112
|
||||
MTU: 1416
|
||||
RecvAddr: 127.0.0.1:4001
|
||||
SendAddr: 127.0.0.1:5001
|
||||
L2HeaderMode: kbdbg
|
||||
NodeID: 1
|
||||
NodeName: Node01
|
||||
NodeName: Node001
|
||||
PostScript: ""
|
||||
DefaultTTL: 200
|
||||
L2FIBTimeout: 3600
|
||||
PrivKey: 6GyDagZKhbm5WNqMiRHhkf43RlbMJ34IieTlIuvfJ1M=
|
||||
ListenPort: 0
|
||||
PrivKey: C0SXvffZh8nDqXYNzG4UqUJtSCiRMEj3ehX5o7QiJz0=
|
||||
ListenPort: 3001
|
||||
LogLevel:
|
||||
LogLevel: error
|
||||
LogTransit: true
|
||||
LogTransit: false
|
||||
LogControl: true
|
||||
LogNormal: true
|
||||
LogNormal: false
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
DynamicRoute:
|
||||
@ -35,12 +35,12 @@ DynamicRoute:
|
||||
SaveNewPeers: true
|
||||
SuperNode:
|
||||
UseSuperNode: true
|
||||
PSKey: iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=
|
||||
EndpointV4: 127.0.0.1:3000
|
||||
PubKeyV4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
EndpointV6: '[::1]:3000'
|
||||
PubKeyV6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
EndpointEdgeAPIUrl: http://127.0.0.1:3000/eg_api
|
||||
PSKey: j2f9Fhdhw2O2zLqUqfL5nTFStjVWPnEXpw7Iqz6VX9M=
|
||||
EndpointV4: 127.0.0.1:3456
|
||||
PubKeyV4: Id/VoZ6HmTU3FSqhxBUswfuHHB0mQxfzcbdoJNGBRzQ=
|
||||
EndpointV6: :3456
|
||||
PubKeyV6: 40tADRhJTvaortwE5Ur4qNXhP+SOMX7ZuSvl251Yxnc=
|
||||
EndpointEdgeAPIUrl: http://127.0.0.1:3456/eg_net/eg_api
|
||||
SkipLocalIP: false
|
||||
SuperNodeInfoTimeout: 50
|
||||
P2P:
|
||||
@ -48,8 +48,10 @@ DynamicRoute:
|
||||
SendPeerInterval: 20
|
||||
GraphRecalculateSetting:
|
||||
StaticMode: false
|
||||
JitterTolerance: 20
|
||||
ManualLatency: {}
|
||||
JitterTolerance: 50
|
||||
JitterToleranceMultiplier: 1.1
|
||||
DampingResistance: 0
|
||||
TimeoutCheckInterval: 5
|
||||
RecalculateCoolDown: 5
|
||||
NTPConfig:
|
@ -1,28 +1,28 @@
|
||||
Interface:
|
||||
IType: stdio
|
||||
Name: tap1
|
||||
VPPIFaceID: 2
|
||||
Name: Node002
|
||||
VPPIFaceID: 1
|
||||
VPPBridgeID: 4242
|
||||
MacAddrPrefix: AA:BB:CC:DD
|
||||
IPv4CIDR: ""
|
||||
IPv6CIDR: ""
|
||||
IPv6LLPrefix: ""
|
||||
MacAddrPrefix: CE:51:BA:B4
|
||||
IPv4CIDR: 192.168.76.0/24
|
||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||
IPv6LLPrefix: fe80::a3df:0/112
|
||||
MTU: 1416
|
||||
RecvAddr: 127.0.0.1:4002
|
||||
SendAddr: 127.0.0.1:5002
|
||||
L2HeaderMode: kbdbg
|
||||
NodeID: 2
|
||||
NodeName: Node02
|
||||
NodeName: Node002
|
||||
PostScript: ""
|
||||
DefaultTTL: 200
|
||||
L2FIBTimeout: 3600
|
||||
PrivKey: OH8BsVUU2Rqzeu9B2J5GPG8PUmxWfX8uVvNFZKhVF3o=
|
||||
ListenPort: 0
|
||||
PrivKey: AErxhLXdZvidPZVXRYgD+84fa2qYWG9ft4MRuCbAtt8=
|
||||
ListenPort: 3002
|
||||
LogLevel:
|
||||
LogLevel: error
|
||||
LogTransit: true
|
||||
LogTransit: false
|
||||
LogControl: true
|
||||
LogNormal: true
|
||||
LogNormal: false
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
DynamicRoute:
|
||||
@ -35,12 +35,12 @@ DynamicRoute:
|
||||
SaveNewPeers: true
|
||||
SuperNode:
|
||||
UseSuperNode: true
|
||||
PSKey: juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=
|
||||
EndpointV4: 127.0.0.1:3000
|
||||
PubKeyV4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
EndpointV6: '[::1]:3000'
|
||||
PubKeyV6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
EndpointEdgeAPIUrl: http://127.0.0.1:3000/eg_api
|
||||
PSKey: iCw096jsW2aWyMwPyzVEvL8C3XXqMpB+jOeWqDC34uU=
|
||||
EndpointV4: 127.0.0.1:3456
|
||||
PubKeyV4: Id/VoZ6HmTU3FSqhxBUswfuHHB0mQxfzcbdoJNGBRzQ=
|
||||
EndpointV6: :3456
|
||||
PubKeyV6: 40tADRhJTvaortwE5Ur4qNXhP+SOMX7ZuSvl251Yxnc=
|
||||
EndpointEdgeAPIUrl: http://127.0.0.1:3456/eg_net/eg_api
|
||||
SkipLocalIP: false
|
||||
SuperNodeInfoTimeout: 50
|
||||
P2P:
|
||||
@ -48,8 +48,10 @@ DynamicRoute:
|
||||
SendPeerInterval: 20
|
||||
GraphRecalculateSetting:
|
||||
StaticMode: false
|
||||
JitterTolerance: 20
|
||||
ManualLatency: {}
|
||||
JitterTolerance: 50
|
||||
JitterToleranceMultiplier: 1.1
|
||||
DampingResistance: 0
|
||||
TimeoutCheckInterval: 5
|
||||
RecalculateCoolDown: 5
|
||||
NTPConfig:
|
@ -1,12 +1,12 @@
|
||||
Interface:
|
||||
IType: stdio
|
||||
Name: tap1
|
||||
VPPIFaceID: 100
|
||||
Name: Node100
|
||||
VPPIFaceID: 1
|
||||
VPPBridgeID: 4242
|
||||
MacAddrPrefix: AA:BB:CC:DD
|
||||
IPv4CIDR: ""
|
||||
IPv6CIDR: ""
|
||||
IPv6LLPrefix: ""
|
||||
MacAddrPrefix: CE:51:BA:B4
|
||||
IPv4CIDR: 192.168.76.0/24
|
||||
IPv6CIDR: fd95:71cb:a3df:e586::/64
|
||||
IPv6LLPrefix: fe80::a3df:0/112
|
||||
MTU: 1416
|
||||
RecvAddr: 127.0.0.1:4100
|
||||
SendAddr: 127.0.0.1:5100
|
||||
@ -16,13 +16,13 @@ NodeName: Node100
|
||||
PostScript: ""
|
||||
DefaultTTL: 200
|
||||
L2FIBTimeout: 3600
|
||||
PrivKey: IJtpnkm9ytbuCukx4VBMENJKuLngo9KSsS1D60BqonQ=
|
||||
ListenPort: 0
|
||||
PrivKey: a04BVvT+YbrX1ejjvMQVI6k5VRFlBkEX8tuLGWNyNrY=
|
||||
ListenPort: 3100
|
||||
LogLevel:
|
||||
LogLevel: error
|
||||
LogTransit: true
|
||||
LogTransit: false
|
||||
LogControl: true
|
||||
LogNormal: true
|
||||
LogNormal: false
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
DynamicRoute:
|
||||
@ -35,12 +35,12 @@ DynamicRoute:
|
||||
SaveNewPeers: true
|
||||
SuperNode:
|
||||
UseSuperNode: true
|
||||
PSKey: j9dS/lYvL16svSeC5lh+ldlq2iZX2MWwZfM3NNWpULI=
|
||||
EndpointV4: 127.0.0.1:3000
|
||||
PubKeyV4: LJ8KKacUcIoACTGB/9Ed9w0osrJ3WWeelzpL2u4oUic=
|
||||
EndpointV6: '[::1]:3000'
|
||||
PubKeyV6: HCfL6YJtpJEGHTlJ2LgVXIWKB/K95P57LHTJ42ZG8VI=
|
||||
EndpointEdgeAPIUrl: http://127.0.0.1:3000/eg_api
|
||||
PSKey: Gfp2RkPNrKTeGKrCJNEvSyiBqYYRmzVnVG6CBuUKUNc=
|
||||
EndpointV4: 127.0.0.1:3456
|
||||
PubKeyV4: Id/VoZ6HmTU3FSqhxBUswfuHHB0mQxfzcbdoJNGBRzQ=
|
||||
EndpointV6: :3456
|
||||
PubKeyV6: 40tADRhJTvaortwE5Ur4qNXhP+SOMX7ZuSvl251Yxnc=
|
||||
EndpointEdgeAPIUrl: http://127.0.0.1:3456/eg_net/eg_api
|
||||
SkipLocalIP: false
|
||||
SuperNodeInfoTimeout: 50
|
||||
P2P:
|
||||
@ -48,8 +48,10 @@ DynamicRoute:
|
||||
SendPeerInterval: 20
|
||||
GraphRecalculateSetting:
|
||||
StaticMode: false
|
||||
JitterTolerance: 20
|
||||
ManualLatency: {}
|
||||
JitterTolerance: 50
|
||||
JitterToleranceMultiplier: 1.1
|
||||
DampingResistance: 0
|
||||
TimeoutCheckInterval: 5
|
||||
RecalculateCoolDown: 5
|
||||
NTPConfig:
|
55
example_config/super_mode/Node_super.yaml
Normal file
55
example_config/super_mode/Node_super.yaml
Normal file
@ -0,0 +1,55 @@
|
||||
NodeName: NodeSP
|
||||
PostScript: ""
|
||||
PrivKeyV4: 2P0mV5RkpFFyg+aLPK841sml5RobQGrxAV5ld4En9Kk=
|
||||
PrivKeyV6: 9JrdnAk1ljXUTn9VFb1uFyey20tQEQuzJJtVueM4vsw=
|
||||
ListenPort: 3456
|
||||
ListenPort_EdgeAPI: "3456"
|
||||
ListenPort_ManageAPI: "3456"
|
||||
API_Prefix: /eg_net/eg_api
|
||||
RePushConfigInterval: 30
|
||||
HttpPostInterval: 50
|
||||
PeerAliveTimeout: 70
|
||||
SendPingInterval: 15
|
||||
LogLevel:
|
||||
LogLevel: normal
|
||||
LogTransit: false
|
||||
LogNormal: false
|
||||
LogControl: true
|
||||
LogInternal: true
|
||||
LogNTP: true
|
||||
Passwords:
|
||||
ShowState: passwd_showstate
|
||||
AddPeer: passwd_addpeer
|
||||
DelPeer: passwd_delpeer
|
||||
UpdatePeer: passwd_updatepeer
|
||||
UpdateSuper: passwd_updatesuper
|
||||
GraphRecalculateSetting:
|
||||
StaticMode: false
|
||||
ManualLatency: {}
|
||||
JitterTolerance: 30
|
||||
JitterToleranceMultiplier: 1.01
|
||||
DampingResistance: 0.9
|
||||
TimeoutCheckInterval: 5
|
||||
RecalculateCoolDown: 5
|
||||
NextHopTable: {}
|
||||
EdgeTemplate: ""
|
||||
UsePSKForInterEdge: true
|
||||
Peers:
|
||||
- NodeID: 1
|
||||
Name: Node001
|
||||
PubKey: awnuKYQOgCywkJbHAynqMzKi5QEGsG0w4iBy2Ja1MDQ=
|
||||
PSKey: j2f9Fhdhw2O2zLqUqfL5nTFStjVWPnEXpw7Iqz6VX9M=
|
||||
AdditionalCost: 10
|
||||
SkipLocalIP: false
|
||||
- NodeID: 2
|
||||
Name: Node002
|
||||
PubKey: WUyblc/DZzPNU5sOQQS2lS0aP53zFEVNjqCHjkhkdzE=
|
||||
PSKey: iCw096jsW2aWyMwPyzVEvL8C3XXqMpB+jOeWqDC34uU=
|
||||
AdditionalCost: 10
|
||||
SkipLocalIP: false
|
||||
- NodeID: 100
|
||||
Name: Node_100
|
||||
PubKey: Bax6wOJpisSVJtrU92ujn8D/2oGUyhyPrKTXkHbGamM=
|
||||
PSKey: Gfp2RkPNrKTeGKrCJNEvSyiBqYYRmzVnVG6CBuUKUNc=
|
||||
AdditionalCost: 1000
|
||||
SkipLocalIP: false
|
@ -1,42 +1,81 @@
|
||||
# Etherguard
|
||||
[English](README.md)
|
||||
|
||||
Super Mode的[範例配置檔](./)的說明文件
|
||||
在了解Super Mode的運作之前,建議您先閱讀[Static Mode的運作](../static_mode/README_zh.md)方法,再閱讀本篇會比較好
|
||||
[English](README.md) | [中文](#)
|
||||
|
||||
## Super Mode
|
||||
|
||||
Super Mode是受到[n2n](https://github.com/ntop/n2n)的啟發
|
||||
分為super node和edge node兩種節點
|
||||
分為SuperNode和EdgeNode兩種節點
|
||||
|
||||
全部節點都會和supernode建立連線
|
||||
藉由supernode交換其他節點的資訊,以及udp打洞
|
||||
由supernode執行[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法),並把計算結果分發給全部edge node
|
||||
全部節點都會和SuperNode建立連線
|
||||
藉由SuperNode交換其他節點的資訊,以及udp打洞
|
||||
由SuperNode執行[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法),並把計算結果分發給全部edge node
|
||||
|
||||
在edge node的super模式下,設定檔裡面的`nexthoptable`以及`peers`是無效的。
|
||||
這些資訊都是從super node上面下載
|
||||
同時,supernode會幫每個連線生成Preshared Key,分發給edge使用(如果`usepskforinteredge`有啟用的話)。
|
||||
```golang
|
||||
psk = shs256("PubkeyPeerA" + "PubkeyPeerB" + "主廚特調當季精選海鹽")[:32]
|
||||
|
||||
## Quick start
|
||||
|
||||
首先按需求修改`gensuper.yaml`
|
||||
|
||||
```yaml
|
||||
Config output dir: /tmp/eg_gen
|
||||
ConfigTemplate for super node: ""
|
||||
ConfigTemplate for edge node: ""
|
||||
Network name: eg_net
|
||||
Super Node:
|
||||
Listen port: 3456
|
||||
EdgeAPI prefix: /eg_net/eg_api
|
||||
Endpoint(IPv4)(optional): example.com
|
||||
Endpoint(IPv6)(optional): example.com
|
||||
Endpoint(EdgeAPI): http://example.com:3456/eg_net/eg_api
|
||||
Edge Node:
|
||||
Node IDs: "[1~10,11,19,23,29,31,55~66,88~99]"
|
||||
MacAddress prefix: "" # 留空隨機產生
|
||||
IPv4 range: 192.168.76.0/24 # IP的部分可以直接省略沒關係
|
||||
IPv6 range: fd95:71cb:a3df:e586::/64 # 這個欄位唯一的目的只是在啟動以後,調用ip命令,幫tap接口加個ip
|
||||
IPv6 LL range: fe80::a3df:0/112 # 和VPN本身運作完全無關
|
||||
```
|
||||
接著執行這個,就會生成所需設定檔了。
|
||||
```
|
||||
$ ./etherguard-go -mode gencfg -cfgmode super -config example_config/super_mode/gensuper.yaml
|
||||
```
|
||||
|
||||
把一個super,2個edge分別搬去三台機器
|
||||
或是2台機器,super和edge可以是同一台
|
||||
|
||||
在Supernode執行
|
||||
```
|
||||
./etherguard-go -config [設定檔位置] -mode super
|
||||
```
|
||||
在EdgeNode執行
|
||||
```
|
||||
./etherguard-go -config [設定檔位置] -mode edge
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
在了解Super Mode的運作之前,建議您先閱讀[Static Mode的運作](../static_mode/README_zh.md)方法,再閱讀本篇會比較好
|
||||
|
||||
|
||||
在EdgeNode的SuperMode下,設定檔裡面的`NextHopTable`以及`Peers`是無效的。
|
||||
這些資訊都是從SuperNode上面下載
|
||||
同時,SuperNode會幫每個連線生成pre-shared key,分發給edge使用(如果啟用`UsePSKForInterEdge`的話)。
|
||||
|
||||
### SuperMsg
|
||||
但是比起Static mode,Super mode引入了一種新的 `終點ID` 叫做 `SuperMsg`。
|
||||
所有送往Super node的封包都會是這種類型。
|
||||
這種封包不會在edge node之間傳播,收到也會不會轉給任何人,如同`終點ID == 自己`一般
|
||||
但是比起StaticMode,SuperMode引入了一種新的 `終點ID` 叫做 `NodeID_SuperNode`。
|
||||
所有送往SuperNode的封包都會是這種類型。
|
||||
這種封包不會在EdgeNode之間傳播,收到也會不會轉給任何人,如同`終點ID == 自己`一般
|
||||
|
||||
## Control Message
|
||||
從Super mode開始,我們有了Static mode不存在的Control Message。他會控制EtherGuard一些行為
|
||||
在Super mode下,我們不會轉發任何控制消息。 我們只會直接接收或發送給目標。
|
||||
從SuperMode開始,我們有了StaticMode不存在的Control Message。他會控制EtherGuard一些行為
|
||||
在SuperMode下,我們不會轉發任何控制消息。 我們只會直接接收或發送給目標。
|
||||
下面列出Super Mode會出現的Control message
|
||||
|
||||
### Register
|
||||
具體運作方式類似這張圖
|
||||
![Register運作流程](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS01.png)
|
||||
1. edge node發送`Register`給super node
|
||||
2. super node收到以後就知道這個edge的endpoint IP和埠號。
|
||||
1. EdgeNode發送`Register`給sSuperNode
|
||||
2. SuperNode收到以後就知道這個EdgeNode的Endpoint IP和Port number。
|
||||
3. 更新進資料庫以後發布`UpdatePeerMsg`。
|
||||
4. 其他edge node收到以後就用HTTP API去下載完整的peer list。並且把自己沒有的peer通通加到本地
|
||||
4. 其他edge node收到以後就用HTTP EdgeAPI去下載完整的peer list。並且把自己沒有的peer通通加到本地
|
||||
|
||||
### Ping/Pong
|
||||
有了peer list以後,接下來的運作方式類似這張圖
|
||||
@ -46,18 +85,58 @@ Edge node 會嘗試向其他所有peer發送`Ping`,裡面會攜帶節點自己
|
||||
收到`Ping`,就會產生一個`Pong`,並攜帶時間差。這個時間就是單向延遲
|
||||
但是他不會把`Pong`送回給原節點,而是送給Super node
|
||||
|
||||
### <a name="AdditionalCost"></a>AdditionalCost
|
||||
有了各個節點的延遲以後,還不會立刻計算`Floyd-Warshall`,而是要先加上`AdditionalCost`
|
||||
|
||||
以這張圖片的情境為例:
|
||||
![EGS08](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS08.png)
|
||||
Path | Latency |Cost|Win
|
||||
--------|:--------|:---|:--
|
||||
A->B->C | 3ms | 3 |
|
||||
A->C | 4ms | 4 | O
|
||||
|
||||
但是這個情境,3ms 4ms 只相差1ms
|
||||
為了這1ms而多繞一趟實在浪費,而且轉發本身也要時間
|
||||
|
||||
每個節點有了`AdditionalCost`參數,就能設定經過這個節點轉發,所需額外增加的成本
|
||||
|
||||
假如ABC全部設定了`AdditionalCost=10`
|
||||
Path | Latency |AdditionalCost|Cost|Win
|
||||
--------|:--------|:-------------|:---|:--
|
||||
A->B->C | 3ms | 20 | 23 |
|
||||
A->C | 4ms | 10 | 14 | O
|
||||
|
||||
A->C 就換選擇直連,不會為了省下1ms而繞路
|
||||
這邊`AdditionalCost=10`可以解釋為: 必須能省下10ms,才會繞這條路
|
||||
|
||||
這個參數也有別的用途
|
||||
針對流量比較貴的節點,可以設定`AdditionalCost=10000`
|
||||
別人就不會走他中轉了,而是盡量繞別的路,或是直連
|
||||
除非別條路線全掛,只剩這挑Cost 10000的路線
|
||||
|
||||
還有一個用法,全部節點都設定`AdditionalCost=10000`
|
||||
無視延遲,全節點都盡量直連,打動失敗才繞路
|
||||
|
||||
### UpdateNhTable
|
||||
Super node收到節點們傳來的Pong以後,就知道他們的單向延遲了。接下來的運作方式類似這張圖
|
||||
![image](https://raw.githubusercontent.com/KusakabeSi/EtherGuard-VPN/master/example_config/super_mode/EGS03.png)
|
||||
Super node收到Pong以後,就會更新它裡面的`Distance matrix`,並且重新計算轉發表
|
||||
如果有變動,就發布`UpdateNhTableMsg`
|
||||
其他edge node收到以後就用HTTP API去下載完整的轉發表
|
||||
其他edge node收到以後就用HTTP EdgeAPI去下載完整的轉發表
|
||||
|
||||
### UpdateError
|
||||
通知edges有錯誤發生,關閉egde端程式
|
||||
發生在版本號不匹被,該edge的NodeID配置錯誤,還有該Edge被刪除時觸發
|
||||
### ServerUpdate
|
||||
通知EdgeNode有事情發生
|
||||
1. 關閉EdgeNode程式
|
||||
* 版本號不匹配
|
||||
* 該edge的NodeID配置錯誤
|
||||
* 該Edge被刪除
|
||||
2. 通知EdgeNode有更新
|
||||
* UpdateNhTable
|
||||
* UpdatePeer
|
||||
* UpdateSuperParams
|
||||
|
||||
### HTTP API
|
||||
|
||||
## HTTP EdgeAPI
|
||||
為什麼要用HTTP額外下載呢?直接`UpdateXXX`夾帶資訊不好嗎?
|
||||
因為udp是不可靠協議,能攜帶的內容量也有上限。
|
||||
但是peer list包含了全部的peer資訊,長度不是固定的,可能超過
|
||||
@ -68,12 +147,15 @@ Super node收到Pong以後,就會更新它裡面的`Distance matrix`,並且
|
||||
這樣super node收到HTTP API看到`state hash`就知道這個edge node確實有收到`UpdateXXX`了。
|
||||
不然每隔一段時間就會重新發送`UpdateXXX`給該節點
|
||||
|
||||
預設配置是走HTTP。但為**了你的安全著想,建議使用nginx反代理成https**
|
||||
有想過SuperNode開發成直接支援https,但是證書動態更新太麻煩就沒有做了
|
||||
|
||||
## HTTP Manage API
|
||||
HTTP還有一些個API,給前端使用,幫助管理整個網路
|
||||
HTTP還有5個Manage API,給前端使用,幫助管理整個網路
|
||||
|
||||
### super/state
|
||||
```bash
|
||||
curl "http://127.0.0.1:3000/eg_api/manage/super/state?Password=passwd_showstate"
|
||||
curl "http://127.0.0.1:3456/eg_net/eg_api/manage/super/state?Password=passwd_showstate"
|
||||
```
|
||||
可以給前端看的,用來顯示現在各節點之間的單向延遲狀況
|
||||
之後可以用來畫力導向圖。
|
||||
@ -145,10 +227,10 @@ curl "http://127.0.0.1:3000/eg_api/manage/super/state?Password=passwd_showstate"
|
||||
再來是新增peer,可以不用重啟Supernode就新增Peer
|
||||
|
||||
範例:
|
||||
```
|
||||
curl -X POST "http://127.0.0.1:3000/eg_api/manage/peer/add?Password=passwd_addpeer" \
|
||||
```bash
|
||||
curl -X POST "http://127.0.0.1:3456/eg_net/eg_api/manage/peer/add?Password=passwd_addpeer" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "NodeID=100&Name=Node_100&PubKey=6SuqwPH9pxGigtZDNp3PABZYfSEzDaBSwuThsUUAcyM=&AdditionalCost=1000&PSKey=j9dS%2FlYvL16svSeC5lh%2Bldlq2iZX2MWwZfM3NNWpULI%3D&SkipLocalIP=false"
|
||||
-d "NodeID=100&Name=Node_100&PubKey=Bax6wOJpisSVJtrU92ujn8D%2F2oGUyhyPrKTXkHbGamM%3D&AdditionalCost=1000&PSKey=Gfp2RkPNrKTeGKrCJNEvSyiBqYYRmzVnVG6CBuUKUNc%3D&SkipLocalIP=false"
|
||||
```
|
||||
參數:
|
||||
1. URL query: Password: 新增peer用的密碼,在設定檔配置
|
||||
@ -172,13 +254,13 @@ curl -X POST "http://127.0.0.1:3000/eg_api/manage/peer/add?Password=passwd_addpe
|
||||
設計上分別是給管理員使用,或是給加入網路的人,想離開網路使用
|
||||
|
||||
使用Password刪除可以刪除任意節點,以上面新增的節點為例,使用這個API即可刪除剛剛新增的節點
|
||||
```
|
||||
curl "http://127.0.0.1:3000/eg_api/manage/peer/del?Password=passwd_delpeer&NodeID=100"
|
||||
```bash
|
||||
curl "http://127.0.0.1:3456/eg_net/eg_api/manage/peer/del?Password=passwd_delpeer&NodeID=100"
|
||||
```
|
||||
|
||||
也可以使用privkey刪除,同上,但是只要附上privkey參數就好
|
||||
```
|
||||
curl "http://127.0.0.1:3000/eg_api/manage/peer/del?PrivKey=IJtpnkm9ytbuCukx4VBMENJKuLngo9KSsS1D60BqonQ="
|
||||
```bash
|
||||
curl "http://127.0.0.1:3456/eg_net/eg_api/manage/peer/del?PrivKey=a04BVvT%2BYbrX1ejjvMQVI6k5VRFlBkEX8tuLGWNyNrY%3D"
|
||||
```
|
||||
|
||||
參數:
|
||||
@ -193,65 +275,121 @@ curl "http://127.0.0.1:3000/eg_api/manage/peer/del?PrivKey=IJtpnkm9ytbuCukx4VBME
|
||||
|
||||
### peer/update
|
||||
更新節點的一些參數
|
||||
```
|
||||
curl -X POST "http://127.0.0.1:12369/eg_net/eg_api/manage/peer/update?Password=e05znou1_updatepeer&NodeID=1" \
|
||||
```bash
|
||||
curl -X POST "http://127.0.0.1:3456/eg_net/eg_api/eg_api/manage/peer/update?Password=e05znou1_updatepeer&NodeID=1" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "AdditionalCost=10&SkipLocalIP=false"
|
||||
```
|
||||
|
||||
### super/update
|
||||
更新SuperNode的一些參數
|
||||
```
|
||||
curl -X POST "http://127.0.0.1:12369/eg_net/eg_api/manage/super/update?Password=e05znou1_updatesuper" \
|
||||
```bash
|
||||
curl -X POST "http://127.0.0.1:3456/eg_net/eg_api/eg_api/manage/super/update?Password=e05znou1_updatesuper" \
|
||||
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||
-d "SendPingInterval=15&HttpPostInterval=60&PeerAliveTimeout=70"
|
||||
```
|
||||
|
||||
### SuperNode Config Parameter
|
||||
|
||||
## Config Parameters
|
||||
Key | Description
|
||||
-------------- |:-----
|
||||
NodeName| 節點名稱
|
||||
PostScript | 初始化完畢之後要跑的腳本
|
||||
PrivKeyV4 | IPv4通訊使用的私鑰
|
||||
PrivKeyV6 | IPv6通訊使用的私鑰
|
||||
ListenPort | udp監聽埠
|
||||
ListenPort_EdgeAPI | HTTP EdgeAPI 的監聽埠
|
||||
ListenPort_ManageAPI| HTTP ManageAPI 的監聽埠
|
||||
API_Prefix | HTTP API prefix
|
||||
RePushConfigInterval| 重新push`UpdateXXX`的間格
|
||||
HttpPostInterval | EdgeNode 使用EdgeAPI回報狀態的頻率
|
||||
PeerAliveTimeout | 判定斷線Timeout
|
||||
SendPingInterval | EdgeNode 之間使用Ping/Pong測量延遲的間格
|
||||
[LogLevel](../static_mode/README_zh.md#LogLevel)| 紀錄log
|
||||
[Passwords](#Passwords) | HTTP ManageAPI 的密碼,5個API密碼是獨立的
|
||||
[GraphRecalculateSetting](#GraphRecalculateSetting) | 一些和[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法)相關的參數
|
||||
[NextHopTable](../static_mode/README_zh.md#NextHopTable) | StaticMode 模式下使用的轉發表
|
||||
EdgeTemplate | HTTP ManageAPI `peer/add` 返回的edge的參考設定檔
|
||||
UsePSKForInterEdge | 幫Edge生成PreSharedKey,供edge之間直接連線使用
|
||||
[Peers](#EdgeNodes) | EdgeNode資訊
|
||||
|
||||
### Super mode的edge node有幾個參數
|
||||
1. `usesupernode`: 是否啟用Super mode
|
||||
1. `pskey`: 和supernode建立連線用的Pre shared Key
|
||||
1. `connurlv4`: Super node的IPv4連線地址
|
||||
1. `pubkeyv4`: Super node的IPv4工鑰
|
||||
1. `connurlv6`: Super node的IPv6連線地址
|
||||
1. `pubkeyv6`: Super node的IPv6工鑰
|
||||
1. `apiurl`: Super node的HTTP(S) API連線地址
|
||||
1. `supernodeinfotimeout`: Supernode Timeout
|
||||
1. `httppostinterval`: 15
|
||||
1. `skiplocalip`: 打洞時,一律使用supernode蒐集到的外部ip,不使用edge自行回報的local ip
|
||||
<a name="Passwords"></a>Passwords | Description
|
||||
--------------------|:-----
|
||||
ShowState | HTTP ManageAPI `super/state` 的密碼
|
||||
AddPeer | HTTP ManageAPI `peer/add` 的密碼
|
||||
DelPeer | HTTP ManageAPI `peer/del` 的密碼
|
||||
UpdatePeer | HTTP ManageAPI `peer/update` 的密碼
|
||||
UpdateSuper | HTTP ManageAPI `super/update` 的密碼
|
||||
|
||||
### Super node本身的設定檔
|
||||
<a name="GraphRecalculateSetting"></a>GraphRecalculateSetting | Description
|
||||
--------------------|:-----
|
||||
StaticMode | 關閉`Floyd-Warshall`演算法,只使用設定檔提供的NextHopTable`。SuperNode單純用來輔助打洞
|
||||
ManualLatency | 手動設定延遲,不採用EdgeNode回報的延遲(單位: 毫秒)
|
||||
JitterTolerance | 抖動容許誤差,收到Pong以後,一個37ms,一個39ms,不會觸發重新計算<br>比較對象是上次更新使用的值。如果37 37 41 43 .. 100 ,每次變動一點點,總變動量超過域值還是會更新
|
||||
JitterToleranceMultiplier | 抖動容許誤差的放大係數,高ping的話允許更多誤差<br>https://www.desmos.com/calculator/raoti16r5n
|
||||
DampingResistance | 防抖阻尼系數,`latency = latency_old * resistance + latency_in * (1-resistance)`
|
||||
TimeoutCheckInterval | 週期性檢查節點的連線狀況,是否斷線需要重新規劃線路
|
||||
RecalculateCoolDown | Floyd-Warshal是O(n^3)時間複雜度,不能太常算。<br>設個冷卻時間<br>有節點加入/斷線觸發的重新計算,無視這個CoolDown
|
||||
|
||||
1. nodename: 節點名稱
|
||||
1. privkeyv4: ipv4用的私鑰
|
||||
1. privkeyv6: ipv6用的私鑰
|
||||
1. listenport: 監聽udp埠號
|
||||
1. loglevel: 參考 [README_zh.md](../README_zh.md)
|
||||
1. repushconfiginterval: 重新push`UpdateXXX`的間格
|
||||
1. passwords: HTTP API 密碼
|
||||
1. showstate: 節點資訊
|
||||
1. addpeer: 新增peer
|
||||
1. delpeer: 刪除peer
|
||||
1. graphrecalculatesetting: 一些和[Floyd-Warshall演算法](https://zh.wikipedia.org/zh-tw/Floyd-Warshall算法)相關的參數
|
||||
1. staticmode: 關閉Floyd-Warshall演算法,只使用一開始載入的nexthoptable。Supernode單純用來輔助打洞
|
||||
1. recalculatecooldown: Floyd-Warshal是O(n^3)時間複雜度,不能太常算。設個冷卻時間
|
||||
1. jittertolerance: 抖動容許誤差,收到Pong以後,一個37ms,一個39ms,不會觸發重新計算
|
||||
1. jittertolerancemultiplier: 一樣是抖動容許誤差,但是高ping的話允許更多誤差
|
||||
https://www.desmos.com/calculator/raoti16r5n
|
||||
1. nodereporttimeout: 收到的`Pong`封包的有效期限。太久沒收到就變回Infinity
|
||||
1. timeoutcheckinterval: 固定間格檢查,有沒有人的Pong封包超過有效期限,要重算轉發表
|
||||
1. nexthoptable: 僅在`staticmode==true` 有效,手動設定的nexthoptable
|
||||
1. edgetemplate: 給`addpeer`API用的。參考這個設定檔,顯示一個範例設定檔給edge
|
||||
1. usepskforinteredge: 是否啟用edge間pre shares key通信。若啟用則幫edge們自動生成PSK
|
||||
1. peers: Peer列表,參考 [README_zh.md](../README_zh.md)
|
||||
1. nodeid: Peer的節點ID
|
||||
1. name: Peer名稱(顯示在前端)
|
||||
1. pubkey: peer 公鑰
|
||||
1. pskey: preshared key 該peer和本Supernode連線的PSK
|
||||
1. additionalcost: 此節點進行封包轉發的額外成本。單位: 毫秒
|
||||
<a name="EdgeNodes"></a>Peers | Description
|
||||
--------------------|:-----
|
||||
NodeID | 節點ID
|
||||
PubKey | 公鑰
|
||||
PSKey | 預共享金鑰
|
||||
[AdditionalCost](#AdditionalCost) | 繞路成本(單位: 毫秒)<br>設定-1代表使用EdgeNode自身設定
|
||||
SkipLocalIP | 打洞時,不使用EdgeNode回報的本地IP,僅使用SuperNode蒐集到的外部IP
|
||||
|
||||
### EdgeNode Config Parameter
|
||||
|
||||
Key | Description
|
||||
-------------- |:-----
|
||||
[Interface](../static_mode/README_zh.md#Interface)| 接口相關設定。VPN有兩端,一端是VPN網路,另一端則是本地接口
|
||||
NodeID | 節點ID。節點之間辨識身分用的,同一網路內節點ID不能重複
|
||||
NodeName | 節點名稱
|
||||
PostScript | 初始化完畢之後要跑的腳本
|
||||
DefaultTTL | TTL,etherguard層使用,和乙太層不共通
|
||||
L2FIBTimeout | MacAddr-> NodeID 查找表的 timeout(秒) ,類似ARP table
|
||||
PrivKey | 私鑰,和wireguard規格一樣
|
||||
ListenPort | 監聽的udp埠
|
||||
[LogLevel](../static_mode/README_zh.md#LogLevel)| 紀錄log
|
||||
[DynamicRoute](#DynamicRoute) | 動態路由相關設定
|
||||
NextHopTable | 轉發表, SuperMode由SuperNode計算,EdgeNode用不到
|
||||
ResetConnInterval | 如果對方是動態ip就要用這個。每隔一段時間就會重置連線,重新解析域名
|
||||
[Peers](#Peers) | 鄰居節點,SuperMode從SuperNode計算,EdgeNode用不到
|
||||
|
||||
<a name="DynamicRoute"></a>DynamicRoute | Description
|
||||
--------------------|:-----
|
||||
SendPingInterval | 發送Ping訊息的間隔(秒)
|
||||
PeerAliveTimeout | 每次收到封包就重置,超過時間(秒)沒收到就標記該peer離線
|
||||
DupCheckTimeout | 重複封包檢查的timeout(秒)<br>完全相同的封包收第二次會被丟棄
|
||||
ConnTimeOut | 檢查peer離線的時間間格<br>如果標記離線,就切換下一個endpoint<br>SuperNode可能傳了多個endpoint過來
|
||||
ConnNextTry | 切換下一個endpoint的間隔
|
||||
[AdditionalCost](#AdditionalCost) | 繞路成本(毫秒)。僅限SuperNode設定-1時生效
|
||||
SaveNewPeers | 是否把下載來的鄰居資訊存到本地設定檔裡面
|
||||
[SuperNode](#SuperNode) | SuperNode相關設定
|
||||
P2P | P2P相關設定,SuperMode用不到
|
||||
[NTPConfig](#NTPConfig) | NTP時間同步相關設定
|
||||
|
||||
<a name="SuperNode"></a>SuperNode | Description
|
||||
---------------------|:-----
|
||||
UseSuperNode | 是否啟用SuperNode
|
||||
PSKey | 和SuperNode通訊用的PreShared Key
|
||||
EndpointV4 | SuperNode的IPv4 Endpoint
|
||||
PubKeyV4 | SuperNode的IPv4公鑰
|
||||
EndpointV6 | SuperNode的IPv6 Endpoint
|
||||
PubKeyV6 | SuperNode的IPv6公鑰
|
||||
EndpointEdgeAPIUrl | SuperNode的EdgeAPI存取路徑
|
||||
SkipLocalIP | 不回報本地IP,避免和其他Edge內網直連
|
||||
SuperNodeInfoTimeout | 實驗性選項,SuperNode離線超時,切換成P2P模式<br>需先打開P2P模式<br>`UseP2P=false`本選項無效<br>P2P模式尚未測試,穩定性未知,不推薦使用
|
||||
|
||||
|
||||
<a name="NTPConfig"></a>NTPConfig | Description
|
||||
--------------------|:-----
|
||||
UseNTP | 是否使用NTP同步時間
|
||||
MaxServerUse | 向多少NTP伺服器發送請求
|
||||
SyncTimeInterval | 多久同步一次時間
|
||||
NTPTimeout | NTP伺服器連線Timeout
|
||||
Servers | NTP伺服器列表
|
||||
|
||||
## V4 V6 兩個公鑰
|
||||
為什麼要分開IPv4和IPv6呢?
|
||||
@ -284,12 +422,14 @@ Relay node其實也是一個edge node,只不過被設定成為interface=dummy
|
||||
因為如果用127.0.0.1連接supernode,supernode看到封包的src IP就是127.0.0.1,就會把127.0.0.1分發給`Node_1`和`Node_2`
|
||||
`Node_1`和`Node_2`看到`Node_R`的連線地址是`127.0.0.1`,就連不上了
|
||||
|
||||
## Quick start
|
||||
執行此範例設定檔(請開三個terminal):
|
||||
#### Run example config
|
||||
|
||||
在**不同terminal**分別執行以下命令
|
||||
|
||||
```bash
|
||||
./etherguard-go -config example_config/super_mode/s1.yaml -mode super
|
||||
./etherguard-go -config example_config/super_mode/n1.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/n2.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/Node_super.yaml -mode super
|
||||
./etherguard-go -config example_config/super_mode/Node_edge001.yaml -mode edge
|
||||
./etherguard-go -config example_config/super_mode/Node_edge002.yaml -mode edge
|
||||
```
|
||||
因為是stdio模式,stdin會讀入VPN網路
|
||||
請在其中一個edge視窗中鍵入
|
||||
|
@ -1,15 +1,15 @@
|
||||
Config output dir: /tmp/eg_gen
|
||||
Config output dir: /tmp/eg_gen_super
|
||||
ConfigTemplate for super node: ""
|
||||
ConfigTemplate for edge node: ""
|
||||
Network name: eg_net
|
||||
Network name: EgNet
|
||||
Super Node:
|
||||
Listen port: 3456
|
||||
EdgeAPI prefix: /eg_net/eg_api
|
||||
Endpoint(IPv4)(optional): example.com
|
||||
Endpoint(IPv6)(optional): example.com
|
||||
Endpoint(EdgeAPI): http://example.com:3456/eg_net/eg_api
|
||||
Endpoint(IPv4)(optional): 127.0.0.1
|
||||
Endpoint(IPv6)(optional):
|
||||
Endpoint(EdgeAPI): http://127.0.0.1:3456/eg_net/eg_api
|
||||
Edge Node:
|
||||
Node IDs: "[1~10,11,19,23,29,31,55~66,88~99]"
|
||||
Node IDs: "[1~2,100]"
|
||||
MacAddress prefix: ""
|
||||
IPv4 range: 192.168.76.0/24
|
||||
IPv6 range: fd95:71cb:a3df:e586::/64
|
||||
|
@ -1,47 +0,0 @@
|
||||
NodeName: NodeSuper
|
||||
PostScript: ""
|
||||
PrivKeyV4: mL5IW0GuqbjgDeOJuPHBU2iJzBPNKhaNEXbIGwwYWWk=
|
||||
PrivKeyV6: +EdOKIoBp/EvIusHDsvXhV1RJYbyN3Qr8nxlz35wl3I=
|
||||
ListenPort: 3000
|
||||
ListenPort_EdgeAPI: "3000"
|
||||
ListenPort_ManageAPI: "3000"
|
||||
API_Prefix: /eg_api
|
||||
RePushConfigInterval: 30
|
||||
HttpPostInterval: 50
|
||||
PeerAliveTimeout: 70
|
||||
SendPingInterval: 15
|
||||
LogLevel:
|
||||
LogLevel: normal
|
||||
LogTransit: true
|
||||
LogControl: true
|
||||
LogNormal: false
|
||||
LogInternal: true
|
||||
LogNTP: false
|
||||
Passwords:
|
||||
ShowState: passwd_showstate
|
||||
AddPeer: passwd_addpeer
|
||||
DelPeer: passwd_delpeer
|
||||
UpdatePeer: passwd_updatepeer
|
||||
UpdateSuper: passwd_updatesuper
|
||||
GraphRecalculateSetting:
|
||||
StaticMode: false
|
||||
JitterTolerance: 5
|
||||
JitterToleranceMultiplier: 1.01
|
||||
TimeoutCheckInterval: 5
|
||||
RecalculateCoolDown: 5
|
||||
NextHopTable: {}
|
||||
EdgeTemplate: example_config/super_mode/n1.yaml
|
||||
UsePSKForInterEdge: true
|
||||
Peers:
|
||||
- NodeID: 1
|
||||
Name: Node_01
|
||||
PubKey: ZqzLVSbXzjppERslwbf2QziWruW3V/UIx9oqwU8Fn3I=
|
||||
PSKey: iPM8FXfnHVzwjguZHRW9bLNY+h7+B1O2oTJtktptQkI=
|
||||
AdditionalCost: 10
|
||||
SkipLocalIP: false
|
||||
- NodeID: 2
|
||||
Name: Node_02
|
||||
PubKey: dHeWQtlTPQGy87WdbUARS4CtwVaR2y7IQ1qcX4GKSXk=
|
||||
PSKey: juJMQaGAaeSy8aDsXSKNsPZv/nFiPj4h/1G70tGYygs=
|
||||
AdditionalCost: 10
|
||||
SkipLocalIP: false
|
@ -92,16 +92,17 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
||||
if !all_verts[NodeID] {
|
||||
return fmt.Errorf("duplicate definition: NodeID %v ", NodeID)
|
||||
}
|
||||
if endpoint != "" {
|
||||
_, err = conn.LookupIP(endpoint, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
pri, pub := device.RandomKeyPair()
|
||||
edge_infos[NodeID] = edge_info{
|
||||
Endpoint: endpoint,
|
||||
PrivKey: pri.ToString(),
|
||||
PubKey: pub.ToString(),
|
||||
PersistentKeepalive: edgeinfo.PersistentKeepalive,
|
||||
ConnectedEdge: make(map[mtypes.Vertex]bool),
|
||||
}
|
||||
all_verts[NodeID] = false
|
||||
@ -118,7 +119,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
||||
s := edge.Src_nodeID
|
||||
d := edge.Dst_nodeID
|
||||
if len(edge_infos[s].Endpoint)+len(edge_infos[d].Endpoint) == 0 {
|
||||
return fmt.Errorf("there are an edge between node %v and %v, but non of them have endpoint", s, d)
|
||||
return fmt.Errorf("there are an edge between node [%v , %v], but non of them have endpoint", s, d)
|
||||
}
|
||||
edge_infos[s].ConnectedEdge[d] = true
|
||||
edge_infos[d].ConnectedEdge[s] = true
|
||||
@ -132,7 +133,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
||||
pbyte := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
|
||||
pbyte[0] &^= 0b00000001
|
||||
pbyte[0] |= 0b00000010
|
||||
NMCfg.EdgeNode.MacPrefix = fmt.Sprintf("%X:%X:%X:%X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
|
||||
NMCfg.EdgeNode.MacPrefix = fmt.Sprintf("%02X:%02X:%02X:%02X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
|
||||
}
|
||||
|
||||
dist, next, err := g.FloydWarshall(false)
|
||||
@ -177,6 +178,8 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
||||
econfig.NodeID = NodeID
|
||||
idstr := fmt.Sprintf("%0"+strconv.Itoa(len(MaxNodeID.ToString()))+"d", NodeID)
|
||||
econfig.NodeName = NMCfg.NetworkName + idstr
|
||||
PersistentKeepalive := uint32(30)
|
||||
econfig.ListenPort = 0
|
||||
if Edge.Endpoint != "" {
|
||||
ps := strings.Split(Edge.Endpoint, ":")
|
||||
pss := ps[len(ps)-1]
|
||||
@ -185,6 +188,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
||||
return err
|
||||
}
|
||||
econfig.ListenPort = int(port)
|
||||
PersistentKeepalive = 0
|
||||
}
|
||||
econfig.Peers = make([]mtypes.PeerInfo, 0)
|
||||
for CNodeID, _ := range Edge.ConnectedEdge {
|
||||
@ -193,7 +197,7 @@ func GenNMCfg(NMCinfigPath string, printExample bool) (err error) {
|
||||
PubKey: edge_infos[CNodeID].PubKey,
|
||||
PSKey: pskdb.GetPSK(NodeID, CNodeID).ToString(),
|
||||
EndPoint: edge_infos[CNodeID].Endpoint,
|
||||
PersistentKeepalive: Edge.PersistentKeepalive,
|
||||
PersistentKeepalive: PersistentKeepalive,
|
||||
Static: true,
|
||||
})
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
|
||||
pbyte := mtypes.RandomBytes(4, []byte{0xaa, 0xbb, 0xcc, 0xdd})
|
||||
pbyte[0] &^= 0b00000001
|
||||
pbyte[0] |= 0b00000010
|
||||
MacPrefix = fmt.Sprintf("%X:%X:%X:%X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
|
||||
MacPrefix = fmt.Sprintf("%02X:%02X:%02X:%02X", pbyte[0], pbyte[1], pbyte[2], pbyte[3])
|
||||
}
|
||||
|
||||
IPv4Block := SMCfg.EdgeNode.IPv4Range
|
||||
@ -264,6 +264,7 @@ func GenSuperCfg(SMCinfigPath string, printExample bool) (err error) {
|
||||
peerceconf.DynamicRoute.SuperNode.EndpointV4 = EndpointV4 + ":" + ListenPort
|
||||
peerceconf.DynamicRoute.SuperNode.EndpointV6 = EndpointV6 + ":" + ListenPort
|
||||
peerceconf.DynamicRoute.SuperNode.EndpointEdgeAPIUrl = EndpointEdgeAPIUrl
|
||||
peerceconf.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance = 0
|
||||
peerceconf.Interface.MacAddrPrefix = MacPrefix
|
||||
peerceconf.Interface.IPv4CIDR = IPv4Block
|
||||
peerceconf.Interface.IPv6CIDR = IPv6Block
|
||||
|
@ -68,5 +68,4 @@ type edge_info struct {
|
||||
ConnectedEdge map[mtypes.Vertex]bool
|
||||
PrivKey string
|
||||
PubKey string
|
||||
PersistentKeepalive uint32
|
||||
}
|
||||
|
@ -51,6 +51,9 @@ func Edge(configPath string, useUAPI bool, printExample bool, bindmode string) (
|
||||
if len(NodeName) > 32 {
|
||||
return errors.New("Node name can't longer than 32 :" + NodeName)
|
||||
}
|
||||
if econfig.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance < 0 || econfig.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance >= 1 {
|
||||
return fmt.Errorf("DampingResistance must in range [0,1) : %v", econfig.DynamicRoute.P2P.GraphRecalculateSetting.DampingResistance)
|
||||
}
|
||||
var logLevel int
|
||||
switch econfig.LogLevel.LogLevel {
|
||||
case "verbose", "debug":
|
||||
|
@ -684,7 +684,7 @@ func manage_peeradd(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func manage_peerupdate(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
toUpdate := mtypes.NodeID_Boardcast
|
||||
toUpdate := mtypes.NodeID_Broadcast
|
||||
|
||||
var err error
|
||||
var NodeID mtypes.Vertex
|
||||
@ -856,7 +856,7 @@ func manage_superupdate(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func manage_peerdel(w http.ResponseWriter, r *http.Request) {
|
||||
params := r.URL.Query()
|
||||
toDelete := mtypes.NodeID_Boardcast
|
||||
toDelete := mtypes.NodeID_Broadcast
|
||||
|
||||
var err error
|
||||
var NodeID mtypes.Vertex
|
||||
@ -900,7 +900,7 @@ func manage_peerdel(w http.ResponseWriter, r *http.Request) {
|
||||
toDelete = peerinfo.NodeID
|
||||
}
|
||||
}
|
||||
if toDelete == mtypes.NodeID_Boardcast {
|
||||
if toDelete == mtypes.NodeID_Broadcast {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(fmt.Sprintf("Paramater PrivKey: \"%v\" not found", PubKey)))
|
||||
return
|
||||
|
@ -100,6 +100,9 @@ func Super(configPath string, useUAPI bool, printExample bool, bindmode string)
|
||||
if sconfig.RePushConfigInterval <= 0 {
|
||||
return fmt.Errorf("RePushConfigInterval must > 0 : %v", sconfig.RePushConfigInterval)
|
||||
}
|
||||
if sconfig.GraphRecalculateSetting.DampingResistance < 0 || sconfig.GraphRecalculateSetting.DampingResistance >= 1 {
|
||||
return fmt.Errorf("DampingResistance must in range [0,1) : %v", sconfig.GraphRecalculateSetting.DampingResistance)
|
||||
}
|
||||
|
||||
var logLevel int
|
||||
switch sconfig.LogLevel.LogLevel {
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
type Vertex uint16
|
||||
|
||||
const (
|
||||
NodeID_Boardcast Vertex = math.MaxUint16 - iota // Normal boardcast, boardcast with route table
|
||||
NodeID_Broadcast Vertex = math.MaxUint16 - iota // Normal boardcast, boardcast with route table
|
||||
NodeID_AllPeer Vertex = math.MaxUint16 - iota // p2p mode: boardcast to every know peer and prevent dup. super mode: send to supernode
|
||||
NodeID_SuperNode Vertex = math.MaxUint16 - iota
|
||||
NodeID_Invalid Vertex = math.MaxUint16 - iota
|
||||
@ -99,15 +99,15 @@ type SuperPeerInfo struct {
|
||||
type LoggerInfo struct {
|
||||
LogLevel string `yaml:"LogLevel"`
|
||||
LogTransit bool `yaml:"LogTransit"`
|
||||
LogControl bool `yaml:"LogControl"`
|
||||
LogNormal bool `yaml:"LogNormal"`
|
||||
LogControl bool `yaml:"LogControl"`
|
||||
LogInternal bool `yaml:"LogInternal"`
|
||||
LogNTP bool `yaml:"LogNTP"`
|
||||
}
|
||||
|
||||
func (v *Vertex) ToString() string {
|
||||
switch *v {
|
||||
case NodeID_Boardcast:
|
||||
case NodeID_Broadcast:
|
||||
return "Boardcast"
|
||||
case NodeID_AllPeer:
|
||||
return "Control"
|
||||
|
@ -32,6 +32,64 @@ const (
|
||||
BroadcastPeer
|
||||
)
|
||||
|
||||
func (v Usage) IsNormal() bool {
|
||||
return v == NormalPacket
|
||||
}
|
||||
|
||||
func (v Usage) IsControl() bool {
|
||||
switch v {
|
||||
case Register:
|
||||
return true
|
||||
case ServerUpdate:
|
||||
return true
|
||||
case PingPacket:
|
||||
return true
|
||||
case PongPacket:
|
||||
return true
|
||||
case QueryPeer:
|
||||
return true
|
||||
case BroadcastPeer:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (v Usage) IsControl_Super2Edge() bool {
|
||||
switch v {
|
||||
case ServerUpdate:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (v Usage) IsControl_Edge2Super() bool {
|
||||
switch v {
|
||||
case Register:
|
||||
return true
|
||||
case PongPacket:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func (v Usage) IsControl_Edge2Edge() bool {
|
||||
switch v {
|
||||
case PingPacket:
|
||||
return true
|
||||
case PongPacket:
|
||||
return true
|
||||
case QueryPeer:
|
||||
return true
|
||||
case BroadcastPeer:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func NewEgHeader(pac []byte) (e EgHeader, err error) {
|
||||
if len(pac) != EgHeaderLen {
|
||||
err = errors.New("invalid packet size")
|
||||
|
@ -189,7 +189,7 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
|
||||
newval := pong_msg.Timediff
|
||||
if _, ok := g.gsetting.ManualLatency[u]; ok {
|
||||
if _, ok := g.gsetting.ManualLatency[u][v]; ok {
|
||||
newval = g.gsetting.ManualLatency[u][v]
|
||||
newval = g.gsetting.ManualLatency[u][v] / 1000 // s to ms
|
||||
}
|
||||
}
|
||||
w := newval
|
||||
@ -206,7 +206,7 @@ func (g *IG) UpdateLatencyMulti(pong_info []mtypes.PongMsg, recalculate bool, ch
|
||||
g.edgelock.Unlock()
|
||||
oldval := g.OldWeight(u, v, false)
|
||||
g.edgelock.Lock()
|
||||
if oldval != mtypes.Infinity {
|
||||
if oldval != mtypes.Infinity && g.IsSuperMode && g.gsetting.DampingResistance > 0 {
|
||||
w = oldval*g.gsetting.DampingResistance + newval*(1-g.gsetting.DampingResistance)
|
||||
}
|
||||
should_update = should_update || g.ShouldUpdate(oldval, w, false)
|
||||
|
@ -100,10 +100,11 @@ func (tap *StdIOTap) Read(buf []byte, offset int) (int, error) {
|
||||
}
|
||||
} // read a packet from the device (without any additional headers)
|
||||
func (tap *StdIOTap) Write(buf []byte, offset int) (size int, err error) {
|
||||
packet := make([]byte, len(buf[offset:]))
|
||||
copy(packet, buf[offset:])
|
||||
packet := buf[offset:]
|
||||
switch tap.L2mode {
|
||||
case KeyboardDebug:
|
||||
packet = make([]byte, len(buf[offset:]))
|
||||
copy(packet, buf[offset:])
|
||||
src := Mac2charForm(packet[6:12])
|
||||
dst := Mac2charForm(packet[0:6])
|
||||
packet[10] = dst
|
||||
|
Loading…
Reference in New Issue
Block a user