Support ssl encrypted fingergw

When using fingergw for inter region log streaming it can be desirable
to support ssl encrypted connections with client auth just like we do
with gearman. This will also make it easy to route traffic to the
finger gateway via an openshift route using SNI and pass-through.

Docs and release note added in a subsequent change.

Change-Id: Ia5c739a3fcf229da140c4e2ebbe1a771c63b0489
This commit is contained in:
Tobias Henkel 2019-06-12 12:40:20 +02:00 committed by James E. Blair
parent 4109322f1c
commit 496e9e3514
16 changed files with 306 additions and 17 deletions

15
tests/fixtures/fingergw/README.rst vendored Normal file
View File

@ -0,0 +1,15 @@
# Steps used to create our certs
# Generate CA cert
openssl req -new -newkey rsa:2048 -nodes -keyout root-ca.key -x509 -days 3650 -out root-ca.pem -subj "/C=US/ST=Texas/L=Austin/O=OpenStack Foundation/CN=fingergw-ca"
# Generate server keys
CLIENT='server'
openssl req -new -newkey rsa:2048 -nodes -keyout $CLIENT.key -out $CLIENT.csr -subj "/C=US/ST=Texas/L=Austin/O=OpenStack Foundation/CN=fingergw-$CLIENT"
openssl x509 -req -days 3650 -in $CLIENT.csr -out $CLIENT.pem -CA root-ca.pem -CAkey root-ca.key -CAcreateserial
# Generate client keys
CLIENT='client'
openssl req -new -newkey rsa:2048 -nodes -keyout $CLIENT.key -out $CLIENT.csr -subj "/C=US/ST=Texas/L=Austin/O=OpenStack Foundation/CN=fingergw-$CLIENT"
openssl x509 -req -days 3650 -in $CLIENT.csr -out $CLIENT.pem -CA root-ca.pem -CAkey root-ca.key -CAcreateserial

17
tests/fixtures/fingergw/client.csr vendored Normal file
View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICrDCCAZQCAQAwZzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYD
VQQHDAZBdXN0aW4xHTAbBgNVBAoMFE9wZW5TdGFjayBGb3VuZGF0aW9uMRgwFgYD
VQQDDA9maW5nZXJndy1jbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDPX5Gp5o1RcWHmZvhTl9HbHYpN83nOLtK9u6l258j7ggSh3H8O6slELCMy
0tIyv4ZYK7WwLtGpjpDegd/L5JOq40xtmDmxXuJI22GJdFsowq/Tc11ShHSrJh2j
JiqmRaCM2zPexya9Fqa6ZkIBI+V/VLVEWZZP2zEXeIZVHDrKLJ5plQkA2LiBYsz1
U/ZiIfXmjYAXQorIVoCA6VWfQvdfkc8z893SJphrOXhNQkG37FRVrZIuMeF/0xV3
eAMhLinfzOs5p8RYpvaNOtol0UglGV2xQZO8L0pXjwVue9NVui7vTVaXMzDUNBQF
PjLIuLsEnV8qhBOCCI7GI62Or8QJAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEA
j/VaictR9BOlM2W7H4GILyxOvIvHWLmXAoh73/TbLwGmzclGPDS3rnV+3oLNK+tk
mYzcHXBxidNg2nMAUiBgNPydy+OSUtuTrUP7lBOPPlV+gDJjx+raVSKEXIRDmHTP
dAcD02xCO8Gr5S6eI4k4lUT8ugQGsm+02MU8e+NzB/v0RFwXTUltcrxJo7CkPY71
WFTs3t/ktAPzFOeIcVaiwa1fKBYnPM7S9LxpUOFTO77T3aq4drDYoZe3VBz9eJOB
Qu6UHiOuHkmKrY9UXfiqvK/AgKGZopc6kj0JP54J3v7jnNhIjcFm97QD1qXcFi6t
v6zk4eF4kvotv/N70gUx+w==
-----END CERTIFICATE REQUEST-----

28
tests/fixtures/fingergw/client.key vendored Normal file
View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDPX5Gp5o1RcWHm
ZvhTl9HbHYpN83nOLtK9u6l258j7ggSh3H8O6slELCMy0tIyv4ZYK7WwLtGpjpDe
gd/L5JOq40xtmDmxXuJI22GJdFsowq/Tc11ShHSrJh2jJiqmRaCM2zPexya9Fqa6
ZkIBI+V/VLVEWZZP2zEXeIZVHDrKLJ5plQkA2LiBYsz1U/ZiIfXmjYAXQorIVoCA
6VWfQvdfkc8z893SJphrOXhNQkG37FRVrZIuMeF/0xV3eAMhLinfzOs5p8RYpvaN
Otol0UglGV2xQZO8L0pXjwVue9NVui7vTVaXMzDUNBQFPjLIuLsEnV8qhBOCCI7G
I62Or8QJAgMBAAECggEAIIMoUE3wTBuNsNTmDB0abtMj0vLgXv4iVlLsz9KpRR1u
Yn4ygYE4CvMslZROFlzG0F4R/0xn3MCYX/pWvx3YNQur+ObL7M4mhiu3EBjpDevw
KyPENuLDc+3m6aRbPXRfJpZbfIsWvMCnZUQRByK8oYkDXnL5SQ3hlX90+DUT1ox9
4LV5sQeqW5xfEraRW9qSGzi9Ns/WokuiFfR+ur3gp1j20w2bEzkZ9Nz+Sipj48jO
uJSv5+upc/osIFiwGz59aPt+sOJq+bt3JJgxyJFvciMjOwLCoNrTsamv/0/Dsykk
UNvBthDcm4lNL3GMEgB/sUQ6UX7XJ1C6IAA11wTgcQKBgQD3HoErqi6D0+mkzhKw
3KkFMQlf+KxeTy9T00rZU3iVnccQUOZ5t1k3C6NRD5fzS3lDfqfD1KixlV3GJcy9
dfxyhPErMJ3DttrIq90eTW1v9h95ZTYnoIoC8kzpwQSIEsEApl/VxQR6u1NHtoYW
ItBffsN1xhGN49JL2AvUxFxDBQKBgQDW02ceujc20Dx44BULwh3tZoo3/8QBhEiG
p+yNNRP4b7UEABE/6F7HZon9tDFxbLTHTnqrYQvIDgvEmuxdBAAxsy8S0WBpHwIy
nNeIc63ENmLfryGUoQ2iLEscYA+/ZD0WN5XQTcVOBJmGDdKbxluFgp1BH9pTb4ZG
5fZqQyuUNQKBgQCkykPLEW55XHxG+WC/bjaMDro4tISFU3q1BIa6TA5yf0d62ugG
rLyil3EuIh7rEB5qYvCPB6YC3h8tfpF8mkxhNcP5UC80jyBwhyMqDOn4qoEsm9C0
NjsyYc/mZV+XOiJYQ5pO3FXzXi3X+aCK7GZV+Btx00Zrf0wCZazmEpeP3QKBgHfe
5IaPz+llDqlAGF5EReDHO879h4h1IOcKYoN0n50b7/y4cOehKOnI/Ky1VHV+++zO
jMJ+V02dENH2xHcumVEiM90jOdHOfLJzNA0ux0JaOpeoKGu/5lSctJizvXXFYBS6
lXzzOGpNRME5i1BiwYThGhBRzsiJzXpYLUSkEHgVAoGATNJDp5kMDbzB8A8dlwL2
LEbufOu9+SLJJB/3M24+WioMSGxoZvkF2rpYdvR83QuOdEKBQlao2gwPNNMckMfh
twLKj1EvkQzQ46y+R8Ay3Sc5XNeTZ7vG8ysewP41b+RDPSkC1jTbCrHvXDO4D7Zi
RJkw3prbAP8PblFPjaa0P9U=
-----END PRIVATE KEY-----

20
tests/fixtures/fingergw/client.pem vendored Normal file
View File

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDRjCCAi4CCQCTQgbVwTy7RzANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJV
UzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1c3RpbjEdMBsGA1UECgwUT3Bl
blN0YWNrIEZvdW5kYXRpb24xFDASBgNVBAMMC2Zpbmdlcmd3LWNhMB4XDTIxMDUz
MDAwMzQ1MFoXDTMxMDUyODAwMzQ1MFowZzELMAkGA1UEBhMCVVMxDjAMBgNVBAgM
BVRleGFzMQ8wDQYDVQQHDAZBdXN0aW4xHTAbBgNVBAoMFE9wZW5TdGFjayBGb3Vu
ZGF0aW9uMRgwFgYDVQQDDA9maW5nZXJndy1jbGllbnQwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDPX5Gp5o1RcWHmZvhTl9HbHYpN83nOLtK9u6l258j7
ggSh3H8O6slELCMy0tIyv4ZYK7WwLtGpjpDegd/L5JOq40xtmDmxXuJI22GJdFso
wq/Tc11ShHSrJh2jJiqmRaCM2zPexya9Fqa6ZkIBI+V/VLVEWZZP2zEXeIZVHDrK
LJ5plQkA2LiBYsz1U/ZiIfXmjYAXQorIVoCA6VWfQvdfkc8z893SJphrOXhNQkG3
7FRVrZIuMeF/0xV3eAMhLinfzOs5p8RYpvaNOtol0UglGV2xQZO8L0pXjwVue9NV
ui7vTVaXMzDUNBQFPjLIuLsEnV8qhBOCCI7GI62Or8QJAgMBAAEwDQYJKoZIhvcN
AQELBQADggEBAA/zWymoNTQBwfYf9sog2I1Dn0AdfjBFUaupbWBD/9iYmqZkesZF
GkrPkHGs4lWhHfLiS/je84/ZKZmdd5h+7d0xydh+DAquSIBxMf8jSxDG6wj51XVi
oTw3qmacncAK7U4EUCH3GCxBwxgFIFYxv2wfyvYfqyPRgLpajWwSkAoKCxIUAvqv
1gNA/Qj6YW8S9yRgwt0F7xxz1v5thnZw80N4OZsxY7kujMa+kBIg9eZj7jcrtVrQ
+1viNToHDb/ty+edZUwUSZmr1JGr0G6mArlQYeS7G4jMOCKdlqdDPbwwFAQGf+l4
ZDnDHBKHUSXtJaCOfYHuAcRq+THmrv5LV+k=
-----END CERTIFICATE-----

28
tests/fixtures/fingergw/root-ca.key vendored Normal file
View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC03ectwEf0Itw1
u9ySo3VJOXWNLg0p01m4t3z4CyA15Oh2XlnDoTrio4FTZnZblZRd8kXZ0AGhC6Ln
eIJqJc+79Y8S2sKrl6nJuNcRt4UFdZqyyUCyU9EgY5nK28zge1OxNlSJ5ZTcM1I8
YFhJDb7sM5ZChTaOp2OjuZOePoF7hp+lZTEdhczLC/e35LY84dd6i6QxBJ9reaOF
nan+EqX5CVmFCGWvmnTpxkZvSFtkhdvG+IC9r1SX9lZi1JZEKCVodgNozcwWTLFD
Pi2CxSY+HMXwYYNJfh7GOxsy6a13TtCJGwNM5F5Ol7iVK35zYrzE4HWnxP+P+TtB
rZ70a4EDAgMBAAECggEAY8/+D1KIouNGEWVOMaKBTFqoU7QxUX6wie7AyYYiTXu5
CfHBqeNlQsOm0CbAdIRUr4/PGoffDkgEq6bmmbuqK3k1bttJCTcWXRtjnQRhJYUk
TTwhNwhoZW5x5fBs3QlSQ37PIpaPEwJDhMxKjG5IicNiTe2EES+xHh6Ap5ipDkhr
7fJ1WEEq2zerSA1K8d/BT7Fx1OCSqmemkfpQsaQ1Na71HT97XPMI2JVBLklKsr2U
aOiagYM6jsxwzVW+rBPmwZie8UC4+/ZKU9+yhkEOB8T/z2/kiuFwHyReYNWlFc4B
wiYk297r/ucwRz0lfMPrPDoUWoTrcLpBNP0wAAnm4QKBgQDmaMtMhldS+RB+CrO1
JbR6o0ek2TN79p4L6klgFw/MLvpsRqsoZ/MPiRiOW3q+vud+wnfSkxD8fLWF2Sk/
xTvgavIgnMiauea0pIlKPmPYcP/TrXT66ApHK/jfN7+M4a1jnqQE1mo3a6bPnjwZ
nBd4RRKM64q2CRrqrVWreeaMUwKBgQDI9HiETLqGnXNihLTqP20oaK7162kI0jJf
Pr04KE8VtvleJAHwf7CVxkeJ6oTySWo+tHfvjDVmsdCwwgXMVhAks+fQLpZv9qOf
U72Kqy5NjDKvyxdB4fVwNpJn/91HbUijfs/gN5wFu6tiyvgNddZiTgjlNo9BT7sW
LpVejqEikQKBgQDGsMnX1OWK7LL3Lj1oUfp/4zwOASuvk60Y81GRJnH+Duju5EYG
0xU8aWoeoO6JfNDec86mbSIxyU0z/l/e2TPYRAFGdE1deEBluJmXx5OMe21xWdxN
3jm2xEmaHFX3pElEZfJlJY10+0VfNsH3B68JjO8BTMFSVym6A/2joLxadwKBgGOw
GyUOZy2mZ/oEeTcHVeBI5hpquMU+eOyU1AtKu8i650PTOv8SaQgzv4NkSqVi1Ajd
P+4esNML/MnixjuSqhl7AdFdexV51buRMCLdPnALz40zg4sUS8xp1gEvhZcMWI96
tia1j3msmp28sIcE4OANdA45HaG5qsabP1AUE01xAoGAbMheTH2x5YpY1mbd68Xf
SOrRuJQd8jjrptQxmdW4x/junLYIVlacth0Fdm8e69qdbOuk1I4+4xeC7+CzVIvX
RrfNrfyTjpY64Kl1xKJIShkKcH7rAKLnCrHJkt9oODtQpvHEqzj8ZYxYBHOVIejp
k8HR+8OE9GDvPXSgyRfz7b4=
-----END PRIVATE KEY-----

22
tests/fixtures/fingergw/root-ca.pem vendored Normal file
View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDpzCCAo+gAwIBAgIUbe9RwznpVY2LaJxgFpfJls0ORlkwDQYJKoZIhvcNAQEL
BQAwYzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYDVQQHDAZBdXN0
aW4xHTAbBgNVBAoMFE9wZW5TdGFjayBGb3VuZGF0aW9uMRQwEgYDVQQDDAtmaW5n
ZXJndy1jYTAeFw0yMTA1MzAwMDM0NTBaFw0zMTA1MjgwMDM0NTBaMGMxCzAJBgNV
BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEPMA0GA1UEBwwGQXVzdGluMR0wGwYDVQQK
DBRPcGVuU3RhY2sgRm91bmRhdGlvbjEUMBIGA1UEAwwLZmluZ2VyZ3ctY2EwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC03ectwEf0Itw1u9ySo3VJOXWN
Lg0p01m4t3z4CyA15Oh2XlnDoTrio4FTZnZblZRd8kXZ0AGhC6LneIJqJc+79Y8S
2sKrl6nJuNcRt4UFdZqyyUCyU9EgY5nK28zge1OxNlSJ5ZTcM1I8YFhJDb7sM5ZC
hTaOp2OjuZOePoF7hp+lZTEdhczLC/e35LY84dd6i6QxBJ9reaOFnan+EqX5CVmF
CGWvmnTpxkZvSFtkhdvG+IC9r1SX9lZi1JZEKCVodgNozcwWTLFDPi2CxSY+HMXw
YYNJfh7GOxsy6a13TtCJGwNM5F5Ol7iVK35zYrzE4HWnxP+P+TtBrZ70a4EDAgMB
AAGjUzBRMB0GA1UdDgQWBBQ5IIU3pSweSOMfg/RpBqMRA8a7TzAfBgNVHSMEGDAW
gBQ5IIU3pSweSOMfg/RpBqMRA8a7TzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
DQEBCwUAA4IBAQBFj7FHoXxAC+jv2o/BeD2Sc+KntYi82Rtlt31aJ35zMk4/qE7Z
mM0pgc/xSZ+mchKzOIW+aVDxE/+WdptVZTiBmJao4hZ3tsCMZZiW9ocSBtlhYICq
vxCpK8ISQ3JjdVMgorsMPEd5pF9PKTbRSBSaDoHiduH4rHYzsBslnPfvx8vstVdI
4CvCEkNKvBfuqir0ZDObXTUT4Q80sZYWy/vcB+rxxofSQjP03Id+Wu0fIxPg6Ggi
ZjO33LNnNWEob1UV1A1VZMlGKHkVK5Ib4wtWdc8fnIbmpWGuGgJeaD+XiXprlrkY
wzMA2im8teUM+u6P0adI42ypyUJa056mHH79
-----END CERTIFICATE-----

1
tests/fixtures/fingergw/root-ca.srl vendored Normal file
View File

@ -0,0 +1 @@
934206D5C13CBB47

17
tests/fixtures/fingergw/server.csr vendored Normal file
View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICrDCCAZQCAQAwZzELMAkGA1UEBhMCVVMxDjAMBgNVBAgMBVRleGFzMQ8wDQYD
VQQHDAZBdXN0aW4xHTAbBgNVBAoMFE9wZW5TdGFjayBGb3VuZGF0aW9uMRgwFgYD
VQQDDA9maW5nZXJndy1zZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQCq3XOVvoXw7TShJeqnJCoc6GoQppYMYcx9hmOs0P/B346fEVPuHi4LZEVO
Z/31tXJUA71LYBYJjhpG1Rk2foJnBaQbpbaFUqrpAWnfPaHIES8Tmty3tdMoDput
C7vCXDX6Dq4g9RkttRir8wPQTkiJ3N9WlnDN4G/4VxqgiGYvn4eK5R1DUd3fy8nL
9Df8l5J/1FuMCLasYJxYu6Q0dIyaqu2gQxvL4BU0pUhtG1Lgzk6hMl5l5/jIlBDP
t+tNNMDMnhtDORhipPwUfAXbu9jTeSOb912CYArGubhxq3Q6/wabhm9fU/ZnmOvc
Z0AMI1I3a8AJ6J9563EBb+DBQcsbAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEA
pHrR07XajgkT51ubWpCcV5yJpEUdBHPcUSsYXp0Ee0PcylAGdfqYhk1iynaToih1
tisOb2p9+Q066Y8Z78OYD+yyMu+cJc96iU5OrP2x4/5QEkF1VBwOryhpAg9PT9sq
bnxN5AQM+q0oA/bJ72Sp1685kfd+bdxTXV5sdpckoCBZ7xVbakc6UM6kmvmAgAMi
2kzYH5r2AAesaT8OE2HYiWEQlK7f/y3rUt0BnazgzdHDjJegyZyAieqyhJ6Eaobq
nlqoftbbxz5fEhnMCy/YE0CcTD1awBThGsUo06K0xD/Um7hH29c+m4dEfSwxOaCq
K9oOg6FxiDg0EzT3KaSnbA==
-----END CERTIFICATE REQUEST-----

28
tests/fixtures/fingergw/server.key vendored Normal file
View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCq3XOVvoXw7TSh
JeqnJCoc6GoQppYMYcx9hmOs0P/B346fEVPuHi4LZEVOZ/31tXJUA71LYBYJjhpG
1Rk2foJnBaQbpbaFUqrpAWnfPaHIES8Tmty3tdMoDputC7vCXDX6Dq4g9RkttRir
8wPQTkiJ3N9WlnDN4G/4VxqgiGYvn4eK5R1DUd3fy8nL9Df8l5J/1FuMCLasYJxY
u6Q0dIyaqu2gQxvL4BU0pUhtG1Lgzk6hMl5l5/jIlBDPt+tNNMDMnhtDORhipPwU
fAXbu9jTeSOb912CYArGubhxq3Q6/wabhm9fU/ZnmOvcZ0AMI1I3a8AJ6J9563EB
b+DBQcsbAgMBAAECggEAKu9CoBoj5gp08xloAV/hBSqRnGV/xtS8Yb5nRYGvArR+
ThI4mNkUkOA9WhpfgmJ5vArEgjA+2V/P0oSxtTPM6L5OInRdjNrc/3fPdr0x7egD
gFWlqLQTvzkMfUs5fvlUxuTxdG6iSQ38iRijmLBTIfFSXZun9NO0zx50Hmqn4sc2
V9+CkZFmOv9VbIOs/tdFIWWAdb5hmEWTSDyHsr3YGHILcSp6d+nFbFnk3gPBGH4J
m0Wii+lWxi4g2MpvcZO/dgrX8SlBwO87uBnYMd4i7/o9jeKZK2Sl7MYhplmtpNX4
yhMS1973vWVO/U59eOF2II51LPlu7uUVV8A22kOK4QKBgQDSOY8ZPSIdQvVMtDhV
/s1Ne/g6cMSwWroRXRHY0UtXf5ZtCG2XuCdN8qjp1Xay2YEji7f8ldd4ttPAdk4i
LzQPs8/qwRPa5rg+I4Jh6zfb2IcPdcOED0wq8yLTYfXwrUsKr7jPGwbKscc+TyD6
C6T2NKtruLgjw+JlXUvL5s/RtQKBgQDQEeHiraQYt50WvqxgTfADlxBlFRDMM1Gs
KN81ir8VC/+8TKCLEPtqc05eGKjOGdhMFO4inNQ0dufwO+NojLKjY6LBk7lfZqS5
2QLWrxCRP+Lh95BzsKvDM3jS1bRVIJS+bFV6Sl33OUD57pCpQL5MD50bneFj4/yq
77qk05FrjwKBgAEB2ZerXVB6k6ZMbsCqud0XLPdKtwaJSL7wjTdWuV+v8s6O7cd+
UGHlOb31Ed6FgELlVnpVVXT0m0sexf0P8NXqbKKZTjkMRfG2RdemQtxAy1TdoZQu
ZpUGGTKeE4mVqvhgIyiK3pt2Aphf1K6eA6pSUkfv2KIDPEB0E/rkHjbJAoGBAIG2
JDPEPECMdwnu5FdFPxN94WKit04V0BybfktKq8TbLhqdSphnhdTe/UP764BQ7F7B
zZMWYdQzLHS/YQ2UaOki/Bvhk/a9boPNnc9oY9OpGC/2vb7hrLKMLA6D22AWZ6Qu
tTr/kYTF1JP6/YQGMJwKP88vpYs4XhPST3Dh1A5RAoGBAMXjBqaV1+hWsNmbvbH3
CrHXum1IQBXRCuhvc6yb4SnC8NSnyrBJC92W44IUmMURZuDY8R7creVTmzwVqWWR
adzcLrZOblcwi0ooW0D8nEZbORobPGGsCjYyvC9M4TQRZS7kWmux5UDWeAa9jORM
1fygOOLhWpOjH7z1NYMjOXgl
-----END PRIVATE KEY-----

20
tests/fixtures/fingergw/server.pem vendored Normal file
View File

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDRjCCAi4CCQCTQgbVwTy7RjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJV
UzEOMAwGA1UECAwFVGV4YXMxDzANBgNVBAcMBkF1c3RpbjEdMBsGA1UECgwUT3Bl
blN0YWNrIEZvdW5kYXRpb24xFDASBgNVBAMMC2Zpbmdlcmd3LWNhMB4XDTIxMDUz
MDAwMzQ1MFoXDTMxMDUyODAwMzQ1MFowZzELMAkGA1UEBhMCVVMxDjAMBgNVBAgM
BVRleGFzMQ8wDQYDVQQHDAZBdXN0aW4xHTAbBgNVBAoMFE9wZW5TdGFjayBGb3Vu
ZGF0aW9uMRgwFgYDVQQDDA9maW5nZXJndy1zZXJ2ZXIwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQCq3XOVvoXw7TShJeqnJCoc6GoQppYMYcx9hmOs0P/B
346fEVPuHi4LZEVOZ/31tXJUA71LYBYJjhpG1Rk2foJnBaQbpbaFUqrpAWnfPaHI
ES8Tmty3tdMoDputC7vCXDX6Dq4g9RkttRir8wPQTkiJ3N9WlnDN4G/4VxqgiGYv
n4eK5R1DUd3fy8nL9Df8l5J/1FuMCLasYJxYu6Q0dIyaqu2gQxvL4BU0pUhtG1Lg
zk6hMl5l5/jIlBDPt+tNNMDMnhtDORhipPwUfAXbu9jTeSOb912CYArGubhxq3Q6
/wabhm9fU/ZnmOvcZ0AMI1I3a8AJ6J9563EBb+DBQcsbAgMBAAEwDQYJKoZIhvcN
AQELBQADggEBAJR0VngrPAMNdbSbVIT5AazqKIlmiEeDjatVhOZWBme9tN7VsKiS
1xnX70dbgyX2pii+xKF4QCzvizz/byDdO9Ckf7hZYR+D1j9qosu0XNdNb0Pcrddh
cSvWk9W5lryzPFs8SDPoVQ4UpdOTYDYBQB0BTtw1w/i8GAy1AobTqzaezmfcTApw
ySnCvqSiLWffKZYaqynw67Lk/tLG6H8kO7bSn9uZzvzvu0X1/E5nSaLu5GltPo5q
eiuj1nUm8m0IgU5VJhT3BsoV3M4A4Gj6yqvFZFIoSudpnfYG0NiXGamWR5K7Qg7c
KbW3b+1ihkhGFq2wyrZczI5TdALqjndTJXs=
-----END CERTIFICATE-----

View File

@ -19,6 +19,7 @@ import os
import os.path
import re
import socket
import ssl
import tempfile
import testtools
import threading
@ -28,7 +29,7 @@ import zuul.web
import zuul.lib.log_streamer
from zuul.lib.fingergw import FingerGateway
import tests.base
from tests.base import iterate_timeout, ZuulWebFixture
from tests.base import iterate_timeout, ZuulWebFixture, FIXTURE_DIR
from ws4py.client import WebSocketBaseClient
@ -99,6 +100,7 @@ class TestStreamingBase(tests.base.AnsibleZuulTestCase):
tenant_config_file = 'config/streamer/main.yaml'
log = logging.getLogger("zuul.test_streaming")
fingergw_use_ssl = False
def setUp(self):
super().setUp()
@ -150,6 +152,17 @@ class TestStreamingBase(tests.base.AnsibleZuulTestCase):
self.streaming_data[name] = ''
with socket.create_connection(gateway_address) as s:
if self.fingergw_use_ssl:
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = False
context.load_cert_chain(
os.path.join(FIXTURE_DIR, 'fingergw/client.pem'),
os.path.join(FIXTURE_DIR, 'fingergw/client.key'))
context.load_verify_locations(
os.path.join(FIXTURE_DIR, 'fingergw/root-ca.pem'))
s = context.wrap_socket(s)
msg = "%s\r\n" % build_uuid
s.sendall(msg.encode('utf-8'))
event.set() # notify we are connected and req sent
@ -174,6 +187,21 @@ class TestStreamingBase(tests.base.AnsibleZuulTestCase):
if zone:
config.set('fingergw', 'zone', zone)
if self.fingergw_use_ssl:
self.log.info('SSL enabled for fingergw')
config.set('fingergw', 'server_ssl_ca',
os.path.join(FIXTURE_DIR, 'fingergw/root-ca.pem'))
config.set('fingergw', 'server_ssl_cert',
os.path.join(FIXTURE_DIR, 'fingergw/server.pem'))
config.set('fingergw', 'server_ssl_key',
os.path.join(FIXTURE_DIR, 'fingergw/server.key'))
config.set('fingergw', 'client_ssl_ca',
os.path.join(FIXTURE_DIR, 'fingergw/root-ca.pem'))
config.set('fingergw', 'client_ssl_cert',
os.path.join(FIXTURE_DIR, 'fingergw/client.pem'))
config.set('fingergw', 'client_ssl_key',
os.path.join(FIXTURE_DIR, 'fingergw/client.key'))
gateway = FingerGateway(
config,
command_socket=None,
@ -595,14 +623,9 @@ class TestStreaming(TestStreamingBase):
class CountingFingerRequestHandler(zuul.lib.fingergw.RequestHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# if not hasattr(self.fingergw, 'history'):
# self.fingergw.history = []
def _fingerClient(self, server, port, build_uuid):
def _fingerClient(self, server, port, build_uuid, use_ssl):
self.fingergw.history.append(build_uuid)
super()._fingerClient(server, port, build_uuid)
super()._fingerClient(server, port, build_uuid, use_ssl)
class TestStreamingZones(TestStreamingBase):
@ -775,3 +798,7 @@ class TestStreamingZones(TestStreamingBase):
self.assertEqual(file_contents, self.streaming_data['unzoned'])
self.assertEqual(file_contents, self.streaming_data['unzoned2'])
self.assertEqual(file_contents, self.streaming_data['eu-central'])
class TestStreamingZonesSSL(TestStreamingZones):
fingergw_use_ssl = True

View File

@ -15,6 +15,7 @@
import functools
import logging
import socket
import ssl
import threading
from configparser import ConfigParser
from typing import Optional
@ -38,10 +39,9 @@ class RequestHandler(streamer_utils.BaseFingerRequestHandler):
def __init__(self, *args, **kwargs):
self.fingergw = kwargs.pop('fingergw')
super(RequestHandler, self).__init__(*args, **kwargs)
def _fingerClient(self, server, port, build_uuid):
def _fingerClient(self, server, port, build_uuid, use_ssl):
'''
Open a finger connection and return all streaming results.
@ -52,6 +52,16 @@ class RequestHandler(streamer_utils.BaseFingerRequestHandler):
Both IPv4 and IPv6 are supported.
'''
with socket.create_connection((server, port), timeout=10) as s:
if use_ssl:
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = False
context.load_cert_chain(self.fingergw.finger_client_ssl_cert,
self.fingergw.finger_client_ssl_key)
context.load_verify_locations(
self.fingergw.finger_client_ssl_ca)
s = context.wrap_socket(s, server_hostname=server)
# timeout only on the connection, let recv() wait forever
s.settimeout(None)
msg = "%s\n" % build_uuid # Must have a trailing newline!
@ -82,7 +92,8 @@ class RequestHandler(streamer_utils.BaseFingerRequestHandler):
server = port_location['server']
port = port_location['port']
self._fingerClient(server, port, build_uuid)
use_ssl = port_location.get('use_ssl', False)
self._fingerClient(server, port, build_uuid, use_ssl)
except BrokenPipeError: # Client disconnect
return
except Exception:
@ -157,6 +168,22 @@ class FingerGateway(object):
self.command_socket_path = command_socket
self.command_socket = None
# Fingergw server ssl settings
self.finger_server_ssl_key = get_default(
config, 'fingergw', 'server_ssl_key')
self.finger_server_ssl_cert = get_default(
config, 'fingergw', 'server_ssl_cert')
self.finger_server_ssl_ca = get_default(
config, 'fingergw', 'server_ssl_ca')
# Fingergw client ssl settings
self.finger_client_ssl_key = get_default(
config, 'fingergw', 'client_ssl_key')
self.finger_client_ssl_cert = get_default(
config, 'fingergw', 'client_ssl_cert')
self.finger_client_ssl_ca = get_default(
config, 'fingergw', 'client_ssl_ca')
self.command_map = dict(
stop=self.stop,
)
@ -173,6 +200,9 @@ class FingerGateway(object):
if self.zone is not None:
self.component_info.zone = self.zone
self.component_info.public_port = self.public_port
if all([self.finger_server_ssl_key,
self.finger_server_ssl_cert, self.finger_server_ssl_ca]):
self.component_info.use_ssl = True
self.component_info.register()
def _runCommand(self):
@ -205,6 +235,9 @@ class FingerGateway(object):
self.server = streamer_utils.CustomThreadingTCPServer(
self.address,
functools.partial(self.handler_class, fingergw=self),
server_ssl_ca=self.finger_server_ssl_ca,
server_ssl_cert=self.finger_server_ssl_cert,
server_ssl_key=self.finger_server_ssl_key,
user=self.user,
pid_file=self.pid_file)

View File

@ -23,6 +23,7 @@ import pwd
import select
import socket
import socketserver
import ssl
import threading
import time
@ -97,6 +98,9 @@ class CustomThreadingTCPServer(socketserver.ThreadingTCPServer):
self.address_family = address_family
self.user = kwargs.pop('user', None)
self.pid_file = kwargs.pop('pid_file', None)
self.server_ssl_key = kwargs.pop('server_ssl_key', None)
self.server_ssl_cert = kwargs.pop('server_ssl_cert', None)
self.server_ssl_ca = kwargs.pop('server_ssl_ca', None)
socketserver.ThreadingTCPServer.__init__(self, *args, **kwargs)
def change_privs(self):
@ -150,3 +154,15 @@ class CustomThreadingTCPServer(socketserver.ThreadingTCPServer):
args=(request, client_address))
t.daemon = self.daemon_threads
t.start()
def get_request(self):
sock, addr = super().get_request()
if all([self.server_ssl_key, self.server_ssl_cert,
self.server_ssl_ca]):
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.load_cert_chain(self.server_ssl_cert, self.server_ssl_key)
context.load_verify_locations(self.server_ssl_ca)
context.verify_mode = ssl.CERT_REQUIRED
sock = context.wrap_socket(sock, server_side=True)
return sock, addr

View File

@ -297,9 +297,7 @@ class RPCListener(RPCListenerBase):
if info:
job_log_stream_address['server'] = info.hostname
job_log_stream_address['port'] = info.public_port
use_ssl = getattr(info, 'use_ssl', False)
if use_ssl:
job_log_stream_address['use_ssl'] = use_ssl
job_log_stream_address['use_ssl'] = info.use_ssl
self.log.debug('Source (%s) and worker (%s) zone '
'are different, routing via %s:%s',
source_zone, build.worker.zone,

View File

@ -26,6 +26,7 @@ import logging
import os
import time
import select
import ssl
import threading
from zuul import exceptions
@ -172,13 +173,13 @@ class LogStreamHandler(WebSocket):
self.streamer = LogStreamer(
self.zuulweb, self,
port_location['server'], port_location['port'],
request['uuid'])
request['uuid'], port_location.get('use_ssl'))
class LogStreamer(object):
log = logging.getLogger("zuul.web")
def __init__(self, zuulweb, websocket, server, port, build_uuid):
def __init__(self, zuulweb, websocket, server, port, build_uuid, use_ssl):
"""
Create a client to connect to the finger streamer and pull results.
@ -189,11 +190,21 @@ class LogStreamer(object):
self.log.debug("Connecting to finger server %s:%s", server, port)
Decoder = codecs.getincrementaldecoder('utf8')
self.decoder = Decoder()
self.zuulweb = zuulweb
self.finger_socket = socket.create_connection(
(server, port), timeout=10)
if use_ssl:
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = False
context.load_cert_chain(
self.zuulweb.finger_ssl_cert, self.zuulweb.finger_ssl_key)
context.load_verify_locations(self.zuulweb.finger_ssl_ca)
self.finger_socket = context.wrap_socket(
self.finger_socket, server_hostname=server)
self.finger_socket.settimeout(None)
self.websocket = websocket
self.zuulweb = zuulweb
self.uuid = build_uuid
msg = "%s\n" % build_uuid # Must have a trailing newline!
self.finger_socket.sendall(msg.encode('utf-8'))
@ -1289,6 +1300,13 @@ class ZuulWeb(object):
'norepl': self.stop_repl,
}
self.finger_ssl_key = get_default(
self.config, 'fingergw', 'client_ssl_key')
self.finger_ssl_cert = get_default(
self.config, 'fingergw', 'client_ssl_cert')
self.finger_ssl_ca = get_default(
self.config, 'fingergw', 'client_ssl_ca')
route_map = cherrypy.dispatch.RoutesDispatcher()
api = ZuulWebAPI(self)
route_map.connect('api', '/api',

View File

@ -148,6 +148,7 @@ class FingerGatewayComponent(BaseComponent):
self.initial_state = {
"zone": None,
"public_port": None,
"use_ssl": False,
}
self.content.update(self.initial_state)