Monitor ssh connection and get login user information from authorized_keys - ssh

is there any way to use .ssh/authorized_keys to get the corresponding login user's email when the linux system is connected through id_rsa.pub?
I try to use the content in /var/log/auth.log while I can't find the direct relationship between the records and .ssh/authorized_keys.
Thanks in advance.

May be someone needs it. Next command prints information about the ssh key that was used for a current session. The key is taken from a standard comment block from ~/.ssh/authorized_keys.
For instance, somebody#test.com will be printed for a key that looks this way: cyb5OrLRv0VR6gZev8...KdECf7Q== somebody#test.com
Command:
export CURRENT_SSH_USER=$(grep $(grep $(grep '#'$(who -m | awk '{print $2}') <(ps -ef) | head -1 | awk '{print $3}')']: Accepted publickey for' /var/log/auth.log | head -1 | awk '{print $16}') <(cat ~/.ssh/authorized_keys | xargs -n1 -I% bash -c 'ssh-keygen -l -f /dev/stdin <<<"%"') | tail -1 | awk '{print $3}')
The command above does these steps:
who -m Only hostname and user associated with stdin.
Taking pseudo terminal slave e.g. pts/2 for a current user from the prev. command.
Searching for pts/2 in a list of processes ps -ef and extracting its pid.
Looking for the pid, e.g. 21996 in /var/log/auth.log in lines like this one:
Jul 22 01:50:39 whatever-i-12345 sshd[21996]: Accepted publickey for ubuntu from 10.10.10.10 port 40411 ssh2: RSA SHA256:V4DD10NklAAAAAHNgxaurm1qaq/TOTejNjXMQABABAB. Be sure you have proper logging enabled.
Once fingerprint SHA256:V4DD10NklAAAAAHNgxaurm1qaq/TOTejNjXMQABABAB is found, it matches it with the line from /.ssh/authorized_keys retrieves info about a name from a comment block.
Notes:
Tested only on Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64)

The last column of ssh public key is just a comment field and it is not present in the private key used to log in nor in the public key send to the server during the authentication attempt.
The comment in the server authorized keys can be completely different than the comment in the clients public key.
You can find the connection between the keys in authorized_keys and in the logs, but you need to convert the keys to fingerprints first using
ssh-keygen -lf ~/.ssh/authorized_keys

Related

ssh still asking for password after ssh-copy-id

[root#spectrumscale ~]# chmod 700 .ssh
[root#spectrumscale ~]# cd .ssh
[root#spectrumscale .ssh]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
/root/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
05:63:ff:2a:82:fc:c9:31:87:fc:a1:61:dc:4e:5a:52 root#spectrumscale
The key's randomart image is:
+--[ RSA 2048]----+
| + |
| . + |
| o |
| . . |
| E . |
| . + + . |
| o # B . |
| + / o |
| * o |
+-----------------+
[root#spectrumscale .ssh]# ssh-copy-id -i /root/.ssh/id_rsa.pub root#192.168.1.215
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root#192.168.1.215's password:
Permission denied, please try again.
root#192.168.1.215's password:
Number of key(s) added: 1
Now try logging into the machine, with: ssh 'root#192.168.1.215'"and check to make sure that only the key(s) you wanted were added.
[root#spectrumscale .ssh]# ssh 192.168.1.215
root#192.168.1.215's password:
Last failed login: Tue Nov 12 17:47:37 IST 2019 from 192.168.1.203 on ssh:notty
There was 1 failed login attempt since the last successful login.
Last login: Tue Nov 12 14:44:01 2019 from localhost
You have to diagnose the root cause for this issue. You can find this by reading logs related sshd using journalctl command on the system you want to login.
Reading logs :
journalctl -t sshd
If the log shows some thing similar to Authentication refused:
bad ownership or modes for directory, this is due to bad ownership or modes for directory /home/<your_user>/.ssh.
fixing permissions by
chmod go-w /home/<your_user>
chmod 700 /home/<your_user>/.ssh
chmod 600 /home/<your_user>/.ssh/authorized_keys
Also make sure that inside sshd configuration file /etc/ssh/sshd_config, make sure that PubkeyAuthentication is not commented and set yes.
Inside /etc/ssh/sshd_config make sure these is a line,
PubkeyAuthentication yes
It might needed to restart sshd service after edit in sshd configuration file.
sudo service sshd restart
This worked for me and hope this helps!.
If you have verified all your permissions are correct, but are still being prompted for a password, make sure to add the below line to the file /etc/ssh/sshd_config on the system you want to login to without a password. This will allow the SSH daemon to accept ssh-rsa key types
pubkeyacceptedkeytypes ssh-rsa
After doing this, simply run the command service sshd restart and passwordless login should work now

ssh -L forward multiple ports

I'm currently running a bunch of:
sudo ssh -L PORT:IP:PORT root#IP
where IP is the target of a secured machine, and PORT represents the ports I'm forwarding.
This is because I use a lot of applications which I cannot access without this forwarding. After performing this, I can access through localhost:PORT.
The main problem occured now that I actually have 4 of these ports that I have to forward.
My solution is to open 4 shells and constantly search my history backwards to look for exactly which ports need to be forwarded etc, and then run this command - one in each shell (having to fill in passwords etc).
If only I could do something like:
sudo ssh -L PORT1+PORT2+PORT+3:IP:PORT+PORT2+PORT3 root#IP
then that would already really help.
Is there a way to make it easier to do this?
The -L option can be specified multiple times within the same command. Every time with different ports. I.e. ssh -L localPort0:ip:remotePort0 -L localPort1:ip:remotePort1 ...
Exactly what NaN answered, you specify multiple -L arguments. I do this all the time. Here is an example of multi port forwarding:
ssh remote-host -L 8822:REMOTE_IP_1:22 -L 9922:REMOTE_IP_2:22
Note: This is same as -L localhost:8822:REMOTE_IP_1:22 if you don't specify localhost.
Now with this, you can now (from another terminal) do:
ssh localhost -p 8822
to connect to REMOTE_IP_1 on port 22
and similarly
ssh localhost -p 9922
to connect to REMOTE_IP_2 on port 22
Of course, there is nothing stopping you from wrapping this into a script or automate it if you have many different host/ports to forward and to certain specific ones.
For people who are forwarding multiple port through the same host can setup something like this in their ~/.ssh/config
Host all-port-forwards
Hostname 10.122.0.3
User username
LocalForward PORT_1 IP:PORT_1
LocalForward PORT_2 IP:PORT_2
LocalForward PORT_3 IP:PORT_3
LocalForward PORT_4 IP:PORT_4
and it becomes a simple ssh all-port-forwards away.
You can use the following bash function (just add it to your ~/.bashrc):
function pfwd {
for i in ${#:2}
do
echo Forwarding port $i
ssh -N -L $i:localhost:$i $1 &
done
}
Usage example:
pfwd hostname {6000..6009}
jbchichoko and yuval have given viable solutions. But jbchichoko's answer isn't a flexible answer as a function, and the opened tunnels by yuval's answer cannot be shut down by ctrl+c because it runs in the background. I give my solution below solving both the two flaws:
Defing a function in ~/.bashrc or ~/.zshrc:
# fsshmap multiple ports
function fsshmap() {
echo -n "-L 1$1:127.0.0.1:$1 " > $HOME/sh/sshports.txt
for ((i=($1+1);i<$2;i++))
do
echo -n "-L 1$i:127.0.0.1:$i " >> $HOME/sh/sshports.txt
done
line=$(head -n 1 $HOME/sh/sshports.txt)
cline="ssh "$3" "$line
echo $cline
eval $cline
}
A example of running the function:
fsshmap 6000 6010 hostname
Result of this example:
You can access 127.0.0.1:16000~16009 the same as hostname:6000~6009
In my company both me and my team members need access to 3 ports of a non-reachable "target" server so I created a permanent tunnel (that is a tunnel that can run in background indefinitely, see params -f and -N) from a reachable server to the target one. On the command line of the reachable server I executed:
ssh root#reachableIP -f -N -L *:8822:targetIP:22 -L *:9006:targetIP:9006 -L *:9100:targetIP:9100
I used user root but your own user will work. You will have to enter the password of the chosen user (even if you are already connected to the reachable server with that user).
Now port 8822 of the reachable machine corresponds to port 22 of the target one (for ssh/PuTTY/WinSCP) and ports 9006 and 9100 on the reachable machine correspond to the same ports of the target one (they host two web services in my case).
Another one liner that I use and works on debian:
ssh user#192.168.1.10 $(for j in $(seq 20000 1 20100 ) ; do echo " -L$j:127.0.0.1:$j " ; done | tr -d "\n")
One of the benefits of logging into a server with port forwarding is facilitating the use of Jupyter Notebook. This link provides an excellent description of how to it. Here I would like to do some summary and expansion for all of you guys to refer.
Situation 1. Login from a local machine named Host-A (e.g. your own laptop) to a remote work machine named Host-B.
ssh user#Host-B -L port_A:localhost:port_B
jupyter notebook --NotebookApp.token='' --no-browser --port=port_B
Then you can open a browser and enter: http://localhost:port_A/ to do your work on Host-B but see it in Host-A.
Situation 2. Login from a local machine named Host-A (e.g. your own laptop) to a remote login machine named Host-B and from there login to the remote work machine named Host-C. This is usually the case for most analytical servers within universities and can be achieved by using two ssh -L connected with -t.
ssh -L port_A:localhost:port_B user#Host-B -t ssh -L port_B:localhost:port_C user#Host-C
jupyter notebook --NotebookApp.token='' --no-browser --port=port_C
Then you can open a browser and enter: http://localhost:port_A/ to do your work on Host-C but see it in Host-A.
Situation 3. Login from a local machine named Host-A (e.g. your own laptop) to a remote login machine named Host-B and from there login to the remote work machine named Host-C and finally login to the remote work machine Host-D. This is not usually the case but might happen sometime. It's an extension of Situation 2 and the same logic can be applied on more machines.
ssh -L port_A:localhost:port_B user#Host-B -t ssh -L port_B:localhost:port_C user#Host-C -t ssh -L port_C:localhost:port_D user#Host-D
jupyter notebook --NotebookApp.token='' --no-browser --port=port_D
Then you can open a browser and enter: http://localhost:port_A/ to do your work on Host-D but see it in Host-A.
Note that port_A, port_B, port_C, port_D can be random numbers except common port numbers listed here. In Situation 1, port_A and port_B can be the same to simplify the procedure.
Here is a solution inspired from the one from Yuval Atzmon.
It has a few benefits over the initial solution:
first it creates a single background process and not one per port
it generates the alias that allows you to kill your tunnels
it binds only to 127.0.0.1 which is a little more secure
You may use it as:
tnl your.remote.com 1234
tnl your.remote.com {1234,1235}
tnl your.remote.com {1234..1236}
And finally kill them all with tnlkill.
function tnl {
TUNNEL="ssh -N "
echo Port forwarding for ports:
for i in ${#:2}
do
echo " - $i"
TUNNEL="$TUNNEL -L 127.0.0.1:$i:localhost:$i"
done
TUNNEL="$TUNNEL $1"
$TUNNEL &
PID=$!
alias tnlkill="kill $PID && unalias tnlkill"
}
An alternative approach is to tell ssh to work as a SOCKS proxy using the -D flag.
That way you would be able to connect to any remote network address/port accesible through the ssh server as long as the client applications are able to go through a SOCKS proxy (or work with something like socksify).
If you want a simple solution that runs in the background and is easy to kill - use a control socket
# start
$ ssh -f -N -M -S $SOCKET -L localhost:9200:localhost:9200 $HOST
# stop
$ ssh -S $SOCKET -O exit $HOST
I've developed loco for help with ssh forwarding. It can be used to share ports 5000 and 7000 on remote locally at the same ports:
pip install loco
loco listen SSHINFO -r 5000 -r 7000
First It can be done using Parallel Execution by xargs -P 0.
Create a file for binding the ports e.g.
localhost:8080:localhost:8080
localhost:9090:localhost:8080
then run
xargs -P 0 -I xxx ssh -vNTCL xxx <REMOTE> < port-forward
or you can do a one-liner
echo localhost:{8080,9090} | tr ' ' '\n' | sed 's/.*/&:&/' | xargs -P 0 -I xxx ssh -vNTCL xxx <REMOTE>
pros independent ssh port-forwarding, they are independent == avoiding Single Point of Failure
cons each ssh port-forwarding is forked separately, somehow not efficient
second it can be done using curly brackets expansion feature in bash
echo "ssh -vNTC $(echo localhost:{10,20,30,40,50} | perl -lpe 's/[^ ]+/-L $&:$&/g') <REMOTE>"
# output
ssh -vNTC -L localhost:10:localhost:10 -L localhost:20:localhost:20 -L localhost:30:localhost:30 -L localhost:40:localhost:40 -L localhost:50:localhost:50 <REMOTE>
real example
echo "-vNTC $(echo localhost:{8080,9090} | perl -lpe 's/[^ ]+/-L $&:$&/g') gitlab" | xargs ssh
Forwarding 8080 and 9090 to gitlab server.
pros one single fork == efficient
cons by closing this process (ssh) all forwarding are closed == Single Point of Failure
You can use this zsh function (probably works with bash, too)(Put it in ~/.zshrc):
ashL () {
local a=() i
for i in "$#[2,-1]"
do
a+=(-L "${i}:localhost:${i}")
done
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -NT "$1" "$a[#]"
}
Examples:
ashL db#114.39.161.24 6480 7690 7477
ashL db#114.39.161.24 {6000..6050} # Forwards the whole range. This is simply shell syntax sugar.

SSH asking for password even after keys set up

I am trying to setup ssh keys via this method.
Here is the starting point on server
server:~/.ssh$ ls
#shows empty
Here is the starting point on client
client: ~/.ssh$ls #shows empty dir
On client, I run
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/me/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/me/.ssh/id_rsa.
Your public key has been saved in /Users/me/.ssh/id_rsa.pub.
The key fingerprint is:
26:25:e0:2f:90:d8:d9:fb:79:03:5d:99:a1:61:a9:dc me#machine
The key's randomart image is:
+--[ RSA 2048]----+
| . o.. |
| o = . ..o + |
|. = o..oo + |
| . oo+E. |
| o + S |
| o = |
| o o |
| . . |
| |
+-----------------+
$ ls
id_rsa id_rsa.pub
So far so good. So then I run
$ ssh-copy-id -p 3457 me#server #running on non standard port
The authenticity of host '[server]:3457 ([104.131.226.216]:3457)' can't be established.
RSA key fingerprint is 1c:52:db:19:22:b8:47:18:24:ad:07:2f:e5:d3:c4:8e.
Are you sure you want to continue connecting (yes/no)? yes
/usr/local/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/local/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
me#server's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh -p '3457' 'me#server'"
and check to make sure that only the key(s) you wanted were added.
I run ssh -p '3457' 'me#server' and see that ~/.ssh/authorized_keys shows that the keys match. I logout, trying sshing in again. But it STILL asks me for a password -- even after running sudo service ssh restart on server. I'm not sure what else I can do. What are the next steps?
Make sure you have that key already loaded in your session
$ ssh-add
It should print ~/.ssh/id_rsa
In case you get an error saying "couldn't get a connection to the authentication agent" then execute
$ eval $(ssh-agent)
and repeat ssh-add
The former should be enough, but I also reccomend having an ssh config file. For this, edit (or create) an ~/.ssh/config file with contents
Host server
HostName 104.131.226.216
User me
Port 3457
IdentityFile ~/.ssh/id_rsa
Are the file access permissions for the authorized_keys file 644 (-rw-r--r--)?
(I would leave this as a comment, but I don't have enough points)
eval ssh-agent
After that, add identity to key file
ssh-add $HOME/.ssh/xxx.pem
After execution of above command it should not prompt you for a password
You need to do this every time if you use a new bash prompt. For that one do one thing.
Edit the above lines in $HOME/.bashrc file

How to append authorized_keys on the remote server with id_rsa.pub key

How to append authorized_keys on the remote server with id_rsa.pub key from the local machine with a single command?
ssh-copy-id user#remote_server
http://linux.die.net/man/1/ssh-copy-id
Adding an authorized key could be one-lined this way (use double-quotes so it's interpreted before sent):
ssh user#server "echo \"`cat ~/.ssh/id_rsa.pub`\" >> .ssh/authorized_keys"
This does the trick:
cat ~/.ssh/id_rsa.pub | (ssh user#host "cat >> ~/.ssh/authorized_keys")
Appends the local public key the remote authorized_keys file.
The ssh-copy-id program is the standard way but the key can be appended manually to the ~/.ssh/authorized_keys file:
cat ~/.ssh/id_rsa.pub | ssh username#host "mkdir ~/.ssh; cat >> ~/.ssh/authorized_keys"
This does not check if the key already exists and can lead to duplicates.
The most convenient option is the ssh-copy-id command. It can append the public key to ~/.ssh/authorized_keys. For example:
ssh-copy-id -f -i id_rsa.pub username#host
Where:
-f: force mode -- copy keys without trying to check if they are already installed
-i: [identity_file]
You can avoid some of the quoting with:
ssh user#host tee -a .ssh/authorized_keys < ~/.ssh/id_rsa.pub

Cannot copy the public key to remote-host using cat

Im trying to setup the passwordless SSh Login like the one stated here
I was able to generate the SSH Key Successfully
ssh-keygen
But when I'm doing this
cat ~/.ssh/id_dsa.pub | ssh user#xxx.xxx.xxx.xxx 'cat >>
~/.ssh/authorized_keys'
it gave me this error
Pseudo-terminal will not be allocated because stdin is not a terminal
ssh : xxx.xxx.xxx.xxxcat >> ~/.ssh/id_rsa.pub | ssh
user#xxx.xxx.xxx.xxx 'cat >>> ~/.ssh/authorized_keys'
I tried to setup passwordless SSH without getting this kind of error but its not working because it is still asking for password. And according to the author of this article, SSH-copy-id has 3 issues which most probably the reason why It still asking for password.
Any ideas?
Note: machines are running on CentOS
Try:
cat ~/.ssh/id_dsa.pub | ssh -t -t user#xxx.xxx.xxx.xxx 'cat >> ~/.ssh/authorized_keys'
-t -t option to force pseudo-tty allocation even if stdin isn't a terminal.