I am trying to automate SSH login by using password. I can't use expect command or sshpass etc. So I am left with only option to use password directly.
Did lot of research in google and didn't get any solution... :(
Please help me with this.
The code I tried is.
#!/bin/bash
USERNAME=user1
PASSWORD=abcd1234
HOSTS="server01.mat.us"
ssh ${HOSTS} -l ${USERNAME} -p ${PASSWORD}
The OpenSSH ssh utility doesn't accept a password on the command line or on its standard input. This also applies to the scp and sftp file transfer utilities, which invoke ssh to make the SSH connection. I believe this is a deliberate decision on the part of the OpenSSH developers. You have these options available to you:
Use an SSH key for authentication, instead of a password.
Use sshpass, expect, or a similar tool to invoke ssh through a TTY and automate responding to the password prompt.
Use (abuse) the SSH_ASKPASS feature to get ssh to get the password by running another program, described here or here, or in some of the answers here.
Get the SSH server administrator to enable host-based authentication and use that. Note that host-based authentication is only suitable for certain network environments. See additional notes here and here.
Write your own ssh client using perl, python, java, or your favorite language. There are ssh client libraries available for most modern programming languages, and you'd have full control over how the client gets the password.
Download the ssh source code and build a modified version of ssh that works the way you want.
Use a different ssh client. There are other ssh clients available, both free and commercial. One of them might suit your needs better than the OpenSSH client.
I'd recommend to use ssh keys instead of password if it's possible.
This script can help you to upload your public key to desired remote machine:
https://github.com/aprey10/ssh-authorizer
Related
I'm working on a C project that makes connections to remote servers. Commonly, this involves using some small terminal macros I've added to my makefile to scp an executable to that remote server. While convenient, the only part of this I've not been able to readily streamline is the part where I need to enter the password.
Additionally, in my code, I'm already using system() calls to accomplish some minor terminal commands (like sort). I'd ALSO like to be able to enter a password if necessary here. For instance, if I wanted to build a string in my code to scp a local file to my remote server, it'd be really nice to have my code pull (and use) a password from somewhere so it can actually access that server.
Does anyone a little more experienced with Make know a way to build passwords into a makefile and/or a system() call in C? Bonus points if I can do it without any third-party software/libraries. I'm trying to keep this as self-contained as possible.
Edit: In reading responses, it's looking like the best strategy is to establish a preexisting ssh key relationship with the server to avoid the login process via something more secure. More work up front for less work in the future, by the sound of it, with additional security.
Thanks for the suggestions, all.
The solution is to not use a password. SSH, and thus SCP, has, among many many others, public key authentication, which is described all over the internet. Use that.
Generally, the problem you're trying to solve is called secret management, and the takeaway is that your authentication tokens (passwords, public keys, API keys…) should not be owned by your application software, but by something instructing the authenticating layer. In other words, the way forward really is that you enable SSH to connect on its own without you entering a password by choosing something that happens to not be an interactive authentication method. So, using a password here is less elegant than just using the generally favorable method of using a public key to authenticate with your server.
Passing passwords as command line option is generally a bad idea – that leaks these passwords into things like process listings, potentially log entries and so on. Don't do it.
Running ssh-keygen to create the keys. Then, adding/appending the local system's (e.g) .ssh/id_rsa.pub file to the remote's .ssh/authorized_keys file is the best way to go.
But, I had remote systems to access without passwords but the file was not installed on the remote (needing ssh-keygen to be run on the remote). Or, the remote .ssh/authorized_keys files did not have the public key from my local system in it.
I wanted a one-time automated/unattended script to add it. A chicken-and-the-egg problem.
I found sshpass
It will work like ssh and provide the password (similar to what expect does).
I installed it once on the local system.
Using this, the script would:
run ssh-keygen on the remote [if necessary]
Append the local .ssh/id_rsa.pub public key file to the remote's .ssh/authorized_keys
Copy back the remote's .ssh/id_rsa.pub file to the local system's .ssh/authorized_keys file [if desired]
Then, ssh etc. worked without any passwords.
UPDATE:
ssh_copy_id is your fried, too.
I had forgotten about that. But, when I was doing this, I had more complex requirements.
The aforementioned script would merge/combine all the public keys and update all the authorized_keys files on all the systems. This would be repeated anytime any new system was added to the mix.
you never need to run ssh-keygen on a remote host, especially not to generate an authorized_keys file. –
Marcus Müller
I think that was inferred but not implied as a requirement [particularly in context]. I hope the answer wasn't -1 for that.
Note that (1) ssh-keygen is needed for (3) copy back the public key.
Ironically, one of the tutorial pages for ssh-copy-id says run ssh-keygen first ...
It's been my exerience when setting up certain types of systems/clusters (e.g. a development host/PC and several remote/target/test ones), if one wants to do local-to-remote actions, invariably one wants to do:
remote-to-local actions -- (e.g.) I'm ssh'ed into a remote system and want to do rcp back to the development system.
The remote system needs to do a git clone/pull from [and, sometimes, git push to] the local git server.
remote-to-remote -- copying/streaming data between target systems.
This requires that each system have a private/public key pair and all systems have an authorized_keys file that has the public keys of all the other systems.
When I've not set up the systems that way it usually comes back to haunt me [usually late at night when I'm tired]. So, I just [axiomatically] set it up that way at the outset.
One of the reasons that I developed the script in the first place. Also, since we didn't want to have to maintain a fork of a given system/distro installer for production systems, we would:
Use the stock/standard distro installer CD/USB
Use the script to add the extra/custom config, S/W, drivers, etc.
I'm trying to automate the process of doing
git add .
git commit -m "some message"
git push origin master
In C.
I've already done a bash script with Expect
#!/bin/bash
HOME="/home/prxvvy"
filename="$HOME/Documents/github_creds.txt"
username=`awk 'NR==1' $filename`
password=`awk 'NR==3' $filename`
echo "Enter a message for commit:"
read message
expect <<EOS
spawn git add .
expect
spawn git commit -m "$message"
expect
spawn git push origin master
expect "Username for 'https://github.com':"
send "$username\r"
expect "Password for 'https://$username#github.com':"
send "$password\r"
expect eof
EOS
So how would I "send" the requested data when the "Username for 'https://github.com':" prompt comes up, with C?
PS: I don't want to use any git api or something as I did in the bash script
Answer #1: you can't. The problem here has nothing to do with Git per se. Programs that read passwords from humans make sure they're not talking to other programs, by making sure they're using the human /dev/tty interface. So your program can't push a password into another program.
Answer #2: you can, but you must re-implement expect. The expect program tricks other programs into thinking they are talking to a human. This is fairly complicated and involves opening a "pseudo tty" from the control side, initializing it properly on the dependent side, and doing any OS-level operations required to make it become the /dev/tty that other programs will get when they open it. Then, having done all this song and dance (some of which is available in some libraries via openpty or similar), you can then run a program. You then must implement the rest of expect to read data coming through the control side of the pty pair, interpret it to figure out what the program is doing, and feed it data.
(Note that if all you want to do is run git push without having to enter a password, Git can invoke authentication methods that do this. Git does not have its own built in authentication: it relies on credential helpers when using https and ssh's credentialing and authentication systems when using ssh. So if you're using https:// for your URL, you want to configure a credential helper to do the job, and if you're using ssh:// for your URL, you want to configure ssh. You said that's not what you're interested in, though.)
I'd like to use terminal for all of my normal git and compiling and running processes (my school has a server that is linked to my repo on bitbucket), but I really don't like terminal-based text editing software such as Emacs and Vim. Is it possible to open and edit files from the terminal using a GUI based text editor? The reason I'm asking is because the terminal is the only way I can access the server files. Thanks in advance!
Aw, but vim is the best! :) Well, you can use nano, which is friendlier. Or, if you insist: if you are using SSH to connect to the server (and the server has an X server running !) then you can look into the ssh -X option to view X windows on your remote machine.
Oh and you could look into scp command as well (behaves almost just like regular cp, but the destination is on another host). That way you could edit on your machine, then copy it via SSH (although you'd want to be careful when copying files directly to the server filesystem)
Edit: Also, if you really don't like using the terminal (why though? (-: ), some file managers allow you to get the same functionality of the previous commands purely via GUI (for example).
You've left out some important information that someone would need to know to answer your questions. The other posters have made some assumptions.
You've mentioned this "terminal", but it's not clear exactly what that is, or how you're getting to it. What kind of computer do you have in front of you? What shell is running in that terminal? Is the shell running on your local computer, or have you remotely connected to a server and running that shell on the remote computer?
Based on what you said, I have a feeling you're making a remote connection to a server, perhaps using ssh. You likely have either a Windows or Mac PC in front of you. In those circumstances, running a GUI editor like Eclipse is possible, but likely not practical. You would have to have Eclipse installed on that remote computer, and you would be displaying the Eclipse window on your local computer using the X11 protocol. That takes a lot of bandwidth.
If my assumptions are correct, my recommendations depend on how long you expect you're going to want to stay familiar with this environment. If you intend to do this sort of work forever, then you should learn vi and Emacs to the best of your ability. As someone who's been using Emacs likely longer than you've been alive, I'd recommend you learn it, but vi is also a critical skill.
UNIXY systems provide open or gopen, depending on your OS, that should get the job done. From the man page:
By default, gopen will open filename with the application currently assigned to the file's extension. But by specifing the -a flag on the command line you can tell gopen to open the file with another application.
This means that you can use it to open files in your preferred editor
with a line like
gopen -a Eclipse file
I have implemented automation through batch file to login into a remote server and run a series of commands therin. My batch file contents are as follows:
#ECHO OFF
ECHO 1 -^> Connect 2 Server
ECHO 2 -^> Quit
SET /p ID=Enter Choice :
IF "%ID%"=="1" start "" C:\work\putty.exe -load SessionName -l UserName -pw Password -m cmd.txt
IF "%ID%"=="2" exit
My cmd.txt file contains the following commands:
su superuser
password
ssh server
password
su MyID
password
The batch successfully connects to the server; but it fails to retain the session. Any tweak would be appreciated.
For my own use I verified what -m switch does for putty
The -m option performs a similar function to the ‘Remote command’ box in the SSH panel of the PuTTY configuration box (see section 4.18.1). However, the -m option expects to be given a local file name, and it will read a command from that file.
With some servers (particularly Unix systems), you can even put multiple lines in this file and execute more than one command in sequence, or a whole shell script; but this is arguably an abuse, and cannot be expected to work on all servers. In particular, it is known not to work with certain ‘embedded’ servers, such as Cisco routers.
Roughly what I guessed. I think what's happening is that your commands might be running ok, but it terminates the session when done (which is also default behaviour for ssh [command] on unix. To get around this you could try running 'bash' at the end to start a terminal as that user, which should stay running until you exit. If this doesn't work you could try running 'sleep 10' to see if the session stays running longer - should verify that's the problem we're dealing with.
Much as stackoverflow demands strictly the answer to the question, which I hope I've provided above. I feel in this case it would be remiss to not flag the serious security concerns I'd have on what you're doing. I would maintain that you shouldn't answer a question about doing something securely (with ssh and root passwords involved) without covering potential security pitfalls.
What you're doing seems like a bad idea because:
it makes a file with two unencrypted root-capable passwords to anyone who finds that file
this script is also giving you root access by default, which isn't a safe way to operate. Ever accidentally type rm -r in the wrong window?
Also, someone messing with your second hop (by say, replacing the ssh server with a script to run ssh but log passwords) would get the password to the third hop with root privileges.
SSH keys should do away with using passwords to log on. Use them.
SSH port forwarding lets you also skip sshing from the second hop - instead just tunnel through it (I'm guessing the third box isn't internet accessible), again using ssh keys lets you skip passwords.
the first 'su superuser' shouldn't be necessary unless your permissions don't allow you ssh (does an ssh_allow group exist on that box?), which might be the problem you should actually fix - not being a member of the group allowed to use SSH.
First of all, the goals are not security nor user-friendliness. (Meaning no visual crap and no password encoding/ mega security stuff)
Server-side I want the simplest thing possible. Just a way to authenticate some ~5 users but knowing who they are when they do. Once they are authenticated I'll serve them a file (I haven't decided yet what, .txt or xml or something) and they won't be able to do anything else.
So from the program standpoint, I need to connect to my server, authenticate somehow, get a file, and disconnect. The user only interacts with the program with a simple user/pass combo. The rest is automatic. I was looking to libcurl for the connection+authentication+download, but I would like to hear suggestions because from this list: libcurl competitors, there seems to be much offer available.
I think of it as the same as when I do sudo aptitude install, but the sudo part would go on the server if that makes any sense.
So my question is, how can I make a page with an authentication (note that it doesn't have to have any visual output) which then lets the program download a file. And how do I connect to it?
Simplest thing possible would be to keep the path to the files secret and authenticating people by giving them the link.
You might find this page on HTTP Basic authentication useful. You can either roll your own HTTP server or configure an existing httpd. Then, you can write a simple shell script that calls out to curl to authenticate and download the page.
If your users can have accounts on the server, a way would be to use the scp command. They will be prompted for their password. You can wrap it in a shell script or call it from a C program using system or equivalent.
Edit: Then you may look into protecting a directory by a .htaccess and a .htpsswd. I don't know it is accessible through libcurl or any other C library though.