Skip to content
Permalink
Browse files

Added the ability to whitelist and ban ip/geolocation. Also supports …

…subnets.
  • Loading branch information...
antoniomika committed Mar 23, 2019
1 parent f4dd86b commit b73099375c8e2fc759b35b74a4d0a41186eae1c8
Showing with 75 additions and 10 deletions.
  1. +3 −0 go.mod
  2. +6 −0 go.sum
  3. +11 −4 http.go
  4. +53 −4 main.go
  5. +2 −2 utils.go
3 go.mod
@@ -6,12 +6,15 @@ require (
github.com/gin-gonic/gin v1.3.0
github.com/golang/protobuf v1.2.0 // indirect
github.com/gorilla/websocket v1.4.0
github.com/jpillora/ipfilter v0.0.0-20190129105630-1af4b191294f
github.com/json-iterator/go v1.1.5 // indirect
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
github.com/mattn/go-isatty v0.0.4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
github.com/oschwald/maxminddb-golang v1.3.0 // indirect
github.com/stretchr/testify v1.3.0 // indirect
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce // indirect
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 // indirect
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67
golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3 // indirect
6 go.sum
@@ -10,6 +10,8 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/jpillora/ipfilter v0.0.0-20190129105630-1af4b191294f h1:yAX19zgDa9nIdbuQeUCY/iYVZArbxFPL3zcsWmA872g=
github.com/jpillora/ipfilter v0.0.0-20190129105630-1af4b191294f/go.mod h1:cVpzWD9ypibSo5IdbBqJf9dVKW/pPeLGx0q+4X7k5rk=
github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c h1:N7A4JCA2G+j5fuFxCsJqjFU/sZe0mj8H0sSoSwbaikw=
@@ -20,11 +22,15 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/oschwald/maxminddb-golang v1.3.0 h1:oTh8IBSj10S5JNlUDg5WjJ1QdBMdeaZIkPEVfESSWgE=
github.com/oschwald/maxminddb-golang v1.3.0/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc=
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
github.com/ugorji/go v1.1.2 h1:JON3E2/GPW2iDNGoSAusl1KDf5TRQ8k8q7Tp097pZGs=
github.com/ugorji/go v1.1.2/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go/codec v0.0.0-20190204201341-e444a5086c43 h1:BasDe+IErOQKrMVXab7UayvSlIpiyGwRvuX3EKYY7UA=
15 http.go
@@ -7,7 +7,6 @@ import (
"net/http"
"net/http/httputil"
"path/filepath"
"strings"

"github.com/gorilla/websocket"
"github.com/koding/websocketproxy"
@@ -29,11 +28,19 @@ func startHTTPHandler(state *State) {
}
gin.SetMode(releaseMode)

r := gin.Default()
r := gin.New()
r.Use(func(c *gin.Context) {
clientIPAddr, _, err := net.SplitHostPort(c.Request.RemoteAddr)
if state.IPFilter.Blocked(c.ClientIP()) || state.IPFilter.Blocked(clientIPAddr) || err != nil {
c.AbortWithStatus(http.StatusForbidden)
return
}
c.Next()
}, gin.Logger(), gin.Recovery())
r.GET("/*proxy", func(c *gin.Context) {
hostname := strings.Split(c.Request.Host, ":")[0]
hostname, _, err := net.SplitHostPort(c.Request.Host)

if hostname == *rootDomain && *redirectRoot {
if err != nil || (hostname == *rootDomain && *redirectRoot) {
c.Redirect(http.StatusFound, *redirectRootLocation)
return
}
57 main.go
@@ -11,6 +11,8 @@ import (
"sync"
"time"

"github.com/jpillora/ipfilter"

"golang.org/x/crypto/ssh"
)

@@ -27,6 +29,7 @@ type State struct {
SSHConnections *sync.Map
Listeners *sync.Map
HTTPListeners *sync.Map
IPFilter *ipfilter.IPFilter
}

var (
@@ -41,6 +44,11 @@ var (
domainLen = flag.Int("sish.subdomainlen", 3, "The length of the random subdomain to generate")
forceRandomSubdomain = flag.Bool("sish.forcerandomsubdomain", true, "Whether or not to force a random subdomain")
bannedSubdomains = flag.String("sish.bannedsubdomains", "localhost", "A comma separated list of banned subdomains")
bannedIPs = flag.String("sish.bannedips", "", "A comma separated list of banned ips")
bannedCountries = flag.String("sish.bannedcountries", "", "A comma separated list of banned countries")
whitelistedIPs = flag.String("sish.whitelistedips", "", "A comma separated list of whitelisted ips")
whitelistedCountries = flag.String("sish.whitelistedcountries", "", "A comma separated list of whitelisted countries")
useGeoDB = flag.Bool("sish.usegeodb", false, "Whether or not to use the maxmind geodb")
pkPass = flag.String("sish.pkpass", "S3Cr3tP4$$phrAsE", "Passphrase to use for the server private key")
pkLoc = flag.String("sish.pkloc", "keys/ssh_key", "SSH server private key")
authEnabled = flag.Bool("sish.auth", false, "Whether or not to require auth on the SSH service")
@@ -50,15 +58,48 @@ var (
cleanupUnbound = flag.Bool("sish.cleanupunbound", true, "Whether or not to cleanup unbound (forwarded) SSH connections")
bindRandom = flag.Bool("sish.bindrandom", true, "Bind ports randomly (OS chooses)")
debug = flag.Bool("sish.debug", false, "Whether or not to print debug information")
bannedList = []string{""}
bannedSubdomainList = []string{""}
filter ipfilter.IPFilter
)

func main() {
flag.Parse()

bannedList = append(bannedList, strings.Split(*bannedSubdomains, ",")...)
for k, v := range bannedList {
bannedList[k] = strings.ToLower(v + "." + *rootDomain)
commaSplitFields := func(c rune) bool {
return c == ','
}

bannedSubdomainList = append(bannedSubdomainList, strings.FieldsFunc(*bannedSubdomains, commaSplitFields)...)
for k, v := range bannedSubdomainList {
bannedSubdomainList[k] = strings.ToLower(strings.TrimSpace(v) + "." + *rootDomain)
}

upperList := func(stringList string) []string {
list := strings.FieldsFunc(stringList, commaSplitFields)
for k, v := range list {
list[k] = strings.ToUpper(v)
}

return list
}

whitelistedCountriesList := upperList(*whitelistedCountries)
whitelistedIPList := strings.FieldsFunc(*whitelistedIPs, commaSplitFields)

ipfilterOpts := ipfilter.Options{
BlockedCountries: upperList(*bannedCountries),
AllowedCountries: whitelistedCountriesList,
BlockedIPs: strings.FieldsFunc(*bannedIPs, commaSplitFields),
AllowedIPs: whitelistedIPList,
BlockByDefault: len(whitelistedIPList) > 0 || len(whitelistedCountriesList) > 0,
}

var filter *ipfilter.IPFilter

if *useGeoDB {
filter = ipfilter.NewLazy(ipfilterOpts)
} else {
filter = ipfilter.NewNoDB(ipfilterOpts)
}

watchCerts()
@@ -67,6 +108,7 @@ func main() {
SSHConnections: &sync.Map{},
Listeners: &sync.Map{},
HTTPListeners: &sync.Map{},
IPFilter: filter,
}

go startHTTPHandler(state)
@@ -125,6 +167,13 @@ func main() {
continue
}

clientRemote, _, err := net.SplitHostPort(conn.RemoteAddr().String())

if err != nil || filter.Blocked(clientRemote) {
conn.Close()
continue
}

log.Println("Accepted SSH connection for:", conn.RemoteAddr())

go func() {
@@ -232,7 +232,7 @@ func loadPrivateKey(passphrase string) ssh.Signer {
return signer
}

func inBannedList(host string) bool {
func inBannedList(host string, bannedList []string) bool {
for _, v := range bannedList {
if strings.TrimSpace(v) == host {
return true
@@ -251,7 +251,7 @@ func getOpenHost(addr string, state *State, sshConn *SSHConnection) string {
}

checkHost := func(checkHost string) bool {
if *forceRandomSubdomain || !first || inBannedList(host) {
if *forceRandomSubdomain || !first || inBannedList(host, bannedSubdomainList) {
host = getRandomHost()
}

0 comments on commit b730993

Please sign in to comment.
You can’t perform that action at this time.