Project

General

Profile

Load Tests » History » Version 15

Martin Willi, 12.11.2012 17:59

1 7 Martin Willi
h1. Load Tests
2 7 Martin Willi
3 7 Martin Willi
4 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.
5 1 Martin Willi
6 1 Martin Willi
7 7 Martin Willi
h2. Setup
8 7 Martin Willi
9 7 Martin Willi
10 1 Martin Willi
To build and enable the plugin, add
11 7 Martin Willi
<pre>
12 9 Martin Willi
--enable-load-tester
13 1 Martin Willi
</pre>
14 8 Tobias Brunner
to your _./configure_ options.
15 8 Tobias Brunner
16 8 Tobias Brunner
17 7 Martin Willi
----
18 8 Tobias Brunner
19 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.*
20 8 Tobias Brunner
21 7 Martin Willi
----
22 8 Tobias Brunner
23 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.
24 6 Martin Willi
25 7 Martin Willi
26 7 Martin Willi
h2. Testing against self
27 7 Martin Willi
28 1 Martin Willi
29 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.
30 1 Martin Willi
31 8 Tobias Brunner
A simple loop-back configuration in [[StrongswanConf|/etc/strongswan.conf]] might look like this:
32 7 Martin Willi
<pre>
33 1 Martin Willi
charon {
34 1 Martin Willi
    # create a new IKE_SA for each CHILD_SA to simulate different clients
35 1 Martin Willi
    reuse_ikesa = no
36 1 Martin Willi
    # turn off denial of service protection
37 1 Martin Willi
    dos_protection = no
38 1 Martin Willi
39 6 Martin Willi
    plugins {
40 9 Martin Willi
        load-tester {
41 1 Martin Willi
            # enable the plugin
42 1 Martin Willi
            enable = yes
43 1 Martin Willi
            # use 4 threads to initiate connections simultaneously
44 1 Martin Willi
            initiators = 4
45 1 Martin Willi
            # each thread initiates 1000 connections
46 1 Martin Willi
            iterations = 1000
47 1 Martin Willi
            # delay each initiation in each thread by 20ms
48 1 Martin Willi
            delay = 20
49 1 Martin Willi
            # fake the kernel interface to avoid SA conflicts
50 1 Martin Willi
            fake_kernel = yes
51 1 Martin Willi
        }
52 1 Martin Willi
    }
53 7 Martin Willi
}
54 1 Martin Willi
</pre>
55 1 Martin Willi
56 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.
57 1 Martin Willi
58 8 Tobias Brunner
h2. Testing against remote host
59 7 Martin Willi
60 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:
61 1 Martin Willi
<pre>
62 7 Martin Willi
charon {
63 1 Martin Willi
    reuse_ikesa = no
64 1 Martin Willi
    threads = 32
65 6 Martin Willi
66 6 Martin Willi
    plugins {
67 9 Martin Willi
        load-tester {
68 1 Martin Willi
            # enable the plugin
69 1 Martin Willi
            enable = yes
70 1 Martin Willi
            # 10000 connections, ten in parallel
71 1 Martin Willi
            initiators = 10
72 1 Martin Willi
            iterations = 1000
73 9 Martin Willi
            # use a delay of 100ms, overall time is: iterations * delay = 100s
74 1 Martin Willi
            delay = 100
75 12 Martin Willi
            # address of the gateway (releases before 5.0.2 used the "remote" keyword!)
76 12 Martin Willi
            responder = 1.2.3.4
77 1 Martin Willi
            # IKE-proposal to use
78 1 Martin Willi
            proposal = aes128-sha1-modp1024
79 1 Martin Willi
            # use faster PSK authentication instead of 1024bit RSA
80 9 Martin Willi
            initiator_auth = psk
81 9 Martin Willi
            responder_auth = psk
82 1 Martin Willi
            # request a virtual IP using configuration payloads
83 1 Martin Willi
            request_virtual_ip = yes
84 9 Martin Willi
            # disable IKE_SA rekeying (default)
85 9 Martin Willi
            ike_rekey = 0
86 9 Martin Willi
            # enable CHILD_SA every 60s
87 9 Martin Willi
            child_rekey = 60
88 9 Martin Willi
            # do not delete the IKE_SA after it has been established (default)
89 9 Martin Willi
            delete_after_established = no
90 9 Martin Willi
            # do not shut down the daemon if all IKE_SAs established
91 9 Martin Willi
            shutdown_when_complete = no
92 1 Martin Willi
        }
93 1 Martin Willi
    }
94 1 Martin Willi
}
95 1 Martin Willi
</pre>
96 1 Martin Willi
97 1 Martin Willi
h2. Configuration details
98 1 Martin Willi
99 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).
100 1 Martin Willi
101 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_.
102 1 Martin Willi
103 9 Martin Willi
For EAP authentication, the client uses a NAI in the form _100000000010001@strongswan.org_.
104 9 Martin Willi
105 9 Martin Willi
To configure multiple authentication, concatenate multiple methods using, e.g.
106 9 Martin Willi
<pre>
107 9 Martin Willi
  initiator_auth = pubkey|psk|eap-md5|eap-aka
108 9 Martin Willi
</pre>
109 9 Martin Willi
110 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.
111 5 Martin Willi
112 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.
113 1 Martin Willi
114 8 Tobias Brunner
There is a list of available configuration options for the load-tester plugin at the [[strongswanConf|strongswan.conf]] page.
115 11 Martin Willi
116 11 Martin Willi
h3. Custom credentials
117 11 Martin Willi
118 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.
119 11 Martin Willi
120 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_.
121 11 Martin Willi
122 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. 
123 11 Martin Willi
124 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.
125 11 Martin Willi
126 11 Martin Willi
An example of a load-test to itself with custom credentials could look like this:
127 11 Martin Willi
<pre>
128 11 Martin Willi
charon {
129 11 Martin Willi
    # ...
130 11 Martin Willi
    plugins {
131 11 Martin Willi
        load-tester {
132 11 Martin Willi
            enable = yes
133 11 Martin Willi
            initiators = 1
134 11 Martin Willi
            iterations = 100
135 11 Martin Willi
            fake_kernel = yes
136 11 Martin Willi
137 11 Martin Willi
            # initiator authenticates twice with on-demand
138 11 Martin Willi
            # generated certificates. Responder authenticates
139 11 Martin Willi
            # once only. 
140 11 Martin Willi
            initiator_auth = pubkey|pubkey
141 11 Martin Willi
            initiator_id = conn-%d-round-%d@strongswan.org
142 11 Martin Willi
            initiator_match = *@strongswan.org
143 11 Martin Willi
            responder_id = srv.strongswan.org
144 11 Martin Willi
            digest = sha256
145 11 Martin Willi
            issuer_cert = /path/to/ca.crt
146 11 Martin Willi
            issuer_key = /path/to/ca.key
147 11 Martin Willi
            ca_dir = /path/to/trustchain/certs
148 11 Martin Willi
        }
149 11 Martin Willi
    }
150 11 Martin Willi
}
151 11 Martin Willi
</pre>
152 13 Martin Willi
153 13 Martin Willi
h3. Traffic selectors
154 13 Martin Willi
155 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.
156 14 Martin Willi
157 14 Martin Willi
h3. On-demand installed external addresses
158 14 Martin Willi
159 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:
160 14 Martin Willi
161 14 Martin Willi
<pre>
162 14 Martin Willi
charon {
163 14 Martin Willi
    # ...
164 14 Martin Willi
    plugins {
165 14 Martin Willi
        load-tester {
166 14 Martin Willi
            # ...
167 14 Martin Willi
            addrs {
168 14 Martin Willi
                # install ~32K addresses on eth0
169 14 Martin Willi
                eth0 = 10.2.0.0/17
170 14 Martin Willi
                # and then ~32K addresses on eth1
171 14 Martin Willi
                eth1 = 10.2.128.0/17
172 14 Martin Willi
            }
173 14 Martin Willi
            # install all addresses with a /16 prefix
174 14 Martin Willi
            addrs_prefix = 16
175 14 Martin Willi
        }
176 14 Martin Willi
    }
177 14 Martin Willi
}
178 14 Martin Willi
</pre>
179 14 Martin Willi
180 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.
181 15 Martin Willi
182 15 Martin Willi
183 15 Martin Willi
h2. Triggered batch initiations
184 15 Martin Willi
185 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.
186 15 Martin Willi
187 15 Martin Willi
The _load-tester_ tool prints the status of the initiation with some simple characters to the console:
188 15 Martin Willi
189 15 Martin Willi
<pre>
190 15 Martin Willi
. : Initiation of a single tunnel started
191 15 Martin Willi
! : Initiation of a tunnel failed
192 15 Martin Willi
+ : A tunnel has been established successfully
193 15 Martin Willi
- : A tunnel failed to establish during the exchange
194 15 Martin Willi
* : A message has been retransmitted
195 15 Martin Willi
</pre>
196 15 Martin Willi
197 15 Martin Willi
A session might look like this:
198 15 Martin Willi
199 15 Martin Willi
<pre>
200 15 Martin Willi
> ipsec load-tester initiate 100 2
201 15 Martin Willi
.....++.+++..+..+.+.++..++.+.+.+.+.+.++..+..++...++.+.+.+.+.+
202 15 Martin Willi
...+++.+.+..++.++..+.++....+.+++++...+..+.++.+.++....++..+++.
203 15 Martin Willi
+..++.+.+.++.++....+++..++..+..+++.+..+..++.+.+..+++...++.++.
204 15 Martin Willi
+..+.+.+.+.+.+++*+
205 15 Martin Willi
</pre>
206 15 Martin Willi
207 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.