-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path6ssh.sh
executable file
·182 lines (148 loc) · 4.29 KB
/
6ssh.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#!/usr/bin/env bash
##################################################################################
#
# Copyright (C) 2024 Craig Miller
#
# See the file "LICENSE" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# Distributed under GPLv2 License
#
##################################################################################
#
# 6ssh: a shell program to ssh _from_ stable SLAAC Address
#
# by Craig Miller
#
# 16 July 2024
# todo:
# 1) allow arbitrary ssh options (e.g. -o AddressFamily=inet6
# BSD Supported - as of v0.9.2 20 July 2024
# Added option -u for ULAs - v0.9.4 20 July 2024
# 2) fix interface seleciton with eth & wlan connected- cheating with sort for now 23 July 2024
# 2 Dec 2024 - v1.1 Fixed VLAN ids from interface names
# 9 Dec 2024 - v1.2 Added "test" option, which displays address and exits
#
# Source in IP command emulator (uses ifconfig, hense more portable)
#
OS=""
# check OS type
OS=$(uname -s)
if [ "$OS" == "Darwin" ] || [ "$OS" == "FreeBSD" ]; then
# MacOS X/BSD compatibility
source ip_em.sh
fi
function usage {
echo " $0 - ssh using Stable SLAAC Source Address "
echo " e.g. $0 <host> "
echo " -i <int> use this interface"
echo " -u use ULA address (default GUA)"
echo " -X use X forwarding"
echo " -t test, show stable slaac address and quit"
echo " "
echo " By Craig Miller - Version: $VERSION"
exit 1
}
VERSION=1.2
# some variables
DEBUG=0
TEST=0
# ULA prefixes start with fd
PREFIX='fd'
# GUA prefixes start with 2
#
# Comment out next line, if only using ULAs
PREFIX='2'
IPV6_REG='[0-9a-f]{2,3}:([0-9a-f]+:){3,6}[:]?[0-9a-f]+'
INTERFACE=""
SSHOPTS=""
numopts=0
while getopts "?hdi:uXYt" options; do
case $options in
i ) INTERFACE=$OPTARG
numopts=$(( numopts + 2));;
d ) DEBUG=1
(( numopts++));;
t ) TEST=1
DEBUG=1
(( numopts++));;
u ) PREFIX='fd'
(( numopts++));;
X ) SSHOPTS="$SSHOPTS -X"
(( numopts++));;
Y ) SSHOPTS="$SSHOPTS -Y"
(( numopts++));;
h ) usage;;
\? ) usage;; # show usage with flag and no value
* ) usage;; # show usage with unknown flag
esac
done
# remove the options as cli arguments
shift $numopts
#debug
#echo "$# $1"
# get HOSTNAME of target
HOST=""
if [ -n "$1" ]; then
HOST="$1"
else
echo "Error: no host specified"
usage
fi
function get_slaac_addr {
local local_intf="$1"
# remove any vlan identifier e.g. eth0@if6
local_intf=$(echo "$local_intf" | cut -d "@" -f 1)
# get IPv6 Stable SLAAC Address
slaac_addr=""
slaac_addr=$(ip addr show dev $local_intf | grep -E '(mngtmpaddr|noprefixroute|autoconf)' | grep -v 'temporary' | grep -o -E "$PREFIX$IPV6_REG" | tail -1)
#if (( DEBUG == 1 )); then echo "DEBUG: slaac_addr: $slaac_addr";fi
echo -e "$slaac_addr"
}
slaac_addr=""
if [ -z "$INTERFACE" ]; then
# set up a list of active interfaces (and ignore DORMANT in Linux)
# fixme: select interface based on 'ip -6 route' and pick lowest metric
INTF_LIST=$(ip link | grep -E '(LOWER_UP|UP,BROADCAST)' | grep -E -v '(LOOPBACK)' | cut -d ':' -f 2 | sort | tr '\n' ' ' )
if (( DEBUG == 1 )); then echo "DEBUG: INTF_LIST:$INTF_LIST";fi
list_length=$(wc -w <<< "$INTF_LIST")
if [ $list_length -gt 1 ]; then
for intf in $INTF_LIST
do
tmp_addr=$(get_slaac_addr "$intf")
if (( DEBUG == 1 )); then echo "DEBUG: intf:$intf tmp_addr:$tmp_addr";fi
if [ -n "$tmp_addr" ]; then
slaac_addr="$tmp_addr"
INTF="$intf"
break
fi
done
#error if no address found
if [ -z "$slaac_addr" ]; then
echo "Error: no IPv6 address found on interfaces"
exit 1
fi
else
slaac_addr=$(get_slaac_addr "$INTF_LIST")
INTF="$INTF_LIST"
fi
else
# User specified interface
INTF=$(ip link | grep -E '(LOWER_UP|UP,BROADCAST)' | cut -d ':' -f 2 | grep -o " $INTERFACE" )
if [ -z "$INTF" ]; then
echo "Error: Selected Interface: $INTERFACE is not found or DOWN"
usage
fi
slaac_addr=$(get_slaac_addr "$INTF")
if [ -z "$slaac_addr" ]; then
echo "Error: No IPv6 address found on $INTERFACE"
exit 1
fi
fi
if (( DEBUG == 1 )); then echo "DEBUG: INTF:$INTF SLAAC ADDR=$slaac_addr";fi
# OK, lets ssh to host using Stable SLAAC Addr as source
if [ $TEST -eq 0 ]; then
ssh -b $slaac_addr $SSHOPTS "$HOST"
else
exit 1
fi
echo "6ssh: Pau"