Get local device IP from connected server - ssh

I connected to my ubuntu server from my MacBook using SSH.
I want to know ip address of MacBook from the server.
How can I do that?
[edit] I would like to get ip using bash.

I would comment this but I cant. We need more information. What language are you programming with. What have you tried.
Edit: Here is what you are looking for. This answer was taken from Find the IP address of the client in an SSH session
Please do a more through search for your problem before posting a question
Check if there is an environment variable called:
$SSH_CLIENT
OR
$SSH_CONNECTION
(or any other environment variables) which gets set when the user logs in. Then process it using the user login script.
Extract the IP:
$ echo $SSH_CLIENT | awk '{ print $1}'
1.2.3.4
$ echo $SSH_CONNECTION | awk '{print $1}'
1.2.3.4

Related

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.

Cannot access server using its ip address

I have web server, I can use it with ssh connection, ssh root#ip
But I can't access it as web server. I tested simply python tool, http.server and also tested installing and starting httpd.
Output for:
# ifconfig eth0 | grep inet | awk '{ print $2 }'
addr:[ip address that I'm using for ssh]
addr:
OS: Centos
What else I must do?
Problem was with firewall. Solved using this instruction: Configure iptables

Ping Server/Domain, capure IP as variable

I have a question that I cannot seem to find an answer for. With Windows, you could ping a given domain name, and capture the ip as a variable, even if no reply was recieved. I believe the command looked something like this:
ping domain.com for /f "tokens=1,2 delims=[]" %%A in ('ping /n 1 /w 1 domain.com ^| find "Pinging"') do set ipaddress=%%B"
This is exactly what I am trying to do with a bash script rather than a batch file. I've stumbled across alot of questions that are really close, but not quite what I am looking for. I cannot seem to figure out the best way to go about this. How can I capture IP address using bash script?
PS: I'm still fairly new to linux environment.
I am pulling the answer out of the question and posting it here for future users
ip=$(ping -c 1 $input | gawk -F'[()]' '/PING/{print $2}')
You can use the ip variable in your script at this point.
As an example, when pinging google.com you get this result:
echo $(ping -c 1 google.com | gawk -F'[()]' '/PING/{print $2}')
74.125.225.96
And at this point the ip variable would contain 74.125.225.96

How I can I get my home network's IP address from a shell script?

I have an account at a server at school, and a home computer that I need to work with sometimes. I have exchanged keys, and now only have one problem. While my school account has a name associated with it, "account_name#school", my home network does not. My plan is to have a script that every hour retrieves my home network's IP address, ssh'es into my school account and updates my ssh config file storing my home network's IP address.
How can I retrieve my home computer's IP address from a shell script?
P.S. Is this a sensible plan?
You have two basic choices:
A dynamic DNS address (e.g. dyndns.org). Setting that up is outside the scope of Stack Overflow, but it's probably The Right Thing™ for you.
Use a tool like http://checkip.dyndns.org/ to report your external IP address, then parse the result.
lynx -dump http://checkip.dyndns.org/ | awk '{print $NF}'
Either way, you'll need to configure your router to allow inbound access for SSH, so further information needs to be asked on Super User or Unix & Linux.
My http://ipcalf.com server supports header-based or explicit content negotiation, which is a fancy way of saying that if you curl -H Accept:text/plain ipcalf.com or curl -s http://ipcalf.com/?format=text you should get your public IP address in raw form.
("Full" documentation and source code are on github.)
You can make a request to http://automation.whatismyip.com/n09230945.asp to fetch your public IP from WIMI. This command:
ssh account_name#school "echo -n "$(wget http://automation.whatismyip.com/n09230945.asp -O -)" > some_remote_file"
will write your home public IP to a file called "some_remote_file" in your home folder at school. Set it up with cron and you will have access to your home's routers public IP from your school.
If you've already set up some sort of port forwarding on your router so that you can ssh to your home computer with the routers IP, you should be good to go :)
I figured out a better way to get the IP address then to use an external service. I am SSHing into the server; therefore, the server must know who is SSHing into it, so I can use a tool like who or pinky to find out who is SSHing in.
Here is the command to get the name of the computer logged in.
echo $SSH_CLIENT | awk '{ print $1 }'

Using ssh to echo text on remote server console

ssh -n -l <login> <server> "echo hello"
Displays the output of the ssh command as "hello". Instead I would like to print the "hello" on the serial console of the remote (freebsd) server. Is this possible ?
see the manpage of wall.
alternatively, if you just want to write to (the first physical, not usb) serial port you could do echo hello > /dev/ttyu0, given you have set up COM1 as a terminal and also have the rights to write to that device. (e.g. you are root)