Skip to content

Commit e487b3a

Browse files
committed
add: filter_grease option
1 parent ed2783b commit e487b3a

File tree

3 files changed

+21
-371
lines changed

3 files changed

+21
-371
lines changed

lib/ngx/ssl.lua

Lines changed: 12 additions & 344 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ if subsystem == 'http' then
123123
const unsigned char *ctx, size_t ctxlen, char **err);
124124

125125
int ngx_http_lua_ffi_req_shared_ssl_ciphers(ngx_http_request_t *r,
126-
unsigned short *ciphers, unsigned short *nciphers, char **err);
126+
unsigned short *ciphers, unsigned short *nciphers, int filter_grease, char **err);
127127

128128
typedef struct {
129129
uint16_t nciphers;
@@ -255,366 +255,34 @@ local intp = ffi.new("int[1]")
255255
local ushortp = ffi.new("unsigned short[1]")
256256

257257
do
258-
--https://datatracker.ietf.org/doc/html/rfc8701
259-
local TLS_GREASE = {
260-
[2570] = true,
261-
[6682] = true,
262-
[10794] = true,
263-
[14906] = true,
264-
[19018] = true,
265-
[23130] = true,
266-
[27242] = true,
267-
[31354] = true,
268-
[35466] = true,
269-
[39578] = true,
270-
[43690] = true,
271-
[47802] = true,
272-
[51914] = true,
273-
[56026] = true,
274-
[60138] = true,
275-
[64250] = true
276-
}
277-
278-
-- TLS cipher suite functionality
279-
local tls_proto_id = {
280-
-- TLS 1.3 ciphers
281-
[0x1301] = {
282-
iana_name = "TLS_AES_128_GCM_SHA256",
283-
tls_version = 1.3,
284-
kex = "any",
285-
auth = "any",
286-
enc = "AESGCM(128)",
287-
hash = "AEAD"
288-
},
289-
[0x1302] = {
290-
iana_name = "TLS_AES_256_GCM_SHA384",
291-
tls_version = 1.3,
292-
kex = "any",
293-
auth = "any",
294-
enc = "AESGCM(256)",
295-
hash = "AEAD"
296-
},
297-
[0x1303] = {
298-
iana_name = "TLS_CHACHA20_POLY1305_SHA256",
299-
tls_version = 1.3,
300-
kex = "any",
301-
auth = "any",
302-
enc = "CHACHA20/POLY1305(256)",
303-
hash = "AEAD"
304-
},
305-
[0x1304] = {
306-
iana_name = "TLS_AES_128_CCM_SHA256",
307-
tls_version = 1.3,
308-
kex = "none",
309-
auth = "none",
310-
enc = "AES 128 CCM",
311-
hash = "SHA256"
312-
},
313-
[0x1305] = {
314-
iana_name = "TLS_AES_128_CCM_8_SHA256",
315-
tls_version = 1.3,
316-
kex = "none",
317-
auth = "none",
318-
enc = "AES 128 CCM 8",
319-
hash = "SHA256"
320-
},
321-
-- TLS 1.2 ciphers (most common ones)
322-
[0xc02b] = {
323-
iana_name = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
324-
tls_version = 1.2,
325-
kex = "ECDH",
326-
auth = "ECDSA",
327-
enc = "AESGCM(128)",
328-
hash = "AEAD"
329-
},
330-
[0xc02f] = {
331-
iana_name = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
332-
tls_version = 1.2,
333-
kex = "ECDH",
334-
auth = "RSA",
335-
enc = "AESGCM(128)",
336-
hash = "AEAD"
337-
},
338-
[0xc02c] = {
339-
iana_name = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
340-
tls_version = 1.2,
341-
kex = "ECDH",
342-
auth = "ECDSA",
343-
enc = "AESGCM(256)",
344-
hash = "AEAD"
345-
},
346-
[0xc030] = {
347-
iana_name = "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
348-
tls_version = 1.2,
349-
kex = "ECDH",
350-
auth = "RSA",
351-
enc = "AESGCM(256)",
352-
hash = "AEAD"
353-
},
354-
[0x9f] = {
355-
iana_name = "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384",
356-
tls_version = 1.2,
357-
kex = "DH",
358-
auth = "RSA",
359-
enc = "AESGCM(256)",
360-
hash = "AEAD"
361-
},
362-
[0xcca9] = {
363-
iana_name = "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
364-
tls_version = 1.2,
365-
kex = "ECDH",
366-
auth = "ECDSA",
367-
enc = "CHACHA20/POLY1305(256)",
368-
hash = "AEAD"
369-
},
370-
[0xcca8] = {
371-
iana_name = "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
372-
tls_version = 1.2,
373-
kex = "ECDH",
374-
auth = "RSA",
375-
enc = "CHACHA20/POLY1305(256)",
376-
hash = "AEAD"
377-
},
378-
[0xccaa] = {
379-
iana_name = "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
380-
tls_version = 1.2,
381-
kex = "DH",
382-
auth = "RSA",
383-
enc = "CHACHA20/POLY1305(256)",
384-
hash = "AEAD"
385-
},
386-
[0x9e] = {
387-
iana_name = "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256",
388-
tls_version = 1.2,
389-
kex = "DH",
390-
auth = "RSA",
391-
enc = "AESGCM(128)",
392-
hash = "AEAD"
393-
},
394-
[0xc024] = {
395-
iana_name = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
396-
tls_version = 1.2,
397-
kex = "ECDH",
398-
auth = "ECDSA",
399-
enc = "AES(256)",
400-
hash = "SHA384"
401-
},
402-
[0xc028] = {
403-
iana_name = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
404-
tls_version = 1.2,
405-
kex = "ECDH",
406-
auth = "RSA",
407-
enc = "AES(256)",
408-
hash = "SHA384"
409-
},
410-
[0x6b] = {
411-
iana_name = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
412-
tls_version = 1.2,
413-
kex = "DH",
414-
auth = "RSA",
415-
enc = "AES(256)",
416-
hash = "SHA256"
417-
},
418-
[0xc023] = {
419-
iana_name = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
420-
tls_version = 1.2,
421-
kex = "ECDH",
422-
auth = "ECDSA",
423-
enc = "AES(128)",
424-
hash = "SHA256"
425-
},
426-
[0xc027] = {
427-
iana_name = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
428-
tls_version = 1.2,
429-
kex = "ECDH",
430-
auth = "RSA",
431-
enc = "AES(128)",
432-
hash = "SHA256"
433-
},
434-
[0x67] = {
435-
iana_name = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
436-
tls_version = 1.2,
437-
kex = "DH",
438-
auth = "RSA",
439-
enc = "AES(128)",
440-
hash = "SHA256"
441-
},
442-
[0xc00a] = {
443-
iana_name = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
444-
tls_version = 1.0,
445-
kex = "ECDH",
446-
auth = "ECDSA",
447-
enc = "AES(256)",
448-
hash = "SHA1"
449-
},
450-
[0xc014] = {
451-
iana_name = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
452-
tls_version = 1.0,
453-
kex = "ECDH",
454-
auth = "RSA",
455-
enc = "AES(256)",
456-
hash = "SHA1"
457-
},
458-
[0x39] = {
459-
iana_name = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
460-
tls_version = 0x0300,
461-
kex = "DH",
462-
auth = "RSA",
463-
enc = "AES(256)",
464-
hash = "SHA1"
465-
},
466-
[0xc009] = {
467-
iana_name = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
468-
tls_version = 1.0,
469-
kex = "ECDH",
470-
auth = "ECDSA",
471-
enc = "AES(128)",
472-
hash = "SHA1"
473-
},
474-
[0xc013] = {
475-
iana_name = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
476-
tls_version = 1.0,
477-
kex = "ECDH",
478-
auth = "RSA",
479-
enc = "AES(128)",
480-
hash = "SHA1"
481-
},
482-
[0x33] = {
483-
iana_name = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
484-
tls_version = 0x0300,
485-
kex = "DH",
486-
auth = "RSA",
487-
enc = "AES(128)",
488-
hash = "SHA1"
489-
},
490-
[0x9d] = {
491-
iana_name = "TLS_RSA_WITH_AES_256_GCM_SHA384",
492-
tls_version = 1.2,
493-
kex = "RSA",
494-
auth = "RSA",
495-
enc = "AESGCM(256)",
496-
hash = "AEAD"
497-
},
498-
[0x9c] = {
499-
iana_name = "TLS_RSA_WITH_AES_128_GCM_SHA256",
500-
tls_version = 1.2,
501-
kex = "RSA",
502-
auth = "RSA",
503-
enc = "AESGCM(128)",
504-
hash = "AEAD"
505-
},
506-
[0x3d] = {
507-
iana_name = "TLS_RSA_WITH_AES_256_CBC_SHA256",
508-
tls_version = 1.2,
509-
kex = "RSA",
510-
auth = "RSA",
511-
enc = "AES(256)",
512-
hash = "SHA256"
513-
},
514-
[0x3c] = {
515-
iana_name = "TLS_RSA_WITH_AES_128_CBC_SHA256",
516-
tls_version = 1.2,
517-
kex = "RSA",
518-
auth = "RSA",
519-
enc = "AES(128)",
520-
hash = "SHA256"
521-
},
522-
[0x35] = {
523-
iana_name = "TLS_RSA_WITH_AES_256_CBC_SHA",
524-
tls_version = 0x0300,
525-
kex = "RSA",
526-
auth = "RSA",
527-
enc = "AES(256)",
528-
hash = "SHA1"
529-
},
530-
[0x2f] = {
531-
iana_name = "TLS_RSA_WITH_AES_128_CBC_SHA",
532-
tls_version = 0x0300,
533-
kex = "RSA",
534-
auth = "RSA",
535-
enc = "AES(128)",
536-
hash = "SHA1"
537-
},
538-
-- 其他 PSK、SRP、RSA-PSK、DHE-PSK、ECDHE-PSK 可继续补充
539-
-- ...
540-
}
541-
542-
local unknown_cipher = {
543-
iana_name = "UNKNOWN",
544-
tls_version = 0,
545-
kex = "UNKNOWN",
546-
auth = "UNKNOWN",
547-
enc = "UNKNOWN",
548-
hash = "UNKNOWN"
549-
}
550-
551-
setmetatable(tls_proto_id, {
552-
__index = function(t, k)
553-
t[k] = unknown_cipher
554-
return unknown_cipher
555-
end
556-
})
557-
558-
-- Iterator function for ciphers
559-
local function iterate_ciphers(ciphers, n)
560-
if n < ciphers.nciphers then
561-
return n + 1, tls_proto_id[ciphers.ciphers[n]]
562-
end
563-
end
564-
565-
-- Buffer for temporary cipher table conversion
566-
local ciphers_t = {}
567-
568-
-- Metatype for cipher structure
569-
ffi.metatype('ngx_lua_ssl_ciphers', {
570-
__ipairs = function(ciphers)
571-
return iterate_ciphers, ciphers, 0
572-
end,
573-
__tostring = function(ciphers)
574-
for n, c in ipairs(ciphers) do
575-
ciphers_t[n] = type(c) == "table" and c.iana_name or
576-
format("0x%.4x", c)
577-
end
578-
return concat(ciphers_t, ":", 1, ciphers.nciphers)
579-
end
580-
})
581-
582-
-- Cipher type and buffer
583-
local ciphers_typ = ffi_typeof("ngx_lua_ssl_ciphers")
584258
local ciphers_buf = ffi_new("uint16_t [?]", 256)
585259

586-
function _M.get_shared_ssl_ciphers()
260+
function _M.get_shared_ssl_ciphers(filter_grease)
587261
local r = get_request()
588262
if not r then
589263
error("no request found")
590264
end
591265

266+
if filter_grease == nil then
267+
filter_grease = true -- Default to filter GREASE
268+
end
269+
592270
ciphers_buf[0] = 255 -- Set max number of ciphers we can hold
271+
local filter_flag = filter_grease and 1 or 0
593272
local rc = ngx_lua_ffi_req_shared_ssl_ciphers(r, ciphers_buf + 1,
594-
ciphers_buf, errmsg)
273+
ciphers_buf, filter_flag, errmsg)
595274
if rc ~= FFI_OK then
596275
return nil, ffi_str(errmsg[0])
597276
end
598277

599-
-- Filter out GREASE ciphers
600-
local filtered_count = 0
601-
local filtered_buf = ffi_new("uint16_t [?]", ciphers_buf[0] + 1)
602-
278+
-- Build result table
279+
local result = {}
603280
for i = 1, ciphers_buf[0] do
604281
local cipher_id = ciphers_buf[i]
605-
if not TLS_GREASE[cipher_id] then
606-
filtered_buf[filtered_count + 1] = cipher_id
607-
filtered_count = filtered_count + 1
608-
end
282+
result[#result + 1] = cipher_id
609283
end
610-
filtered_buf[0] = filtered_count
611-
612-
-- Create the cipher structure
613-
local ciphers = ciphers_typ(filtered_count)
614-
ffi_copy(ciphers, filtered_buf,
615-
(filtered_count + 1) * ffi_sizeof('uint16_t'))
616284

617-
return ciphers
285+
return result
618286
end
619287
end
620288

0 commit comments

Comments
 (0)