自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

從服務(wù)器到iOS客戶端對(duì)ATS的適配

移動(dòng)開(kāi)發(fā) iOS
ATS(App Transport Security)是為了提高App與服務(wù)器之間安全傳輸數(shù)據(jù)一個(gè)特性,這個(gè)特性從iOS9和OSX10.11開(kāi)始出現(xiàn),它默認(rèn)需要滿足以下幾個(gè)條件

iOS 9系統(tǒng)已經(jīng)出來(lái)了,而網(wǎng)絡(luò)方面的ATS(App Transport Security)特性可以說(shuō)每個(gè)人都要經(jīng)歷。而我這篇博客,就是結(jié)合我最近幾天的經(jīng)歷,來(lái)談?wù)剰姆?wù)器到iOS客戶端對(duì)ATS的適配。

一、簡(jiǎn)單談?wù)凙TS(App Transport Security)

ATS(App Transport Security)是為了提高App與服務(wù)器之間安全傳輸數(shù)據(jù)一個(gè)特性,這個(gè)特性從iOS9和OSX10.11開(kāi)始出現(xiàn),它默認(rèn)需要滿足以下幾個(gè)條件:

服務(wù)器TLS版本至少是1.2版本

連接加密只允許幾種先進(jìn)的加密

證書(shū)必須使用SHA256或者更好的哈希算法進(jìn)行簽名,要么是2048位或者更長(zhǎng)的RSA密鑰,要么就是256位或更長(zhǎng)的ECC密鑰。

如果想了解哪幾種先進(jìn)的加密是被允許的,詳情請(qǐng)見(jiàn)官方文檔App Transport Security Technote

二、搭建HTTPS服務(wù)器

搭建HTTPS服務(wù)器有兩種方式,一種是創(chuàng)建證書(shū)請(qǐng)求,然后到權(quán)威機(jī)構(gòu)認(rèn)證,隨之配置到服務(wù)器;另外一種是自建證書(shū),然后配置給服務(wù)器。***種方式搭建的HTTPS服務(wù)器當(dāng)然是***的了,建立網(wǎng)站的話,直接就會(huì)被信任,而作為移動(dòng)端app的服務(wù)器時(shí),也不需要為ATS做過(guò)多的適配。雖然說(shuō)權(quán)威的機(jī)構(gòu)認(rèn)證都是需要錢(qián)的,但是如今也不乏存在免費(fèi)的第三方認(rèn)證機(jī)構(gòu);第二種方式搭建的HTTPS服務(wù)器,對(duì)于網(wǎng)站來(lái)說(shuō)完全不可行,用戶打開(kāi)時(shí)直接彈出一個(gè)警告提醒,說(shuō)這是一個(gè)不受信任的網(wǎng)站,讓用戶是否繼續(xù),體驗(yàn)很差,而且讓用戶感覺(jué)網(wǎng)站不安全。對(duì)于移動(dòng)端來(lái)說(shuō),在iOS9出現(xiàn)之前,這個(gè)沒(méi)什么問(wèn)題,但是在iOS9出來(lái)之后,第二種方式是通不過(guò)ATS特性,需要將NSAllowsArbitraryLoads設(shè)置為YES才行。所以,我推薦使用***種方式搭建HTTPS服務(wù)器。

下面,咱們來(lái)說(shuō)說(shuō)這兩種方式都如何進(jìn)行操作。

***種、使用CA機(jī)構(gòu)認(rèn)證的證書(shū)搭建HTTPS服務(wù)器

1、創(chuàng)建證書(shū)請(qǐng)求,并提交給CA機(jī)構(gòu)認(rèn)證

  1. #成私鑰 
  2. openssl genrsa -des3 -out private.key 2048 
  3. #生成服務(wù)器的私鑰,去除密鑰口令 
  4. openssl rsa -in private.key -out server.key 
  5. #生成證書(shū)請(qǐng)求 
  6. openssl req -new -key private.key -out server.csr 

將生成server.csr提交給CA機(jī)構(gòu),CA機(jī)構(gòu)對(duì)它進(jìn)行簽名之后,然后會(huì)生成簽名后的根證書(shū)和服務(wù)器證書(shū)發(fā)送給你,這個(gè)時(shí)候的證書(shū)就是CA認(rèn)證之后的證書(shū)。我們這里將根證書(shū)和服務(wù)器證書(shū)分別改名為ca.crt和serve.crt。

2、配置Apache服務(wù)器

將ca.crt、server.key、server.crt上傳到阿里云服務(wù)器,使用SSH登陸進(jìn)入這三個(gè)文件的目錄,執(zhí)行下面命令

mkdir ssl
cp server.crt /alidata/server/httpd/conf/ssl/server.crt
cp server.key /alidata/server/httpd/conf/ssl/server.key
cp demoCA/cacert.pem /alidata/server/httpd/conf/ssl/ca.crt
cp -r ssl /alidata/server/httpd/conf/

編輯/alidata/server/httpd/conf/extra/httpd-ssl.conf文件,找到SSLCertificateFile、SSLCertificateKeyFile、SSLCACertificatePath、SSLCACertificateFile進(jìn)行修改:

  1. # 指定服務(wù)器證書(shū)位置 
  2. SSLCertificateFile "/alidata/server/httpd/conf/ssl/server.crt" 
  3. # 指定服務(wù)器證書(shū)key位置 
  4. SSLCertificateKeyFile "/alidata/server/httpd/conf/ssl/server.key" 
  5. # 證書(shū)目錄 
  6. SSLCACertificatePath "/alidata/server/httpd/conf/ssl" 
  7. # 根證書(shū)位置 
  8. SSLCACertificateFile "/alidata/server/httpd/conf/ssl/ca.crt" 
  9.  
  10. 修改vhost配置vim /alidata/server/httpd/conf/vhosts/phpwind.conf 

 

  1. SSLCertificateFile /alidata/server/httpd/conf/ssl/server.crt 
  2. SSLCertificateKeyFile /alidata/server/httpd/conf/ssl/server.key 
  3. SSLCACertificatePath /alidata/server/httpd/conf/ssl 
  4. SSLCACertificateFile /alidata/server/httpd/conf/ssl/ca.crt 
  5. ServerName www.casetree.cn 
  6. DocumentRoot /alidata/www 

***,重啟Apache服務(wù)器,在瀏覽器輸入網(wǎng)址查看是否配置成功。我這里是個(gè)人使用,申請(qǐng)的是免費(fèi)的證書(shū),我申請(qǐng)證書(shū)的網(wǎng)站是沃通。

搭建的成果:https://www.casetree.cn

第二種、自建證書(shū)配置HTTPS服務(wù)器

請(qǐng)查看我的上一篇自建證書(shū)配置HTTPS服務(wù)器

三、使用nscurl對(duì)服務(wù)器進(jìn)行檢測(cè)

搭建完HTTPS服務(wù)器之后,可以使用nscurl命令來(lái)進(jìn)行檢測(cè),查看建立的HTTPS服務(wù)器是否能通過(guò)ATS特性。

  1. nscurl --ats-diagnostics --verbose https://casetree.cn 

如果HTTPS服務(wù)器能通過(guò)ATS特性,則上面所有測(cè)試案例都是PASS;如果某一項(xiàng)的Reuslt是FAIL,就找到ATS Dictionary來(lái)查看,就能知道HTTPS服務(wù)器不滿足ATS哪個(gè)條件。 這里我前面碰到一個(gè)問(wèn)題,就是自建證書(shū)的時(shí)候,通過(guò)此命令進(jìn)行測(cè)試時(shí),發(fā)現(xiàn)Result全是FAIL,而且在iOS的代碼測(cè)試中也出現(xiàn)了一個(gè)很奇怪的現(xiàn)象,就是相同的代碼,在iOS8.4請(qǐng)求數(shù)據(jù)完全正常,但是在iOS9上,直接是連接失敗。最終發(fā)現(xiàn),其實(shí)就是因?yàn)樽越ㄗC書(shū)不受信任,是通不過(guò)ATS的,除非將NSAllowsArbitraryLoads設(shè)置為YES。

四、iOS客戶端

在上面的第二大步驟當(dāng)中,HTTPS服務(wù)器滿足ATS默認(rèn)的條件,而且SSL證書(shū)是通過(guò)權(quán)威的CA機(jī)構(gòu)認(rèn)證過(guò)的,那么我們?cè)谑褂肵code7開(kāi)發(fā)的時(shí)候,對(duì)網(wǎng)絡(luò)的適配什么都不用做,我們也能正常與服務(wù)器通信。但是,當(dāng)我們對(duì)安全性有更高的要求時(shí)或者我們自建證書(shū)時(shí),我們需要本地導(dǎo)入證書(shū)來(lái)進(jìn)行驗(yàn)證。

那么,如何本地導(dǎo)入證書(shū)進(jìn)行驗(yàn)證呢?

在這里先提一下,由于iOS客戶端支持的證書(shū)是DER格式的,我們需要?jiǎng)?chuàng)建客戶端證書(shū)。創(chuàng)建客戶端證書(shū),直接將服務(wù)端的CA根證書(shū)導(dǎo)出成DER格式就行。
 

  1. openssl x509 -inform PEM -outform DER -in ca.crt -out ca.cer 

導(dǎo)入完證書(shū)之后,我們分別來(lái)說(shuō)說(shuō)使用NSURLSession和AFNetworking來(lái)進(jìn)行本地驗(yàn)證。

首先,來(lái)說(shuō)說(shuō)使用NSURLSession驗(yàn)證

驗(yàn)證步驟如下:

導(dǎo)入CA根證書(shū)到工程中,即我們創(chuàng)建的ca.cer

獲取trust object,通過(guò)SecCertificateCreateWithData方法讀取導(dǎo)入的證書(shū)的數(shù)據(jù)生成一個(gè)證書(shū)對(duì)象,然后通過(guò)SecTrustSetAnchorCertificates 設(shè)置這個(gè)證書(shū)為trust object的信任根證書(shū)(trusted anchor)

通過(guò)SecTrustEvaluate方法去驗(yàn)證trust object

下面是主要OC實(shí)現(xiàn)代碼,Demo工程我也放在github上了,有OC和Swift兩種語(yǔ)言,下載Demo請(qǐng)點(diǎn)擊HTTPSConnectDemo。

  1. - (void)viewDidLoad { 
  2. [super viewDidLoad]; 
  3. //導(dǎo)入客戶端證書(shū) 
  4. NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"ca" ofType:@"cer"]; 
  5. NSData *data = [NSData dataWithContentsOfFile:cerPath]; 
  6. SecCertificateRef certificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) data); 
  7. self.trustedCerArr = @[(__bridge_transfer id)certificate]; 
  8. //發(fā)送請(qǐng)求 
  9. NSURL *testURL = [NSURL URLWithString:@"https://casetree.cn/web/test/demo.php"]; 
  10. NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]]; 
  11. NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:testURL]]; 
  12. [task resume]; 
  13. // Do any additional setup after loading the view, typically from a nib. 
  14.  
  15. #pragma mark - NSURLSessionDelegate 
  16. - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge 
  17. completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * __nullable credential))completionHandler{ 
  18.  
  19. OSStatus err; 
  20. NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; 
  21. SecTrustResultType trustResult = kSecTrustResultInvalid; 
  22. NSURLCredential *credential = nil; 
  23.  
  24. //獲取服務(wù)器的trust object 
  25. SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; 
  26. //將讀取的證書(shū)設(shè)置為serverTrust的根證書(shū) 
  27. err = SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)self.trustedCerArr); 
  28.  
  29. if(err == noErr){ 
  30. //通過(guò)本地導(dǎo)入的證書(shū)來(lái)驗(yàn)證服務(wù)器的證書(shū)是否可信,如果將SecTrustSetAnchorCertificatesOnly設(shè)置為NO,則只要通過(guò)本地或者系統(tǒng)證書(shū)鏈任何一方認(rèn)證就行 
  31. err = SecTrustEvaluate(serverTrust, &trustResult); 
  32.  
  33. if (err == errSecSuccess && (trustResult == kSecTrustResultProceed || trustResult == kSecTrustResultUnspecified)){ 
  34. //認(rèn)證成功,則創(chuàng)建一個(gè)憑證返回給服務(wù)器 
  35. disposition = NSURLSessionAuthChallengeUseCredential; 
  36. credential = [NSURLCredential credentialForTrust:serverTrust]; 
  37. else
  38. disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; 
  39.  
  40. //回調(diào)憑證,傳遞給服務(wù)器 
  41. if(completionHandler){ 
  42. completionHandler(disposition, credential); 

注意:

1、SecTrustSetAnchorCertificates方法會(huì)設(shè)置一個(gè)標(biāo)示去屏蔽trust object對(duì)其它根證書(shū)的信任;如果你也想信任系統(tǒng)默認(rèn)的根證書(shū),請(qǐng)調(diào)用SecTrustSetAnchorCertificatesOnly方法,清空這個(gè)標(biāo)示(設(shè)置為NO) 2、驗(yàn)證的方法不僅僅只有這一種,更多的驗(yàn)證方法,請(qǐng)參考HTTPS Server Trust Evaluation

下面,來(lái)談?wù)凙FNetworking是如何驗(yàn)證的,我們?nèi)绾问褂肁FNetworking。

AFNetworking的證書(shū)驗(yàn)證工作是由AFSecurityPolicy來(lái)完成的,所以這里我們主要來(lái)了解一下AFSecurityPolicy。注意:我這里使用的是AFNetworking2.6.0,它跟2.5.0是有區(qū)別的。

說(shuō)到AFSecurityPolicy,我們必須要提到它三個(gè)重要的屬性,如下:

  1. @property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode; 
  2. @property (nonatomic, assign) BOOL allowInvalidCertificates; 
  3. @property (nonatomic, assign) BOOL validatesDomainName; 

SSLPingMode是最重要的屬性,它標(biāo)明了AFSecurityPolicy是以何種方式來(lái)驗(yàn)證。它是一個(gè)枚舉類(lèi)型,這個(gè)枚舉類(lèi)型有三個(gè)值,分別是AFSSLPinningModeNone、AFSSLPinningModePublicKey、AFSSLPinningModeCertificate。其中,AFSSLPinningModeNone代表了AFSecurityPolicy不做更嚴(yán)格的驗(yàn)證,只要是系統(tǒng)信任的證書(shū)就可以通過(guò)驗(yàn)證,不過(guò),它受到allowInvalidCertificates和validatesDomainName的影響;AFSSLPinningModePublicKey是通過(guò)比較證書(shū)當(dāng)中公鑰(PublicKey)部分來(lái)進(jìn)行驗(yàn)證,通過(guò)SecTrustCopyPublicKey方法獲取本地證書(shū)和服務(wù)器證書(shū),然后進(jìn)行比較,如果有一個(gè)相同,則通過(guò)驗(yàn)證,此方式主要適用于自建證書(shū)搭建的HTTPS服務(wù)器和需要較高安全要求的驗(yàn)證;AFSSLPinningModeCertificate則是直接將本地的證書(shū)設(shè)置為信任的根證書(shū),然后來(lái)進(jìn)行判斷,并且比較本地證書(shū)的內(nèi)容和服務(wù)器證書(shū)內(nèi)容是否相同,來(lái)進(jìn)行二次判斷,此方式適用于較高安全要求的驗(yàn)證。

allowInvalidCertificates屬性代表是否允許不信任的證書(shū)通過(guò)驗(yàn)證,默認(rèn)為NO。

validatesDomainName屬性代表是否驗(yàn)證主機(jī)名,默認(rèn)為YES。

接下來(lái),我們說(shuō)下驗(yàn)證流程。驗(yàn)證流程主要放在AFSecurityPolicy的- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust forDomain:(NSString *)domain方法當(dāng)中。

c

  1. - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust 
  2. forDomain:(NSString *)domain 
  3. //當(dāng)使用自建證書(shū)驗(yàn)證域名時(shí),需要使用AFSSLPinningModePublicKey或者AFSSLPinningModeCertificate 
  4. if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AFSSLPinningModeNone || [self.pinnedCertificates count] == 0)) { 
  5. NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning."); 
  6. return NO; 
  7.  
  8. NSMutableArray *policies = [NSMutableArray array]; 
  9. //需要驗(yàn)證域名時(shí),需要添加一個(gè)驗(yàn)證域名的策略 
  10. if (self.validatesDomainName) { 
  11. [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)]; 
  12. else { 
  13. [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()]; 
  14.  
  15. //設(shè)置驗(yàn)證的策略,可以是多個(gè) 
  16. SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); 
  17. //SSLPinningMode為AFSSLPinningModeNone時(shí),allowInvalidCertificates為YES,則代表服務(wù)器任何證書(shū)都能驗(yàn)證通過(guò);如果它為NO,則需要判斷此服務(wù)器證書(shū)是否是系統(tǒng)信任的證書(shū) 
  18. if (self.SSLPinningMode == AFSSLPinningModeNone) { 
  19. if (self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust)){ 
  20. return YES; 
  21. else { 
  22. return NO; 
  23. else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { 
  24. return NO; 
  25.  
  26. //獲取服務(wù)器證書(shū)的內(nèi)容 
  27. NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust); 
  28. switch (self.SSLPinningMode) { 
  29. case AFSSLPinningModeNone: 
  30. default
  31. return NO; 
  32. case AFSSLPinningModeCertificate: { 
  33. //AFSSLPinningModeCertificate是直接將本地的證書(shū)設(shè)置為信任的根證書(shū),然后來(lái)進(jìn)行判斷,并且比較本地證書(shū)的內(nèi)容和服務(wù)器證書(shū)內(nèi)容是否相同,如果有一個(gè)相同則返回YES 
  34.  
  35. NSMutableArray *pinnedCertificates = [NSMutableArray array]; 
  36. for (NSData *certificateData in self.pinnedCertificates) { 
  37. [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)]; 
  38. //設(shè)置本地的證書(shū)為根證書(shū) 
  39. SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates); 
  40.  
  41. //通過(guò)本地的證書(shū)來(lái)判斷服務(wù)器證書(shū)是否可信,不可信,則驗(yàn)證不通過(guò) 
  42. if (!AFServerTrustIsValid(serverTrust)) { 
  43. return NO; 
  44.  
  45. //判斷本地證書(shū)和服務(wù)器證書(shū)的內(nèi)容是否相同 
  46. NSUInteger trustedCertificateCount = 0
  47. for (NSData *trustChainCertificate in serverCertificates) { 
  48. if ([self.pinnedCertificates containsObject:trustChainCertificate]) { 
  49. trustedCertificateCount++; 
  50. return trustedCertificateCount > 0
  51. case AFSSLPinningModePublicKey: { 
  52. //AFSSLPinningModePublicKey是通過(guò)比較證書(shū)當(dāng)中公鑰(PublicKey)部分來(lái)進(jìn)行驗(yàn)證,通過(guò)SecTrustCopyPublicKey方法獲取本地證書(shū)和服務(wù)器證書(shū),然后進(jìn)行比較,如果有一個(gè)相同,則通過(guò)驗(yàn)證 
  53. NSUInteger trustedPublicKeyCount = 0
  54. NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust); 
  55. //判斷服務(wù)器證書(shū)的公鑰與本地的證書(shū)公鑰是否相同,相同則客戶端認(rèn)證通過(guò) 
  56. for (id trustChainPublicKey in publicKeys) { 
  57. for (id pinnedPublicKey in self.pinnedPublicKeys) { 
  58. if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) { 
  59. trustedPublicKeyCount += 1
  60. return trustedPublicKeyCount > 0
  61. return NO; 

說(shuō)了驗(yàn)證流程,我們***來(lái)看看AFNetworking怎么使用,代碼如下:

  1. _httpClient = [[BGAFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:baseURL]]; 
  2. AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; 
  3. //是否允許CA不信任的證書(shū)通過(guò) 
  4. policy.allowInvalidCertificates = YES; 
  5. //是否驗(yàn)證主機(jī)名 
  6. policy.validatesDomainName = YES; 
  7. _httpClient.securityPolicy = policy; 

這里我就沒(méi)有建立Demo了,如果要看的話,可以看看我寫(xiě)的一個(gè)框架BGNetwork,里面的Demo對(duì)ATS進(jìn)行了適配,AFNetworking的使用放在BGNetworkConnector類(lèi)里面的- (instancetype)initWithBaseURL:(NSString *)baseURL delegate:(id)delegate初始化方法中。

五、適配ATS

前面的內(nèi)容講述都是滿足ATS特性的情況,但若是服務(wù)器是自建證書(shū)搭建的,或者TLS版本是1.0的話,服務(wù)器又不能輕易改動(dòng),那么我們客戶端如何適配呢? 不急,我們可以在工程中的Info.plist文件當(dāng)中進(jìn)行設(shè)置,主要參照下圖:

適配iOS 9之ATS

如果是自建證書(shū),沒(méi)有經(jīng)過(guò)權(quán)威機(jī)構(gòu)認(rèn)證的證書(shū),那么需要將NSAllowsArbitraryLoads設(shè)置為YES才能通過(guò)。NSAllowsArbitraryLoads為YES,以前的HTTP請(qǐng)求也能通過(guò)。

如果是認(rèn)證過(guò)的證書(shū),那么可以通過(guò)nscurl --ats-diagnostics --verbose https://casetree.cn這樣的命令來(lái)查看服務(wù)器支持的ATS Dictionary,然后進(jìn)行對(duì)應(yīng)的設(shè)置。

適配的部分,也可以參照Demo1_iOS9網(wǎng)絡(luò)適配_ATS:改用更安全的HTTPS

責(zé)任編輯:chenqingxiang 來(lái)源: CocoaChina
相關(guān)推薦

2009-08-18 12:51:19

服務(wù)器+客戶端

2011-06-09 10:51:26

Qt 服務(wù)器 客戶端

2014-01-17 15:23:55

Nagios

2010-06-09 14:39:58

2018-12-18 10:47:37

2018-07-17 09:59:10

PythonUDP服務(wù)器

2009-12-25 10:47:17

DNS服務(wù)器

2009-09-16 16:09:41

NIS服務(wù)器客戶端NIS

2019-08-28 15:19:15

PythonTCP服務(wù)器

2018-12-19 10:31:32

客戶端IP服務(wù)器

2012-05-29 09:38:04

Linux客戶端服務(wù)器

2010-10-11 17:46:01

mysql客戶端

2018-12-20 08:50:53

TCPIP服務(wù)器

2010-10-26 13:54:45

連接Oracle服務(wù)器

2009-06-27 20:32:00

LinuxNFS客戶端

2010-08-27 10:18:24

DHCP服務(wù)

2014-06-01 11:03:13

VDI零客戶端

2024-02-22 13:47:40

2010-08-27 14:43:03

DB2服務(wù)器

2009-06-10 16:25:02

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)