Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow self signed certs with insecureSkipVerify #1769

Merged
merged 6 commits into from
Aug 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelogs/unreleased/1769-s12chung
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
adds `insecureSkipTLSVerify` server config for AWS storage and `--insecure-skip-tls-verify` flag on client for self-signed certs
54 changes: 37 additions & 17 deletions pkg/cloudprovider/aws/object_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ limitations under the License.
package aws

import (
"crypto/tls"
"io"
"net/http"
"sort"
"strconv"
"time"
Expand All @@ -36,13 +38,14 @@ import (
)

const (
s3URLKey = "s3Url"
publicURLKey = "publicUrl"
kmsKeyIDKey = "kmsKeyId"
s3ForcePathStyleKey = "s3ForcePathStyle"
bucketKey = "bucket"
signatureVersionKey = "signatureVersion"
credentialProfileKey = "profile"
s3URLKey = "s3Url"
publicURLKey = "publicUrl"
kmsKeyIDKey = "kmsKeyId"
s3ForcePathStyleKey = "s3ForcePathStyle"
bucketKey = "bucket"
signatureVersionKey = "signatureVersion"
credentialProfileKey = "profile"
insecureSkipTLSVerifyKey = "insecureSkipTLSVerify"
)

type s3Interface interface {
Expand Down Expand Up @@ -83,26 +86,29 @@ func (o *ObjectStore) Init(config map[string]string) error {
s3ForcePathStyleKey,
signatureVersionKey,
credentialProfileKey,
insecureSkipTLSVerifyKey,
); err != nil {
return err
}

var (
region = config[regionKey]
s3URL = config[s3URLKey]
publicURL = config[publicURLKey]
kmsKeyID = config[kmsKeyIDKey]
s3ForcePathStyleVal = config[s3ForcePathStyleKey]
signatureVersion = config[signatureVersionKey]
credentialProfile = config[credentialProfileKey]
region = config[regionKey]
s3URL = config[s3URLKey]
publicURL = config[publicURLKey]
kmsKeyID = config[kmsKeyIDKey]
s3ForcePathStyleVal = config[s3ForcePathStyleKey]
signatureVersion = config[signatureVersionKey]
credentialProfile = config[credentialProfileKey]
insecureSkipTLSVerifyVal = config[insecureSkipTLSVerifyKey]

// note that bucket is automatically added to the config map
// by the server from the ObjectStorageProviderConfig so
// doesn't need to be explicitly set by the user within
// config.
bucket = config[bucketKey]
s3ForcePathStyle bool
err error
bucket = config[bucketKey]
s3ForcePathStyle bool
insecureSkipTLSVerify bool
err error
)

if s3ForcePathStyleVal != "" {
Expand All @@ -127,6 +133,20 @@ func (o *ObjectStore) Init(config map[string]string) error {
return err
}

if insecureSkipTLSVerifyVal != "" {
if insecureSkipTLSVerify, err = strconv.ParseBool(insecureSkipTLSVerifyVal); err != nil {
return errors.Wrapf(err, "could not parse %s (expected bool)", insecureSkipTLSVerifyKey)
}
}

if insecureSkipTLSVerify {
serverConfig.HTTPClient = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
}

serverSession, err := getSession(serverConfig, credentialProfile)
if err != nil {
return err
Expand Down
8 changes: 5 additions & 3 deletions pkg/cmd/cli/backup/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ import (

func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
var (
listOptions metav1.ListOptions
details bool
listOptions metav1.ListOptions
details bool
insecureSkipTLSVerify bool
)

c := &cobra.Command{
Expand Down Expand Up @@ -71,7 +72,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
fmt.Fprintf(os.Stderr, "error getting PodVolumeBackups for backup %s: %v\n", backup.Name, err)
}

s := output.DescribeBackup(&backup, deleteRequestList.Items, podVolumeBackupList.Items, details, veleroClient)
s := output.DescribeBackup(&backup, deleteRequestList.Items, podVolumeBackupList.Items, details, veleroClient, insecureSkipTLSVerify)
if first {
first = false
fmt.Print(s)
Expand All @@ -85,6 +86,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {

c.Flags().StringVarP(&listOptions.LabelSelector, "selector", "l", listOptions.LabelSelector, "only show items matching this label selector")
c.Flags().BoolVar(&details, "details", details, "display additional detail in the command output")
c.Flags().BoolVar(&insecureSkipTLSVerify, "insecure-skip-tls-verify", insecureSkipTLSVerify, "do not verify the TLS certificate for storage requests only. This is susceptible to man-in-the-middle attacks.")

return c
}
14 changes: 8 additions & 6 deletions pkg/cmd/cli/backup/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ func NewDownloadCommand(f client.Factory) *cobra.Command {
}

type DownloadOptions struct {
Name string
Output string
Force bool
Timeout time.Duration
writeOptions int
Name string
Output string
Force bool
Timeout time.Duration
InsecureSkipTLSVerify bool
writeOptions int
}

func NewDownloadOptions() *DownloadOptions {
Expand All @@ -69,6 +70,7 @@ func (o *DownloadOptions) BindFlags(flags *pflag.FlagSet) {
flags.StringVarP(&o.Output, "output", "o", o.Output, "path to output file. Defaults to <NAME>-data.tar.gz in the current directory")
flags.BoolVar(&o.Force, "force", o.Force, "forces the download and will overwrite file if it exists already")
flags.DurationVar(&o.Timeout, "timeout", o.Timeout, "maximum time to wait to process download request")
flags.BoolVar(&o.InsecureSkipTLSVerify, "insecure-skip-tls-verify", o.InsecureSkipTLSVerify, "do not verify the TLS certificate for storage requests only. This is susceptible to man-in-the-middle attacks.")
}

func (o *DownloadOptions) Validate(c *cobra.Command, args []string, f client.Factory) error {
Expand Down Expand Up @@ -111,7 +113,7 @@ func (o *DownloadOptions) Run(c *cobra.Command, f client.Factory) error {
}
defer backupDest.Close()

err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), o.Name, v1.DownloadTargetKindBackupContents, backupDest, o.Timeout)
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), o.Name, v1.DownloadTargetKindBackupContents, backupDest, o.Timeout, o.InsecureSkipTLSVerify)
if err != nil {
os.Remove(o.Output)
cmd.CheckError(err)
Expand Down
4 changes: 3 additions & 1 deletion pkg/cmd/cli/backup/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (

func NewLogsCommand(f client.Factory) *cobra.Command {
timeout := time.Minute
insecureSkipTLSVerify := false

c := &cobra.Command{
Use: "logs BACKUP",
Expand All @@ -58,12 +59,13 @@ func NewLogsCommand(f client.Factory) *cobra.Command {
"until the backup has a phase of Completed or Failed and try again.", backupName)
}

err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), backupName, v1.DownloadTargetKindBackupLog, os.Stdout, timeout)
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), backupName, v1.DownloadTargetKindBackupLog, os.Stdout, timeout, insecureSkipTLSVerify)
cmd.CheckError(err)
},
}

c.Flags().DurationVar(&timeout, "timeout", timeout, "how long to wait to receive logs")
c.Flags().BoolVar(&insecureSkipTLSVerify, "insecure-skip-tls-verify", insecureSkipTLSVerify, "do not verify the TLS certificate for storage requests only. This is susceptible to man-in-the-middle attacks.")

return c
}
8 changes: 5 additions & 3 deletions pkg/cmd/cli/restore/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ import (

func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
var (
listOptions metav1.ListOptions
details bool
listOptions metav1.ListOptions
details bool
insecureSkipTLSVerify bool
)

c := &cobra.Command{
Expand Down Expand Up @@ -64,7 +65,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {
fmt.Fprintf(os.Stderr, "error getting PodVolumeRestores for restore %s: %v\n", restore.Name, err)
}

s := output.DescribeRestore(&restore, podvolumeRestoreList.Items, details, veleroClient)
s := output.DescribeRestore(&restore, podvolumeRestoreList.Items, details, veleroClient, insecureSkipTLSVerify)
if first {
first = false
fmt.Print(s)
Expand All @@ -78,6 +79,7 @@ func NewDescribeCommand(f client.Factory, use string) *cobra.Command {

c.Flags().StringVarP(&listOptions.LabelSelector, "selector", "l", listOptions.LabelSelector, "only show items matching this label selector")
c.Flags().BoolVar(&details, "details", details, "display additional detail in the command output")
c.Flags().BoolVar(&insecureSkipTLSVerify, "insecure-skip-tls-verify", insecureSkipTLSVerify, "do not verify the TLS certificate for storage requests only. This is susceptible to man-in-the-middle attacks.")

return c
}
4 changes: 3 additions & 1 deletion pkg/cmd/cli/restore/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (

func NewLogsCommand(f client.Factory) *cobra.Command {
timeout := time.Minute
insecureSkipTLSVerify := false

c := &cobra.Command{
Use: "logs RESTORE",
Expand All @@ -58,12 +59,13 @@ func NewLogsCommand(f client.Factory) *cobra.Command {
"until the restore has a phase of Completed or Failed and try again.", restoreName)
}

err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), restoreName, v1.DownloadTargetKindRestoreLog, os.Stdout, timeout)
err = downloadrequest.Stream(veleroClient.VeleroV1(), f.Namespace(), restoreName, v1.DownloadTargetKindRestoreLog, os.Stdout, timeout, insecureSkipTLSVerify)
cmd.CheckError(err)
},
}

c.Flags().DurationVar(&timeout, "timeout", timeout, "how long to wait to receive logs")
c.Flags().BoolVar(&insecureSkipTLSVerify, "insecure-skip-tls-verify", insecureSkipTLSVerify, "do not verify the TLS certificate for storage requests only. This is susceptible to man-in-the-middle attacks.")

return c
}
15 changes: 14 additions & 1 deletion pkg/cmd/util/downloadrequest/downloadrequest.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ package downloadrequest

import (
"compress/gzip"
"crypto/tls"
"crypto/x509"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"time"

"github.com/pkg/errors"
Expand All @@ -36,7 +39,7 @@ import (
// not found
var ErrNotFound = errors.New("file not found")

func Stream(client velerov1client.DownloadRequestsGetter, namespace, name string, kind v1.DownloadTargetKind, w io.Writer, timeout time.Duration) error {
func Stream(client velerov1client.DownloadRequestsGetter, namespace, name string, kind v1.DownloadTargetKind, w io.Writer, timeout time.Duration, insecureSkipTLSVerify bool) error {
req := &v1.DownloadRequest{
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
Expand Down Expand Up @@ -105,6 +108,11 @@ Loop:
}

httpClient := new(http.Client)
if insecureSkipTLSVerify {
httpClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
}

httpReq, err := http.NewRequest("GET", req.Status.DownloadURL, nil)
if err != nil {
Expand All @@ -118,6 +126,11 @@ Loop:

resp, err := httpClient.Do(httpReq)
if err != nil {
if urlErr, ok := err.(*url.Error); ok {
if _, ok := urlErr.Err.(x509.UnknownAuthorityError); ok {
return fmt.Errorf(err.Error() + "\n\nThe --insecure-skip-tls-verify flag can also be used to accept any TLS certificate for the download, but it is susceptible to man-in-the-middle attacks.")
}
}
return err
}
defer resp.Body.Close()
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/util/downloadrequest/downloadrequest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func TestStream(t *testing.T) {
output := new(bytes.Buffer)
errCh := make(chan error)
go func() {
err := Stream(client.VeleroV1(), "namespace", "name", test.kind, output, timeout)
err := Stream(client.VeleroV1(), "namespace", "name", test.kind, output, timeout, false)
errCh <- err
}()

Expand Down
13 changes: 7 additions & 6 deletions pkg/cmd/util/output/backup_describer.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func DescribeBackup(
podVolumeBackups []velerov1api.PodVolumeBackup,
details bool,
veleroClient clientset.Interface,
insecureSkipTLSVerify bool,
) string {
return Describe(func(d *Describer) {
d.DescribeMetadata(backup.ObjectMeta)
Expand Down Expand Up @@ -74,7 +75,7 @@ func DescribeBackup(
DescribeBackupSpec(d, backup.Spec)

d.Println()
DescribeBackupStatus(d, backup, details, veleroClient)
DescribeBackupStatus(d, backup, details, veleroClient, insecureSkipTLSVerify)

if len(deleteRequests) > 0 {
d.Println()
Expand Down Expand Up @@ -211,7 +212,7 @@ func DescribeBackupSpec(d *Describer, spec velerov1api.BackupSpec) {
}

// DescribeBackupStatus describes a backup status in human-readable format.
func DescribeBackupStatus(d *Describer, backup *velerov1api.Backup, details bool, veleroClient clientset.Interface) {
func DescribeBackupStatus(d *Describer, backup *velerov1api.Backup, details bool, veleroClient clientset.Interface, insecureSkipTLSVerify bool) {
status := backup.Status

d.Printf("Backup Format Version:\t%d\n", status.Version)
Expand All @@ -234,7 +235,7 @@ func DescribeBackupStatus(d *Describer, backup *velerov1api.Backup, details bool
d.Println()

if details {
describeBackupResourceList(d, backup, veleroClient)
describeBackupResourceList(d, backup, veleroClient, insecureSkipTLSVerify)
d.Println()
}

Expand All @@ -245,7 +246,7 @@ func DescribeBackupStatus(d *Describer, backup *velerov1api.Backup, details bool
}

buf := new(bytes.Buffer)
if err := downloadrequest.Stream(veleroClient.VeleroV1(), backup.Namespace, backup.Name, velerov1api.DownloadTargetKindBackupVolumeSnapshots, buf, downloadRequestTimeout); err != nil {
if err := downloadrequest.Stream(veleroClient.VeleroV1(), backup.Namespace, backup.Name, velerov1api.DownloadTargetKindBackupVolumeSnapshots, buf, downloadRequestTimeout, insecureSkipTLSVerify); err != nil {
d.Printf("Persistent Volumes:\t<error getting volume snapshot info: %v>\n", err)
return
}
Expand All @@ -266,9 +267,9 @@ func DescribeBackupStatus(d *Describer, backup *velerov1api.Backup, details bool
d.Printf("Persistent Volumes: <none included>\n")
}

func describeBackupResourceList(d *Describer, backup *velerov1api.Backup, veleroClient clientset.Interface) {
func describeBackupResourceList(d *Describer, backup *velerov1api.Backup, veleroClient clientset.Interface, insecureSkipTLSVerify bool) {
buf := new(bytes.Buffer)
if err := downloadrequest.Stream(veleroClient.VeleroV1(), backup.Namespace, backup.Name, velerov1api.DownloadTargetKindBackupResourceList, buf, downloadRequestTimeout); err != nil {
if err := downloadrequest.Stream(veleroClient.VeleroV1(), backup.Namespace, backup.Name, velerov1api.DownloadTargetKindBackupResourceList, buf, downloadRequestTimeout, insecureSkipTLSVerify); err != nil {
if err == downloadrequest.ErrNotFound {
d.Println("Resource List:\t<backup resource list not found, this could be because this backup was taken prior to Velero 1.1.0>")
} else {
Expand Down
8 changes: 4 additions & 4 deletions pkg/cmd/util/output/restore_describer.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
pkgrestore "github.com/heptio/velero/pkg/restore"
)

func DescribeRestore(restore *v1.Restore, podVolumeRestores []v1.PodVolumeRestore, details bool, veleroClient clientset.Interface) string {
func DescribeRestore(restore *v1.Restore, podVolumeRestores []v1.PodVolumeRestore, details bool, veleroClient clientset.Interface, insecureSkipTLSVerify bool) string {
return Describe(func(d *Describer) {
d.DescribeMetadata(restore.ObjectMeta)

Expand All @@ -56,7 +56,7 @@ func DescribeRestore(restore *v1.Restore, podVolumeRestores []v1.PodVolumeRestor
}
}

describeRestoreResults(d, restore, veleroClient)
describeRestoreResults(d, restore, veleroClient, insecureSkipTLSVerify)

d.Println()
d.Printf("Backup:\t%s\n", restore.Spec.BackupName)
Expand Down Expand Up @@ -114,15 +114,15 @@ func DescribeRestore(restore *v1.Restore, podVolumeRestores []v1.PodVolumeRestor
})
}

func describeRestoreResults(d *Describer, restore *v1.Restore, veleroClient clientset.Interface) {
func describeRestoreResults(d *Describer, restore *v1.Restore, veleroClient clientset.Interface, insecureSkipTLSVerify bool) {
if restore.Status.Warnings == 0 && restore.Status.Errors == 0 {
return
}

var buf bytes.Buffer
var resultMap map[string]pkgrestore.Result

if err := downloadrequest.Stream(veleroClient.VeleroV1(), restore.Namespace, restore.Name, v1.DownloadTargetKindRestoreResults, &buf, downloadRequestTimeout); err != nil {
if err := downloadrequest.Stream(veleroClient.VeleroV1(), restore.Namespace, restore.Name, v1.DownloadTargetKindRestoreResults, &buf, downloadRequestTimeout, insecureSkipTLSVerify); err != nil {
d.Printf("Warnings:\t<error getting warnings: %v>\n\nErrors:\t<error getting errors: %v>\n", err, err)
return
}
Expand Down
1 change: 1 addition & 0 deletions site/docs/master/api-types/backupstoragelocation.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ The configurable parameters are as follows:
| `kmsKeyId` | string | Empty | *Example*: "502b409c-4da1-419f-a16e-eif453b3i49f" or "alias/`<KMS-Key-Alias-Name>`"<br><br>Specify an [AWS KMS key][10] id or alias to enable encryption of the backups stored in S3. Only works with AWS S3 and may require explicitly granting key usage rights.|
| `signatureVersion` | string | `"4"` | Version of the signature algorithm used to create signed URLs that are used by velero cli to download backups or fetch logs. Possible versions are "1" and "4". Usually the default version 4 is correct, but some S3-compatible providers like Quobyte only support version 1.|
| `profile` | string | "default" | AWS profile within the credential file to use for given store |
| `insecureSkipTLSVerify` | bool | `false` | Set this to `true` if you do not want to verify the TLS certificate for storage requests only--like self-signed certs in Minio. This is susceptible to man-in-the-middle attacks and is not recommended for production. |

#### Azure

Expand Down