feat: support ssl key-encrypt-salt rotation#7925
Conversation
| key_encrypt_salt: edd1c9f0985e76a2 # If not set, will save origin ssl key into etcd. | ||
| # If set this, must be a string of length 16. And it will encrypt ssl key with AES-128-CBC | ||
| # !!! So do not change it after saving your ssl, it can't decrypt the ssl keys have be saved if you change !! | ||
| key_encrypt_salt: # If not set, will save origin ssl key into etcd. |
There was a problem hiding this comment.
it's backward compatible, we could use 2 ways at the same time
There was a problem hiding this comment.
I have test case about this case
| local aes_with_iv = assert(aes:new(iv, nil, aes.cipher(128, "cbc"), {iv = iv})) | ||
| core.table.insert(_aes_128_cbc_with_iv_tbl, aes_with_iv) | ||
| else | ||
| core.log.error("the key_encrypt_salt does not meet the " |
There was a problem hiding this comment.
We can use , instead of .. as separator
| if not decrypted then | ||
| core.log.error("decrypt ssl key failed. key[", key, "] ") | ||
| local aes_128_cbc_with_iv_tbl = get_aes_128_cbc_with_iv() | ||
| if core.table.isempty(aes_128_cbc_with_iv_tbl) then |
There was a problem hiding this comment.
Use # would be better as the table must be array
| ngx.say(body) | ||
| } | ||
| } | ||
| --- request |
There was a problem hiding this comment.
Let's move the common part to the top like other test files
|
|
||
| if type_ivs == "table" then | ||
| for index, iv in ipairs(ivs) do | ||
| if type(iv) == "string" and #iv == 16 then |
There was a problem hiding this comment.
Better to check this via schema in https://github.com/apache/apisix/blob/master/apisix/cli/schema.lua
| key_encrypt_salt: # If not set, will save origin ssl key into etcd. | ||
| - edd1c9f0985e76a2 # If set this, must be a string of length 16. And it will encrypt ssl key with AES-128-CBC | ||
| # !!! So do not change it after saving your ssl, it can't decrypt the ssl keys have be saved if you change !! | ||
| # Only use the first key to encrypt, and decrypt in the order of the array. |
There was a problem hiding this comment.
The comment is not accurate to describe the field, since the comment says it "must be a string of length 16".
There was a problem hiding this comment.
The comment is still wrong.
The key_encrypt_salt should either be a string whose size is 16 or an array whose elements are string, and the size is also 16.
There was a problem hiding this comment.
Should we only recommend using array?
There was a problem hiding this comment.
I'm updating this to a hexadecimal string of length 16. It's technically a 8 byte value in hex representation. Size isn't accurate.
| key_encrypt_salt = { | ||
| anyOf = { | ||
| { | ||
| type = "array", |
There was a problem hiding this comment.
Let's add length check for the array
There was a problem hiding this comment.
minItems = 1? why need this check?
| maxLength = 16 | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
Why add an extra blank line?
| local aes_with_iv = assert(aes:new(iv, nil, aes.cipher(128, "cbc"), {iv = iv})) | ||
| core.table.insert(_aes_128_cbc_with_iv_tbl, aes_with_iv) | ||
| end | ||
| elseif type_ivs == "string" and #ivs == 16 then |
There was a problem hiding this comment.
We can remove the #ivs == 16 check as we already checked it in the schema.
| node_listen: 1984 | ||
| ssl: | ||
| key_encrypt_salt: "edd1c9f0985e76a1" | ||
| --- response_body eval |
There was a problem hiding this comment.
The judgment of the response body does not seem necessary.
There was a problem hiding this comment.
Just a double check, i prefer to leave it there
| while true do | ||
| local line, err = sock:receive() | ||
| if not line then | ||
| -- ngx.say("failed to receive response status line: ", err) |
There was a problem hiding this comment.
Please remove redundant comments.
| } | ||
| }, | ||
| key_encrypt_salt = { | ||
| anyOf = { |
There was a problem hiding this comment.
I know anyOf can satisfy the schema check but it should be oneOf in this scene?
There was a problem hiding this comment.
But this is the conventional way in APISIX, it's used everywhere, so i think i should follow this.
| key_encrypt_salt: # If not set, will save origin ssl key into etcd. | ||
| - edd1c9f0985e76a2 # If set this, must be a string of length 16. And it will encrypt ssl key with AES-128-CBC | ||
| # !!! So do not change it after saving your ssl, it can't decrypt the ssl keys have be saved if you change !! | ||
| # Only use the first key to encrypt, and decrypt in the order of the array. |
There was a problem hiding this comment.
The comment is still wrong.
The key_encrypt_salt should either be a string whose size is 16 or an array whose elements are string, and the size is also 16.
|
|
||
|
|
||
| local _aes_128_cbc_with_iv = false | ||
| local _aes_128_cbc_with_iv_tbl = false |
There was a problem hiding this comment.
Better to avoid using boolean value as the default value of a table?
…nkeyDluffy6017/apisix into support-ssl-key-encrypt-salt-rotation
Description
Currently, the key_encryption_salt cannot be changed once users use it to encrypt the private key, otherwise, Apache APISIX cannot decrypt the private key correctly. This may become a pain point when the user leaks the salt.
As a user, I can configure multiple key_encryption_salt for Apache APISIX, and Apache APISIX will use them to decrypt private keys in turn
Checklist