Merge pull request #5 from BrendanHalley/master

Add source IP filtering/allow list feature to proxy
This commit is contained in:
Yuhui Xu 2020-10-26 00:34:39 +08:00 committed by GitHub
commit 5f7cc934b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 5 deletions

View File

@ -54,13 +54,11 @@ Features implemented:
- If you are using BIRDv2, simply point both `--bird` and `--bird6` to the only socket file of BIRDv2
- Sending "restrict" command to BIRD to prevent unauthorized changes
- Executing traceroute command on Linux, FreeBSD and OpenBSD
Features not implemented yet:
- Source IP restriction
Usage: all configuration is done via commandline parameters or environment variables, no config file.
- --allowed / ALLOWED_IPS: IPs allowed to access this proxy, separated by commas. Don't set to allow all IPs. (default "")
- --bird / BIRD_SOCKET: socket file for bird, set either in parameter or environment variable BIRD_SOCKET (default "/var/run/bird/bird.ctl")
- --bird6 / BIRD6_SOCKET: socket file for bird6, set either in parameter or environment variable BIRD6_SOCKET (default "/var/run/bird/bird6.ctl")
- --listen / BIRDLG_LISTEN: listen address, set either in parameter or environment variable BIRDLG_LISTEN (default ":8000")
@ -85,7 +83,7 @@ Example: the following docker-compose.yml entry does the same as above, but by s
ports:
- "192.168.0.1:8000:8000"
(As the proxy doesn't have source IP restriction yet, you should only bind the proxy to a specific interface, or use external firewall for security)
You can use source IP restriction to increase security. You should also bind the proxy to a specific interface and use an external firewall/iptables for added security.
Credits
-------
@ -97,3 +95,4 @@ License
-------
GPL 3.0

View File

@ -4,6 +4,7 @@ import (
"flag"
"net/http"
"os"
"strings"
"github.com/gorilla/handlers"
)
@ -19,10 +20,38 @@ func invalidHandler(httpW http.ResponseWriter, httpR *http.Request) {
httpW.Write([]byte("Invalid Request\n"))
}
// Access handler, check to see if client IP in allowed IPs, continue if it is, send to invalidHandler if not
func accessHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(httpW http.ResponseWriter, httpR *http.Request) {
// setting.allowedIPs will always have at least one element because of how it's defined
if setting.allowedIPs[0] == "" {
next.ServeHTTP(httpW, httpR)
}
IPPort := httpR.RemoteAddr
// Remove port from IP and remove brackets that are around IPv6 addresses
requestIp := IPPort[0:strings.LastIndex(IPPort, ":")]
requestIp = strings.Replace(requestIp, "[", "", -1)
requestIp = strings.Replace(requestIp, "]", "", -1)
for _, allowedIP := range setting.allowedIPs {
if requestIp == allowedIP {
next.ServeHTTP(httpW, httpR)
}
}
invalidHandler(httpW, httpR)
return
})
}
type settingType struct {
birdSocket string
bird6Socket string
listen string
allowedIPs []string
}
var setting settingType
@ -34,6 +63,7 @@ func main() {
"/var/run/bird/bird.ctl",
"/var/run/bird/bird6.ctl",
":8000",
[]string{""},
}
if birdSocketEnv := os.Getenv("BIRD_SOCKET"); birdSocketEnv != "" {
@ -45,16 +75,21 @@ func main() {
if listenEnv := os.Getenv("BIRDLG_LISTEN"); listenEnv != "" {
settingDefault.listen = listenEnv
}
if AllowedIPsEnv := os.Getenv("ALLOWED_IPS"); AllowedIPsEnv != "" {
settingDefault.allowedIPs = strings.Split(AllowedIPsEnv, ",")
}
// Allow parameters to override environment variables
birdParam := flag.String("bird", settingDefault.birdSocket, "socket file for bird, set either in parameter or environment variable BIRD_SOCKET")
bird6Param := flag.String("bird6", settingDefault.bird6Socket, "socket file for bird6, set either in parameter or environment variable BIRD6_SOCKET")
listenParam := flag.String("listen", settingDefault.listen, "listen address, set either in parameter or environment variable BIRDLG_LISTEN")
AllowedIPsParam := flag.String("allowed", strings.Join(settingDefault.allowedIPs, ","), "IPs allowed to access this proxy, separated by commas. Don't set to allow all IPs.")
flag.Parse()
setting.birdSocket = *birdParam
setting.bird6Socket = *bird6Param
setting.listen = *listenParam
setting.allowedIPs = strings.Split(*AllowedIPsParam, ",")
// Start HTTP server
http.HandleFunc("/", invalidHandler)
@ -62,5 +97,6 @@ func main() {
http.HandleFunc("/bird6", bird6Handler)
http.HandleFunc("/traceroute", tracerouteIPv4Wrapper)
http.HandleFunc("/traceroute6", tracerouteIPv6Wrapper)
http.ListenAndServe(*listenParam, handlers.LoggingHandler(os.Stdout, http.DefaultServeMux))
http.ListenAndServe(*listenParam, handlers.LoggingHandler(os.Stdout, accessHandler(http.DefaultServeMux)))
}