ブラウザのSSLプロトコルの対応状況を調べるためにSSLプロトコルを簡単に切り替えられるサーバーをGoで書いてみた。
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{
MinVersion: convertTlSNumber(minprtcl),
MaxVersion: convertTlSNumber(maxprtcl),
}
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.ListenAndServeTLS(crtfile, keyfile)
if err != nil {
log.Fatal(err)
}
}