感谢支持
我们一直在努力

Linux安全体系学习笔记

最近在读倪继利的《Linux安全体系分析与编程》,想把一些笔记发出来,这是第一篇。


Linux的日志系统主要就是syslog系统构架,其实现是内核函数printk将消息写入一个环形缓冲区中,供高层的sys_syslog系统调用读取。代码部分在linux/kernel/printk.c


相关链接:http://lxr.linux.no/linux+v3.1.6/kernel/audit.c


Linux的审核系统提供了一种记录系统安全信息的方法,为系统管理员在用户违反系统安全规则时提供及时的警告信息。内核其他线程通过内核审计API写入套接字缓冲区队列audit_skb_queue中,内核线程kauditd通过netlink机制将审计消息定向发送给用户控件的审计后台auditd的主线程,auditd主线程再通过事件队列将审计消息传给审计后台的写log文件线程,写入log文件。另一方面,审计后台还通过一个与套接字绑定的管道将审计消息发送给dispatcher应用程序。代码部分主要在 linux/kernel/audit.c 


auditd在Debian里默认没有安装启动,需要通过aptitude install auditd开启。


《Linux安全体系分析与编程》部分章节下载见 http://www.linuxidc.com/Linux/2012-02/53191.htm

OpenSSL的源代码包括三部分:加密算法库、SSL库和应用程序。


加密算法库的源代码主要在crypto文件夹里,包括ASN.1编码与解码接口(crypto/asn1/asn1.h),伪随机数产生器(crypto/rand/rand.h),ENGINE机制(crypto/engine),统一密码算法的EVP密码算法接口(crypto/evp/evp.h),大数运算接口(crypto/bn/bn.h),私钥信息语法(crypto/x509/x509.h),非对称密码算法(crypto/rsa/ras.h)等。


SSL库的源代码主要在ssl文件夹里,我们重点分析。


SSL相关的几个重要的数据结构包括:


1、SSL连接结构:核心结构,应用程序通过该结构获取所有其他结构。


2、上下文结构SSL_CTX:是全局的上下文结构,含有结构SSL的主要默认值,包含SSL会话结构。


3、会话结构SSL_SESSION:含有链接的当前TLS/SSL会话细节。


4、密码结构SSL_CIPHER:含有制定的加密算法信息。


5、方法结构SSL_METHOD:功能函数接口,统一了各种SSL协议版本(SSLv1, SSLv2, SSLv3, TLSv1)。


SSL连接结构列出如下:


[cpp]


  1. struct ssl_st  

  2.     {  

  3.     /* protocol version 

  4.      * (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, DTLS1_VERSION) 

  5.      */  

  6.     int version;  

  7.     int type; /* SSL_ST_CONNECT or SSL_ST_ACCEPT */  

  8.   

  9.     const SSL_METHOD *method; /* SSLv3 */  

  10.   

  11.     /* There are 2 BIO’s even though they are normally both the 

  12.      * same.  This is so data can be read and written to different 

  13.      * handlers */  

  14.   

  15. #ifndef OPENSSL_NO_BIO   

  16.     BIO *rbio; /* used by SSL_read */  

  17.     BIO *wbio; /* used by SSL_write */  

  18.     BIO *bbio; /* used during session-id reuse to concatenate 

  19.             * messages */  

  20. #else   

  21.     char *rbio; /* used by SSL_read */  

  22.     char *wbio; /* used by SSL_write */  

  23.     char *bbio;  

  24. #endif   

  25.     /* This holds a variable that indicates what we were doing 

  26.      * when a 0 or -1 is returned.  This is needed for 

  27.      * non-blocking IO so we know what request needs re-doing when 

  28.      * in SSL_accept or SSL_connect */  

  29.     int rwstate;  

  30.   

  31.     /* true when we are actually in SSL_accept() or SSL_connect() */  

  32.     int in_handshake;  

  33.     int (*handshake_func)(SSL *);  

  34.   

  35.     /* Imagine that here’s a boolean member “init” that is 

  36.      * switched as soon as SSL_set_{accept/connect}_state 

  37.      * is called for the first time, so that “state” and 

  38.      * “handshake_func” are properly initialized.  But as 

  39.      * handshake_func is == 0 until then, we use this 

  40.      * test instead of an “init” member. 

  41.      */  

  42.   

  43.     int server; /* are we the server side? – mostly used by SSL_clear*/  

  44.   

  45.     int new_session;/* 1 if we are to use a new session. 

  46.                      * 2 if we are a server and are inside a handshake 

  47.                      *   (i.e. not just sending a HelloRequest) 

  48.                      * NB: For servers, the ‘new’ session may actually be a previously 

  49.                      * cached session or even the previous session unless 

  50.                      * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set */  

  51.     int quiet_shutdown;/* don’t send shutdown packets */  

  52.     int shutdown;   /* we have shut things down, 0x01 sent, 0x02 

  53.              * for received */  

  54.     int state;  /* where we are */  

  55.     int rstate; /* where we are when reading */  

  56.   

  57.     BUF_MEM *init_buf;  /* buffer used during init */  

  58.     void *init_msg;     /* pointer to handshake message body, set by ssl3_get_message() */  

  59.     int init_num;       /* amount read/written */  

  60.     int init_off;       /* amount read/written */  

  61.   

  62.     /* used internally to point at a raw packet */  

  63.     unsigned char *packet;  

  64.     unsigned int packet_length;  

  65.   

  66.     struct ssl2_state_st *s2; /* SSLv2 variables */  

  67.     struct ssl3_state_st *s3; /* SSLv3 variables */  

  68.     struct dtls1_state_st *d1; /* DTLSv1 variables */  

  69.   

  70.     int read_ahead;     /* Read as many input bytes as possible 

  71.                          * (for non-blocking reads) */  

  72.   

  73.     /* callback that allows applications to peek at protocol messages */  

  74.     void (*msg_callback)(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);  

  75.     void *msg_callback_arg;  

  76.   

  77.     int hit;        /* reusing a previous session */  

  78.   

  79.     X509_VERIFY_PARAM *param;  

  80.   

  81. #if 0   

  82.     int purpose;        /* Purpose setting */  

  83.     int trust;      /* Trust setting */  

  84. #endif   

  85.   

  86.     /* crypto */  

  87.     STACK_OF(SSL_CIPHER) *cipher_list;  

  88.     STACK_OF(SSL_CIPHER) *cipher_list_by_id;  

  89.   

  90.     /* These are the ones being used, the ones in SSL_SESSION are 

  91.      * the ones to be ‘copied’ into these ones */  

  92.     int mac_flags;   

  93.     EVP_CIPHER_CTX *enc_read_ctx;       /* cryptographic state */  

  94.     EVP_MD_CTX *read_hash;      /* used for mac generation */  

  95. #ifndef OPENSSL_NO_COMP   

  96.     COMP_CTX *expand;           /* uncompress */  

  97. #else   

  98.     char *expand;  

  99. #endif   

  100.   

  101.     EVP_CIPHER_CTX *enc_write_ctx;      /* cryptographic state */  

  102.     EVP_MD_CTX *write_hash;     /* used for mac generation */  

  103. #ifndef OPENSSL_NO_COMP   

  104.     COMP_CTX *compress;         /* compression */  

  105. #else   

  106.     char *compress;   

  107. #endif   

  108.   

  109.     /* session info */  

  110.   

  111.     /* client cert? */  

  112.     /* This is used to hold the server certificate used */  

  113.     struct cert_st /* CERT */ *cert;  

  114.   

  115.     /* the session_id_context is used to ensure sessions are only reused 

  116.      * in the appropriate context */  

  117.     unsigned int sid_ctx_length;  

  118.     unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];  

  119.   

  120.     /* This can also be in the session once a session is established */  

  121.     SSL_SESSION *session;  

  122.   

  123.     /* Default generate session ID callback. */  

  124.     GEN_SESSION_CB generate_session_id;  

  125.   

  126.     /* Used in SSL2 and SSL3 */  

  127.     int verify_mode;    /* 0 don’t care about verify failure. 

  128.                  * 1 fail if verify fails */  

  129.     int (*verify_callback)(int ok,X509_STORE_CTX *ctx); /* fail if callback returns 0 */  

  130.   

  131.     void (*info_callback)(const SSL *ssl,int type,int val); /* optional informational callback */  

  132.   

  133.     int error;      /* error bytes to be written */  

  134.     int error_code;     /* actual code */  

  135.   

  136. #ifndef OPENSSL_NO_KRB5   

  137.     KSSL_CTX *kssl_ctx;     /* Kerberos 5 context */  

  138. #endif  /* OPENSSL_NO_KRB5 */   

  139.   

  140. #ifndef OPENSSL_NO_PSK   

  141.     unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, char *identity,  

  142.         unsigned int max_identity_len, unsigned char *psk,  

  143.         unsigned int max_psk_len);  

  144.     unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,  

  145.         unsigned char *psk, unsigned int max_psk_len);  

  146. #endif   

  147.   

  148.     SSL_CTX *ctx;  

  149.     /* set this flag to 1 and a sleep(1) is put into all SSL_read() 

  150.      * and SSL_write() calls, good for nbio debuging 🙂 */  

  151.     int debug;    

  152.   

  153.     /* extra application data */  

  154.     long verify_result;  

  155.     CRYPTO_EX_DATA ex_data;  

  156.   

  157.     /* for server side, keep the list of CA_dn we can use */  

  158.     STACK_OF(X509_NAME) *client_CA;  

  159.   

  160.     int references;  

  161.     unsigned long options; /* protocol behaviour */  

  162.     unsigned long mode; /* API behaviour */  

  163.     long max_cert_list;  

  164.     int first_packet;  

  165.     int client_version; /* what was passed, used for 

  166.                  * SSLv3/TLS rollback check */  

  167.     unsigned int max_send_fragment;  

  168. #ifndef OPENSSL_NO_TLSEXT   

  169.     /* TLS extension debug callback */  

  170.     void (*tlsext_debug_cb)(SSL *s, int client_server, int type,  

  171.                     unsigned char *data, int len,  

  172.                     void *arg);  

  173.     void *tlsext_debug_arg;  

  174.     char *tlsext_hostname;  

  175.     int servername_done;   /* no further mod of servername  

  176.                               0 : call the servername extension callback. 

  177.                               1 : prepare 2, allow last ack just after in server callback. 

  178.                               2 : don’t call servername callback, no ack in server hello 

  179.                            */  

  180.     /* certificate status request info */  

  181.     /* Status type or -1 if no status type */  

  182.     int tlsext_status_type;  

  183.     /* Expect OCSP CertificateStatus message */  

  184.     int tlsext_status_expected;  

  185.     /* OCSP status request only */  

  186.     STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids;  

  187.     X509_EXTENSIONS *tlsext_ocsp_exts;  

  188.     /* OCSP response received or to be sent */  

  189.     unsigned char *tlsext_ocsp_resp;  

  190.     int tlsext_ocsp_resplen;  

  191.   

  192.     /* RFC4507 session ticket expected to be received or sent */  

  193.     int tlsext_ticket_expected;  

  194. #ifndef OPENSSL_NO_EC   

  195.     size_t tlsext_ecpointformatlist_length;  

  196.     unsigned char *tlsext_ecpointformatlist; /* our list */  

  197.     size_t tlsext_ellipticcurvelist_length;  

  198.     unsigned char *tlsext_ellipticcurvelist; /* our list */  

  199. #endif /* OPENSSL_NO_EC */   

  200.   

  201.     /* draft-rescorla-tls-opaque-prf-input-00.txt information to be used for handshakes */  

  202.     void *tlsext_opaque_prf_input;  

  203.     size_t tlsext_opaque_prf_input_len;  

  204.   

  205.     /* TLS Session Ticket extension override */  

  206.     TLS_SESSION_TICKET_EXT *tlsext_session_ticket;  

  207.   

  208.     /* TLS Session Ticket extension callback */  

  209.     tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;  

  210.     void *tls_session_ticket_ext_cb_arg;  

  211.   

  212.     /* TLS pre-shared secret session resumption */  

  213.     tls_session_secret_cb_fn tls_session_secret_cb;  

  214.     void *tls_session_secret_cb_arg;  

  215.   

  216.     SSL_CTX * initial_ctx; /* initial ctx, used to store sessions */  

  217. #define session_ctx initial_ctx   

  218. #else   

  219. #define session_ctx ctx   

  220. #endif /* OPENSSL_NO_TLSEXT */   

  221.     };  

列出SSL方法结构SSL_METHOD如下:


[cpp]


  1. /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */  

  2. typedef struct ssl_method_st  

  3.     {  

  4.     int version;  

  5.     int (*ssl_new)(SSL *s);  

  6.     void (*ssl_clear)(SSL *s);  

  7.     void (*ssl_free)(SSL *s);  

  8.     int (*ssl_accept)(SSL *s);  

  9.     int (*ssl_connect)(SSL *s);  

  10.     int (*ssl_read)(SSL *s,void *buf,int len);  

  11.     int (*ssl_peek)(SSL *s,void *buf,int len);  

  12.     int (*ssl_write)(SSL *s,const void *buf,int len);  

  13.     int (*ssl_shutdown)(SSL *s);  

  14.     int (*ssl_renegotiate)(SSL *s);  

  15.     int (*ssl_renegotiate_check)(SSL *s);  

  16.     long (*ssl_get_message)(SSL *s, int st1, int stn, int mt, long  

  17.         max, int *ok);  

  18.     int (*ssl_read_bytes)(SSL *s, int type, unsigned char *buf, int len,   

  19.         int peek);  

  20.     int (*ssl_write_bytes)(SSL *s, int type, const void *buf_, int len);  

  21.     int (*ssl_dispatch_alert)(SSL *s);  

  22.     long (*ssl_ctrl)(SSL *s,int cmd,long larg,void *parg);  

  23.     long (*ssl_ctx_ctrl)(SSL_CTX *ctx,int cmd,long larg,void *parg);  

  24.     const SSL_CIPHER *(*get_cipher_by_char)(const unsigned char *ptr);  

  25.     int (*put_cipher_by_char)(const SSL_CIPHER *cipher,unsigned char *ptr);  

  26.     int (*ssl_pending)(const SSL *s);  

  27.     int (*num_ciphers)(void);  

  28.     const SSL_CIPHER *(*get_cipher)(unsigned ncipher);  

  29.     const struct ssl_method_st *(*get_ssl_method)(int version);  

  30.     long (*get_timeout)(void);  

  31.     struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */  

  32.     int (*ssl_version)(void);  

  33.     long (*ssl_callback_ctrl)(SSL *s, int cb_id, void (*fp)(void));  

  34.     long (*ssl_ctx_callback_ctrl)(SSL_CTX *s, int cb_id, void (*fp)(void));  

  35.     } SSL_METHOD;

SSL工作方式:双向证书认证的SSL握手过程。
以下简要介绍SSL协议的工作方式。客户端要收发几个握手信号:
1、发送一个“ClientHello”消息,说明它支持的密码算法列表、压缩方法及最高协议版本,也发送稍后将被使用的随机数。
2、然后收到一个“ServerHello”消息,包含服务器选择的连接参数,源自客户端初期所提供的“ClientHello”。
3、当双方知道了连接参数,客户端与服务器交换证书(依靠被选择的公钥系统)。这些证书通常基于X.509,不过已有草案支持以OpenPGP为基础的证书。
4、服务器请求客户端公钥。客户端有证书即双向身份认证,没证书时随机生成公钥。
5、客户端与服务器通过公钥保密协商共同的主私钥(双方随机协商),这通过精心谨慎设计的伪随机数功能实现。结果可能使用Diffie-Hellman交换,或简化的公钥加密,双方各自用私钥解密。所有其他关键数据的加密均使用这个“主密钥”。


数据传输中记录层(Record layer)用于封装更高层的HTTP等协议。记录层数据可以被随意压缩、加密,与消息验证码压缩在一起。每个记录层包都有一个Content-Type段用以记录更上层用的协议。


使用SSL层接口函数有以下几个步骤:


1、初始化OpenSSL库


初始化函数列出如下:


#define OpenSSL_add_ssl_algorithms()SSL_library_init()
#define SSLeay_add_ssl_algorithms() SSL_library_init()



2、选择会话协议


客户端使用下面的函数选择会话协议:


const SSL_METHOD *SSLv2_client_method(void);/* SSLv2 */



const SSL_METHOD *SSLv3_client_method(void);/* SSLv3 */



const SSL_METHOD *SSLv23_client_method(void);/* SSLv3 but can rollback to v2 */



const SSL_METHOD *TLSv1_client_method(void);/* TLSv1.0 */



const SSL_METHOD *DTLSv1_client_method(void);/* DTLSv1.0 */



服务器端使用下面的函数选择会话协议:


const SSL_METHOD *SSLv2_server_method(void);/* SSLv2 */
const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
const SSL_METHOD *SSLv23_server_method(void); /* SSLv3 but can rollback to v2 */
const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */



3、创建会话环境


创建会话环境:


SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);



设置证书验证方式:


void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
int (*callback)(int, X509_STORE_CTX *));



给会话环境加载CA证书:


int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d);



给会话环境加载用户私钥:


int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
int SSL_CTX_use_PrivateKey_ASN1(int pk,SSL_CTX *ctx,
const unsigned char *d, long len);



验证私钥和证书是否相符:


int SSL_CTX_check_private_key(const SSL_CTX *ctx);



4、建立SSL套接字


SSL套接字建立在普通的TCP套接字基础上,应用程序在创建普通套接字、得到套接字描述符fd之后,再创建SSL套接字,并将fd绑定在SSL套接字上。


SSL *SSL_new(SSL_CTX *ctx);



intSSL_set_fd(SSL *s, int fd);
int SSL_set_rfd(SSL *s, int fd);
int SSL_set_wfd(SSL *s, int fd);



5、完成SSL握手


与普通socket编程类似,创建SSL套接字后,客户端使用SSL_connect替代普通socket的connect函数,服务器端则以SSL_accept代替普通socket的accept()函数。


int SSL_accept(SSL *ssl);
int SSL_connect(SSL *ssl);



握手完成之后,询问通信双方的证书信息:


X509 *SSL_get_peer_certificate(const SSL *s);



X509_NAME *X509_get_subject_name(X509 *a);  // <openssl/x509.h>



6、数据传输


对数据的安全传输包括了加密/解密、压缩/解压缩的过程。


int SSL_read(SSL *ssl,void *buf,int num);
int SSL_peek(SSL *ssl,void *buf,int num);
int SSL_write(SSL *ssl,const void *buf,int num);



7、SSL通信结束


关闭SSL套接字、释放会话环境。


int SSL_shutdown(SSL *s);


voidSSL_free(SSL *ssl);



voidSSL_CTX_free(SSL_CTX *);

BIO是对IO操作的封装,OpenSSL的BIO抽象接口不仅可以对SSL连接的I/O使用,也可以对非加密的网络连接和文件的I/O使用。BIO的相关源代码在crypto/bio文件夹下。


BIO的相关数据结构列出如下。


BIO结构:


[cpp] view plaincopyprint?


  1. struct bio_st  

  2.     {  

  3.     BIO_METHOD *method;  

  4.     /* bio, mode, argp, argi, argl, ret */  

  5.     long (*callback)(struct bio_st *,int,const char *,intlong,long);  

  6.     char *cb_arg; /* first argument for the callback */  

  7.   

  8.     int init;  

  9.     int shutdown;  

  10.     int flags;  /* extra storage */  

  11.     int retry_reason;  

  12.     int num;  

  13.     void *ptr;  

  14.     struct bio_st *next_bio;    /* used by filter BIOs */  

  15.     struct bio_st *prev_bio;    /* used by filter BIOs */  

  16.     int references;  

  17.     unsigned long num_read;  

  18.     unsigned long num_write;  

  19.   

  20.     CRYPTO_EX_DATA ex_data;  

  21.     };  
BIO操作的结构:


[cpp] view plaincopyprint?


  1. typedef struct bio_method_st  

  2.     {  

  3.     int type;  

  4.     const char *name;  

  5.     int (*bwrite)(BIO *, const char *, int);  

  6.     int (*bread)(BIO *, char *, int);  

  7.     int (*bputs)(BIO *, const char *);  

  8.     int (*bgets)(BIO *, char *, int);  

  9.     long (*ctrl)(BIO *, intlongvoid *);  

  10.     int (*create)(BIO *);  

  11.     int (*destroy)(BIO *);  

  12.         long (*callback_ctrl)(BIO *, int, bio_info_cb *);  

  13.     } BIO_METHOD;  
BIO接口类型分为源/接收类型和过滤类型两种。


[cpp] view plaincopyprint?


  1. #define BIO_TYPE_DESCRIPTOR0x0100 /* socket, fd, connect or accept */   

  2. #define BIO_TYPE_FILTER 0x0200   

  3. #define BIO_TYPE_SOURCE_SINK 0x0400  


1、源/接收类型


[cpp] view plaincopyprint?


  1. #define BIO_TYPE_MEM(1|0x0400)   

  2. #define BIO_TYPE_FILE (2|0x0400)   

  3. #define BIO_TYPE_FD (4|0x0400|0x0100)   

  4. #define BIO_TYPE_SOCKET (5|0x0400|0x0100)   

  5. #define BIO_TYPE_NULL (6|0x0400)   

  6. #define BIO_TYPE_CONNECT(12|0x0400|0x0100)/* socket – connect */   

  7. #define BIO_TYPE_ACCEPT(13|0x0400|0x0100)/* socket for accept */   

  8. #define BIO_TYPE_BIO(19|0x0400)/* (half a) BIO pair */   

  9. #define BIO_TYPE_DGRAM(21|0x0400|0x0100)  


2、过滤类型


[cpp] view plaincopyprint?


  1. #define BIO_TYPE_SSL(7|0x0200)   

  2. #define BIO_TYPE_MD(8|0x0200) /* passive filter */   

  3. #define BIO_TYPE_BUFFER (9|0x0200)/* filter */   

  4. #define BIO_TYPE_CIPHER (10|0x0200)/* filter */   

  5. #define BIO_TYPE_BASE64 (11|0x0200)/* filter */   

  6. #define BIO_TYPE_PROXY_CLIENT (14|0x0200)/* client proxy BIO */   

  7. #define BIO_TYPE_PROXY_SERVER (15|0x0200)/* server proxy BIO */   

  8. #define BIO_TYPE_NBIO_TEST (16|0x0200)/* server proxy BIO */   

  9. #define BIO_TYPE_NULL_FILTER (17|0x0200)   

  10. #define BIO_TYPE_BER (18|0x0200)/* BER -> bin filter */   

  11. #define BIO_TYPE_LINEBUFFER (20|0x0200)/* filter */   

  12. #define BIO_TYPE_ASN1 (22|0x0200)/* filter */   

  13. #define BIO_TYPE_COMP (23|0x0200)/* filter */  


BIO过滤缓冲结构:


[cpp] view plaincopyprint?


  1. typedef struct bio_f_buffer_ctx_struct  

  2.     {  

  3.     /* BIO *bio; */ /* this is now in the BIO struct */  

  4.     int ibuf_size;  /* how big is the input buffer */  

  5.     int obuf_size;  /* how big is the output buffer */  

  6.   

  7.     char *ibuf;     /* the char array */  

  8.     int ibuf_len;       /* how many bytes are in it */  

  9.     int ibuf_off;       /* write/read offset */  

  10.   

  11.     char *obuf;     /* the char array */  

  12.     int obuf_len;       /* how many bytes are in it */  

  13.     int obuf_off;       /* write/read offset */  

  14.     } BIO_F_BUFFER_CTX;  

赞(0) 打赏
转载请注明出处:服务器评测 » Linux安全体系学习笔记
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏