ssl证书有效性检测

因为公司的业务原因,所以基本上全站都是使用https。然后又因为各种各样的问题造成有的域名不能使用通配符证书,只能使用单独的证书,这样就造成了网络配置上同一个应用要配置多个公网IP以便绑定不同的证书(很多浏览器不支持SNI,所以只能配置多个IP了)。今天简单写了一个脚本,测试了一下可以把某个机房全站应用的公网IP对于的证书都检查一遍。

脚本如下:



#!/usr/bin/env perl  
#===============================================================================  
#  
#         FILE: comcheck.pl  
#  
#        USAGE: perl comcheck.pl  host_list  
#  
#  DESCRIPTION: test ssl cert  
#  
#      OPTIONS: —  
# REQUIREMENTS: —  
#         BUGS: —  
#        NOTES: —  
#       AUTHOR: @GNUer

#      VERSION: 1.0  
#      CREATED: 2012年09月18日 09时48分21秒  
#     REVISION: —  
#===============================================================================

use strict;  
use warnings;  
use utf8;  
use IO::Socket::SSL;  
my %vips;  
if ( !-f $ARGV[0] ) {  
&help;  
}  
open my $HOSTS, "<$ARGV[0]" or die "open $ARGV[0]\n";  
while ( my $line = <$HOSTS> ) {  
if ( $line =~ /\s*([\d\.]+)\s+(.*)\s*#/ ) {  
my $tdms = $2;  
my $ip   = $1;  
my @dms  = split( /\s+/, $tdms );  
foreach (@dms) {  
$vips{$_} = $ip;  
}  
}  
}  
close $HOSTS;

foreach my $name ( sort keys %vips ) {  
my $ip = $vips{$name};  
&check_cert_com( $ip, $name );  
}

sub check_cert_com() {  
my $vip      = shift;  
my $hostname = shift;  
chomp $hostname;  
chomp $vip;  
my $sock = IO::Socket::SSL->new(  
PeerAddr        => $vip,  
PeerPort        => 443,  
Proto           => tcp,  
SSL_verify_mode => 0x00,    #does no authentication.  
Timeout         => 3,

#You may combine 0x01 (verify peer),  
# 0x02 (fail verification if no peer certificate exists; ignored for clients)  
# 0x04 (verify client once) to change the default.  
SSL_hostname => $hostname,    # specifiy the hostname used for SNI  
SSL_verifycn_name => $hostname,    #Set the name which is used in verification of hostname  
SSL_ca_path => "/etc/ssl/certs/",

);

if ( !( ref $sock eq "IO::Socket::SSL" ) ) {  
print "connect $hostname failed\n";  
return 1;  
}  
if ( $sock->verify_hostname( $hostname, http ) ) {  
print "$hostname verification ok\n";  
return 0;  
}  
else {  
print STDERR "$hostname verify failed\n";  
}  
my $comname = $sock->peer_certificate("commonName");  
my $tname   = $hostname;  
my $tcom    = $comname;  
$tname =~ s/\.xxx.com//g;  
$tcom  =~ s/\.xxx.com//g;  
if ( $tcom eq "*" && $tname !~ /\./ ) {  
;  
print "$hostname $comname\n";  
}  
elsif ( $tname eq $tcom ) {  
;  
#        print "$hostname eq $comname\n";  
}  
else {

print STDERR "$vip \e[1;32m$hostname\e[m error cert:\e[1;31m $comname\e[m\n";  
}  
$sock->close();

}

sub help() {  
print "perl comcheck.pl hostlist\n";  
exit 0;  
}

输入文件的格式如下:

12.75.123.70 app1.xxx.com #appxxx  
12.75.123.20 app2.xxx.com #appxxx  
12.75.123.76 app3.xxx.com #appxxx  
12.75.123.42 app41.xxx.com app42.xxx.com air.xxx.com #appxxx  
12.75.123.43 app5xxx.com #appxxx

如果只看错误的话可以

perl certcheck.pl host >/dev/null