-
Notifications
You must be signed in to change notification settings - Fork 2
/
run-proxy
executable file
·243 lines (210 loc) · 6.75 KB
/
run-proxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
#!/bin/sh -e
HELP_STRING=$(cat <<"EOF"
Usage: run-proxy --listen $MY_POD_IP:9090 --proxy-pass http://127.0.0.1
Arguments:
--listen [ADDRESS:]PORT sets the address and port on which the server will accept requests
--proxy-pass URL sets the url to proxy to
--user USER sets the name of the authorized user
--nginx-user USER sets the user to run nginx
--location URI sets the uri for the location (default: /metrics)
--proxy-ssl-ca-file PATH specify path to CA file in PEM format used to verify peer certificate,
implies "proxy_ssl_verify on;"
--probe-proxy-pass URL sets the probe url to proxy to
--probe-listen [ADDRESS:]PORT sets the address and port on which the server will accept request for probe
--proxy-ssl-cert-file PATH specify path to cert file in PEM format used to authenticate to peer
--proxy-ssl-key-file PATH specify path to key file in PEM format used to authenticate to peer
--proxy-ssl-name NAME specify custom CN to use, when verifiying remote certificate,
this option should only be used CN in the remote certificate
differs from the host in "--proxy-pass" URL
--proxy-bearer-token-from-service-account add header 'Authorization: Bearer ...' with token from pod ServiceAccount
--debug enable nginx debug log output
-h, --help output this message
EOF
)
if ! temp=$(getopt -o h --long "listen:,proxy-pass:,user:,nginx-user:,location:,help,proxy-ssl-ca-file:,
proxy-ssl-cert-file:,proxy-ssl-key-file:,proxy-ssl-name:,probe-proxy-pass:,probe-listen:,proxy-bearer-token-from-service-account,debug" -n 'run-proxy' -- "$@") ; then
>&2 echo
>&2 echo "$HELP_STRING"
exit 1
fi
eval set -- "$temp"
LOCATION=/metrics
NGINX_BINARY_NAME=nginx
ERROR_LOG_LEVEL=warn
NGINX_USER=nginx
while true; do
case "$1" in
--listen )
LISTEN=$2; shift 2;;
--proxy-pass )
PROXY_PASS=$2; shift 2;;
--user )
USER=$2; shift 2;;
--nginx-user )
NGINX_USER=$2; shift 2;;
--location )
LOCATION=$2; shift 2;;
--proxy-ssl-ca-file )
PROXY_SSL_CA=$2; shift 2;;
--proxy-ssl-cert-file )
PROXY_SSL_CERT=$2; shift 2;;
--proxy-ssl-key-file )
PROXY_SSL_KEY=$2; shift 2;;
--proxy-ssl-name )
PROXY_SSL_NAME=$2; shift 2;;
--proxy-bearer-token-from-service-account )
PROXY_BEARER_TOKEN_FROM_SA=yes; shift 1;;
--probe-proxy-pass )
PROBE_PROXY_PASS=$2; shift 2;;
--probe-listen )
PROBE_LISTEN=$2; shift 2;;
--debug )
DEBUG=yes; shift 1;;
-h | --help )
echo "$HELP_STRING"; exit 0 ;;
-- )
shift; break ;;
* )
break ;;
esac
done
if [[ -z "$LISTEN" ]] ; then
>&2 echo "--listen is required"
>&2 echo
>&2 echo "$HELP_STRING"
exit 1
fi
if [[ -z "$PROXY_PASS" ]] ; then
>&2 echo "--proxy-pass is required"
>&2 echo
>&2 echo "$HELP_STRING"
exit 1
fi
if [[ -z "$USER" ]] ; then
>&2 echo "--user is required"
>&2 echo
>&2 echo "$HELP_STRING"
exit 1
fi
if [[ -n "$PROXY_SSL_CA" ]]; then
PROXY_SSL_VERIFY="$(cat <<EOF | sed 's/^ */ /g'
proxy_ssl_verify on;
proxy_ssl_trusted_certificate $PROXY_SSL_CA;
EOF
)"
fi
if [[ -n "$PROXY_SSL_KEY" ]] || [[ -n "$PROXY_SSL_CERT" ]]; then
if [[ -z "$PROXY_SSL_KEY" ]]; then
>&2 echo "--proxy-ssl-key-file is required when --proxy-ssl-cert-file is specified"
>&2 echo
>&2 echo "$HELP_STRING"
exit 1
fi
if [[ -z "$PROXY_SSL_CERT" ]]; then
>&2 echo "--proxy-ssl-cert-file is required when --proxy-ssl-key-file is specified"
>&2 echo
>&2 echo "$HELP_STRING"
exit 1
fi
PROXY_SSL_CONFIG="$(cat <<EOF | sed 's/^ */ /g'
proxy_ssl_certificate_key $PROXY_SSL_KEY;
proxy_ssl_certificate $PROXY_SSL_CERT;
EOF
)"
if [[ -n "$PROXY_SSL_NAME" ]]; then
PROXY_SSL_NAME="$(cat <<EOF | sed 's/^ */ /g'
proxy_ssl_name $PROXY_SSL_NAME;
EOF
)"
fi
fi
if [[ -n "$PROBE_PROXY_PASS" ]] || [[ -n "$PROBE_LISTEN" ]]; then
if [[ -z "$PROBE_PROXY_PASS" ]]; then
>&2 echo "--probe-proxy-pass is required when --probe-listen is specified"
>&2 echo
>&2 echo "$HELP_STRING"
exit 1
fi
if [[ -z "$PROBE_LISTEN" ]]; then
>&2 echo "--probe-listen is required when --probe-proxy-pass is specified"
>&2 echo
>&2 echo "$HELP_STRING"
exit 1
fi
PROBE_CONFIG="$(cat <<EOF
server {
server_name ${HOSTNAME};
listen ${PROBE_LISTEN};
location / {
proxy_pass ${PROBE_PROXY_PASS};
}
}
EOF
)"
fi
if [[ x"$PROXY_BEARER_TOKEN_FROM_SA" = x"yes" ]]; then
token="$(cat /run/secrets/kubernetes.io/serviceaccount/token)"
PROXY_BEARER_CONFIG="
proxy_set_header Authorization \"Bearer $token\";
"
fi
if [[ x"$DEBUG" = x"yes" ]]; then
NGINX_BINARY_NAME=nginx-debug
ERROR_LOG_LEVEL=debug
fi
cat > /etc/nginx/nginx.conf <<EOF
user ${NGINX_USER};
worker_processes 1;
error_log /dev/stderr ${ERROR_LOG_LEVEL};
events {
worker_connections 100;
}
http {
access_log off;
map \$ssl_client_s_dn \$ssl_client_s_dn_cn {
default "";
~CN=(?<CN>[^,]+) \$CN;
}
server {
server_name ${HOSTNAME};
listen ${LISTEN} ssl;
ssl_protocols TLSv1.2;
ssl_certificate /etc/nginx/server.crt;
ssl_certificate_key /etc/nginx/server.key;
ssl_client_certificate /var/run/secrets/kubernetes.io/serviceaccount/ca.crt;
ssl_verify_client on;
large_client_header_buffers 4 32k;
location ${LOCATION} {
if (\$ssl_client_s_dn_cn !~ "^${USER}$") {
return 403;
}
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_read_timeout 3600;
proxy_send_timeout 3600;
proxy_pass ${PROXY_PASS};
${PROXY_SSL_CONFIG}
${PROXY_SSL_VERIFY}
${PROXY_SSL_NAME}
${PROXY_BEARER_CONFIG}
}
}
${PROBE_CONFIG}
}
EOF
# Generate self-signed certificate
openssl genrsa -des3 -passout pass:xxxx -out /etc/nginx/server.pass.key 2048
openssl rsa -passin pass:xxxx -in /etc/nginx/server.pass.key -out /etc/nginx/server.key
openssl req -new -key /etc/nginx/server.key -out /etc/nginx/server.csr -subj "/CN=$HOSTNAME"
openssl x509 -req -sha256 -days 300065 -in /etc/nginx/server.csr -signkey /etc/nginx/server.key -out /etc/nginx/server.crt
rm /etc/nginx/server.pass.key /etc/nginx/server.csr
# Check Nginx config (and exit on error)
if ! nginx -t ; then
>&2 echo
>&2 cat /etc/nginx/nginx.conf
exit 1
fi
# Run nginx
exec "$NGINX_BINARY_NAME" -g 'daemon off;'