Skip to content

Commit

Permalink
Merge pull request #13586 from danwinship/egress-router-proxy
Browse files Browse the repository at this point in the history
Merged by openshift-bot
  • Loading branch information
OpenShift Bot authored Jun 9, 2017
2 parents 2458531 + 351b252 commit cc2ed8f
Show file tree
Hide file tree
Showing 6 changed files with 280 additions and 4 deletions.
1 change: 1 addition & 0 deletions hack/build-images.sh
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ image "${tag_prefix}-haproxy-router" images/router/haproxy
image "${tag_prefix}-keepalived-ipfailover" images/ipfailover/keepalived
image "${tag_prefix}-docker-registry" images/dockerregistry
image "${tag_prefix}-egress-router" images/egress/router
image "${tag_prefix}-egress-http-proxy" images/egress/http-proxy
image "${tag_prefix}-federation" images/federation
# images that depend on "${tag_prefix}
image "${tag_prefix}-gitserver" examples/gitserver
Expand Down
1 change: 1 addition & 0 deletions images/egress/http-proxy/.cccp.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
job-id: origin-egress-http-proxy
17 changes: 17 additions & 0 deletions images/egress/http-proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# This is the egress router HTTP proxy for OpenShift Origin
#
# The standard name for this image is openshift/origin-egress-http-proxy

FROM openshift/origin-base

RUN INSTALL_PKGS="squid" && \
yum install -y $INSTALL_PKGS && \
rpm -V $INSTALL_PKGS && \
yum clean all && \
rmdir /var/log/squid /var/spool/squid && \
rm -f /etc/squid/squid.conf

ADD egress-http-proxy.sh /bin/egress-http-proxy.sh

ENTRYPOINT /bin/egress-http-proxy.sh
93 changes: 93 additions & 0 deletions images/egress/http-proxy/egress-http-proxy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#!/bin/bash

# OpenShift egress HTTP proxy setup script

set -o errexit
set -o nounset
set -o pipefail

function die() {
echo "$*" 1>&2
exit 1
}

if [[ -z "${EGRESS_HTTP_PROXY_DESTINATION}" ]]; then
die "No EGRESS_HTTP_PROXY_DESTINATION specified"
fi

IPADDR_REGEX="[[:xdigit:].:]*[.:][[:xdigit:].:]+"
OPT_CIDR_MASK_REGEX="(/[[:digit:]]+)?"
HOSTNAME_REGEX="[[:alnum:]][[:alnum:].-]+"
DOMAIN_REGEX="\*\.${HOSTNAME_REGEX}"

function generate_acls() {
n=0
saw_wildcard=
while read dest; do
if [[ "${dest}" =~ ^\w*$ || "${dest}" =~ ^# ]]; then
# comment or blank line
continue
fi
n=$(($n + 1))

if [[ "${dest}" == "*" ]]; then
saw_wildcard=1
continue
elif [[ -n "${saw_wildcard}" ]]; then
die "Wildcard must be last rule, if present"
fi

if [[ "${dest}" =~ ^! ]]; then
rule=deny
dest="${dest#!}"
else
rule=allow
fi

echo ""
if [[ "${dest}" =~ ^${IPADDR_REGEX}${OPT_CIDR_MASK_REGEX}$ ]]; then
echo acl dest$n dst "${dest}"
echo http_access "${rule}" dest$n
elif [[ "${dest}" =~ ^${DOMAIN_REGEX}$ ]]; then
echo acl dest$n dstdomain "${dest#\*}"
echo http_access "${rule}" dest$n
elif [[ "${dest}" =~ ^${HOSTNAME_REGEX}$ ]]; then
echo acl dest$n dstdomain "${dest}"
echo http_access "${rule}" dest$n
else
die "Bad destination '${dest}'"
fi
done <<< "${EGRESS_HTTP_PROXY_DESTINATION}"

echo ""
if [[ -n "${saw_wildcard}" ]]; then
echo "http_access allow all"
else
echo "http_access deny all"
fi
}

if [[ "${EGRESS_HTTP_PROXY_MODE:-}" == "unit-test" ]]; then
generate_acls
exit 0
fi

CONF=/etc/squid/squid.conf
rm -f ${CONF}

cat > ${CONF} <<EOF
http_port 8080
cache deny all
access_log none all
debug_options ALL,0
shutdown_lifetime 0
EOF

generate_acls >> ${CONF}

echo "Running squid with config:"
sed -e 's/^/ /' ${CONF}
echo ""
echo ""

exec squid -N
159 changes: 159 additions & 0 deletions images/egress/http-proxy/egress_http_proxy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package egress_http_proxy_test

import (
"fmt"
"os/exec"
"strings"
"testing"
)

func TestGenerateSquidConf(t *testing.T) {
tests := []struct {
in string
out string
}{
{
in: "*",
out: `
http_access allow all
`,
},
{
in: "example.com",
out: `
acl dest1 dstdomain example.com
http_access allow dest1
http_access deny all
`,
},
{
in: "!example.com",
out: `
acl dest1 dstdomain example.com
http_access deny dest1
http_access deny all
`,
},
{
in: "*.example.com",
out: `
acl dest1 dstdomain .example.com
http_access allow dest1
http_access deny all
`,
},
{
in: "192.168.1.1",
out: `
acl dest1 dst 192.168.1.1
http_access allow dest1
http_access deny all
`,
},
{
in: "192.168.1.0/24",
out: `
acl dest1 dst 192.168.1.0/24
http_access allow dest1
http_access deny all
`,
},
{
in: `
!*.example.net
*
`,
out: `
acl dest1 dstdomain .example.net
http_access deny dest1
http_access allow all
`,
},
{
in: `
# HTTP proxy config
!*.bad.example.com
*.example.com
192.168.0.0/16
fe80::/10
# end
`,
out: `
acl dest1 dstdomain .bad.example.com
http_access deny dest1
acl dest2 dstdomain .example.com
http_access allow dest2
acl dest3 dst 192.168.0.0/16
http_access allow dest3
acl dest4 dst fe80::/10
http_access allow dest4
http_access deny all
`,
},
}

for n, test := range tests {
cmd := exec.Command("./egress-http-proxy.sh")
cmd.Env = []string{
fmt.Sprintf("EGRESS_HTTP_PROXY_MODE=unit-test"),
fmt.Sprintf("EGRESS_HTTP_PROXY_DESTINATION=%s", test.in),
}
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("test %d expected output %q but got error %v / %q", n+1, test.out, err, string(out))
}
if string(out) != test.out {
t.Fatalf("test %d expected output %q but got %q", n+1, test.out, string(out))
}
}
}

func TestGenerateSquidConfBad(t *testing.T) {
tests := []struct {
in string
err string
}{
{
in: "",
err: "No EGRESS_HTTP_PROXY_DESTINATION specified",
},
{
in: "*\nexample.com",
err: "Wildcard must be last rule, if present",
},
{
in: "foo bar",
err: "Bad destination 'foo bar'",
},
}

for n, test := range tests {
cmd := exec.Command("./egress-http-proxy.sh")
cmd.Env = []string{
fmt.Sprintf("EGRESS_HTTP_PROXY_MODE=unit-test"),
fmt.Sprintf("EGRESS_HTTP_PROXY_DESTINATION=%s", test.in),
}
out, err := cmd.CombinedOutput()
out_lines := strings.Split(string(out), "\n")
got := out_lines[len(out_lines)-2]
if err == nil {
t.Fatalf("test %d expected error %q but got output %q", n+1, test.err, got)
}
if got != test.err {
t.Fatalf("test %d expected output %q but got %q", n+1, test.err, got)
}
}
}
13 changes: 9 additions & 4 deletions images/egress/router/egress-router.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ if [[ ! "${EGRESS_SOURCE:-}" =~ ^${IP_REGEX}$ ]]; then
echo "EGRESS_SOURCE unspecified or invalid"
exit 1
fi
if [[ -z "${EGRESS_DESTINATION:-}" ]]; then
echo "EGRESS_DESTINATION unspecified"
exit 1
fi
if [[ ! "${EGRESS_GATEWAY:-}" =~ ^${IP_REGEX}$ ]]; then
echo "EGRESS_GATEWAY unspecified or invalid"
exit 1
Expand Down Expand Up @@ -48,6 +44,11 @@ function setup_network() {
}

function gen_iptables_rules() {
if [[ -z "${EGRESS_DESTINATION:-}" ]]; then
echo "EGRESS_DESTINATION unspecified"
exit 1
fi

did_fallback=
while read dest; do
if [[ "${dest}" =~ ^${BLANK_LINE_OR_COMMENT_REGEX}$ ]]; then
Expand Down Expand Up @@ -122,6 +123,10 @@ case "${EGRESS_ROUTER_MODE:=legacy}" in
wait_until_killed
;;

http-proxy)
setup_network
;;

unit-test)
gen_iptables_rules
;;
Expand Down

0 comments on commit cc2ed8f

Please sign in to comment.