Compare commits

...

15 Commits

Author SHA1 Message Date
Sudarsan Reddy d6d65d183b Release 2021.5.10 2021-05-26 12:05:30 +01:00
Sudarsan Reddy 951d13d76c TUN-4456: Replaced instances of Tick() with Ticker() in h2mux paths
time.Tick() does not get garbage collected because the channel
underneath never gets deleted and the underlying Ticker can never be
recovered by the garbage collector. We replace this with NewTicker() to
avoid this.
2021-05-25 18:07:06 +01:00
Michael Borkenstein f99ae90ca1 Release 2021.5.9 2021-05-20 14:08:22 -05:00
Michael Borkenstein e99d0b5bc4 Update changelog 2021-05-20 13:09:07 -05:00
Michael Borkenstein 48c5721bc6 TUN-4426: Fix centos builds 2021-05-20 11:29:14 -05:00
Michael Borkenstein 235897ba21 AUTH-3426: Point to new transfer service URL and eliminate PUT /ok 2021-05-19 19:39:56 +00:00
Adam Chalmers bf737a0efc Release 2021.5.8 2021-05-19 13:30:15 -05:00
Adam Chalmers 4c5ebccacc TUN-4425: --overwrite-dns flag for in adhoc and route dns cmds 2021-05-19 18:22:01 +00:00
Adam Chalmers a3153c6add TUN-4419: Improve error message when cloudflared cannot reach origin 2021-05-18 15:35:51 +00:00
cthuang a2bbe1bdc2 Release 2021.5.7 2021-05-17 17:12:21 +01:00
cthuang 6526211a69 TUN-4421: Named Tunnels will automatically select the protocol to connect to Cloudflare's edge network 2021-05-17 15:57:44 +01:00
Silver 103b2eca00 Merge pull request #371 from thundergolfer/patch-1
Fix typo in Changes.md
2021-05-17 11:18:55 +01:00
Jonathon Belotti 14ea6298bc Fix typo in Changes.md 2021-05-17 12:03:59 +10:00
Adam Chalmers b297e8bb90 Release 2021.5.6 2021-05-14 18:22:58 -05:00
Igor Postelnik 6cc8c39fa8 Release 2021.5.5 2021-05-14 17:51:08 -05:00
12 changed files with 114 additions and 65 deletions
+19 -1
View File
@@ -1,6 +1,24 @@
**Experimental**: This is a new format for release notes. The format and availability is subject to change.
## 2020.5.0
## 2021.5.9
### New Features
- Uses new Worker based login helper service to facilitate token exchange in cloudflared flows.
### Bug Fixes
- Fixes Centos-7 builds.
## 2021.5.8
### New Features
- When creating a DNS record to point a hostname at a tunnel, you can now use --overwrite-dns to overwrite any existing
DNS records with that hostname. This works when using the CLI to provision DNS, and when starting an adhoc tunnel, e.g.
- `cloudflared route --overwrite-dns dns foo foo.example.com`
- `cloudflared tunnel --overwrite-dns --name foo --hostname foo.example.com`
## 2021.5.7
### New Features
- Named Tunnels will automatically select the protocol to connect to Cloudflare's edge network.
## 2021.5.0
### New Features
- It is now possible to run the same tunnel using more than one `cloudflared` instance. This is a server-side change and
+22
View File
@@ -1,3 +1,25 @@
2021.5.10
- 2021-05-25 TUN-4456: Replaced instances of Tick() with Ticker() in h2mux paths
2021.5.9
- 2021-05-20 TUN-4426: Fix centos builds
- 2021-05-20 Update changelog
- 2021-04-30 AUTH-3426: Point to new transfer service URL and eliminate PUT /ok
2021.5.8
- 2021-05-14 TUN-4419: Improve error message when cloudflared cannot reach origin
- 2021-05-19 TUN-4425: --overwrite-dns flag for in adhoc and route dns cmds
2021.5.7
- 2021-05-17 Fix typo in Changes.md
- 2021-05-17 TUN-4421: Named Tunnels will automatically select the protocol to connect to Cloudflare's edge network
2021.5.6
- 2021-05-14 TUN-4418: Downgrade to Go 1.16.3
2021.5.5
2021.5.4
- Fix release pipeline
+7 -5
View File
@@ -1,4 +1,4 @@
pinned_go: &pinned_go go=1.16.4-1
pinned_go: &pinned_go go=1.16.3-1
pinned_go_fips: &pinned_go_fips go-fips=1.15.5-3
build_dir: &build_dir /cfsetup_build
@@ -279,8 +279,9 @@ centos-7:
- https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
pre-cache:
- yum install -y fakeroot
- wget https://golang.org/dl/go1.16.4.linux-amd64.tar.gz -P /tmp/
- tar -C /usr/local -xzf /tmp/go1.16.4.linux-amd64.tar.gz
- yum upgrade -y binutils-2.27-44.base.el7.x86_64
- wget https://golang.org/dl/go1.16.3.linux-amd64.tar.gz -P /tmp/
- tar -C /usr/local -xzf /tmp/go1.16.3.linux-amd64.tar.gz
post-cache:
- export PATH=$PATH:/usr/local/go/bin
- export GOOS=linux
@@ -291,8 +292,9 @@ centos-7:
builddeps: *el7_builddeps
pre-cache:
- yum install -y fakeroot
- wget https://golang.org/dl/go1.16.4.linux-amd64.tar.gz -P /tmp/
- tar -C /usr/local -xzf /tmp/go1.16.4.linux-amd64.tar.gz
- yum upgrade -y binutils-2.27-44.base.el7.x86_64
- wget https://golang.org/dl/go1.16.3.linux-amd64.tar.gz -P /tmp/
- tar -C /usr/local -xzf /tmp/go1.16.3.linux-amd64.tar.gz
post-cache:
- export PATH=$PATH:/usr/local/go/bin
- export GOOS=linux
+8 -3
View File
@@ -87,6 +87,10 @@ const (
var (
graceShutdownC chan struct{}
version string
routeFailMsg = fmt.Sprintf("failed to provision routing, please create it manually via Cloudflare dashboard or UI; "+
"most likely you already have a conflicting record there. You can also rerun this command with --%s to overwrite "+
"any existing DNS records for this hostname.", overwriteDNSFlag)
)
func Flags() []cli.Flag {
@@ -181,7 +185,7 @@ func runAdhocNamedTunnel(sc *subcommandContext, name, credentialsOutputPath stri
if r, ok := routeFromFlag(sc.c); ok {
if res, err := sc.route(tunnel.ID, r); err != nil {
sc.log.Err(err).Str("route", r.String()).Msg("failed to provision routing, please create it manually via Cloudflare dashboard or UI; most likely you already have a conflicting record there")
sc.log.Err(err).Str("route", r.String()).Msg(routeFailMsg)
} else {
sc.log.Info().Msg(res.SuccessSummary())
}
@@ -199,12 +203,12 @@ func runClassicTunnel(sc *subcommandContext) error {
return StartServer(sc.c, version, nil, sc.log, sc.isUIEnabled)
}
func routeFromFlag(c *cli.Context) (tunnelstore.Route, bool) {
func routeFromFlag(c *cli.Context) (route tunnelstore.Route, ok bool) {
if hostname := c.String("hostname"); hostname != "" {
if lbPool := c.String("lb-pool"); lbPool != "" {
return tunnelstore.NewLBRoute(hostname, lbPool), true
}
return tunnelstore.NewDNSRoute(hostname), true
return tunnelstore.NewDNSRoute(hostname, c.Bool(overwriteDNSFlagName)), true
}
return nil, false
}
@@ -613,6 +617,7 @@ func tunnelFlags(shouldHide bool) []cli.Flag {
Hidden: shouldHide,
}),
selectProtocolFlag,
overwriteDNSFlag,
}...)
return flags
+1 -1
View File
@@ -20,7 +20,7 @@ import (
const (
baseLoginURL = "https://dash.cloudflare.com/argotunnel"
callbackStoreURL = "https://login.argotunnel.com/"
callbackStoreURL = "https://login.cloudflareaccess.org/"
)
func buildLoginSubcommand(hidden bool) *cli.Command {
+16 -8
View File
@@ -29,10 +29,11 @@ import (
)
const (
allSortByOptions = "name, id, createdAt, deletedAt, numConnections"
connsSortByOptions = "id, startedAt, numConnections, version"
CredFileFlagAlias = "cred-file"
CredFileFlag = "credentials-file"
allSortByOptions = "name, id, createdAt, deletedAt, numConnections"
connsSortByOptions = "id, startedAt, numConnections, version"
CredFileFlagAlias = "cred-file"
CredFileFlag = "credentials-file"
overwriteDNSFlagName = "overwrite-dns"
LogFieldTunnelID = "tunnelID"
)
@@ -110,7 +111,7 @@ var (
}
selectProtocolFlag = altsrc.NewStringFlag(&cli.StringFlag{
Name: "protocol",
Value: "h2mux",
Value: "auto",
Aliases: []string{"p"},
Usage: fmt.Sprintf("Protocol implementation to connect with Cloudflare's edge network. %s", connection.AvailableProtocolFlagMessage),
EnvVars: []string{"TUNNEL_TRANSPORT_PROTOCOL"},
@@ -133,6 +134,12 @@ var (
Usage: `Constraints the cleanup to stop the connections of a single Connector (by its ID). You can find the various Connectors (and their IDs) currently connected to your tunnel via 'cloudflared tunnel info <name>'.`,
EnvVars: []string{"TUNNEL_CLEANUP_CONNECTOR"},
}
overwriteDNSFlag = &cli.BoolFlag{
Name: overwriteDNSFlagName,
Aliases: []string{"f"},
Usage: `Overwrites existing DNS records with this hostname`,
EnvVars: []string{"TUNNEL_FORCE_PROVISIONING_DNS"},
}
)
func buildCreateCommand() *cli.Command {
@@ -670,10 +677,11 @@ Further information about managing Cloudflare WARP traffic to your tunnel is ava
Subcommands: []*cli.Command{
buildRouteIPSubcommand(),
},
Flags: []cli.Flag{overwriteDNSFlag},
}
}
func dnsRouteFromArg(c *cli.Context) (tunnelstore.Route, error) {
func dnsRouteFromArg(c *cli.Context, overwriteExisting bool) (tunnelstore.Route, error) {
const (
userHostnameIndex = 2
expectedNArgs = 3
@@ -687,7 +695,7 @@ func dnsRouteFromArg(c *cli.Context) (tunnelstore.Route, error) {
} else if !validateHostname(userHostname, true) {
return nil, errors.Errorf("%s is not a valid hostname", userHostname)
}
return tunnelstore.NewDNSRoute(userHostname), nil
return tunnelstore.NewDNSRoute(userHostname, overwriteExisting), nil
}
func lbRouteFromArg(c *cli.Context) (tunnelstore.Route, error) {
@@ -756,7 +764,7 @@ func routeCommand(c *cli.Context) error {
if err != nil {
return err
}
route, err = dnsRouteFromArg(c)
route, err = dnsRouteFromArg(c, c.Bool(overwriteDNSFlagName))
if err != nil {
return err
}
+3 -2
View File
@@ -167,7 +167,8 @@ func (h *h2muxConnection) serveMuxer(ctx context.Context) error {
}
func (h *h2muxConnection) controlLoop(ctx context.Context, connectedFuse ConnectedFuse, isNamedTunnel bool) {
updateMetricsTickC := time.Tick(h.muxerConfig.MetricsUpdateFreq)
updateMetricsTicker := time.NewTicker(h.muxerConfig.MetricsUpdateFreq)
defer updateMetricsTicker.Stop()
var shutdownCompleted <-chan struct{}
for {
select {
@@ -191,7 +192,7 @@ func (h *h2muxConnection) controlLoop(ctx context.Context, connectedFuse Connect
// don't wait for shutdown to finish when context is closed, this is the hard termination path
return
case <-updateMetricsTickC:
case <-updateMetricsTicker.C:
h.observer.metrics.updateMuxerMetrics(h.connIndexStr, h.muxer.Metrics())
}
}
+3 -2
View File
@@ -69,12 +69,13 @@ func (r *MuxReader) run(log *zerolog.Logger) error {
// routine to periodically update bytesRead
go func() {
tickC := time.Tick(updateFreq)
ticker := time.NewTicker(updateFreq)
defer ticker.Stop()
for {
select {
case <-r.abortChan:
return
case <-tickC:
case <-ticker.C:
r.metricsUpdater.updateInBoundBytes(r.bytesRead.Count())
}
}
+3 -2
View File
@@ -78,12 +78,13 @@ func (w *MuxWriter) run(log *zerolog.Logger) error {
// routine to periodically communicate bytesWrote
go func() {
tickC := time.Tick(updateFreq)
ticker := time.NewTicker(updateFreq)
defer ticker.Stop()
for {
select {
case <-w.abortChan:
return
case <-tickC:
case <-ticker.C:
w.metricsUpdater.updateOutBoundBytes(w.bytesWrote.Count())
}
}
+18 -11
View File
@@ -18,9 +18,10 @@ import (
)
const (
TagHeaderNamePrefix = "Cf-Warp-Tag-"
LogFieldCFRay = "cfRay"
LogFieldRule = "ingressRule"
TagHeaderNamePrefix = "Cf-Warp-Tag-"
LogFieldCFRay = "cfRay"
LogFieldRule = "ingressRule"
LogFieldOriginService = "originService"
)
type proxy struct {
@@ -70,7 +71,7 @@ func (p *proxy) Proxy(w connection.ResponseWriter, req *http.Request, sourceConn
rule: ingress.ServiceWarpRouting,
}
if err := p.proxyStreamRequest(serveCtx, w, req, p.warpRouting.Proxy, logFields); err != nil {
p.logRequestError(err, cfRay, ingress.ServiceWarpRouting)
p.logRequestError(err, cfRay, "", ingress.ServiceWarpRouting)
return err
}
return nil
@@ -86,7 +87,8 @@ func (p *proxy) Proxy(w connection.ResponseWriter, req *http.Request, sourceConn
if sourceConnectionType == connection.TypeHTTP {
if err := p.proxyHTTPRequest(w, req, rule, logFields); err != nil {
p.logRequestError(err, cfRay, ruleField(p.ingressRules, ruleNum))
rule, srv := ruleField(p.ingressRules, ruleNum)
p.logRequestError(err, cfRay, rule, srv)
return err
}
return nil
@@ -99,17 +101,19 @@ func (p *proxy) Proxy(w connection.ResponseWriter, req *http.Request, sourceConn
}
if err := p.proxyStreamRequest(serveCtx, w, req, connectionProxy, logFields); err != nil {
p.logRequestError(err, cfRay, ruleField(p.ingressRules, ruleNum))
rule, srv := ruleField(p.ingressRules, ruleNum)
p.logRequestError(err, cfRay, rule, srv)
return err
}
return nil
}
func ruleField(ing ingress.Ingress, ruleNum int) string {
func ruleField(ing ingress.Ingress, ruleNum int) (ruleID string, srv string) {
srv = ing.Rules[ruleNum].Service.String()
if ing.IsSingleRule() {
return ""
return "", srv
}
return fmt.Sprintf("%d", ruleNum)
return fmt.Sprintf("%d", ruleNum), srv
}
func (p *proxy) proxyHTTPRequest(w connection.ResponseWriter, req *http.Request, rule *ingress.Rule, fields logFields) error {
@@ -133,7 +137,7 @@ func (p *proxy) proxyHTTPRequest(w connection.ResponseWriter, req *http.Request,
resp, err := httpService.RoundTrip(req)
if err != nil {
return errors.Wrap(err, "Error proxying request to origin")
return errors.Wrap(err, "Unable to reach the origin service. The service may be down or it may not be responding to traffic from cloudflared")
}
defer resp.Body.Close()
@@ -271,7 +275,7 @@ func (p *proxy) logOriginResponse(resp *http.Response, fields logFields) {
}
}
func (p *proxy) logRequestError(err error, cfRay string, rule string) {
func (p *proxy) logRequestError(err error, cfRay string, rule, service string) {
requestErrors.Inc()
log := p.log.Error().Err(err)
if cfRay != "" {
@@ -280,6 +284,9 @@ func (p *proxy) logRequestError(err error, cfRay string, rule string) {
if rule != "" {
log = log.Str(LogFieldRule, rule)
}
if service != "" {
log = log.Str(LogFieldOriginService, service)
}
log.Msg("")
}
+3 -23
View File
@@ -15,7 +15,7 @@ import (
)
const (
baseStoreURL = "https://login.argotunnel.com/"
baseStoreURL = "https://login.cloudflareaccess.org/"
clientTimeout = time.Second * 60
)
@@ -83,11 +83,13 @@ func buildRequestURL(baseURL *url.URL, key, value string, cli, useHostOnly bool)
if useHostOnly {
baseURL.Path = ""
}
// TODO: pass arg for tunnel login
if !cli {
return baseURL.String(), nil
}
q.Set("redirect_url", baseURL.String()) // we add the token as a query param on both the redirect_url and the main url
q.Set("send_org_token", "true") // indicates that the cli endpoint should return both the org and app token
q.Set("edge_token_transfer", "true") // use new LoginHelper service built on workers
baseURL.RawQuery = q.Encode() // and this actual baseURL.
baseURL.Path = "cdn-cgi/access/cli"
return baseURL.String(), nil
@@ -103,9 +105,6 @@ func transferRequest(requestURL string, log *zerolog.Logger) ([]byte, string, er
if err != nil {
return nil, "", err
} else if len(buf) > 0 {
if err := putSuccess(client, requestURL); err != nil {
log.Err(err).Msg("Failed to update resource success")
}
return buf, key, nil
}
}
@@ -136,22 +135,3 @@ func poll(client *http.Client, requestURL string, log *zerolog.Logger) ([]byte,
}
return buf.Bytes(), resp.Header.Get("service-public-key"), nil
}
// putSuccess tells the server we successfully downloaded the resource
func putSuccess(client *http.Client, requestURL string) error {
req, err := http.NewRequest("PUT", requestURL+"/ok", nil)
if err != nil {
return err
}
resp, err := client.Do(req)
if err != nil {
return err
}
resp.Body.Close()
if resp.StatusCode != 200 {
return fmt.Errorf("HTTP Response Status Code: %d", resp.StatusCode)
}
return nil
}
+11 -7
View File
@@ -81,7 +81,8 @@ type RouteResult interface {
}
type DNSRoute struct {
userHostname string
userHostname string
overwriteExisting bool
}
type DNSRouteResult struct {
@@ -89,19 +90,22 @@ type DNSRouteResult struct {
CName Change `json:"cname"`
}
func NewDNSRoute(userHostname string) Route {
func NewDNSRoute(userHostname string, overwriteExisting bool) Route {
return &DNSRoute{
userHostname: userHostname,
userHostname: userHostname,
overwriteExisting: overwriteExisting,
}
}
func (dr *DNSRoute) MarshalJSON() ([]byte, error) {
s := struct {
Type string `json:"type"`
UserHostname string `json:"user_hostname"`
Type string `json:"type"`
UserHostname string `json:"user_hostname"`
OverwriteExisting bool `json:"overwrite_existing"`
}{
Type: dr.RecordType(),
UserHostname: dr.userHostname,
Type: dr.RecordType(),
UserHostname: dr.userHostname,
OverwriteExisting: dr.overwriteExisting,
}
return json.Marshal(&s)
}