• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0-or-later
3# Copyright (c) 2021 Joerg Vehlow <joerg.vehlow@aox-tech.de>
4# Copyright (c) 2015 Oracle and/or its affiliates. All Rights Reserved.
5# Copyright (c) International Business Machines Corp., 2005
6# Author: Mitsuru Chinen <mitch@jp.ibm.com>
7
8TST_CLEANUP="cleanup"
9TST_SETUP="setup"
10TST_TESTFUNC="test"
11TST_CNT=3
12TST_NEEDS_ROOT=1
13TST_NEEDS_TMPDIR=1
14TST_NEEDS_CMDS="sshd ssh ssh-keygen od pkill pgrep"
15
16. tst_net.sh
17
18# SSH config file on the remote host
19RHOST_SSH_CONF=
20# SSH command to connect from the remote host to the test host
21RHOST_SSH=
22# Processes started on the remote host, killed at cleanup
23RHOST_PIDS=
24# Netstress process started on the test host, killed at cleanup
25NETSTRESS_PID=
26
27cleanup()
28{
29	local pids
30
31	# Stop the ssh daemon
32	[ -s sshd.pid ] && kill $(cat sshd.pid)
33	[ -n "$NETSTRESS_PID" ] && kill -INT $NETSTRESS_PID >/dev/null 2>&1
34
35	[ -n "$RHOST_PIDS" ] && tst_rhost_run -c "kill $RHOST_PIDS" >/dev/null 2>&1
36
37	# Kill all remaining ssh processes
38	[ -n "$RHOST_SSH_CONF" ] && tst_rhost_run -c "pkill -f '^ssh $RHOST_SSH_CONF'"
39}
40
41setup()
42{
43	local port rc
44
45
46	port=$(tst_rhost_run -c "tst_get_unused_port ipv${TST_IPVER} stream")
47
48	cat << EOF > sshd_config
49Port $port
50ListenAddress $(tst_ipaddr)
51PermitRootLogin yes
52AuthorizedKeysFile $TST_TMPDIR/authorized_keys
53PasswordAuthentication no
54AllowTcpForwarding yes
55TCPKeepAlive yes
56UseDNS no
57StrictModes no
58PidFile $TST_TMPDIR/sshd.pid
59HostKey $TST_TMPDIR/ssh_host_rsa_key
60HostKey $TST_TMPDIR/ssh_host_ecdsa_key
61HostKey $TST_TMPDIR/ssh_host_ed25519_key
62EOF
63
64	ssh-keygen -q -N "" -t rsa -b 4096 -f $TST_TMPDIR/ssh_host_rsa_key
65	ssh-keygen -q -N "" -t ecdsa -f $TST_TMPDIR/ssh_host_ecdsa_key
66	ssh-keygen -q -N "" -t ed25519 -f $TST_TMPDIR/ssh_host_ed25519_key
67
68	tst_res TINFO "Generate configuration file and key at the remote host"
69	tst_rhost_run -s -c "ssh-keygen -t rsa -N \"\" -f $TST_TMPDIR/id_rsa \
70		>/dev/null"
71
72	RHOST_SSH_CONF=$TST_TMPDIR/ssh_config
73
74	tst_rhost_run -s -c "printf \"\
75Port $port\n\
76StrictHostKeyChecking no\n\
77PasswordAuthentication no\n\
78ExitOnForwardFailure yes\n\
79UserKnownHostsFile $TST_TMPDIR/known_hosts\n\
80IdentityFile $TST_TMPDIR/id_rsa\n\" > $RHOST_SSH_CONF"
81
82	tst_res TINFO "Generate authorized_keys"
83	tst_rhost_run -c "cat ${TST_TMPDIR}/id_rsa.pub" > authorized_keys
84
85	tst_res TINFO "restore context of authorized_keys"
86	rc=$(command -v restorecon)
87	[ -n "$rc" ] && $rc authorized_keys
88
89	$(command -v sshd) -f $TST_TMPDIR/sshd_config || \
90		tst_brk TBROK "Failed to run sshd daemon"
91
92	RHOST_SSH="ssh -$TST_IPVER -F $RHOST_SSH_CONF $(tst_ipaddr)"
93}
94
95test_ssh_connectivity()
96{
97	tst_rhost_run -c "$RHOST_SSH 'true >/dev/null 2>&1' >/dev/null"
98	[ $? -ne 0 ] && tst_brk TFAIL "SSH not reachable"
99}
100
101test1()
102{
103	local num all_conn pid
104
105	tst_res TINFO "Verify SSH connectivity over IPv$TST_IPVER is not broken after creating many SSH sessions"
106
107	test_ssh_connectivity
108
109	RHOST_PIDS=
110	num=0
111	while [ $num -lt $CONNECTION_TOTAL ]; do
112		pid=$(tst_rhost_run -c "$RHOST_SSH -N </dev/null 1>/dev/null 2>&1 \
113			& echo \$!")
114		RHOST_PIDS="$RHOST_PIDS $pid"
115		num=$(($num + 1))
116	done
117
118	tst_res TINFO "Killing all ssh sessions"
119	num=0
120	for pid in $RHOST_PIDS; do
121		tst_rhost_run -c "kill $pid" >/dev/null
122		[ $? -ne 0 ] && num=$((num + 1))
123	done
124
125	[ $num -ne 0 ] && tst_brk TFAIL "$num ssh processes died unexpectedly during execution"
126
127	test_ssh_connectivity
128
129	tst_res TPASS "Test finished successfully"
130}
131
132test2()
133{
134	local start_epoc pids total_connections elapse_epoc new_pids
135	local ssh_num wait_sec login_sec
136
137	tst_res TINFO "Verify SSH connectivity over IPv$TST_IPVER is not broken after logging in/out by many clients asynchronously"
138
139	test_ssh_connectivity
140
141	start_epoc=$(date +%s)
142	RHOST_PIDS=
143	total_connections=0
144	while true; do
145		# Exit after the specified time has elapsed.
146		elapse_epoc=$(( $(date +%s) - $start_epoc))
147		[ $elapse_epoc -ge $NS_DURATION ] && break
148
149		new_pids=
150		for pid in $RHOST_PIDS; do
151			if tst_rhost_run -c "kill -0 $pid" >/dev/null; then
152				new_pids="$new_pids $pid"
153			fi
154		done
155		RHOST_PIDS="$new_pids"
156
157		# Do not make ssh connection over the specified quantity
158		ssh_num=$(echo "$pids" | wc -w)
159		if [ $ssh_num -ge $CONNECTION_TOTAL ]; then
160			tst_res TINFO "Max connections reached"
161			tst_sleep 1
162			continue
163		fi
164
165		# specified wait time and login time
166		wait_sec=$(( $(od -A n -d -N 1 /dev/urandom) * 3 / 255 ))
167		login_sec=$(( $(od -A n -d -N 1 /dev/urandom) * 10 / 255 ))
168
169		# Login to the server
170		pid=$(tst_rhost_run -c "( \
171			  sleep $wait_sec && $RHOST_SSH -l root \"sleep $login_sec\" \
172			) </dev/null 1>/dev/null 2>&1 & echo \$!"
173		)
174		RHOST_PIDS="$RHOST_PIDS $pid"
175		total_connections=$(( total_connections + 1 ))
176	done
177
178	tst_res TINFO "Waiting for all connections to terminate"
179	while [ -n "$RHOST_PIDS" ]; do
180		tst_sleep 1
181		new_pids=
182		for pid in $RHOST_PIDS; do
183			if tst_rhost_run -c "kill -0 $pid" >/dev/null 2>&1; then
184				new_pids="$new_pids $pid"
185			fi
186		done
187		RHOST_PIDS="$new_pids"
188	done
189
190	test_ssh_connectivity
191
192	tst_res TPASS "Test finished successfully ($total_connections connections)"
193}
194
195test3()
196{
197	local port lport localhost rhost ret
198	tst_res TINFO "Verify SSH connectivity over IPv$TST_IPVER is not broken after forwarding TCP traffic"
199
200	localhost="127.0.0.1"
201	rhost="$(tst_ipaddr)"
202	if [ "$TST_IPVER" = "6" ]; then
203		localhost="::1"
204		rhost="[$(tst_ipaddr)]"
205	fi
206
207	test_ssh_connectivity
208
209	# Get an ssh forwarding port
210	lport=$(tst_rhost_run -c "tst_get_unused_port ipv${TST_IPVER} stream")
211
212	# Start a tcp server
213	netstress -R 3 -B $TST_TMPDIR >/dev/null 2>&1
214	[ $? -ne 0 ] && tst_brk TBROK "Unable to start netstress server"
215	NETSTRESS_PID=$(pgrep -f "^netstress .*$TST_TMPDIR")
216	port=$(cat netstress_port)
217
218	# Setup an ssh tunnel from the remote host to testhost
219	tst_rhost_run -c "$RHOST_SSH -f -N -L $lport:$rhost:$port </dev/null >/dev/null 2>&1"
220	[ "$?" -ne 0 ] && tst_brk TFAIL "Failed to create an SSH session with port forwarding"
221	RHOST_PIDS=$(tst_rhost_run -c "pgrep -f '^ssh .*$lport:$rhost:$port'")
222
223	# Start the TCP traffic clients
224	tst_rhost_run -s -c "netstress -r $NS_TIMES -l -H $localhost -g $lport > /dev/null"
225
226	tst_rhost_run -c "kill $RHOST_PIDS >/dev/null 2>&1"
227
228	test_ssh_connectivity
229
230	tst_res TPASS "Test finished successfully"
231}
232
233tst_run
234