Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-workhorse
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-workhorse
Commits
b46237ac
Commit
b46237ac
authored
Apr 24, 2018
by
Jacob Vosmaer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Guess RemoteAddr from X-Forwarded-For
parent
31b10f9e
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
233 additions
and
0 deletions
+233
-0
internal/upstream/upstream.go
internal/upstream/upstream.go
+5
-0
vendor/github.com/sebest/xff/LICENSE
vendor/github.com/sebest/xff/LICENSE
+20
-0
vendor/github.com/sebest/xff/README.md
vendor/github.com/sebest/xff/README.md
+44
-0
vendor/github.com/sebest/xff/xff.go
vendor/github.com/sebest/xff/xff.go
+158
-0
vendor/vendor.json
vendor/vendor.json
+6
-0
No files found.
internal/upstream/upstream.go
View file @
b46237ac
...
@@ -16,6 +16,8 @@ import (
...
@@ -16,6 +16,8 @@ import (
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/helper"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/upload"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/upload"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/urlprefix"
"gitlab.com/gitlab-org/gitlab-workhorse/internal/urlprefix"
"github.com/sebest/xff"
)
)
var
(
var
(
...
@@ -54,6 +56,9 @@ func (u *Upstream) configureURLPrefix() {
...
@@ -54,6 +56,9 @@ func (u *Upstream) configureURLPrefix() {
}
}
func
(
u
*
Upstream
)
ServeHTTP
(
ow
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
func
(
u
*
Upstream
)
ServeHTTP
(
ow
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
// Automatic quasi-intelligent X-Forwarded-For parsing
r
.
RemoteAddr
=
xff
.
GetRemoteAddr
(
r
)
w
:=
helper
.
NewStatsCollectingResponseWriter
(
ow
)
w
:=
helper
.
NewStatsCollectingResponseWriter
(
ow
)
defer
w
.
RequestFinished
(
r
)
defer
w
.
RequestFinished
(
r
)
...
...
vendor/github.com/sebest/xff/LICENSE
0 → 100644
View file @
b46237ac
Copyright (c) 2015 Sebastien Estienne (sebastien.estienne@gmail.com)
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
vendor/github.com/sebest/xff/README.md
0 → 100644
View file @
b46237ac
# X-Forwarded-For middleware fo Go [![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/sebest/xff) [![Build Status](https://travis-ci.org/sebest/xff.svg?branch=master)](https://travis-ci.org/sebest/xff)
Package
`xff`
is a
`net/http`
middleware/handler to parse
[
Forwarded HTTP Extension
](
http://tools.ietf.org/html/rfc7239
)
in Golang.
## Example usage
Install
`xff`
:
go get github.com/sebest/xff
Edit
`server.go`
:
```
go
package
main
import
(
"net/http"
"github.com/sebest/xff"
)
func
main
()
{
handler
:=
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
w
.
Write
([]
byte
(
"hello from "
+
r
.
RemoteAddr
+
"
\n
"
))
})
xffmw
,
_
:=
xff
.
Default
()
http
.
ListenAndServe
(
":8080"
,
xffmw
.
Handler
(
handler
))
}
```
Then run your server:
go run server.go
The server now runs on
`localhost:8080`
:
$ curl -D - -H 'X-Forwarded-For: 42.42.42.42' http://localhost:8080/
HTTP/1.1 200 OK
Date: Fri, 20 Feb 2015 20:03:02 GMT
Content-Length: 29
Content-Type: text/plain; charset=utf-8
hello from 42.42.42.42:52661
vendor/github.com/sebest/xff/xff.go
0 → 100644
View file @
b46237ac
package
xff
import
(
"log"
"net"
"net/http"
"os"
"strings"
)
// list of private subnets
var
privateMasks
,
_
=
toMasks
([]
string
{
"127.0.0.0/8"
,
"10.0.0.0/8"
,
"172.16.0.0/12"
,
"192.168.0.0/16"
,
"fc00::/7"
,
})
// converts a list of subnets' string to a list of net.IPNet.
func
toMasks
(
ips
[]
string
)
(
masks
[]
net
.
IPNet
,
err
error
)
{
for
_
,
cidr
:=
range
ips
{
var
network
*
net
.
IPNet
_
,
network
,
err
=
net
.
ParseCIDR
(
cidr
)
if
err
!=
nil
{
return
}
masks
=
append
(
masks
,
*
network
)
}
return
}
// checks if a net.IP is in a list of net.IPNet
func
ipInMasks
(
ip
net
.
IP
,
masks
[]
net
.
IPNet
)
bool
{
for
_
,
mask
:=
range
masks
{
if
mask
.
Contains
(
ip
)
{
return
true
}
}
return
false
}
// IsPublicIP returns true if the given IP can be routed on the Internet.
func
IsPublicIP
(
ip
net
.
IP
)
bool
{
if
!
ip
.
IsGlobalUnicast
()
{
return
false
}
return
!
ipInMasks
(
ip
,
privateMasks
)
}
// Parse parses the value of the X-Forwarded-For Header and returns the IP address.
func
Parse
(
ipList
string
)
string
{
for
_
,
ip
:=
range
strings
.
Split
(
ipList
,
","
)
{
ip
=
strings
.
TrimSpace
(
ip
)
if
IP
:=
net
.
ParseIP
(
ip
);
IP
!=
nil
&&
IsPublicIP
(
IP
)
{
return
ip
}
}
return
""
}
// GetRemoteAddr parses the given request, resolves the X-Forwarded-For header
// and returns the resolved remote address.
func
GetRemoteAddr
(
r
*
http
.
Request
)
string
{
return
GetRemoteAddrIfAllowed
(
r
,
func
(
sip
string
)
bool
{
return
true
})
}
// GetRemoteAddrIfAllowed parses the given request, resolves the X-Forwarded-For header
// and returns the resolved remote address if allowed.
func
GetRemoteAddrIfAllowed
(
r
*
http
.
Request
,
allowed
func
(
sip
string
)
bool
)
string
{
if
xffh
:=
r
.
Header
.
Get
(
"X-Forwarded-For"
);
xffh
!=
""
{
if
sip
,
sport
,
err
:=
net
.
SplitHostPort
(
r
.
RemoteAddr
);
err
==
nil
&&
sip
!=
""
{
if
allowed
(
sip
)
{
if
xip
:=
Parse
(
xffh
);
xip
!=
""
{
return
net
.
JoinHostPort
(
xip
,
sport
)
}
}
}
}
return
r
.
RemoteAddr
}
// Options is a configuration container to setup the XFF middleware.
type
Options
struct
{
// AllowedSubnets is a list of Subnets from which we will accept the
// X-Forwarded-For header.
// If this list is empty we will accept every Subnets (default).
AllowedSubnets
[]
string
// Debugging flag adds additional output to debug server side XFF issues.
Debug
bool
}
// XFF http handler
type
XFF
struct
{
// Debug logger
Log
*
log
.
Logger
// Set to true if all IPs or Subnets are allowed.
allowAll
bool
// List of IP subnets that are allowed.
allowedMasks
[]
net
.
IPNet
}
// New creates a new XFF handler with the provided options.
func
New
(
options
Options
)
(
*
XFF
,
error
)
{
allowedMasks
,
err
:=
toMasks
(
options
.
AllowedSubnets
)
if
err
!=
nil
{
return
nil
,
err
}
xff
:=
&
XFF
{
allowAll
:
len
(
options
.
AllowedSubnets
)
==
0
,
allowedMasks
:
allowedMasks
,
}
if
options
.
Debug
{
xff
.
Log
=
log
.
New
(
os
.
Stdout
,
"[xff] "
,
log
.
LstdFlags
)
}
return
xff
,
nil
}
// Default creates a new XFF handler with default options.
func
Default
()
(
*
XFF
,
error
)
{
return
New
(
Options
{})
}
// Handler updates RemoteAdd from X-Fowarded-For Headers.
func
(
xff
*
XFF
)
Handler
(
h
http
.
Handler
)
http
.
Handler
{
return
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
r
.
RemoteAddr
=
GetRemoteAddrIfAllowed
(
r
,
xff
.
allowed
)
h
.
ServeHTTP
(
w
,
r
)
})
}
// Negroni compatible interface
func
(
xff
*
XFF
)
ServeHTTP
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
,
next
http
.
HandlerFunc
)
{
r
.
RemoteAddr
=
GetRemoteAddrIfAllowed
(
r
,
xff
.
allowed
)
next
(
w
,
r
)
}
// HandlerFunc provides Martini compatible handler
func
(
xff
*
XFF
)
HandlerFunc
(
w
http
.
ResponseWriter
,
r
*
http
.
Request
)
{
r
.
RemoteAddr
=
GetRemoteAddrIfAllowed
(
r
,
xff
.
allowed
)
}
// checks that the IP is allowed.
func
(
xff
*
XFF
)
allowed
(
sip
string
)
bool
{
if
xff
.
allowAll
{
return
true
}
else
if
ip
:=
net
.
ParseIP
(
sip
);
ip
!=
nil
&&
ipInMasks
(
ip
,
xff
.
allowedMasks
)
{
return
true
}
return
false
}
// convenience method. checks if debugging is turned on before printing
func
(
xff
*
XFF
)
logf
(
format
string
,
a
...
interface
{})
{
if
xff
.
Log
!=
nil
{
xff
.
Log
.
Printf
(
format
,
a
...
)
}
}
vendor/vendor.json
View file @
b46237ac
...
@@ -176,6 +176,12 @@
...
@@ -176,6 +176,12 @@
"revision"
:
"46f70867da7b79c74c21ef022c4a47f138af3d27"
,
"revision"
:
"46f70867da7b79c74c21ef022c4a47f138af3d27"
,
"revisionTime"
:
"2017-01-16T09:20:13Z"
"revisionTime"
:
"2017-01-16T09:20:13Z"
},
},
{
"checksumSHA1"
:
"bQ+Wb430AXpen54AYtrR1Igfh18="
,
"path"
:
"github.com/sebest/xff"
,
"revision"
:
"6c115e0ffa35d6a2e3f7a9e797c9cf07f0da4b9f"
,
"revisionTime"
:
"2016-09-10T04:38:05Z"
},
{
{
"checksumSHA1"
:
"ySaT8G3I3y4MmnoXOYAAX0rC+p8="
,
"checksumSHA1"
:
"ySaT8G3I3y4MmnoXOYAAX0rC+p8="
,
"path"
:
"github.com/sirupsen/logrus"
,
"path"
:
"github.com/sirupsen/logrus"
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment