Release Argo Tunnel Client 2018.4.3
This commit is contained in:
parent
471dde57b0
commit
3dc84750c7
|
@ -32,7 +32,7 @@ func runApp(app *cli.App) {
|
|||
}
|
||||
|
||||
var launchdTemplate = ServiceTemplate{
|
||||
Path: fmt.Sprintf("~/Library/LaunchAgents/%s.plist", launchAgentIdentifier),
|
||||
Path: installPath(launchAgentIdentifier),
|
||||
Content: fmt.Sprintf(`<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
|
@ -60,6 +60,19 @@ var launchdTemplate = ServiceTemplate{
|
|||
</plist>`, launchAgentIdentifier, launchAgentIdentifier, launchAgentIdentifier),
|
||||
}
|
||||
|
||||
func installPath(launchAgentIdentifier string) string {
|
||||
const pathPattern = "%s/Library/LaunchAgents/%s.plist"
|
||||
|
||||
pathPrefix := "~"
|
||||
|
||||
// User is root, use /Library instead of home directory
|
||||
if os.Geteuid() == 0 {
|
||||
pathPrefix = ""
|
||||
}
|
||||
|
||||
return fmt.Sprintf(pathPattern, pathPrefix, launchAgentIdentifier)
|
||||
}
|
||||
|
||||
func installLaunchd(c *cli.Context) error {
|
||||
Log.Infof("Installing Argo Tunnel as an user launch agent")
|
||||
etPath, err := os.Executable()
|
||||
|
|
|
@ -43,8 +43,6 @@ const (
|
|||
quickStartUrl = "https://developers.cloudflare.com/argo-tunnel/quickstart/quickstart/"
|
||||
noAutoupdateMessage = "cloudflared will not automatically update when run from the shell. To enable auto-updates, run cloudflared as a service: https://developers.cloudflare.com/argo-tunnel/reference/service/"
|
||||
licenseUrl = "https://developers.cloudflare.com/argo-tunnel/licence/"
|
||||
minDNSInitWait = time.Second * 15
|
||||
minPingFreq = time.Second * 2
|
||||
)
|
||||
|
||||
var listeners = gracenet.Net{}
|
||||
|
@ -295,31 +293,6 @@ func main() {
|
|||
Value: cli.NewStringSlice("https://cloudflare-dns.com/dns-query"),
|
||||
EnvVars: []string{"TUNNEL_DNS_UPSTREAM"},
|
||||
}),
|
||||
altsrc.NewBoolFlag(&cli.BoolFlag{
|
||||
Name: "skip-hostname-propagation-check",
|
||||
Usage: "Flag to instruct cloudflared to skip checking whether DNS record for the hostname has been propagated.",
|
||||
EnvVars: []string{"TUNNEL_SKIP_HOSTNAME_PROPAGATION_CHECK"},
|
||||
}),
|
||||
altsrc.NewUintFlag(&cli.UintFlag{
|
||||
Name: "hostname-propagated-retries",
|
||||
Usage: "How many pings to test whether send DNS record has been propagated before reregistering tunnel",
|
||||
Value: 25,
|
||||
EnvVars: []string{"TUNNEL_HOSTNAME_PROPAGATED_RETRIES"},
|
||||
}),
|
||||
altsrc.NewDurationFlag(&cli.DurationFlag{
|
||||
Name: "init-wait-time",
|
||||
Usage: "Initial waiting time to checking whether DNS record has propagated",
|
||||
Value: minDNSInitWait,
|
||||
EnvVars: []string{"TUNNEL_INIT_WAIT_TIME"},
|
||||
Hidden: true,
|
||||
}),
|
||||
altsrc.NewDurationFlag(&cli.DurationFlag{
|
||||
Name: "ping-freq",
|
||||
Usage: "Ping frequency for checking DNS record has propagated",
|
||||
Value: minPingFreq,
|
||||
EnvVars: []string{"TUNNEL_PING_FREQ"},
|
||||
Hidden: true,
|
||||
}),
|
||||
altsrc.NewDurationFlag(&cli.DurationFlag{
|
||||
Name: "grace-period",
|
||||
Usage: "Duration to accpet new requests after cloudflared receives first SIGINT/SIGTERM. A second SIGINT/SIGTERM will force cloudflared to shutdown immediately.",
|
||||
|
@ -602,7 +575,6 @@ If you don't have a certificate signed by Cloudflare, run the command:
|
|||
Logger: Log,
|
||||
IsAutoupdated: c.Bool("is-autoupdated"),
|
||||
GracePeriod: c.Duration("grace-period"),
|
||||
DNSValidationConfig: getDNSValidationConfig(c),
|
||||
}
|
||||
|
||||
go writePidFile(connectedSignal, c.String("pidfile"))
|
||||
|
@ -633,7 +605,7 @@ func runServer(c *cli.Context, wg *sync.WaitGroup, errC chan error, shutdownC ch
|
|||
raven.CaptureErrorAndWait(err, nil)
|
||||
errCode = 1
|
||||
} else {
|
||||
Log.Info("Quitting...")
|
||||
Log.Info("Graceful shutdown...")
|
||||
}
|
||||
// Wait for clean exit, discarding all errors
|
||||
go func() {
|
||||
|
@ -855,19 +827,3 @@ func isAutoupdateEnabled(c *cli.Context) bool {
|
|||
|
||||
return !c.Bool("no-autoupdate") && c.Duration("autoupdate-freq") != 0
|
||||
}
|
||||
|
||||
func getDNSValidationConfig(c *cli.Context) *origin.DNSValidationConfig {
|
||||
dnsValidationConfig := &origin.DNSValidationConfig{
|
||||
VerifyDNSPropagated: !c.Bool("skip-hostname-propagation-check"),
|
||||
DNSPingRetries: c.Uint("hostname-propagated-retries"),
|
||||
DNSInitWaitTime: c.Duration("init-wait-time"),
|
||||
PingFreq: c.Duration("ping-freq"),
|
||||
}
|
||||
if dnsValidationConfig.DNSInitWaitTime < minDNSInitWait {
|
||||
dnsValidationConfig.DNSInitWaitTime = minDNSInitWait
|
||||
}
|
||||
if dnsValidationConfig.PingFreq < minPingFreq {
|
||||
dnsValidationConfig.PingFreq = minPingFreq
|
||||
}
|
||||
return dnsValidationConfig
|
||||
}
|
||||
|
|
|
@ -3,10 +3,8 @@ package origin
|
|||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
@ -144,12 +142,6 @@ func (s *Supervisor) initialize(ctx context.Context, connectedSignal chan struct
|
|||
return tunnelError.err
|
||||
case <-connectedSignal:
|
||||
}
|
||||
if s.config.VerifyDNSPropagated {
|
||||
err = s.verifyDNSPropagated(ctx)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Failed to register tunnel")
|
||||
}
|
||||
}
|
||||
// At least one successful connection, so start the rest
|
||||
for i := 1; i < s.config.HAConnections; i++ {
|
||||
go s.startTunnel(ctx, i, make(chan struct{}))
|
||||
|
@ -186,53 +178,6 @@ func (s *Supervisor) startFirstTunnel(ctx context.Context, connectedSignal chan
|
|||
}
|
||||
}
|
||||
|
||||
func (s *Supervisor) verifyDNSPropagated(ctx context.Context) (err error) {
|
||||
Log.Infof("Waiting for %s DNS record to propagate...", s.config.Hostname)
|
||||
time.Sleep(s.config.DNSInitWaitTime)
|
||||
var lastResponseStatus string
|
||||
tickC := time.Tick(s.config.PingFreq)
|
||||
req, client, err := s.createPingRequestAndClient()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot create GET request to %s", s.config.Hostname)
|
||||
}
|
||||
for i := 0; i < int(s.config.DNSPingRetries); i++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("Context was canceled")
|
||||
case <-tickC:
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
Log.Infof("Tunnel created and available at %s", s.config.Hostname)
|
||||
return nil
|
||||
}
|
||||
if i == 0 {
|
||||
Log.Infof("First ping to origin through Argo Tunnel returned %s", resp.Status)
|
||||
}
|
||||
lastResponseStatus = resp.Status
|
||||
}
|
||||
}
|
||||
Log.Infof("Last ping to origin through Argo Tunnel returned %s", lastResponseStatus)
|
||||
return fmt.Errorf("Exceed DNS record validation retry limit")
|
||||
}
|
||||
|
||||
func (s *Supervisor) createPingRequestAndClient() (*http.Request, *http.Client, error) {
|
||||
url := fmt.Sprintf("https://%s", s.config.Hostname)
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
req.Header.Add(CloudflaredPingHeader, s.config.ClientID)
|
||||
transport := s.config.HTTPTransport
|
||||
if transport == nil {
|
||||
transport = http.DefaultTransport
|
||||
}
|
||||
return req, &http.Client{Transport: transport}, nil
|
||||
}
|
||||
|
||||
// startTunnel starts a new tunnel connection. The resulting error will be sent on
|
||||
// s.tunnelErrors.
|
||||
func (s *Supervisor) startTunnel(ctx context.Context, index int, connectedSignal chan struct{}) {
|
||||
|
|
|
@ -35,16 +35,8 @@ const (
|
|||
|
||||
TagHeaderNamePrefix = "Cf-Warp-Tag-"
|
||||
DuplicateConnectionError = "EDUPCONN"
|
||||
CloudflaredPingHeader = "Cloudflard-Ping"
|
||||
)
|
||||
|
||||
type DNSValidationConfig struct {
|
||||
VerifyDNSPropagated bool
|
||||
DNSPingRetries uint
|
||||
DNSInitWaitTime time.Duration
|
||||
PingFreq time.Duration
|
||||
}
|
||||
|
||||
type TunnelConfig struct {
|
||||
EdgeAddrs []string
|
||||
OriginUrl string
|
||||
|
@ -67,7 +59,6 @@ type TunnelConfig struct {
|
|||
Logger *logrus.Logger
|
||||
IsAutoupdated bool
|
||||
GracePeriod time.Duration
|
||||
*DNSValidationConfig
|
||||
}
|
||||
|
||||
type dialError struct {
|
||||
|
@ -410,7 +401,6 @@ type TunnelHandler struct {
|
|||
metrics *tunnelMetrics
|
||||
// connectionID is only used by metrics, and prometheus requires labels to be string
|
||||
connectionID string
|
||||
clientID string
|
||||
}
|
||||
|
||||
var dialer = net.Dialer{DualStack: true}
|
||||
|
@ -428,7 +418,6 @@ func NewTunnelHandler(ctx context.Context, config *TunnelConfig, addr string, co
|
|||
tags: config.Tags,
|
||||
metrics: config.Metrics,
|
||||
connectionID: uint8ToString(connectionID),
|
||||
clientID: config.ClientID,
|
||||
}
|
||||
if h.httpClient == nil {
|
||||
h.httpClient = http.DefaultTransport
|
||||
|
@ -484,10 +473,6 @@ func (h *TunnelHandler) ServeStream(stream *h2mux.MuxedStream) error {
|
|||
h.AppendTagHeaders(req)
|
||||
cfRay := FindCfRayHeader(req)
|
||||
h.logRequest(req, cfRay)
|
||||
if h.isCloudflaredPing(req) {
|
||||
stream.WriteHeaders([]h2mux.Header{{Name: ":status", Value: fmt.Sprintf("%d", http.StatusOK)}})
|
||||
return nil
|
||||
}
|
||||
if websocket.IsWebSocketUpgrade(req) {
|
||||
conn, response, err := websocket.ClientConnect(req, h.tlsConfig)
|
||||
if err != nil {
|
||||
|
@ -515,13 +500,6 @@ func (h *TunnelHandler) ServeStream(stream *h2mux.MuxedStream) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (h *TunnelHandler) isCloudflaredPing(h1 *http.Request) bool {
|
||||
if h1.Header.Get(CloudflaredPingHeader) == h.clientID {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (h *TunnelHandler) logError(stream *h2mux.MuxedStream, err error) {
|
||||
Log.WithError(err).Error("HTTP request error")
|
||||
stream.WriteHeaders([]h2mux.Header{{Name: ":status", Value: "502"}})
|
||||
|
|
Loading…
Reference in New Issue