mirror of
https://github.com/halverneus/static-file-server.git
synced 2024-11-24 09:05:30 +00:00
Merge pull request #19 from mobreza/referrer-check
Allow only specified referrers
This commit is contained in:
commit
c3f3305dc7
11
Dockerfile
11
Dockerfile
@ -1,7 +1,9 @@
|
||||
################################################################################
|
||||
## GO BUILDER
|
||||
################################################################################
|
||||
FROM golang:1.11.3 as builder
|
||||
|
||||
EXPOSE 8080
|
||||
ENV VERSION 1.5.1
|
||||
ENV VERSION 1.5.2
|
||||
ENV BUILD_DIR /build
|
||||
|
||||
RUN mkdir -p ${BUILD_DIR}
|
||||
@ -14,7 +16,12 @@ COPY . .
|
||||
RUN go test -cover ./...
|
||||
RUN CGO_ENABLED=0 go build -a -tags netgo -installsuffix netgo -ldflags "-X github.com/halverneus/static-file-server/cli/version.version=${VERSION}" -o /serve /build/bin/serve
|
||||
|
||||
################################################################################
|
||||
## DEPLOYMENT CONTAINER
|
||||
################################################################################
|
||||
FROM scratch
|
||||
|
||||
EXPOSE 8080
|
||||
COPY --from=builder /serve /
|
||||
ENTRYPOINT ["/serve"]
|
||||
CMD []
|
||||
|
@ -1,7 +1,6 @@
|
||||
FROM golang:1.11.3 as builder
|
||||
|
||||
EXPOSE 8080
|
||||
ENV VERSION 1.5.1
|
||||
ENV VERSION 1.5.2
|
||||
ENV BUILD_DIR /build
|
||||
|
||||
RUN mkdir -p ${BUILD_DIR}
|
||||
|
10
README.md
10
README.md
@ -35,6 +35,13 @@ URL_PREFIX=
|
||||
# served using HTTP.
|
||||
TLS_CERT=
|
||||
TLS_KEY=
|
||||
# List of accepted HTTP referrers. Return 403 if HTTP header `Referer` does not
|
||||
# match prefixes provided in the list.
|
||||
# Examples:
|
||||
# 'REFERRERS=http://localhost,https://...,https://another.name'
|
||||
# To accept missing referrer header, add a blank entry (start comma):
|
||||
# 'REFERRERS=,http://localhost,https://another.name'
|
||||
REFERRERS=
|
||||
```
|
||||
|
||||
### YAML Configuration File
|
||||
@ -53,6 +60,9 @@ folder: /web
|
||||
url-prefix: ""
|
||||
tls-cert: ""
|
||||
tls-key: ""
|
||||
referrers:
|
||||
- http://localhost
|
||||
- https://my.site
|
||||
```
|
||||
|
||||
## Deployment
|
||||
|
@ -63,6 +63,10 @@ ENVIRONMENT VARIABLES
|
||||
The prefix to use in the URL path. If supplied, then the prefix must
|
||||
start with a forward-slash and NOT end with a forward-slash. If not
|
||||
supplied then no prefix is used.
|
||||
REFERRERS
|
||||
A comma-separated list of valid HTTP Referer prefixes. If incoming header
|
||||
value is not in this list, a 403 HTTP error is returned.
|
||||
Examples: 'http://localhost,https://some.site,http://other.site:8080'
|
||||
|
||||
CONFIGURATION FILE
|
||||
Configuration can also managed used a YAML configuration file. To select the
|
||||
@ -81,6 +85,8 @@ CONFIGURATION FILE
|
||||
tls-cert: ""
|
||||
tls-key: ""
|
||||
url-prefix: ""
|
||||
referrers:
|
||||
- http://localhost
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
USAGE
|
||||
@ -99,7 +105,7 @@ USAGE
|
||||
export PORT=80
|
||||
static-file-server
|
||||
Retrieve with: wget http://my.machine/sub/my.file
|
||||
|
||||
|
||||
export FOLDER=/var/www
|
||||
static-file-server -c config.yml
|
||||
Result: Runs with values from config.yml, but with the folder being
|
||||
|
@ -34,11 +34,16 @@ func Run() error {
|
||||
// configuration.
|
||||
func handlerSelector() (handler http.HandlerFunc) {
|
||||
var serveFileHandler handle.FileServerFunc
|
||||
|
||||
serveFileHandler = http.ServeFile
|
||||
if config.Get.Debug {
|
||||
serveFileHandler = handle.WithLogging(serveFileHandler)
|
||||
}
|
||||
|
||||
if config.Get.Referrers != nil {
|
||||
serveFileHandler = handle.WithReferrers(serveFileHandler, config.Get.Referrers)
|
||||
}
|
||||
|
||||
// Choose and set the appropriate, optimized static file serving function.
|
||||
if 0 == len(config.Get.URLPrefix) {
|
||||
handler = handle.Basic(serveFileHandler, config.Get.Folder)
|
||||
|
@ -22,6 +22,7 @@ var (
|
||||
TLSCert string `yaml:"tls-cert"`
|
||||
TLSKey string `yaml:"tls-key"`
|
||||
URLPrefix string `yaml:"url-prefix"`
|
||||
Referrers []string `yaml:"referrers"`
|
||||
}
|
||||
)
|
||||
|
||||
@ -34,6 +35,7 @@ const (
|
||||
tlsCertKey = "TLS_CERT"
|
||||
tlsKeyKey = "TLS_KEY"
|
||||
urlPrefixKey = "URL_PREFIX"
|
||||
referrersKey = "REFERRERS"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -61,6 +63,7 @@ func setDefaults() {
|
||||
Get.TLSCert = defaultTLSCert
|
||||
Get.TLSKey = defaultTLSKey
|
||||
Get.URLPrefix = defaultURLPrefix
|
||||
Get.Referrers = nil
|
||||
}
|
||||
|
||||
// Load the configuration file.
|
||||
@ -108,6 +111,7 @@ func overrideWithEnvVars() {
|
||||
Get.TLSCert = envAsStr(tlsCertKey, Get.TLSCert)
|
||||
Get.TLSKey = envAsStr(tlsKeyKey, Get.TLSKey)
|
||||
Get.URLPrefix = envAsStr(urlPrefixKey, Get.URLPrefix)
|
||||
Get.Referrers = strAsArray(envAsStr(referrersKey, ""))
|
||||
}
|
||||
|
||||
// validate the configuration.
|
||||
@ -211,3 +215,11 @@ func strAsBool(value string) (result bool, err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func strAsArray(value string) (result []string) {
|
||||
if (value == "") {
|
||||
return nil
|
||||
}
|
||||
result = strings.Split(value, ",");
|
||||
return
|
||||
}
|
@ -26,12 +26,54 @@ type ListenerFunc func(string, http.HandlerFunc) error
|
||||
// requesting client.
|
||||
type FileServerFunc func(http.ResponseWriter, *http.Request, string)
|
||||
|
||||
func validReferrer(s []string, e string) bool {
|
||||
if (s == nil) {
|
||||
// log.Printf("No referrers specified, all fine.")
|
||||
return true
|
||||
}
|
||||
|
||||
// log.Printf("Checking referrers " + strings.Join(s, ",") + " against " + e)
|
||||
|
||||
for _, a := range s {
|
||||
// Handle blank HTTP Referer header, if configured
|
||||
if (a == "") {
|
||||
if (e == "") {
|
||||
// log.Printf("No referrer in request. Allowing.");
|
||||
return true;
|
||||
}
|
||||
// Continue loop (all strings start with "")
|
||||
continue;
|
||||
}
|
||||
|
||||
// Compare header with allowed prefixes
|
||||
if strings.HasPrefix(e, a) {
|
||||
// log.Printf(strings.Join([]string{ "Referrer match", e, a }, " "));
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func WithReferrers(serveFile FileServerFunc, referrers []string) FileServerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request, name string) {
|
||||
if (validReferrer(referrers, r.Referer())) {
|
||||
// log.Printf("Serving file.")
|
||||
serveFile(w, r, name)
|
||||
} else {
|
||||
// log.Printf(strings.Join([]string{"Invalid referrer", r.Referer(), "Not in", strings.Join(referrers, ",")}, " "))
|
||||
http.Error(w, strings.Join([]string{ "Invalid source", r.Referer() }, " "), 403)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithLogging returns a function that logs information about the request prior
|
||||
// to serving the requested file.
|
||||
func WithLogging(serveFile FileServerFunc) FileServerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request, name string) {
|
||||
log.Printf(
|
||||
"REQ: %s %s %s%s -> %s\n",
|
||||
"REQ from %s: %s %s %s%s -> %s\n",
|
||||
r.Referer(),
|
||||
r.Method,
|
||||
r.Proto,
|
||||
r.Host,
|
||||
|
Loading…
Reference in New Issue
Block a user