Skip to content

Commit 3c8adf0

Browse files
committed
Add haproxy to benchmarking tool
Adding as a proxy - a middle actor. Currently adding only for apache. Support all the encryption modes for haproxy: - client to proxy - proxy to server - client to server - pure http without encryption Signed-off-by: Norbert Pocs <norbertp@openssl.org>
1 parent dd3a90c commit 3c8adf0

File tree

3 files changed

+268
-8
lines changed

3 files changed

+268
-8
lines changed

bench-scripts/apache_bench.sh

Lines changed: 90 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ CERT_ALT_SUBJ=${BENCH_CERT_ALT_SUBJ:-'subjectAltName=DNS:localhost,IP:127.0.0.1'
6363
TEST_TIME=${BENCH_TEST_TIME:-'5M'}
6464
HOST=${BENCH_HOST:-'127.0.0.1'}
6565
APACHE_VERSION='2.4.65'
66+
HAPROXY='no'
6667

6768
. ./common_util.sh
69+
. ./haproxy_bench.sh
6870

6971
function install_wolfssl_for_apache {
7072
typeset VERSION=$1
@@ -810,18 +812,25 @@ function enable_mpm_prefork {
810812

811813
function run_test {
812814
typeset SSL_LIB=$1
813-
typeset HTTP='https'
815+
typeset HAPROXY=$2
814816
typeset i=0
815817
typeset PORT=${HTTPS_PORT}
818+
typeset PROTOCOL="https"
816819
if [[ -z "${SSL_LIB}" ]] ; then
817820
SSL_LIB='openssl-master'
818821
fi
822+
if [[ -z "${HAPROXY}" ]] ; then
823+
HAPROXY='no'
824+
fi
819825
typeset RESULTS="${SSL_LIB}".txt
820826
if [[ "${SSL_LIB}" = 'nossl' ]] ; then
821-
HTTP='http'
822827
SSL_LIB='openssl-master'
823828
RESULTS='nossl.txt'
824829
PORT=${HTTP_PORT}
830+
PROTOCOL="http"
831+
fi
832+
if [[ "${HAPROXY}" != 'no' ]] ; then
833+
RESULTS="haproxy-${SSL_LIB}-${HAPROXY}.txt"
825834
fi
826835
typeset HTDOCS="${INSTALL_ROOT}/${SSL_LIB}"/htdocs
827836
typeset SIEGE="${INSTALL_ROOT}"/openssl-master/bin/siege
@@ -839,11 +848,35 @@ function run_test {
839848
#
840849
# generate URLs for sewage
841850
#
851+
# The different modes for haproxy are:
852+
# no: client - server
853+
# no-ssl: client -http- haproxy -http- server
854+
# server: client -https- haproxy -http- server
855+
# client: client -http- haproxy -https- server
856+
# both: client -https- haproxy -https- server
857+
#
858+
# Otherwise said, haproxy is a client when it encrypts the outgoing encryption;
859+
# or it's client side.
860+
#
842861
rm -f siege_urls.txt
843862
for i in `ls -1 ${HTDOCS}/*.txt` ; do
844-
echo "${HTTP}://${HOST}:${PORT}/`basename $i`" >> siege_urls.txt
863+
if [[ "${HAPROXY}" = "no" ]] ; then
864+
echo "${PROTOCOL}://${HOST}:${PORT}/`basename $i`" >> siege_urls.txt
865+
elif [[ "${HAPROXY}" = "no-ssl" ]] ; then
866+
echo "http://${HOST}:${HAPROXY_NOSSL_PORT}/`basename $i`" >> siege_urls.txt
867+
elif [[ "${HAPROXY}" = "server" ]] ; then
868+
echo "https://${HOST}:${HAPROXY_C2P_PORT}/`basename $i`" >> siege_urls.txt
869+
elif [[ "${HAPROXY}" = "client" ]] ; then
870+
echo "http://${HOST}:${HAPROXY_P2S_PORT}/`basename $i`" >> siege_urls.txt
871+
elif [[ "${HAPROXY}" = "both" ]] ; then
872+
echo "https://${HOST}:${HAPROXY_C2S_PORT}/`basename $i`" >> siege_urls.txt
873+
fi
845874
done
846875

876+
if [[ "${HAPROXY}" = "server" ]] || [[ "${HAPROXY}" = "both" ]] ; then
877+
conf_siege_haproxy_cert $SSL_LIB
878+
fi
879+
847880
#
848881
# start apache httpd server
849882
#
@@ -856,13 +889,14 @@ function run_test {
856889
LD_LIBRARY_PATH=${INSTALL_ROOT}/openssl-master/lib "${SIEGE}" -t ${TEST_TIME} -b \
857890
-f siege_urls.txt 2> "${RESULT_DIR}/${RESULTS}"
858891
if [[ $? -ne 0 ]] ; then
859-
echo "${INSTALL_ROOT}/${SSL_LIB} can not run siege"
892+
echo "${INSTALL_ROOT}/${SSL_LIB} can not run siege"
860893
cat "${RESULT_DIR}/${RESULTS}"
861894
exit 1
862895
fi
863896

864897
LD_LIBRARY_PATH=${INSTALL_ROOT}/${SSL_LIB}/lib \
865898
${INSTALL_ROOT}/${SSL_LIB}/bin/httpd -k stop || exit 1
899+
sleep 1
866900
pgrep httpd
867901
while [[ $? -eq 0 ]] ; do
868902
sleep 1
@@ -881,20 +915,26 @@ function run_test {
881915
${RESULT_DIR}/httpd-${SSL_LIB}.conf
882916
cp ${INSTALL_ROOT}/${SSL_LIB}/conf/extra/httpd-ssl.conf \
883917
${RESULT_DIR}/httpd-ssl-${SSL_LIB}.conf
918+
919+
if [[ "${HAPROXY}" = "server" ]] || [[ "${HAPROXY}" = "both" ]] ; then
920+
unconf_siege_haproxy_cert
921+
fi
884922
}
885923

886924
function setup_tests {
887925
install_openssl master
888926
install_siege openssl-master
889927
install_apache openssl-master
890928
config_apache openssl-master
929+
install_haproxy openssl-master
891930
cd "${WORKSPACE_ROOT}"
892931
clean_build
893932

894933
for i in 3.0 3.1 3.2 3.3 3.4 3.5 3.6 ; do
895934
install_openssl openssl-$i ;
896935
install_apache openssl-$i
897936
config_apache openssl-$i
937+
install_haproxy openssl-$i
898938
cd "${WORKSPACE_ROOT}"
899939
clean_build
900940
done
@@ -967,6 +1007,7 @@ function setup_tests {
9671007

9681008
function run_tests {
9691009
typeset SAVE_RESULT_DIR="${RESULT_DIR}"
1010+
typeset HAPROXY_OPTIONS=('no' 'client' 'server' 'both')
9701011

9711012
for i in event worker pre-fork ; do
9721013
mkdir -p ${RESULT_DIR}/$i || exit 1
@@ -975,12 +1016,25 @@ function run_tests {
9751016
enable_mpm_event
9761017
RESULT_DIR="${SAVE_RESULT_DIR}/event"
9771018
run_test nossl
1019+
run_haproxy
1020+
run_test nossl 'no-ssl'
1021+
kill_haproxy
9781022
for i in 3.0 3.1 3.2 3.3 3.4 3.5 3.6 ; do
9791023
enable_mpm_event openssl-${i}
980-
run_test openssl-${i}
1024+
run_haproxy openssl-${i}
1025+
for OPTION in ${HAPROXY_OPTIONS[@]}
1026+
do
1027+
run_test openssl-${i} ${OPTION}
1028+
done
1029+
kill_haproxy
9811030
done
9821031
enable_mpm_event openssl-master
983-
run_test openssl-master
1032+
run_haproxy openssl-master
1033+
for OPTION in ${HAPROXY_OPTIONS[@]}
1034+
do
1035+
run_test openssl-master ${OPTION}
1036+
done
1037+
kill_haproxy
9841038
enable_mpm_event OpenSSL_1_1_1-stable
9851039
run_test OpenSSL_1_1_1-stable
9861040
enable_mpm_event libressl-4.1.0
@@ -995,12 +1049,26 @@ function run_tests {
9951049
enable_mpm_worker
9961050
RESULT_DIR="${SAVE_RESULT_DIR}/worker"
9971051
run_test nossl
1052+
run_haproxy
1053+
run_test nossl 'no-ssl'
1054+
kill_haproxy
9981055
for i in 3.0 3.1 3.2 3.3 3.4 3.5 3.6 ; do
9991056
enable_mpm_worker openssl-${i}
10001057
run_test openssl-${i}
1058+
run_haproxy openssl-${i}
1059+
for OPTION in ${HAPROXY_OPTIONS[@]}
1060+
do
1061+
run_test openssl-${i} ${OPTION}
1062+
done
1063+
kill_haproxy
10011064
done
10021065
enable_mpm_worker openssl-master
1003-
run_test openssl-master
1066+
run_haproxy openssl-master
1067+
for OPTION in ${HAPROXY_OPTIONS[@]}
1068+
do
1069+
run_test openssl-master ${OPTION}
1070+
done
1071+
kill_haproxy
10041072
enable_mpm_worker OpenSSL_1_1_1-stable
10051073
run_test OpenSSL_1_1_1-stable
10061074
enable_mpm_worker libressl-4.1.0
@@ -1015,12 +1083,26 @@ function run_tests {
10151083
enable_mpm_prefork
10161084
RESULT_DIR="${SAVE_RESULT_DIR}/pre-fork"
10171085
run_test nossl
1086+
run_haproxy
1087+
run_test nossl 'no-ssl'
1088+
kill_haproxy
10181089
for i in 3.0 3.1 3.2 3.3 3.4 3.5 3.6 ; do
10191090
enable_mpm_prefork openssl-${i}
10201091
run_test openssl-${i}
1092+
run_haproxy openssl-${i}
1093+
for OPTION in ${HAPROXY_OPTIONS[@]}
1094+
do
1095+
run_test openssl-${i} ${OPTION}
1096+
done
1097+
kill_haproxy
10211098
done
10221099
enable_mpm_prefork openssl-master
1023-
run_test openssl-master
1100+
run_haproxy openssl-master
1101+
for OPTION in ${HAPROXY_OPTIONS[@]}
1102+
do
1103+
run_test openssl-master ${OPTION}
1104+
done
1105+
kill_haproxy
10241106
enable_mpm_prefork OpenSSL_1_1_1-stable
10251107
run_test OpenSSL_1_1_1-stable
10261108
enable_mpm_prefork libressl-4.1.0

bench-scripts/common_util.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ set term png size 1600, 600
292292
set boxwidth 0.4
293293
set autoscale
294294
set output "${PNG_FILE}"
295+
set xtics rotate by 90 right
295296
plot "${DATA_FILE}" using 1:3:xtic(2) with boxes
296297
EOF
297298
gnuplot ${PLOT_FILE}

bench-scripts/haproxy_bench.sh

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#!/usr/bin/env ksh
2+
#
3+
# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
4+
#
5+
# Licensed under the Apache License 2.0 (the "License"). You may not use
6+
# this file except in compliance with the License. You can obtain a copy
7+
# in the file LICENSE in the source distribution or at
8+
# https://www.openssl.org/source/license.html
9+
#
10+
11+
set -x
12+
13+
INSTALL_ROOT=${BENCH_INSTALL_ROOT:-"/tmp/bench.binaries"}
14+
RESULT_DIR=${BENCH_RESULTS:-"${INSTALL_ROOT}/results"}
15+
WORKSPACE_ROOT=${BENCH_WORKSPACE_ROOT:-"/tmp/bench.workspace"}
16+
MAKE_OPTS=${BENCH_MAKE_OPTS}
17+
HAPROXY_NOSSL_PORT='42128'
18+
HAPROXY_C2P_PORT='42132'
19+
HAPROXY_P2S_PORT='42134'
20+
HAPROXY_C2S_PORT='42136'
21+
CERT_SUBJ=${BENCH_CERT_SUBJ:-'/CN=localhost'}
22+
CERT_ALT_SUBJ=${BENCH_CERT_ALT_SUBJ:-'subjectAltName=DNS:localhost,IP:127.0.0.1'}
23+
HOST=${BENCH_HOST:-'127.0.0.1'}
24+
HAPROXY_VERSION='v3.2.0'
25+
26+
function install_haproxy {
27+
typeset SSL_LIB=$1
28+
typeset VERSION=${HAPROXY_VERSION:-v3.2.0}
29+
typeset HAPROXY_REPO="https://github.com/haproxy/haproxy.git"
30+
typeset BASENAME='haproxy'
31+
typeset DIRNAME="${BASENAME}-${VERSION}"
32+
typeset CERTDIR="${INSTALL_ROOT}/${SSL_LIB}/conf/certs"
33+
34+
if [[ -z "${SSL_LIB}" ]] ; then
35+
SSL_LIB="openssl-master"
36+
fi
37+
38+
if [[ -f "${INSTALL_ROOT}/${SSL_LIB}/sbin/haproxy" ]] ; then
39+
echo "haproxy already installed; skipping.."
40+
else
41+
cd "${WORKSPACE_ROOT}"
42+
mkdir -p "${DIRNAME}" || exit 1
43+
cd "${DIRNAME}"
44+
git clone "${HAPROXY_REPO}" -b ${VERSION} --depth 1 . || exit 1
45+
46+
# haproxy does not have a configure script; only a big makefile
47+
make ${MAKE_OPTS} \
48+
TARGET=generic \
49+
USE_OPENSSL=1 \
50+
SSL_INC="${INSTALL_ROOT}/${SSL_LIB}/include" \
51+
SSL_LIB="${INSTALL_ROOT}/${SSL_LIB}/lib" || exit 1
52+
53+
make install ${MAKE_OPTS} \
54+
PREFIX="${INSTALL_ROOT}/${SSL_LIB}" || exit 1
55+
fi
56+
57+
mkdir -p ${CERTDIR}
58+
59+
# now generate the certificates
60+
echo "generating new certificates for haproxy"
61+
OPENSSL_BIN="env LD_LIBRARY_PATH=${INSTALL_ROOT}/${SSL_LIB}/lib ${INSTALL_ROOT}/${SSL_LIB}/bin/openssl"
62+
63+
# generating the key, cert of ca
64+
$OPENSSL_BIN genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -out "${CERTDIR}/ca_key.pem" || exit 1
65+
$OPENSSL_BIN req -new -x509 -days 1 -key "${CERTDIR}/ca_key.pem" -out "${CERTDIR}/ca_cert.pem" -subj "/CN=Root CA" \
66+
-addext "basicConstraints=critical,CA:true" \
67+
-addext "keyUsage=critical,keyCertSign,cRLSign" || exit 1
68+
69+
# generating the client side
70+
$OPENSSL_BIN genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -out "${CERTDIR}/client_key.pem" || exit 1
71+
$OPENSSL_BIN pkey -in "${CERTDIR}/client_key.pem" -pubout -out "${CERTDIR}/client_key_pub.pem" || exit 1
72+
$OPENSSL_BIN req -new -out "${CERTDIR}/client_csr.pem" -subj "/CN=${HOST}" -key "${CERTDIR}/client_key.pem" \
73+
-addext "${CERT_ALT_SUBJ}" \
74+
-addext "keyUsage=critical,digitalSignature" || exit 1
75+
$OPENSSL_BIN x509 -req -out "${CERTDIR}/client_cert.pem" -CAkey "${CERTDIR}/ca_key.pem" -CA "${CERTDIR}/ca_cert.pem" \
76+
-days 1 -in "${CERTDIR}/client_csr.pem" -copy_extensions copy -ext "subjectAltName,keyUsage" \
77+
-extfile <(printf "basicConstraints=critical,CA:false\nsubjectKeyIdentifier=none\n") || exit 1
78+
79+
# generating the server side
80+
$OPENSSL_BIN genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 -out "${CERTDIR}/server_key.pem" || exit 1
81+
$OPENSSL_BIN pkey -in "${CERTDIR}/server_key.pem" -pubout -out "${CERTDIR}/server_key_pub.pem" || exit 1
82+
$OPENSSL_BIN req -new -out "${CERTDIR}/server_csr.pem" -subj "/CN=${HOST}" -key "${CERTDIR}/server_key.pem" \
83+
-addext "${CERT_ALT_SUBJ}" \
84+
-addext "keyUsage=critical,digitalSignature" || exit 1
85+
$OPENSSL_BIN x509 -req -out "${CERTDIR}/server_cert.pem" -CAkey "${CERTDIR}/ca_key.pem" -CA "${CERTDIR}/ca_cert.pem" \
86+
-days 1 -in "${CERTDIR}/server_csr.pem" -copy_extensions copy -ext "subjectAltName,keyUsage" \
87+
-extfile <(printf "subjectKeyIdentifier=none\n"
88+
printf "${CERT_ALT_SUBJ}\n"
89+
printf "basicConstraints=critical,CA:false\n"
90+
printf "keyUsage=critical,keyEncipherment\n") || exit 1
91+
92+
# HAProxy PEM must be: server cert + server key (+ chain)
93+
cat "${CERTDIR}/server_cert.pem" "${CERTDIR}/server_key.pem" "${CERTDIR}/ca_cert.pem" > "${CERTDIR}/haproxy_server.pem"
94+
95+
# setting up SSL Termination mode for now
96+
# haproxy modes: encoding from client to haproxy, to server from haproxy, both
97+
# the first needs a non TLS connection to the server - use the HTTP_PORT, otherwise use the HTTPS_PORT
98+
cat <<EOF > "${INSTALL_ROOT}/${SSL_LIB}/conf/haproxy.cfg"
99+
defaults
100+
timeout server 10s
101+
timeout client 10s
102+
timeout connect 10s
103+
104+
frontend test_no_ssl
105+
mode http
106+
bind :${HAPROXY_NOSSL_PORT}
107+
default_backend http_test
108+
109+
frontend test_client2proxy
110+
mode http
111+
bind :${HAPROXY_C2P_PORT} ssl crt ${CERTDIR}/haproxy_server.pem ca-file ${CERTDIR}/ca_cert.pem verify required
112+
default_backend http_test
113+
114+
frontend test_proxy2server
115+
mode http
116+
bind :${HAPROXY_P2S_PORT}
117+
default_backend https_test
118+
119+
frontend test_client2server
120+
mode http
121+
bind :${HAPROXY_C2S_PORT} ssl crt ${CERTDIR}/haproxy_server.pem ca-file ${CERTDIR}/ca_cert.pem verify required
122+
default_backend https_test
123+
124+
backend http_test
125+
mode http
126+
balance random
127+
server s1 ${HOST}:${HTTP_PORT}
128+
129+
backend https_test
130+
mode http
131+
balance random
132+
server s2 ${HOST}:${HTTPS_PORT} ssl verify required ca-file ${INSTALL_ROOT}/${SSL_LIB}/conf/server.crt
133+
EOF
134+
}
135+
136+
function run_haproxy {
137+
typeset SSL_LIB=$1
138+
if [[ -z "${SSL_LIB}" ]] ; then
139+
SSL_LIB="openssl-master"
140+
fi
141+
typeset OPENSSL_DIR="${INSTALL_ROOT}/${SSL_LIB}"
142+
143+
LD_LIBRARY_PATH="${OPENSSL_DIR}/lib:${LD_LIBRARY_PATH}" "${OPENSSL_DIR}/sbin/haproxy" -f "${OPENSSL_DIR}/conf/haproxy.cfg" -D
144+
if [[ $? -ne 0 ]] ; then
145+
echo "could not start haproxy"
146+
exit 1
147+
fi
148+
}
149+
150+
function conf_siege_haproxy_cert {
151+
typeset SSL_LIB=$1
152+
if [[ -z "${SSL_LIB}" ]] ; then
153+
SSL_LIB="openssl-master"
154+
fi
155+
typeset OPENSSL_DIR="${INSTALL_ROOT}/${SSL_LIB}"
156+
# siege is currently installed only with openssl-master
157+
typeset SIEGE_CONF="${INSTALL_ROOT}/openssl-master/etc/siegerc"
158+
# configure siege to use haproxy
159+
if [[ ! -f "${SIEGE_CONF}" ]] ; then
160+
echo "Did not found siegerc. Siege should be installed first."
161+
exit 1
162+
fi
163+
echo "#haproxy" >> "${SIEGE_CONF}"
164+
echo "ssl-cert = ${OPENSSL_DIR}/conf/certs/client_cert.pem" >> "${SIEGE_CONF}"
165+
echo "ssl-key = ${OPENSSL_DIR}/conf/certs/client_key.pem" >> "${SIEGE_CONF}"
166+
}
167+
168+
function unconf_siege_haproxy_cert {
169+
typeset SIEGE_CONF="${INSTALL_ROOT}/openssl-master/etc/siegerc"
170+
171+
# clear the siege config
172+
sed -i '/#haproxy/{N;d;}' "${SIEGE_CONF}" || exit 1
173+
}
174+
175+
function kill_haproxy {
176+
pkill -TERM -f haproxy
177+
}

0 commit comments

Comments
 (0)