Skip to content

Commit c613cdb

Browse files
authored
feat: support alter key expiration time. (#34390)
1 parent 059f51d commit c613cdb

File tree

18 files changed

+348
-15
lines changed

18 files changed

+348
-15
lines changed

include/common/tglobal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ extern int32_t tsEncryptKeyVersion; // Key update version (starts from 1,
220220
extern int64_t tsEncryptKeyCreateTime; // Key creation timestamp
221221
extern int64_t tsSvrKeyUpdateTime; // SVR_KEY last update timestamp
222222
extern int64_t tsDbKeyUpdateTime; // DB_KEY last update timestamp
223+
extern int32_t tsKeyExpirationDays; // Key expiration days (default: 30)
224+
extern char tsKeyExpirationStrategy[ENCRYPT_KEY_EXPIRE_STRATEGY_LEN + 1]; // Key expiration strategy (default: "ALARM")
223225

224226
// monitor
225227
extern bool tsEnableMonitor;

include/common/tmsg.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,8 @@ typedef enum ENodeType {
437437
QUERY_NODE_ALTER_ROLE_STMT,
438438
QUERY_NODE_CREATE_TOTP_SECRET_STMT,
439439
QUERY_NODE_DROP_TOTP_SECRET_STMT,
440+
QUERY_NODE_ALTER_KEY_EXPIRATION_STMT,
441+
440442

441443
// placeholder for [155, 180]
442444
QUERY_NODE_SHOW_CREATE_VIEW_STMT = 181,
@@ -3502,6 +3504,17 @@ int32_t tSerializeSMAlterEncryptKeyReq(void* buf, int32_t bufLen, SMAlterEncrypt
35023504
int32_t tDeserializeSMAlterEncryptKeyReq(void* buf, int32_t bufLen, SMAlterEncryptKeyReq* pReq);
35033505
void tFreeSMAlterEncryptKeyReq(SMAlterEncryptKeyReq* pReq);
35043506

3507+
typedef struct {
3508+
int32_t days;
3509+
char strategy[64];
3510+
int32_t sqlLen;
3511+
char* sql;
3512+
} SMAlterKeyExpirationReq;
3513+
3514+
int32_t tSerializeSMAlterKeyExpirationReq(void* buf, int32_t bufLen, SMAlterKeyExpirationReq* pReq);
3515+
int32_t tDeserializeSMAlterKeyExpirationReq(void* buf, int32_t bufLen, SMAlterKeyExpirationReq* pReq);
3516+
void tFreeSMAlterKeyExpirationReq(SMAlterKeyExpirationReq* pReq);
3517+
35053518
typedef struct {
35063519
char config[TSDB_DNODE_CONFIG_LEN];
35073520
char value[TSDB_DNODE_VALUE_LEN];

include/common/tmsgdef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
TD_DEF_MSG_TYPE(TDMT_MND_ALTER_ENCRYPT_KEY, "alter-encrypt-key", NULL, NULL)
162162
TD_DEF_MSG_TYPE(TDMT_MND_CREATE_TOTP_SECRET, "create-totp-secret", NULL, NULL)
163163
TD_DEF_MSG_TYPE(TDMT_MND_DROP_TOTP_SECRET, "drop-totp-secret", NULL, NULL)
164+
TD_DEF_MSG_TYPE(TDMT_MND_ALTER_KEY_EXPIRATION, "alter-key-expiration", NULL, NULL)
164165
TD_CLOSE_MSG_SEG(TDMT_DND_MSG)
165166

166167
TD_NEW_MSG_SEG(TDMT_MND_MSG) // 1<<8

include/libs/nodes/cmdnodes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,12 @@ typedef struct SAlterEncryptKeyStmt {
10031003
char newKey[ENCRYPT_KEY_LEN + 1];
10041004
} SAlterEncryptKeyStmt;
10051005

1006+
typedef struct SAlterKeyExpirationStmt {
1007+
ENodeType type;
1008+
int32_t days;
1009+
char strategy[ENCRYPT_KEY_EXPIRE_STRATEGY_LEN + 1];
1010+
} SAlterKeyExpirationStmt;
1011+
10061012
typedef struct SDescribeStmt {
10071013
ENodeType type;
10081014
char dbName[TSDB_DB_NAME_LEN];

include/util/tdef.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ typedef enum ELogicConditionType {
242242
#define ENCRYPT_KEY_LEN 16
243243
#define ENCRYPT_KEY_LEN_MIN 8
244244

245+
#define ENCRYPT_KEY_EXPIRE_STRATEGY_LEN 16
246+
245247
#define TSDB_INT32_ID_LEN 11
246248

247249
#define TSDB_NAME_DELIMITER_LEN 1

source/common/src/msg/tmsg.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5985,6 +5985,48 @@ int32_t tDeserializeSMAlterEncryptKeyReq(void *buf, int32_t bufLen, SMAlterEncry
59855985

59865986
void tFreeSMAlterEncryptKeyReq(SMAlterEncryptKeyReq *pReq) { FREESQL(); }
59875987

5988+
int32_t tSerializeSMAlterKeyExpirationReq(void *buf, int32_t bufLen, SMAlterKeyExpirationReq *pReq) {
5989+
SEncoder encoder = {0};
5990+
int32_t code = 0;
5991+
int32_t lino;
5992+
int32_t tlen;
5993+
tEncoderInit(&encoder, buf, bufLen);
5994+
5995+
TAOS_CHECK_EXIT(tStartEncode(&encoder));
5996+
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pReq->days));
5997+
TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pReq->strategy));
5998+
ENCODESQL();
5999+
tEndEncode(&encoder);
6000+
6001+
_exit:
6002+
if (code) {
6003+
tlen = code;
6004+
} else {
6005+
tlen = encoder.pos;
6006+
}
6007+
tEncoderClear(&encoder);
6008+
return tlen;
6009+
}
6010+
6011+
int32_t tDeserializeSMAlterKeyExpirationReq(void *buf, int32_t bufLen, SMAlterKeyExpirationReq *pReq) {
6012+
SDecoder decoder = {0};
6013+
int32_t code = 0;
6014+
int32_t lino;
6015+
tDecoderInit(&decoder, buf, bufLen);
6016+
6017+
TAOS_CHECK_EXIT(tStartDecode(&decoder));
6018+
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &pReq->days));
6019+
TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, pReq->strategy));
6020+
DECODESQL();
6021+
tEndDecode(&decoder);
6022+
6023+
_exit:
6024+
tDecoderClear(&decoder);
6025+
return code;
6026+
}
6027+
6028+
void tFreeSMAlterKeyExpirationReq(SMAlterKeyExpirationReq *pReq) { FREESQL(); }
6029+
59886030
int32_t tSerializeSDCfgDnodeReq(void *buf, int32_t bufLen, SDCfgDnodeReq *pReq) {
59896031
SEncoder encoder = {0};
59906032
int32_t code = 0;

source/common/src/tglobal.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ int32_t tsEncryptKeyVersion = 0; // Key update version (starts from 1, in
203203
int64_t tsEncryptKeyCreateTime = 0; // Key creation timestamp
204204
int64_t tsSvrKeyUpdateTime = 0; // SVR_KEY last update timestamp
205205
int64_t tsDbKeyUpdateTime = 0; // DB_KEY last update timestamp
206+
int32_t tsKeyExpirationDays = 30; // Key expiration days (default: 30)
207+
char tsKeyExpirationStrategy[ENCRYPT_KEY_EXPIRE_STRATEGY_LEN + 1] =
208+
"ALARM"; // Key expiration strategy (default: "ALARM")
206209
uint32_t tsGrant = 1;
207210

208211
bool tsCompareAsStrInGreatest = true;

source/dnode/mgmt/mgmt_dnode/inc/dmInt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ int32_t dmProcessGrantReq(void *pInfo, SRpcMsg *pMsg);
7474
int32_t dmProcessGrantNotify(void *pInfo, SRpcMsg *pMsg);
7575
int32_t dmProcessCreateEncryptKeyReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
7676
int32_t dmProcessAlterEncryptKeyReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
77+
int32_t dmProcessAlterKeyExpirationReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);
7778
int32_t dmVerifyAndInitEncryptionKeys(void);
7879

7980
int32_t dmProcessReloadTlsConfig(SDnodeMgmt *pMgmt, SRpcMsg *pMsg);

source/dnode/mgmt/mgmt_dnode/src/dmHandle.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,30 @@ static int32_t dmUpdateSvrKey(const char *newKey) {
13191319
return 0;
13201320
}
13211321

1322+
static int32_t dmUpdateKeyExpiration(int32_t days, const char *strategy) {
1323+
if (days < 0) {
1324+
dError("invalid days value:%d, must be >= 0", days);
1325+
return TSDB_CODE_INVALID_PARA;
1326+
}
1327+
1328+
if (strategy == NULL || strategy[0] == '\0') {
1329+
dError("invalid strategy, strategy is empty");
1330+
return TSDB_CODE_INVALID_PARA;
1331+
}
1332+
1333+
// Validate strategy value
1334+
if (strcmp(strategy, "ALARM") != 0) {
1335+
dWarn("unknown strategy:%s, supported values: ALARM. Will use it anyway.", strategy);
1336+
}
1337+
1338+
// Update global variables directly
1339+
tsKeyExpirationDays = days;
1340+
tstrncpy(tsKeyExpirationStrategy, strategy, sizeof(tsKeyExpirationStrategy));
1341+
1342+
dInfo("successfully updated key expiration config: days=%d, strategy=%s", days, strategy);
1343+
return 0;
1344+
}
1345+
13221346
static int32_t dmUpdateDbKey(const char *newKey) {
13231347
if (newKey == NULL || newKey[0] == '\0') {
13241348
dError("invalid new DB_KEY, key is empty");
@@ -1467,6 +1491,41 @@ int32_t dmProcessAlterEncryptKeyReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
14671491
#endif
14681492
}
14691493

1494+
int32_t dmProcessAlterKeyExpirationReq(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
1495+
#if defined(TD_ENTERPRISE) && defined(TD_HAS_TAOSK)
1496+
int32_t code = 0;
1497+
SMAlterKeyExpirationReq alterReq = {0};
1498+
if (tDeserializeSMAlterKeyExpirationReq(pMsg->pCont, pMsg->contLen, &alterReq) != 0) {
1499+
code = TSDB_CODE_INVALID_MSG;
1500+
dError("failed to deserialize alter key expiration req, since %s", tstrerror(code));
1501+
goto _exit;
1502+
}
1503+
1504+
dInfo("received alter key expiration req, days:%d, strategy:%s", alterReq.days, alterReq.strategy);
1505+
1506+
// Update key expiration configuration
1507+
code = dmUpdateKeyExpiration(alterReq.days, alterReq.strategy);
1508+
if (code == 0) {
1509+
dInfo("successfully updated key expiration: %d days, strategy: %s", alterReq.days, alterReq.strategy);
1510+
} else {
1511+
dError("failed to update key expiration, since %s", tstrerror(code));
1512+
}
1513+
1514+
_exit:
1515+
tFreeSMAlterKeyExpirationReq(&alterReq);
1516+
pMsg->code = code;
1517+
pMsg->info.rsp = NULL;
1518+
pMsg->info.rspLen = 0;
1519+
return code;
1520+
#else
1521+
dError("key expiration management is only available in enterprise edition");
1522+
pMsg->code = TSDB_CODE_OPS_NOT_SUPPORT;
1523+
pMsg->info.rsp = NULL;
1524+
pMsg->info.rspLen = 0;
1525+
return TSDB_CODE_OPS_NOT_SUPPORT;
1526+
#endif
1527+
}
1528+
14701529
int32_t dmProcessReloadTlsConfig(SDnodeMgmt *pMgmt, SRpcMsg *pMsg) {
14711530
int32_t code = 0;
14721531
int32_t lino = 0;
@@ -1756,6 +1815,7 @@ SArray *dmGetMsgHandles() {
17561815
if (dmSetMgmtHandle(pArray, TDMT_DND_ALTER_MNODE_TYPE, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER;
17571816
if (dmSetMgmtHandle(pArray, TDMT_DND_CREATE_ENCRYPT_KEY, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER;
17581817
if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_ENCRYPT_KEY, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER;
1818+
if (dmSetMgmtHandle(pArray, TDMT_MND_ALTER_KEY_EXPIRATION, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER;
17591819
if (dmSetMgmtHandle(pArray, TDMT_MND_STREAM_HEARTBEAT_RSP, dmPutMsgToStreamMgmtQueue, 0) == NULL) goto _OVER;
17601820
if (dmSetMgmtHandle(pArray, TDMT_DND_RELOAD_DNODE_TLS, dmPutNodeMsgToMgmtQueue, 0) == NULL) goto _OVER;
17611821

source/dnode/mgmt/mgmt_dnode/src/dmWorker.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
#endif
2424

2525
// Encryption key expiration constants
26-
#define ENCRYPT_KEY_EXPIRE_DAYS 30
27-
#define MILLISECONDS_PER_DAY (24 * 3600 * 1000)
28-
#define ENCRYPT_KEY_EXPIRE_THRESHOLD ((int64_t)ENCRYPT_KEY_EXPIRE_DAYS * MILLISECONDS_PER_DAY)
26+
#define MILLISECONDS_PER_DAY (24 * 3600 * 1000)
2927

3028
static void *dmStatusThreadFp(void *param) {
3129
SDnodeMgmt *pMgmt = param;
@@ -85,14 +83,17 @@ static void *dmKeySyncThreadFp(void *param) {
8583
if (interval >= tsStatusIntervalMs) {
8684
// Sync keys periodically (every 30 seconds) or on first run
8785
if (tsEncryptKeysStatus == TSDB_ENCRYPT_KEY_STAT_LOADED) {
88-
// Check if encryption keys are expired
86+
// Check if encryption keys are expired based on configured threshold
87+
int64_t keyExpirationThreshold = (int64_t)tsKeyExpirationDays * MILLISECONDS_PER_DAY;
8988
int64_t svrKeyAge = curTime - tsSvrKeyUpdateTime;
9089
int64_t dbKeyAge = curTime - tsDbKeyUpdateTime;
9190

92-
if (svrKeyAge > ENCRYPT_KEY_EXPIRE_THRESHOLD || dbKeyAge > ENCRYPT_KEY_EXPIRE_THRESHOLD) {
93-
dWarn("encryption keys may be expired, svrKeyAge:%" PRId64 " days, dbKeyAge:%" PRId64
94-
" days, attempting reload",
95-
svrKeyAge / MILLISECONDS_PER_DAY, dbKeyAge / MILLISECONDS_PER_DAY);
91+
if (svrKeyAge > keyExpirationThreshold || dbKeyAge > keyExpirationThreshold) {
92+
const char *action = (strcmp(tsKeyExpirationStrategy, "ALARM") == 0) ? "warning" : "attempting reload";
93+
dWarn("encryption keys may be expired (threshold:%d days, strategy:%s), svrKeyAge:%" PRId64
94+
" days, dbKeyAge:%" PRId64 " days, %s",
95+
tsKeyExpirationDays, tsKeyExpirationStrategy, svrKeyAge / MILLISECONDS_PER_DAY,
96+
dbKeyAge / MILLISECONDS_PER_DAY, action);
9697
#if defined(TD_ENTERPRISE) && defined(TD_HAS_TAOSK)
9798
// Try to reload keys from file
9899
char masterKeyFile[PATH_MAX] = {0};
@@ -139,19 +140,20 @@ static void *dmKeySyncThreadFp(void *param) {
139140
// Check if keys are still expired after reload
140141
svrKeyAge = curTime - tsSvrKeyUpdateTime;
141142
dbKeyAge = curTime - tsDbKeyUpdateTime;
142-
if (svrKeyAge > ENCRYPT_KEY_EXPIRE_THRESHOLD || dbKeyAge > ENCRYPT_KEY_EXPIRE_THRESHOLD) {
143-
dError("encryption keys are still expired after reload, svrKeyAge:%" PRId64 " days, dbKeyAge:%" PRId64
144-
" days, please rotate keys",
145-
svrKeyAge / MILLISECONDS_PER_DAY, dbKeyAge / MILLISECONDS_PER_DAY);
143+
if (svrKeyAge > keyExpirationThreshold || dbKeyAge > keyExpirationThreshold) {
144+
dError("encryption keys are still expired after reload (threshold:%d days), svrKeyAge:%" PRId64
145+
" days, dbKeyAge:%" PRId64 " days, please rotate keys",
146+
tsKeyExpirationDays, svrKeyAge / MILLISECONDS_PER_DAY, dbKeyAge / MILLISECONDS_PER_DAY);
146147
} else {
147-
dInfo("successfully reloaded encryption keys, svrKeyAge:%" PRId64 " days, dbKeyAge:%" PRId64 " days",
148-
svrKeyAge / MILLISECONDS_PER_DAY, dbKeyAge / MILLISECONDS_PER_DAY);
148+
dInfo("successfully reloaded encryption keys, svrKeyAge:%" PRId64 " days, dbKeyAge:%" PRId64
149+
" days (threshold:%d days)",
150+
svrKeyAge / MILLISECONDS_PER_DAY, dbKeyAge / MILLISECONDS_PER_DAY, tsKeyExpirationDays);
149151
}
150152
} else {
151153
dError("failed to reload encryption keys since %s", tstrerror(code));
152154
}
153155
#endif
154-
}
156+
}
155157
} else if (tsEncryptKeysStatus == TSDB_ENCRYPT_KEY_STAT_DISABLED) {
156158
dInfo("encryption keys are disabled, stopping key sync thread");
157159
break;
@@ -767,6 +769,9 @@ static void dmProcessMgmtQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
767769
case TDMT_MND_ALTER_ENCRYPT_KEY:
768770
code = dmProcessAlterEncryptKeyReq(pMgmt, pMsg);
769771
break;
772+
case TDMT_MND_ALTER_KEY_EXPIRATION:
773+
code = dmProcessAlterKeyExpirationReq(pMgmt, pMsg);
774+
break;
770775
case TDMT_DND_RELOAD_DNODE_TLS:
771776
code = dmProcessReloadTlsConfig(pMgmt, pMsg);
772777
// code = dmProcessReloadEncryptKeyReq(pMgmt, pMsg);

0 commit comments

Comments
 (0)