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