动态

详情 返回 返回

nginx證書緩存功能 - 动态 详情

本文分享自天翼雲開發者社區《nginx證書緩存功能》.作者:雲海

背景:

ssl證書之前是不支持公用的,不同的域名,如果引用同一本證書,是無法公用的,每個域名都要加載同一個證書,浪費內存

新版本:

在1.27.2版本中,nginx官方更新了ssl證書相關的實現,支持了ssl證書緩存共享。

實現原理:

在配置初始化時,初始了ssl證書緩存的紅黑樹:
ngx_openssl_cache_create_conf -> ngx_rbtree_init

在要獲取ssl證書時,通過如下接口獲取對應ssl證書:
ngx_ssl_cache_fetch
該接口的index參數可以傳遞不同的標記位,因為不同功能ssl證書有不同的創建釋放和引用增加處理
不同功能ssl證書有如下定義:
typedef struct {
    ngx_ssl_cache_create_pt     create;
    ngx_ssl_cache_free_pt       free;
    ngx_ssl_cache_ref_pt        ref;
} ngx_ssl_cache_type_t;

核心函數分析:
void *
ngx_ssl_cache_fetch(ngx_conf_t *cf, ngx_uint_t index, char **err,
    ngx_str_t *path, void *data)
{
    uint32_t               hash;              // 用於存儲計算出的哈希值
    ngx_ssl_cache_t       *cache;             // 指向 SSL 緩存的指針
    ngx_ssl_cache_key_t    id;                // 緩存鍵,用於標識特定緩存項
    ngx_ssl_cache_type_t  *type;              // 緩存類型對象指針
    ngx_ssl_cache_node_t  *cn;                // 指向緩存節點的指針

    // 初始化緩存鍵(如失敗則返回 NULL)
    if (ngx_ssl_cache_init_key(cf->pool, index, path, &id) != NGX_OK) {
        return NULL;
    }

    // 獲取全局的 SSL 緩存對象
    cache = (ngx_ssl_cache_t *) ngx_get_conf(cf->cycle->conf_ctx,
                                             ngx_openssl_cache_module);

    // 根據索引獲取對應的緩存類型
    type = &ngx_ssl_cache_types[index];

    // 計算緩存鍵的哈希值
    hash = ngx_murmur_hash2(id.data, id.len);

    // 在緩存中查找節點
    cn = ngx_ssl_cache_lookup(cache, type, &id, hash);
    if (cn != NULL) {
        // 如果找到節點,則調用類型的 ref 函數返回緩存值
        return type->ref(err, cn->value);
    }

    // 如果未找到,則分配一個新的緩存節點內存
    cn = ngx_palloc(cf->pool, sizeof(ngx_ssl_cache_node_t) + id.len + 1);
    if (cn == NULL) {
        return NULL; // 分配失敗,返回 NULL
    }

    // 初始化緩存節點的屬性
    cn->node.key = hash;                // 設置節點的哈希鍵
    cn->id.data = (u_char *)(cn + 1);   // 將 ID 數據存儲在分配內存之後
    cn->id.len = id.len;                // 設置 ID 長度
    cn->id.type = id.type;              // 設置 ID 類型
    cn->type = type;                    // 設置節點的類型指針

    // 複製緩存鍵數據
    ngx_cpystrn(cn->id.data, id.data, id.len + 1);

    // 調用類型的 create 函數創建緩存值
    cn->value = type->create(&id, err, data);
    if (cn->value == NULL) {
        return NULL; // 創建失敗,返回 NULL
    }

    // 將新節點插入到緩存的紅黑樹中
    ngx_rbtree_insert(&cache->rbtree, &cn->node);

    // 返回節點值的引用
    return type->ref(err, cn->value);
}


nginx官方此功能並沒有開關控制,是默認開啓的

Add a new 评论

Some HTML is okay.