ssh-tunnel interview questions
Top ssh-tunnel frequently asked interview questions
I have a nat and it has various server
So from my local server I want to go to nat and then from nat i have to ssh to other machines
Local-->NAT(abcuser@publicIP with key 1)-->server1(xyzuser@localIP with key 2)
nat has different ssh key
and each of the server has different ssh key
how can i accomplish this type of multihop ssh using fabric
I tried using env.roledefs feature but it doesnt seems to be working
also I am not sure how to define two ssh keys.I know we can define a list of keys with env.key_filename but issue is will it check each key with each server?How can I be more specific and match a key with one server only
I have tried using command from my local machine
fab deploy -g 'ec2-user@54.251.151.39' -i '/home/aman/Downloads/aws_oms.pem'
and my script is
from __future__ import with_statement
from fabric.api import local, run, cd, env, execute
env.hosts=['ubuntu@10.0.0.77']
env.key_filename=['/home/ec2-user/varnish_cache.pem']
def deploy():
run("uname -a")
Source: (StackOverflow)
I am trying to use dplyr to connect to a remote database, that I usually query through a ssh tunnel.
I first set up a ssh tunnel like the following:
alias tunnel_ncg='ssh -fNg -L 3307:127.0.0.1:3306 mysqluser@myhost mysql5 -h 127.0.0.1:3306 -P 3307 -u mysqluser -p mypassword'
At this point I can access the database by connecting to localhost:3307. For example:
mysql -h '127.0.0.1' -P 3307 -u mysqluser
If I try to access the same database through dplyr, I get an error complaining that it can't connect to the local MySQL socket:
> conDplyr = src_mysql(dbname = "mydb", user = "mysqluser", password = "mypassword", host = "localhost", port=3307)
Error in .local(drv, ...) :
Failed to connect to database: Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
My understanding is that RMySQL/dplyr are trying to looking for a socket file in the local computer, however they should really be looking for it in the remote server. Is there a way to fix this, or a work-around?
UPDATE:
If I try to connect through dbConnect/RMySQL, the connection works fine:
> dbConnect(dbDriver("MySQL"), user="mysqluser", password="mypassword", dbname="mydb", host="127.0.0.1", port=3307)
<MySQLConnection:0,1>
Source: (StackOverflow)
I have about 100 raspberries, each of them installed in place without ethernet connection, so they have to transmit data to a main server with a 3G modem dongle. When the 3G connects the ISP gives a dynamic IP.
I have a solution of SSH reverse tunneling (explained here http://www.thirdway.ch/En/projects/raspberry_pi_3g/index.php) but I can just connect to port 22, and in the main server I have 100 different ports for each tunneling ... a nightmare.
Also I can not connect to other ports if I need, just 22.
About dynamic IP I know the "dyndns" (or similar) solution.
Is there any nice solution to operate with all of them easily, and can connect to ANY port ?
I would like to do things like:
- install munin (I need 4949)
- connect to myraspberry45.mydomain.com to 80
- ... or 22 if I want
- ...
Any idea?
Source: (StackOverflow)
I have access to an SSH account that can access a GIT server and am able to clone/push/pull the repo in this SSH login. However I cannot access this repo from elsewhere.
On the SSH account I use,
git clone git@gitserver:proj/myrepo.git
to clone the repo.
I tried setting up a ssh tunnel to the git server from another machine using,
ssh -L 3333:gitserver:22 userid@sshserver
git clone ssh://localhost:3333/proj/repo.git
However I keep getting prompted for a password for the user 'git'. Any ideas what I am doing wrong here?
Source: (StackOverflow)
I'm trying to generate an SSH server in a machine behind a router.
First I tried to bind the SSH to my public IP address:
ssh -R 10002:localhost:22 <ip_address>
Then I'm prompted with a password request, however my username password doesn't seem to work.
Obviously I know my username password, so it seems to me that it's trying to authenticate in another computer under the same network.
Any suggestions how to fix this?
It would also help me any alternative on how to create an SSH server behind a Router when you don't have access to the Router.
The ports in iptables are all open.
UPDATE
As suggested by Thomas Oster answer I've tried the following.
In the machine behind the router I've executed the following command:
$ ssh -R10002:localhost:22 <remote_public_ip_address> -l <my_remote_server_username>
<remote_ip_address>
being the remote_ip_address of a server with public IP and SSH server on which I have full control.
<my_remote_server_username>
being the remote server username.
After that, I've tried to connect from the remote server to the server behind the router like this:
$ ssh -p 10002 <remote_public_ip_address>
However this command displays the following output:
ssh: connect to host <remote_public_ip_address> port 10002: Connection refused
So I opened the 10002 port in the iptables firewall using the following command:
sudo iptables -A INPUT -p tcp --dport 10002 -j ACCEPT
After that I've executed again the command but it displays the same error message.
In my machine behind the router I have all ports open in iptables.
UPDATE 2
You have to allow port-forwarding in the /etc/ssh/sshd_config of the
remove_public_ip_address server
I've tried to allow portforwarding in the sshd_config file adding this command:
LocalForward 10002 <my_remote_public_server_ip>:22
But it gave me this error message:
Bad configuration option: LocalForward
After "ssh -R...." did you leave the window open?
After executing that command, it connects to the remote public machine, and yes, I left the window open.
Can you use ssh -p 10002 localhost on the public server after the
tunnel is created?
Yes, if I execute that command in the public server, it connects after asking me for credentials.
Please try "ssh localhost" on the machine behind the router to check if sshd is running and working.
This also works.
UPDATE 3
I've been finally able to make it work (thanks again to Thomas Oster)
We are going to work with three machines:
Destination Machine: That we want to connect to.
Middle Machine: A server acting as an intermediary for the connection (a Linode in my case)
Home Computer: Where we will access to the destination machine.
These are the steps I followed
Step 1:
[destination computer]$ vi /etc/ssh/sshd_config
Add the GatewayPorts option:
GatewayPorts yes
Restart ssh.
Step 2:
[destination computer]$ ssh -R 4040:localhost:22 middle-machine-user@middle-machine-public-ip
This will link your public machine with your destination computer via port 4040
It will connect to the middle machine and prompt the terminal, you must leave this tab open.
Step 3:
Connect from home:
ssh destination-user@destination-ip -p4040
Or connect from the middle machine:
[home computer]$ ssh middle-machine-user@middle-machine-ip
[middle computer]$ ssh destination-user@localhost -p4040
Source
Source: (StackOverflow)
I am using eclipse with RSE, and it works well connecting to my linux server when I am in the same network, but as the server is behind a firewall with a gate entry, I need to make a ssh tunnelling when outside its network.
I have not find a way of adding the local port where I have the tunnel to the host name nor in other places.
Is it possible to connect to localhost:port with RSE?
Source: (StackOverflow)
We're using Capistrano to automate pushing new versions of a PHP application to a production server. The production server (we'll call it production) is public, while our repository server (we'll call it repo) sits behind our corporate firewall, along with our own machines.
Capistrano, as configured by default, won't work, as production can't talk to repo.
I was wondering if there was someway I could setup capistrano to SSH to repo first, then SSH to production opening a tunnel on a port that I can then use to SSH from production back to repo to pull the changes from SCM.
I just can't figure out how to set this up or figure out a better solution. Ideas?
Edit:
I've tried this:
role :web, "deploy.com"
namespace :deploy do
task :remote_tunnel do
run 'Creating SSH tunnel...' do |channel, stream, data|
ssh = channel.connection
ssh.forward.remote(22, 'server.com', 10000, '127.0.0.1')
ssh.loop {!ssh.forward.active_remotes.include?([10000, '127.0.0.1'])}
end
end
end
before "deploy:update_code", "deploy:remote_tunnel"
But I keep getting this error:
failed: "sh -c 'Creating SSH tunnel...'" on deploy.com
Source: (StackOverflow)
I'm writing a "tool" - a couple of bash scripts - that automate the installation and configuration on each server in a cluster.
The "tool" runs from a primary server. It tars and distributes it's self (via SCP) to every other server and untars the copies via "batch" SSH.
During set-up the tool issues remote commands such as the following from the primary server: echo './run_audit.sh' | ssh host4 'bash -s'
. The approach works in many cases, except when there's interactive behavior since standard input is already in use.
Is there a way to run remote bash scripts interactively over SSH?
As a starting point, consider the following case: echo 'read -p "enter name:" name; echo "your name is $name"' | ssh host4 'bash -s'
In the case above the prompt never happens, how do I work around that?
Thanks in advance.
Source: (StackOverflow)
I'm trying to set up the WebStorm NodeJS debugger to connect to a NodeJS project hosted on a Vagrant box. I'm coming up with some difficulties.
If I tunnel into the server the traditional way (ie, via Terminal), it all works fine and I'm able to cURL to it, debug it via WebStorm etc.
ssh -L 5858:127.0.0.1:5858 -N vagrant@10.20.30.40
Once I'd gotten that working, I put the following into my Vagrantfile:
config.vm.network :forwarded_port, guest: 5858, host: 5858
Unlike before, this still works on the Vagrant box but not on my local machine. When I cURL to it, I get the following error:
curl: (56) Recv failure: Connection reset by peer
Does anyone have any ideas as to what I'm doing wrong? Is this even possible to configure through the Vagrantfile?
I want to do it through this so my team can connect their debuggers with zero configuration.
Thanks
Source: (StackOverflow)
My aim is to connect to a server (host) which is behind a firewall. I am able to access this server by connecting to another server (tunnel) in the network and then SSH to this server. However I am not able to implement the same scenario via JSch.
I am not able to have the below code work, which I have written for this purpose. Please let me know if I am doing anything silly here.
public class JschExecutor {
public static void main(String[] args){
JschExecutor t=new JschExecutor();
try{
t.go();
} catch(Exception ex){
ex.printStackTrace();
}
}
public void go() throws Exception{
StringBuilder outputBuffer = new StringBuilder();
String host="xxx.xxx.xxx.xxx"; // The host to be connected finally
String user="user";
String password="passwrd";
int port=22;
String tunnelRemoteHost="xx.xx.xx.xx"; // The host from where the tunnel is created
JSch jsch=new JSch();
Session session=jsch.getSession(user, host, port);
session.setPassword(password);
localUserInfo lui=new localUserInfo();
session.setUserInfo(lui);
session.setConfig("StrictHostKeyChecking", "no");
ProxySOCKS5 proxyTunnel = new ProxySOCKS5(tunnelRemoteHost, 22);
proxyTunnel.setUserPasswd(user, password);
session.setProxy(proxyTunnel);
session.connect(30000);
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand("hostname");
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in=channel.getInputStream();
BufferedReader ebr = new BufferedReader(new InputStreamReader(in));
channel.connect();
while (true) {
byte[] tmpArray=new byte[1024];
while(in.available()>0){
int i=in.read(tmpArray, 0, 1024);
if(i<0)break;
outputBuffer.append(new String(tmpArray, 0, i)).append("\n");
}
if(channel.isClosed()){
System.out.println("exit-status: "+channel.getExitStatus());
break;
}
}
ebr.close();
channel.disconnect();
session.disconnect();
System.out.println(outputBuffer.toString());
}
class localUserInfo implements UserInfo{
String passwd;
public String getPassword(){ return passwd; }
public boolean promptYesNo(String str){return true;}
public String getPassphrase(){ return null; }
public boolean promptPassphrase(String message){return true; }
public boolean promptPassword(String message){return true;}
public void showMessage(String message){}
}
}
The above code gives the below exception on the session.connect(30000);
line.
com.jcraft.jsch.JSchException: ProxySOCKS5: com.jcraft.jsch.JSchException: fail in SOCKS5 proxy
at com.jcraft.jsch.ProxySOCKS5.connect(ProxySOCKS5.java:317)
at com.jcraft.jsch.Session.connect(Session.java:231)
at com.ukris.main.JschExecutor.go(JschExecutor.java:50)
at com.ukris.main.JschExecutor.main(JschExecutor.java:19)
Caused by: com.jcraft.jsch.JSchException: fail in SOCKS5 proxy
at com.jcraft.jsch.ProxySOCKS5.connect(ProxySOCKS5.java:200)
... 3 more
Source: (StackOverflow)
I have a specific scenario that I want to solve. I currently connect to a host via port forwarding:
laptop -> gateway -> remote_server_1
and another host:
laptop -> remote_server_2
with passwordless login working on both. Neither of the remote servers are visible to the outside world. Now I'm running a service on remote_server_2, that I'd like to be able to access on remote_server_1. I presume I have to setup reverse port forwarding from remote_server_1 to my laptop, and then on to remote_server_2, but I'm not sure how to do this. Anyone come across this situation before?
Edit:
The full solution in case anyone else needs it:
mylaptop$ ssh -L 3001:localhost:3000 server_2
server_2$ netcat -l 3000
Then setup the tunnel via gateway
to server_1
:
ssh -t -t -L 3003:server_1:22 gateway
Then access it from server_1
:
ssh -R 3002:localhost:3001 -p3003 localhost
echo "bar" | nc localhost 3002`
and hey presto server_2
shows bar
:-)
Source: (StackOverflow)
cURL + proxy noob here, having a hard time. I'm having trouble trying to retrieve a web page from a remote secure server via a proxy. Everything has apparently been set up correctly by a remote dev, such that the following command line instruction works and returns what we're looking for:
curl -k --socks5-hostname localhost:xxxx https://hostname/
However, the following PHP does not echo the requested webpage. Instead it echoes the error 'Couldn't resolve host name':
$proxy = 'localhost:xxxx';
$url = 'https://hostname/';
//$proxyauth = 'user:password';
$ch = curl_init();
curl_setopt($ch, CURLOPT_PROXY, $proxy);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
//curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyauth);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_URL, $url);
$curl_scraped_page = curl_exec($ch);
$error = curl_error($ch);
curl_close($ch);
if ($error)
echo $error;
elseif ($curl_scraped_page)
echo $curl_scraped_page;
If the $url is changed to a public page, such as Google, the request is successful and everyone is happy.
The connection requires an SSH tunnel if that changes anything at all. The tunnel is open and functioning, as proven by the command line request succeeding.
Is there something obvious that is being missed here?
Source: (StackOverflow)
I need to create SSH tunnel with PuTTY in Windows, that would do the same as this command in Linux:
ssh -fN -L 2000:SomeIp:2000 myusername@myLinuxBox
I tried many options in PuTTY, including setting source port in GUI to "2000" and destination to "SomeIp:2000". Destination is set to local (as the -L
switch suggests).
I successfully login to my SSH box but port forward is not made.
Is this even possible in Windows, so that all the connections made by programs that use this port (2000) will go through this tunnel?
Source: (StackOverflow)
I have a perl script which, when destilled a bit, looks like this:
my $randport = int(10000 + rand(1000)); # Random port as other scripts like this run at the same time
my $localip = '192.168.100.' . ($port - 4000); # Don't ask... backwards compatibility
system("ssh -NL $randport:$localip:23 root\@$ip -o ConnectTimeout=60 -i somekey &"); # create the tunnel in the background
sleep 10; # Give the tunnel some time to come up
# Create the telnet object
my $telnet = new Net::Telnet(
Timeout => 10,
Host => 'localhost',
Port => $randport,
Telnetmode => 0,
Errmode => \&fail,
);
# SNIPPED... a bunch of parsing data from $telnet
The thing is that the target $ip is on a link with very unpredictable bandwidth, so the tunnel might come up right away, it might take a while, it might not come up at all. So a sleep is necessary to give the tunnel some time to get up and running.
So the question is: How can i test if the tunnel is up and running? 10 seconds is a really undesirable delay if the tunnel comes up straight away. Ideally, i would like to check if it's up and continue with creating the telnet object once it is, to a maximum of, say, 30 seconds.
Edit: Ping doesn't help me mouch, as the remote end of the tunnel is generally up, but with a very high amount of packetloss
Solved: Extrapolating from the tip suggested by mikebabcock, sleep 10
has been replaced with this block which works like a charm:
my $starttime = time();
while (1)
{
# Check for success
if (system("nc -dzw10 localhost $randport > /dev/null") == 0) { last }
# Check for timeout
if (time() > $starttime + 30) { &fail() }
# 250ms delay before recheck
select (undef, undef, undef, 0.25);
}
Source: (StackOverflow)