Skip to content

Commit

Permalink
Merge pull request #7 from project-ncl/rename-domain-proxy-whitelist
Browse files Browse the repository at this point in the history
Rename whitelist to allowlist
  • Loading branch information
tecarter94 authored Jan 13, 2025
2 parents dc605a8 + 0c0b844 commit c8c2f21
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 20 deletions.
71 changes: 70 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,70 @@
# domain-proxy
# Domain Proxy

This proxy enables build tools running within a network isolated unshare environment to download artifacts from a list
of allowed target hosts.

## Components

### Domain Proxy Server

* Runs outside unshare environment
* Listens on Unix domain socket for connections from Domain Proxy Client
* Forwards HTTP requests from Domain Proxy Client to target hosts
* Forwards HTTP responses from target hosts to Domain Proxy Client
* Optionally uses an internally configured proxy for HTTP connections to target hosts

### Domain Proxy Client

* Runs inside unshare environment
* Connects to Domain Proxy Server via Unix domain socket
* Listens on HTTP port for connections from build tools
* Forwards HTTP requests from build tools to Domain Proxy Server
* Forwards HTTP responses from Domain Proxy Server to build tools

## Environment variables

### Common

* DOMAIN_PROXY_BYTE_BUFFER_SIZE
* Default: `32768`
* DOMAIN_PROXY_DOMAIN_SOCKET
* Default: `/tmp/domain-socket.sock`
* DOMAIN_PROXY_CONNECTION_TIMEOUT
* Default: `10000` milliseconds
* DOMAIN_PROXY_IDLE_TIMEOUT
* Default: `30000` milliseconds

### Domain Proxy Server

* DOMAIN_PROXY_TARGET_ALLOWLIST
* Default:
`localhost,repo.maven.apache.org,repository.jboss.org,packages.confluent.io,jitpack.io,repo.gradle.org,plugins.gradle.org`
* DOMAIN_PROXY_ENABLE_INTERNAL_PROXY
* Default: `false`
* DOMAIN_PROXY_INTERNAL_PROXY_HOST
* Default: `indy-generic-proxy`
* DOMAIN_PROXY_INTERNAL_PROXY_PORT
* Default: `80`
* DOMAIN_PROXY_INTERNAL_PROXY_USER
* DOMAIN_PROXY_INTERNAL_PROXY_PASSWORD
* DOMAIN_PROXY_INTERNAL_NON_PROXY_HOSTS
* Default: `localhost`

### Domain Proxy Client

* DOMAIN_PROXY_HTTP_PORT
* Default: `8080`

## Build

* `go build -v -o bin/domainproxyserver cmd/server/main.go`
* `go build -v -o bin/domainproxyclient cmd/client/main.go`

## Run

* `./bin/domainproxyserver`
* `./bin/domainproxyclient`

## Test

* `go test -v ./test`
26 changes: 13 additions & 13 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import (
const (
HttpPort = 80
HttpsPort = 443
TargetWhitelistKey = "DOMAIN_PROXY_TARGET_WHITELIST"
DefaultTargetWhitelist = "localhost,repo.maven.apache.org,repository.jboss.org,packages.confluent.io,jitpack.io,repo.gradle.org,plugins.gradle.org"
TargetAllowlistKey = "DOMAIN_PROXY_TARGET_ALLOWLIST"
DefaultTargetAllowlist = "localhost,repo.maven.apache.org,repository.jboss.org,packages.confluent.io,jitpack.io,repo.gradle.org,plugins.gradle.org"
EnableInternalProxyKey = "DOMAIN_PROXY_ENABLE_INTERNAL_PROXY"
DefaultEnableInternalProxy = false
InternalProxyHostKey = "DOMAIN_PROXY_INTERNAL_PROXY_HOST"
Expand All @@ -40,7 +40,7 @@ var common = NewCommon(logger)

type DomainProxyServer struct {
sharedParams *SharedParams
targetWhitelist map[string]bool
targetAllowlist map[string]bool
enableInternalProxy bool
internalProxyHost string
internalProxyPort int
Expand All @@ -53,7 +53,7 @@ type DomainProxyServer struct {
func NewDomainProxyServer() *DomainProxyServer {
return &DomainProxyServer{
sharedParams: common.NewSharedParams(),
targetWhitelist: getTargetWhitelist(),
targetAllowlist: getTargetAllowlist(),
enableInternalProxy: getEnableInternalProxy(),
internalProxyHost: getInternalProxyHost(),
internalProxyPort: getInternalProxyPort(),
Expand Down Expand Up @@ -140,8 +140,8 @@ func (dps *DomainProxyServer) handleHttpConnection(sourceConnection net.Conn, wr
} else {
logger.Printf("Handling %s Connection %d with target %s:%d", DomainSocketToHttp, connectionNo, actualTargetHost, actualTargetPort)
}
// Check if target is whitelisted
if !dps.isTargetWhitelisted(actualTargetHost, writer) {
// Check if target is allowed
if !dps.isTargetAllowed(actualTargetHost, writer) {
if err := sourceConnection.Close(); err != nil {
common.HandleConnectionCloseError(err)
}
Expand Down Expand Up @@ -212,8 +212,8 @@ func (dps *DomainProxyServer) handleHttpsConnection(sourceConnection net.Conn, w
} else {
logger.Printf("Handling %s Connection %d with target %s:%d", DomainSocketToHttps, connectionNo, actualTargetHost, actualTargetPort)
}
// Check if target is whitelisted
if !dps.isTargetWhitelisted(actualTargetHost, writer) {
// Check if target is allowed
if !dps.isTargetAllowed(actualTargetHost, writer) {
if err := sourceConnection.Close(); err != nil {
common.HandleConnectionCloseError(err)
}
Expand Down Expand Up @@ -311,9 +311,9 @@ func getTargetHostAndPort(host string, defaultPort int) (string, int) {
return targetHost, targetPort
}

func (dps *DomainProxyServer) isTargetWhitelisted(targetHost string, writer http.ResponseWriter) bool {
if !dps.targetWhitelist[targetHost] {
message := fmt.Sprintf("Target host %s is not whitelisted", targetHost)
func (dps *DomainProxyServer) isTargetAllowed(targetHost string, writer http.ResponseWriter) bool {
if !dps.targetAllowlist[targetHost] {
message := fmt.Sprintf("Target host %s is not allowed", targetHost)
logger.Println(message)
http.Error(writer, message, http.StatusForbidden)
return false
Expand Down Expand Up @@ -391,8 +391,8 @@ func (rw *responseWriter) WriteHeader(statusCode int) {
}
}

func getTargetWhitelist() map[string]bool {
return common.GetCsvEnvVariable(TargetWhitelistKey, DefaultTargetWhitelist)
func getTargetAllowlist() map[string]bool {
return common.GetCsvEnvVariable(TargetAllowlistKey, DefaultTargetAllowlist)
}

func getEnableInternalProxy() bool {
Expand Down
12 changes: 6 additions & 6 deletions test/domainproxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const (
ContentLength = "403"
MockUrlPath = "/com/foo/bar/1.0/bar-1.0.pom"
NonExistentUrlPath = "/com/foo/bar/1.0/bar-2.0.pom"
NonWhitelistedUrl = "repo1.maven.org/maven2/org/apache/maven/plugins/maven-jar-plugin/3.4.1/maven-jar-plugin-3.4.1.jar"
NonAllowedUrl = "repo1.maven.org/maven2/org/apache/maven/plugins/maven-jar-plugin/3.4.1/maven-jar-plugin-3.4.1.jar"
NonExistentHost = "foo.bar"
User = "foo"
Password = "bar"
Expand Down Expand Up @@ -143,7 +143,7 @@ func commonTestBehaviour(t *testing.T, qualifier string) {
// Set env variables
t.Setenv(DomainSocketKey, getRandomDomainSocket())
t.Setenv(HttpPortKey, DomainProxyPort)
t.Setenv(TargetWhitelistKey, "127.0.0.1,foo.bar")
t.Setenv(TargetAllowlistKey, "127.0.0.1,foo.bar")
// Start services
domainProxyServer, domainProxyClient := startDomainProxy()
defer stopDomainProxy(domainProxyServer, domainProxyClient)
Expand Down Expand Up @@ -215,8 +215,8 @@ func commonTestBehaviour(t *testing.T, qualifier string) {
}
})

t.Run(fmt.Sprintf("Test HTTP non-whitelisted host%s", qualifier), func(t *testing.T) {
response, err := httpClient.Get("http://" + NonWhitelistedUrl)
t.Run(fmt.Sprintf("Test HTTP non-allowed host%s", qualifier), func(t *testing.T) {
response, err := httpClient.Get("http://" + NonAllowedUrl)
if err != nil {
t.Fatal(err)
}
Expand All @@ -226,8 +226,8 @@ func commonTestBehaviour(t *testing.T, qualifier string) {
}
})

t.Run(fmt.Sprintf("Test HTTPS non-whitelisted host%s", qualifier), func(t *testing.T) {
_, err := httpClient.Get("https://" + NonWhitelistedUrl)
t.Run(fmt.Sprintf("Test HTTPS non-allowed host%s", qualifier), func(t *testing.T) {
_, err := httpClient.Get("https://" + NonAllowedUrl)
statusText := http.StatusText(http.StatusForbidden)
if !strings.Contains(err.Error(), statusText) {
t.Fatalf("Actual error %s did not contain expected HTTP status text %s", err.Error(), statusText)
Expand Down

0 comments on commit c8c2f21

Please sign in to comment.