Skip to content

Commit

Permalink
Implemented TLS support
Browse files Browse the repository at this point in the history
  • Loading branch information
Raffo committed May 18, 2016
1 parent 08b8adf commit b1cf28a
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 13 deletions.
16 changes: 13 additions & 3 deletions cmd/skipper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ package main

import (
"flag"
"strings"
"time"

log "github.com/Sirupsen/logrus"
"github.com/zalando/skipper"
"github.com/zalando/skipper/proxy"
"strings"
"time"
)

const (
Expand Down Expand Up @@ -70,6 +71,8 @@ const (
accessLogUsage = "output file for the access log, When not set, /dev/stderr is used"
accessLogDisabledUsage = "when this flag is set, no access log is printed"
debugEndpointUsage = "when this address is set, skipper starts an additional listener returning the original and transformed requests"
certPathTLSUsage = "path of the certificate file"
keyPathTLSUsage = "path of the key"
)

var (
Expand Down Expand Up @@ -97,6 +100,8 @@ var (
accessLog string
accessLogDisabled bool
debugListener string
certPathTLS string
keyPathTLS string
)

func init() {
Expand Down Expand Up @@ -124,6 +129,8 @@ func init() {
flag.StringVar(&accessLog, "access-log", "", accessLogUsage)
flag.BoolVar(&accessLogDisabled, "access-log-disabled", false, accessLogDisabledUsage)
flag.StringVar(&debugListener, "debug-listener", "", debugEndpointUsage)
flag.StringVar(&certPathTLS, "tls-cert", "", certPathTLSUsage)
flag.StringVar(&keyPathTLS, "tls-key", "", keyPathTLSUsage)
flag.Parse()
}

Expand Down Expand Up @@ -156,7 +163,10 @@ func main() {
ApplicationLogPrefix: applicationLogPrefix,
AccessLogOutput: accessLog,
AccessLogDisabled: accessLogDisabled,
DebugListener: debugListener}
DebugListener: debugListener,
CertPathTLS: certPathTLS,
KeyPathTLS: keyPathTLS,
}

if insecure {
options.ProxyOptions |= proxy.OptionsInsecure
Expand Down
20 changes: 20 additions & 0 deletions fixtures/test.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDTjCCAjYCCQCsd4M/nAhEeDANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJE
RTEPMA0GA1UECAwGQmVybGluMRMwEQYDVQQKDApaYWxhbmRvIFNFMRMwEQYDVQQL
DApUZWNobm9sb2d5MR8wHQYDVQQDDBZkby1ub3QtdHJ1c3QtdGVzdC1kYXRhMB4X
DTE2MDQwNDA4NTEyN1oXDTI2MDQwMjA4NTEyN1owaTELMAkGA1UEBhMCREUxDzAN
BgNVBAgMBkJlcmxpbjETMBEGA1UECgwKWmFsYW5kbyBTRTETMBEGA1UECwwKVGVj
aG5vbG9neTEfMB0GA1UEAwwWZG8tbm90LXRydXN0LXRlc3QtZGF0YTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALZY9V/Psbq/9nqTQEnwz0CjHV7t+THG
wo5Xa3BGO4hKWKdAODDXc5Z7M6OmnboP0FmlKF8IKVsrdtKHxK4WzrlRiUDoRSgc
2lOuO8/kGr/MhIqEapQ95WJMiG6yGBkaZulmg8pb3FL+iHARCDzYIoWcozU69nvF
HPNgeFGUE/jjkZJLyHmOgbxhfhJYin2X/OFyN0DkPGzpHBnGGqYXCHUt25mkYgqG
OAQSwpR7XwRSJCg+Z09tXvUV06G/yfU+zFfzimD6CmQRa03Z8zXP5yRaJfxavqVV
kKwL9awCnoIeXBZGdOO6Y0+I71+72m6KwwvpHZK2nEBj23BT9xHbFfkCAwEAATAN
BgkqhkiG9w0BAQsFAAOCAQEASkABIkz//wxTOiAmVfY7NVndAYMzSbQJ+hrfmUhr
uyx8eF/UYFNf/lQ6IqGYF09xi/8CexliMoYQNnRhHG5KyFWyHi52lMLjTiMCpn4w
PyQZhy3PUQoK/69+4zVDytTGIlOC9epYgYTGEhvRSNsm192sq+BXuibSoEOSOwKV
Hd9lvhdeumeScWxUComl83HHhLE1rVRE4RzH0JTkGwgKrFbBBgaapJVCw2238QfE
ZtMlh+BBvFJcQgldlhHn4PHDZwPWxn7i6kcGCILvO/EIRFvgUvYn1Y+gvwFJinlU
cBOOedjhYVj+nPc3uL480Mo5fPWgHHI04uqDD77m1fkG3w==
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions fixtures/test.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC2WPVfz7G6v/Z6
k0BJ8M9Aox1e7fkxxsKOV2twRjuISlinQDgw13OWezOjpp26D9BZpShfCClbK3bS
h8SuFs65UYlA6EUoHNpTrjvP5Bq/zISKhGqUPeViTIhushgZGmbpZoPKW9xS/ohw
EQg82CKFnKM1OvZ7xRzzYHhRlBP445GSS8h5joG8YX4SWIp9l/zhcjdA5Dxs6RwZ
xhqmFwh1LduZpGIKhjgEEsKUe18EUiQoPmdPbV71FdOhv8n1PsxX84pg+gpkEWtN
2fM1z+ckWiX8Wr6lVZCsC/WsAp6CHlwWRnTjumNPiO9fu9puisML6R2StpxAY9tw
U/cR2xX5AgMBAAECggEBAI8AjM4qz7MpQF84g754/9AtG6eK8Va8DXAb1sIiEiX8
SDJCBs8m6BsnW4QH8sIsDLWA9Hwyplw9Zd4NY40zjcN/0if4/+NJXV8q0PVkaiXo
ejk3R24ibHX+lzBYstVdA0AfiVN1XwAnZVCdytwMlGY8RTJFn2/JUb779N/lRRR1
76YownyL6WDEl3qvdIvfP3jbR0UGfLJu2+NeRfWmVf0QsL80iVMq/ZScRaT6GkSN
U8//A51D2tX6Rx2GVgNbTPfRNja8kFaObiq3Ut7n7tSvYFLOvYWo1eBeehG0jRJC
jEvkq/puOqsykBFKB+j1Kyrr3W9VaY6DquFftNcXhkECgYEA6QNvYqI/DOSUveaJ
eLhnkY651tG0m91eLTG/ByxGqQpHWL2jrOd0Nh5uQeiKXX2bPkPZh++rwwqXRKgK
aRsLsnDqnJSU392efqxzRYyAR0M0CF7twNtYgtNWgdZKsLPmTG8DlAiD2wDxWwAg
UiagX5GC2oFlo+GNJMHfMulJanUCgYEAyFX/HyUpDcYta1wCefmHoO/26qnkfHlo
3zw27R9/i0C1Y+Dlybg83BBZjukwMBg9SCElt12loriFJdbBS4aIiFL9nz1KA8IM
A8GXJRfQYgh8vTFxnK3DxpLGVe2sdX331ZBDsiO+i9ioTJvi5KcBlEVY7mVSCqkr
Bhy4mHOo5PUCgYBGkYvCS3Dc7r09ZfxsWyzCoH8X2BriuYA0H8TC313nA/3nmkdf
rhk76qtpuottFQVXLiVLTgKu5x445MuCWXaJbDkhgr4zrmK56nBet9aBvpCbmGRY
7BU6SdcBK20jZthwfY6P3qRQR1DRRpCDUL9xMhh3JIkrwLuGTlDSkmRxoQKBgQC4
tAjWp0U1jNy9WgRyfuxcJkIJ0v90/97/yp19fAf01IEoh+Z0V+fMoUpg53/lJ8QA
Z4dFixK2dtdTrq9iObRRs+pf0XsXAeZf5DG9Ijqe1+Jh8F8mLFMPFq3D9bCGVtCT
10GC0U/R0bxBfYvwckWTdWhry4CbkaK4LOzIqgIyrQKBgQCvh7xmwIFAWIBPYqH8
o0njbU6N4dSTyXuY61a30bo5dc3X6DDgdMkoIp6vhs3WBbmOr7AH2oBBkfs3RIcC
TIa9KaUEWBhO2DZoUcDY49kwUeAjoVjQetxJgdS4gDejBugmI13jJMuGfxbDw+Qi
E5hUPz8TmgWaDNQWBQqnB8CIPQ==
-----END PRIVATE KEY-----
37 changes: 27 additions & 10 deletions skipper.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@
package skipper

import (
"io"
"net/http"
"os"
"path"
"time"

log "github.com/Sirupsen/logrus"
"github.com/zalando/skipper/eskipfile"
"github.com/zalando/skipper/etcd"
Expand All @@ -27,11 +33,6 @@ import (
"github.com/zalando/skipper/predicates/source"
"github.com/zalando/skipper/proxy"
"github.com/zalando/skipper/routing"
"io"
"net/http"
"os"
"path"
"time"
)

const (
Expand Down Expand Up @@ -159,6 +160,11 @@ type Options struct {
AccessLogDisabled bool

DebugListener string

//Path of certificate when using TLS
CertPathTLS string
//Path of
KeyPathTLS string
}

func createDataClients(o Options, auth innkeeper.Authentication) ([]routing.DataClient, error) {
Expand Down Expand Up @@ -246,6 +252,21 @@ func initLog(o Options) error {
return nil
}

func (o *Options) isHTTPS() bool {
return o.CertPathTLS != "" && o.KeyPathTLS != ""
}

func listenAndServe(proxy *http.Handler, o *Options) error {
// create the access log handler
loggingHandler := logging.NewHandler(*proxy)
log.Infof("proxy listener on %v", o.Address)
if o.isHTTPS() {
return http.ListenAndServeTLS(o.Address, o.CertPathTLS, o.KeyPathTLS, loggingHandler)
}
log.Infof("certPathTLS or keyPathTLS not found, defaulting to HTTP")
return http.ListenAndServe(o.Address, loggingHandler)
}

// Run skipper.
func Run(o Options) error {
// init log
Expand Down Expand Up @@ -329,10 +350,6 @@ func Run(o Options) error {
// create the proxy
proxy := proxy.New(routing, o.ProxyOptions, o.PriorityRoutes...)

// create the access log handler
loggingHandler := logging.NewHandler(proxy)
return listenAndServe(&proxy, &o)

// start the http server
log.Infof("proxy listener on %v", o.Address)
return http.ListenAndServe(o.Address, loggingHandler)
}
98 changes: 98 additions & 0 deletions skipper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package skipper

import (
"crypto/tls"
"io/ioutil"
"net/http"
"testing"

"github.com/zalando/skipper/filters/builtin"
"github.com/zalando/skipper/proxy"
"github.com/zalando/skipper/routing"
)

func initializeProxy() *http.Handler {
filterRegistry := builtin.MakeRegistry()
proxy := proxy.New(routing.New(routing.Options{
FilterRegistry: filterRegistry,
DataClients: []routing.DataClient{}}), proxy.OptionsNone)
return &proxy
}

func TestMissingOptionHTTP(t *testing.T) {
o := Options{}
if o.isHTTPS() {
t.FailNow()
}
}

func TestWithOptionHTTPS(t *testing.T) {
o := Options{CertPathTLS: "foo", KeyPathTLS: "bar"}
if !o.isHTTPS() {
t.FailNow()
}
}

func TestWrongCert(t *testing.T) {
o := Options{Address: ":9091",
CertPathTLS: "fixtures/notFound.crt",
KeyPathTLS: "fixtures/test.key",
}
proxy := initializeProxy()

err := listenAndServe(proxy, &o)
if err == nil {
t.Fatal(err)
}
}

func TestWrongKey(t *testing.T) {
o := Options{Address: ":9091",
CertPathTLS: "fixtures/test.crt",
KeyPathTLS: "fixtures/notFound.key",
}
proxy := initializeProxy()
err := listenAndServe(proxy, &o)
if err == nil {
t.Fatal(err)
}
}

func TestHTTPSServer(t *testing.T) {
o := Options{
Address: ":9091",
CertPathTLS: "fixtures/test.crt",
KeyPathTLS: "fixtures/test.key",
}
proxy := initializeProxy()
go listenAndServe(proxy, &o)

tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
r, err := client.Get("https://localhost:9091")
if err == nil {
defer r.Body.Close()
_, _ = ioutil.ReadAll(r.Body)
if r.StatusCode != 404 {
t.Fatalf("Status code should be 404, instead got: %d\n", r.StatusCode)
}
}
}

func TestHTTPServer(t *testing.T) {
o := Options{
Address: ":9090",
}
proxy := initializeProxy()
go listenAndServe(proxy, &o)
r, err := http.Get("http://localhost:9090")
if err == nil {
defer r.Body.Close()
_, _ = ioutil.ReadAll(r.Body)
if r.StatusCode != 404 {
t.Fatalf("Status code should be 404, instead got: %d\n", r.StatusCode)
}
}
}

0 comments on commit b1cf28a

Please sign in to comment.