Skip to content

Commit 25c9d5a

Browse files
ZhengYa-0110SongZhen0704
authored andcommitted
feat: encrypt agent cmd content
1 parent 1bc5a63 commit 25c9d5a

4 files changed

Lines changed: 93 additions & 7 deletions

File tree

server/controller/common/aes.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@ import (
2222
"crypto/aes"
2323
"crypto/cipher"
2424
"crypto/md5"
25+
"crypto/sha256"
2526
"encoding/base64"
2627
"errors"
2728
"fmt"
2829
"net"
2930
"os"
3031

32+
"golang.org/x/crypto/pbkdf2"
3133
"google.golang.org/grpc"
3234

3335
"github.com/deepflowio/deepflow/message/controller"
@@ -164,3 +166,8 @@ func getCAMD5() string {
164166
func GetCAMD5() string {
165167
return CAMD5
166168
}
169+
170+
func DerivePBKDF2Key(userID, orgID int) []byte {
171+
salt := fmt.Sprintf("%d", orgID) + "_deepflow"
172+
return pbkdf2.Key([]byte(fmt.Sprintf("%d", userID)), []byte(salt), 10000, 32, sha256.New)
173+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package common
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
)
7+
8+
func TestAesDecrypt(t *testing.T) {
9+
// Test data
10+
origData := "Hello, World!"
11+
key := "1234567890123456" // 16 bytes for AES-128
12+
13+
// Encrypt first
14+
encrypted, err := AesEncrypt(origData, key)
15+
if err != nil {
16+
t.Fatalf("AesEncrypt failed: %v", err)
17+
}
18+
fmt.Printf("Encrypted data: %s\n", encrypted)
19+
20+
// Now decrypt
21+
decrypted, err := AesDecrypt(encrypted, key)
22+
if err != nil {
23+
t.Fatalf("AesDecrypt failed: %v", err)
24+
}
25+
fmt.Printf("Decrypted data: %s\n", decrypted)
26+
27+
if decrypted != origData {
28+
t.Errorf("Expected %s, got %s", origData, decrypted)
29+
}
30+
}
31+
32+
func TestDerivePBKDF2Key(t *testing.T) {
33+
userID := 1
34+
orgID := 1
35+
36+
key := DerivePBKDF2Key(userID, orgID)
37+
fmt.Printf("Derived key: %x\n", key)
38+
39+
// Check length
40+
if len(key) != 32 {
41+
t.Errorf("Expected key length 32, got %d", len(key))
42+
}
43+
44+
// Test with different inputs
45+
key2 := DerivePBKDF2Key(2, 1)
46+
fmt.Printf("Derived key2: %x\n", key2)
47+
48+
if string(key) == string(key2) {
49+
t.Errorf("Keys should be different for different userIDs")
50+
}
51+
}

server/controller/http/router/agent/agent_cmd.go

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package agent
1818

1919
import (
2020
"bytes"
21+
"encoding/json"
2122
"errors"
2223
"fmt"
2324
"io"
@@ -27,7 +28,6 @@ import (
2728
"strconv"
2829

2930
"github.com/gin-gonic/gin"
30-
"github.com/gin-gonic/gin/binding"
3131

3232
grpcapi "github.com/deepflowio/deepflow/message/agent"
3333
"github.com/deepflowio/deepflow/server/controller/common"
@@ -263,8 +263,32 @@ func getAgentID(c *gin.Context, db *metadb.DB) (int, error) {
263263

264264
func (a *AgentCMD) cmdRunHandler() gin.HandlerFunc {
265265
return func(c *gin.Context) {
266+
userID, ok := c.Get(common.HEADER_KEY_X_USER_ID)
267+
if !ok {
268+
response.JSON(c, response.SetOptStatus(httpcommon.INVALID_PARAMETERS), response.SetError(fmt.Errorf("missing header %s", common.HEADER_KEY_X_USER_ID)))
269+
return
270+
}
271+
orgID, ok := c.Get(common.HEADER_KEY_X_ORG_ID)
272+
if !ok {
273+
response.JSON(c, response.SetOptStatus(httpcommon.INVALID_PARAMETERS), response.SetError(fmt.Errorf("missing header %s", common.HEADER_KEY_X_ORG_ID)))
274+
return
275+
}
276+
277+
cipherKey := string(common.DerivePBKDF2Key(userID.(int), orgID.(int)))
278+
rawPayload, err := io.ReadAll(c.Request.Body)
279+
if err != nil {
280+
response.JSON(c, response.SetOptStatus(httpcommon.INVALID_PARAMETERS), response.SetError(err))
281+
return
282+
}
283+
284+
decryptedPayload, err := common.AesDecrypt(string(rawPayload), cipherKey)
285+
if err != nil {
286+
response.JSON(c, response.SetOptStatus(httpcommon.INVALID_PARAMETERS), response.SetError(err))
287+
return
288+
}
289+
266290
req := service.RemoteExecReq{}
267-
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
291+
if err := json.Unmarshal([]byte(decryptedPayload), &req); err != nil {
268292
response.JSON(c, response.SetOptStatus(httpcommon.INVALID_PARAMETERS), response.SetError(err))
269293
return
270294
}
@@ -287,7 +311,6 @@ func (a *AgentCMD) cmdRunHandler() gin.HandlerFunc {
287311
Params: req.Params,
288312
}
289313

290-
orgID, _ := c.Get(common.HEADER_KEY_X_ORG_ID)
291314
db, err := metadb.GetDB(orgID.(int))
292315
if err != nil {
293316
response.JSON(c, response.SetError(err))
@@ -299,16 +322,21 @@ func (a *AgentCMD) cmdRunHandler() gin.HandlerFunc {
299322
return
300323
}
301324
content, err := service.RunAgentCMD(a.cfg.AgentCommandTimeout, orgID.(int), agentID, &agentReq, req.CMD)
325+
encryptedContent, encryptErr := common.AesEncrypt(content, cipherKey)
326+
if encryptErr != nil {
327+
response.JSON(c, response.SetData(content), response.SetOptStatus(httpcommon.SERVER_ERROR), response.SetError(encryptErr))
328+
return
329+
}
302330
if err != nil {
303-
response.JSON(c, response.SetData(content), response.SetOptStatus(httpcommon.SERVER_ERROR), response.SetError(err))
331+
response.JSON(c, response.SetData(encryptedContent), response.SetOptStatus(httpcommon.SERVER_ERROR), response.SetError(err))
304332
return
305333
}
306334

307335
if req.OutputFormat.String() == grpcapi.OutputFormat_TEXT.String() {
308-
response.JSON(c, response.SetData(content))
336+
response.JSON(c, response.SetData(encryptedContent))
309337
return
310338
}
311-
sendAsFile(c, req.OutputFilename, bytes.NewBuffer([]byte(content)))
339+
sendAsFile(c, req.OutputFilename, bytes.NewBuffer([]byte(encryptedContent)))
312340
}
313341
}
314342

server/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ require (
138138
go.opentelemetry.io/otel/sdk v1.43.0
139139
go.opentelemetry.io/otel/trace v1.43.0
140140
go.opentelemetry.io/proto/otlp v1.1.0
141+
golang.org/x/crypto v0.42.0
141142
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
142143
golang.org/x/net v0.43.0
143144
golang.org/x/sync v0.17.0
@@ -305,7 +306,6 @@ require (
305306
go4.org/intern v0.0.0-20211027215823-ae77deb06f29 // indirect
306307
go4.org/unsafe/assume-no-moving-gc v0.0.0-20231121144256-b99613f794b6 // indirect
307308
golang.org/x/arch v0.20.0 // indirect
308-
golang.org/x/crypto v0.42.0 // indirect
309309
golang.org/x/mod v0.27.0 // indirect
310310
golang.org/x/oauth2 v0.30.0 // indirect
311311
golang.org/x/term v0.35.0 // indirect

0 commit comments

Comments
 (0)