ブラウザのSSLプロトコルの対応状況を調べるためにSSLプロトコルを簡単に切り替えられるサーバーをGoで書いてみた。
- httpd における POODLE SSLv3.0 脆弱性問題の解決方法 (CVE-2014-3566) - Red Hat Customer Portal
- [iOS 9] iOS 9 で追加された App Transport Security の概要 | Developers.IO
SSLv3は脆弱性がみつかってるので最新のブラウザだとデフォルト無効化されはじめているんだけど、 SSLv3を切り捨てると通信できなくなるブラウザもいくつかあるわけで切り捨てる前の検証用にサーバーを書いてみた感じ。
ちなみに、TlSConfig.MaxVersionの設定が優先されてTlSconfig.MaxVersionがSSL3.0でTLSCOnfig.MinVersionがTLS1.2ならSSL3.0が勝つって振る舞いをする。
package main import ( "crypto/tls" "flag" "fmt" "log" "net/http" "time" ) type BaseHandler struct{} func (bh *BaseHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, "Hey World!") } var keyfile, crtfile string var port int var minprtcl, maxprtcl string func init() { flag.IntVar(&port, "port", 443, "listen port") flag.StringVar(&keyfile, "keyfile", "server.key", "ssl server.key") flag.StringVar(&crtfile, "crtfile", "server.crt", "ssl server.crt") flag.StringVar(&minprtcl, "minprotocol", "tls10", "minimum negotiation protocol: ssl30, tls10, tls11,tls12") flag.StringVar(&maxprtcl, "maxprotocol", "tls12", "maximum negotiation protocol: ssl30, tls10, tls11,tls12") flag.Parse() } func convertTlSNumber(protocol string) uint16 { var version uint16 switch protocol { case "ssl30": version = tls.VersionSSL30 case "tls10": version = tls.VersionTLS10 case "tls11": version = tls.VersionTLS11 case "tls12": version = tls.VersionTLS12 default: log.Fatal("Unknown Protocol: ", protocol) } return version } func main() { mux := http.NewServeMux() bh := &BaseHandler{} mux.Handle("/hey", bh) mux.Handle("/", http.RedirectHandler("/hey", http.StatusFound)) addr := fmt.Sprintf(":%d", port) config := &tls.Config{ // ClientAuth: tls.RequireAnyClientCert, MinVersion: convertTlSNumber(minprtcl), MaxVersion: convertTlSNumber(maxprtcl), // Info: MAXのバージョンが優先される => Cap } config.CipherSuites = []uint16{tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, tls.TLS_RSA_WITH_AES_128_CBC_SHA, tls.TLS_RSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, } svr := http.Server{ Addr: addr, Handler: mux, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, TLSConfig: config, } log.Printf("Listening on " + svr.Addr) // err := svr.ListenAndServe() err := svr.ListenAndServeTLS(crtfile, keyfile) if err != nil { log.Fatal(err) } }