Project

General

Profile

Load Tests » History » Version 16

Martin Willi, 12.11.2012 17:59

1 7 Martin Willi
h1. Load Tests
2 7 Martin Willi
3 16 Martin Willi
{{>toc}}
4 7 Martin Willi
5 6 Martin Willi
To do stability testing and performance optimizations, charon provides a load-tester plugin. This plugin allows to set up thousands of tunnels concurrently against the daemon itself or a remote host.
6 1 Martin Willi
7 1 Martin Willi
8 7 Martin Willi
h2. Setup
9 7 Martin Willi
10 7 Martin Willi
11 1 Martin Willi
To build and enable the plugin, add
12 7 Martin Willi
<pre>
13 9 Martin Willi
--enable-load-tester
14 1 Martin Willi
</pre>
15 8 Tobias Brunner
to your _./configure_ options.
16 8 Tobias Brunner
17 8 Tobias Brunner
18 7 Martin Willi
----
19 8 Tobias Brunner
20 1 Martin Willi
*Warning: Never enable the load-testing plugin on productive systems. It provides preconfigured credentials and allows an attacker to authenticate as any user.*
21 8 Tobias Brunner
22 7 Martin Willi
----
23 8 Tobias Brunner
24 7 Martin Willi
To make sure you are aware of this risk, an additional _enable_ switch in _strongswan.conf_ is required to load the plugin.
25 6 Martin Willi
26 7 Martin Willi
27 7 Martin Willi
h2. Testing against self
28 7 Martin Willi
29 1 Martin Willi
30 1 Martin Willi
In the simplest case, the the daemon initiates IKE_SAs against self using the loopback interface. This will actually establish the doubled number of IKE_SAs, as the daemon is initiator and responder for each IKE_SA at the same time. Installation of IPsec SAs would fail, as each SA gets installed twice. To simulate the correct behavior, a faked kernel interface can be enabled which does not install the IPsec SAs at the kernel level.
31 1 Martin Willi
32 8 Tobias Brunner
A simple loop-back configuration in [[StrongswanConf|/etc/strongswan.conf]] might look like this:
33 7 Martin Willi
<pre>
34 1 Martin Willi
charon {
35 1 Martin Willi
    # create a new IKE_SA for each CHILD_SA to simulate different clients
36 1 Martin Willi
    reuse_ikesa = no
37 1 Martin Willi
    # turn off denial of service protection
38 1 Martin Willi
    dos_protection = no
39 1 Martin Willi
40 6 Martin Willi
    plugins {
41 9 Martin Willi
        load-tester {
42 1 Martin Willi
            # enable the plugin
43 1 Martin Willi
            enable = yes
44 1 Martin Willi
            # use 4 threads to initiate connections simultaneously
45 1 Martin Willi
            initiators = 4
46 1 Martin Willi
            # each thread initiates 1000 connections
47 1 Martin Willi
            iterations = 1000
48 1 Martin Willi
            # delay each initiation in each thread by 20ms
49 1 Martin Willi
            delay = 20
50 1 Martin Willi
            # fake the kernel interface to avoid SA conflicts
51 1 Martin Willi
            fake_kernel = yes
52 1 Martin Willi
        }
53 1 Martin Willi
    }
54 7 Martin Willi
}
55 1 Martin Willi
</pre>
56 1 Martin Willi
57 8 Tobias Brunner
This will initiate 4000 IKE_SAs within 20 seconds. You may increase the delay value if your box can not handle that much load, or decrease it to put more load on it. If the daemon starts retransmitting messages, your box probably can not handle all connection attempts.
58 1 Martin Willi
59 8 Tobias Brunner
h2. Testing against remote host
60 7 Martin Willi
61 7 Martin Willi
The plugin also allows to test against a remote host. This might help to test against a real world configuration. A connection setup to do stress testing of a gateway might look like this:
62 1 Martin Willi
<pre>
63 7 Martin Willi
charon {
64 1 Martin Willi
    reuse_ikesa = no
65 1 Martin Willi
    threads = 32
66 6 Martin Willi
67 6 Martin Willi
    plugins {
68 9 Martin Willi
        load-tester {
69 1 Martin Willi
            # enable the plugin
70 1 Martin Willi
            enable = yes
71 1 Martin Willi
            # 10000 connections, ten in parallel
72 1 Martin Willi
            initiators = 10
73 1 Martin Willi
            iterations = 1000
74 9 Martin Willi
            # use a delay of 100ms, overall time is: iterations * delay = 100s
75 1 Martin Willi
            delay = 100
76 12 Martin Willi
            # address of the gateway (releases before 5.0.2 used the "remote" keyword!)
77 12 Martin Willi
            responder = 1.2.3.4
78 1 Martin Willi
            # IKE-proposal to use
79 1 Martin Willi
            proposal = aes128-sha1-modp1024
80 1 Martin Willi
            # use faster PSK authentication instead of 1024bit RSA
81 9 Martin Willi
            initiator_auth = psk
82 9 Martin Willi
            responder_auth = psk
83 1 Martin Willi
            # request a virtual IP using configuration payloads
84 1 Martin Willi
            request_virtual_ip = yes
85 9 Martin Willi
            # disable IKE_SA rekeying (default)
86 9 Martin Willi
            ike_rekey = 0
87 9 Martin Willi
            # enable CHILD_SA every 60s
88 9 Martin Willi
            child_rekey = 60
89 9 Martin Willi
            # do not delete the IKE_SA after it has been established (default)
90 9 Martin Willi
            delete_after_established = no
91 9 Martin Willi
            # do not shut down the daemon if all IKE_SAs established
92 9 Martin Willi
            shutdown_when_complete = no
93 1 Martin Willi
        }
94 1 Martin Willi
    }
95 1 Martin Willi
}
96 1 Martin Willi
</pre>
97 1 Martin Willi
98 1 Martin Willi
h2. Configuration details
99 1 Martin Willi
100 9 Martin Willi
For public key authentication, the responder uses the _"CN=srv, OU=load-test, O=strongSwan"_ identity. The initiator, each connection attempt uses a different identity in the form _"CN=c1-r1, OU=load-test, O=strongSwan"_, where the first number inidicated the client number, the second the authentication round (if multiple authentication is used).
101 1 Martin Willi
102 9 Martin Willi
For PSK authentication, FQDN identities are used. The server uses _srv.strongswan.org_, the client uses an identity in the form _c1-r1.strongswan.org_.
103 1 Martin Willi
104 9 Martin Willi
For EAP authentication, the client uses a NAI in the form _100000000010001@strongswan.org_.
105 9 Martin Willi
106 9 Martin Willi
To configure multiple authentication, concatenate multiple methods using, e.g.
107 9 Martin Willi
<pre>
108 9 Martin Willi
  initiator_auth = pubkey|psk|eap-md5|eap-aka
109 9 Martin Willi
</pre>
110 9 Martin Willi
111 10 Tobias Brunner
The responder uses a hardcoded certificate based on a 1024-bit RSA key (see source:src/libcharon/plugins/load_tester/load_tester_creds.c). This certificate additionally serves as CA certificate. A peer uses the same private key, but generates client certificates on demand signed by the CA certificate. Install the Responder/CA certificate on the remote host to authenticate all clients.
112 5 Martin Willi
113 7 Martin Willi
To speed up testing, the load tester plugin implements a special Diffie-Hellman implementation called _modpnull_. By setting _proposal = aes128-sha1-modpnull_, this wicked fast DH implementation is used. It does not provide any security at all, but allows to run tests without DH calculation overhead.
114 1 Martin Willi
115 8 Tobias Brunner
There is a list of available configuration options for the load-tester plugin at the [[strongswanConf|strongswan.conf]] page.
116 11 Martin Willi
117 11 Martin Willi
h3. Custom credentials
118 11 Martin Willi
119 11 Martin Willi
Starting with strongSwan [[502|5.0.2]], load-tester can use a custom set of certificates for authentication. Certificates are still issued on demand, and the _issuer_key_ and _isser_cert_ options define the path to load the CA certificate and private key to load for issuing certificates. To load additional certificates to verify the trust chain (above _issuer_cert_), the _ca_dir_ option takes a directory to load trusted certificates from.
120 11 Martin Willi
121 11 Martin Willi
By default, the on-demand generated peer certificates are issued with RSA signatures using SHA1. To use a different hashing algorithm, the _digest_ option can be used, which accepts hash algorithms, such as _md5_, _sha1_, _sha256_ or _sha512_.
122 11 Martin Willi
123 11 Martin Willi
To use other peer identities than those hard-coded, the _initiator_id_ and _responder_id_ options can be used. These options can contain up to two _%d_ printf specifiers to replace. The first one is replaced by a unique number for each tunnel established, starting from 1. The second is replaced by the authentication round for this connection, starting at one. Take care to use _%d_ identifiers only, and just two of them, as the format string is not validated. To include % characters in an identity, prefix it with an additional %, as you would do it in a printf format string. As a responder, a specific _initiator_id_ wouldn't match to a custom _initiator_id_ configured on the client. Hence the _initiator_match_ option is introduced, which can be defined to an identity with wildcards that should match to all identities the initiator generates from the _initiator_id_ template. 
124 11 Martin Willi
125 11 Martin Willi
The identities generated from the configured templates are included in the on-demand issued certificates. Distinguished Name identities are encoded as subject. FQDN, email, IPv4/v6 identities are encoded as subjectAltName. If a subjectAltName gets encoded, the subject Distinguished Name of the certificate is a single Common Name Relative Distinguished Name equal to the subjectAltName.
126 11 Martin Willi
127 11 Martin Willi
An example of a load-test to itself with custom credentials could look like this:
128 11 Martin Willi
<pre>
129 11 Martin Willi
charon {
130 11 Martin Willi
    # ...
131 11 Martin Willi
    plugins {
132 11 Martin Willi
        load-tester {
133 11 Martin Willi
            enable = yes
134 11 Martin Willi
            initiators = 1
135 11 Martin Willi
            iterations = 100
136 11 Martin Willi
            fake_kernel = yes
137 11 Martin Willi
138 11 Martin Willi
            # initiator authenticates twice with on-demand
139 11 Martin Willi
            # generated certificates. Responder authenticates
140 11 Martin Willi
            # once only. 
141 11 Martin Willi
            initiator_auth = pubkey|pubkey
142 11 Martin Willi
            initiator_id = conn-%d-round-%d@strongswan.org
143 11 Martin Willi
            initiator_match = *@strongswan.org
144 11 Martin Willi
            responder_id = srv.strongswan.org
145 11 Martin Willi
            digest = sha256
146 11 Martin Willi
            issuer_cert = /path/to/ca.crt
147 11 Martin Willi
            issuer_key = /path/to/ca.key
148 11 Martin Willi
            ca_dir = /path/to/trustchain/certs
149 11 Martin Willi
        }
150 11 Martin Willi
    }
151 11 Martin Willi
}
152 11 Martin Willi
</pre>
153 13 Martin Willi
154 13 Martin Willi
h3. Traffic selectors
155 13 Martin Willi
156 13 Martin Willi
Starting with strongSwan [[502|5.0.2]], custom traffic selectors can be defined. The _initiator_tsi_, _initiator_tsr_, _responder_tsi_ and _responder_tsr_ define a traffic selector to propose as initiator or narrow down as responder. Only a single CIDR style subnet definition is allowed, protocol/port selectors are currently not supported.
157 14 Martin Willi
158 14 Martin Willi
h3. On-demand installed external addresses
159 14 Martin Willi
160 14 Martin Willi
To generate load against a responder that simulates more closely the real world, load-tester can use a unique external tunnel address for each established IKE_SA. The IPs are installed on-demand just before tunnel establishment on one or more interfaces. The _addrs_ sections takes key/value pairs of address pools to use, the _addrs_prefix_ defines the network prefix how the address is installed on the interface. An example could look like this:
161 14 Martin Willi
162 14 Martin Willi
<pre>
163 14 Martin Willi
charon {
164 14 Martin Willi
    # ...
165 14 Martin Willi
    plugins {
166 14 Martin Willi
        load-tester {
167 14 Martin Willi
            # ...
168 14 Martin Willi
            addrs {
169 14 Martin Willi
                # install ~32K addresses on eth0
170 14 Martin Willi
                eth0 = 10.2.0.0/17
171 14 Martin Willi
                # and then ~32K addresses on eth1
172 14 Martin Willi
                eth1 = 10.2.128.0/17
173 14 Martin Willi
            }
174 14 Martin Willi
            # install all addresses with a /16 prefix
175 14 Martin Willi
            addrs_prefix = 16
176 14 Martin Willi
        }
177 14 Martin Willi
    }
178 14 Martin Willi
}
179 14 Martin Willi
</pre>
180 14 Martin Willi
181 14 Martin Willi
> *Note:* Make sure to shut down unused network services when installing hundreds of addresses. Some services don't scale very well to this many addresses, the Avahi daemon for example can significantly slow down the system when running such tests.
182 15 Martin Willi
183 15 Martin Willi
184 15 Martin Willi
h2. Triggered batch initiations
185 15 Martin Willi
186 15 Martin Willi
With strongSwan [[502|5.0.2]], tunnels can not only be initiated on daemon startup with the _initiators_/_iterations_ keywords, but also while the daemon is running. The _ipsec load-tester_ tool takes as first argument the number of tunnels, and as second argument the delay between each initiation. Multiple clients can trigger initiation at the same time.
187 15 Martin Willi
188 15 Martin Willi
The _load-tester_ tool prints the status of the initiation with some simple characters to the console:
189 15 Martin Willi
190 15 Martin Willi
<pre>
191 15 Martin Willi
. : Initiation of a single tunnel started
192 15 Martin Willi
! : Initiation of a tunnel failed
193 15 Martin Willi
+ : A tunnel has been established successfully
194 15 Martin Willi
- : A tunnel failed to establish during the exchange
195 15 Martin Willi
* : A message has been retransmitted
196 15 Martin Willi
</pre>
197 15 Martin Willi
198 15 Martin Willi
A session might look like this:
199 15 Martin Willi
200 15 Martin Willi
<pre>
201 15 Martin Willi
> ipsec load-tester initiate 100 2
202 15 Martin Willi
.....++.+++..+..+.+.++..++.+.+.+.+.+.++..+..++...++.+.+.+.+.+
203 15 Martin Willi
...+++.+.+..++.++..+.++....+.+++++...+..+.++.+.++....++..+++.
204 15 Martin Willi
+..++.+.+.++.++....+++..++..+..+++.+..+..++.+.+..+++...++.++.
205 15 Martin Willi
+..+.+.+.+.+.+++*+
206 15 Martin Willi
</pre>
207 15 Martin Willi
208 15 Martin Willi
100 tunnels have been initiated and established successfully, one packet has been lost and was retransmitted. If many packets get retransmitted, this can be an indication that one of the systems is overloaded.