For SSH certificates, is it possible to know the embedded command at the server side? - openssh

we're using SSH certificates with a command inside:
ssh-keygen -s ca-key -n user -O force-command="date" user-key.pub
and they work as expected.
However, we also want to use ForceCommand option on the server (inside a Match section of sshd_config) to log the commands executed. As the command is embedded inside the certificate, the server passes an empty SSH_ORIGINAL_COMMAND to the wrapper. I couldn't find any additional environment variable for this case.
So, can the wrapper know the command embedded inside the certificate?
It would be useful too if the OpenSSH server could log it directly (aside from CA, certificate serial, etc), but couldn't find any option either.

Related

SSH tectia, how to run batch commands?

I have tectia ssh server in a windows environment.
When I use sftpg3 -B cmd.txt username#host that works fine. The only problem is that it doesnt let me execute files remotely, it only lets me move files. It reads the commands from cmd.txt but since I cant execute anything it ignores the commands.
Well when I do the same thing but use sshg3, it doesnt recognize the -B flag at all.
SSHG3 -B cmd.txt username#host
cmd.txt' is not recognized as an internal or external command,
operable program or batch file.
I've tried putting -B "cmd.txt"
I tried just putting the cmd.txt contents in the same script instead of housing them in cmd.txt and getting rid of -B, but it doesnt run them that way either.
The docs dont have much to go off of. All it says is use -B for batch processing.
Contents of cmd.txt:
D:
cd Library
cd Backup
parseLibrary.cmd
exit
Trying to sshg3 into a host, navigate to a path and run a batch file on that host.
Any ideas?
-B, --batch-mode
Uses batch mode. Fails authentication if it requires user interaction on the terminal.
Using batch mode requires that you have previously saved the server host key on the client and set up a non-interactive method for user authentication (for example, host-based authentication or public-key authentication without a passphrase).
It does use public key authentication, there is no user interaction needed on the terminal.
Noticed this on the docs for sftpg3
-B [ - | batch_file ]
The -B - option enables reading from the standard input. This option is useful when you want to launch processes with sftpg3 and redirect the stdin pipes.
By defining the name of a batch_file as an attribute, you can execute SFTP commands from the given file in batch mode. The file can contain any allowed SFTP commands. For a description of the commands, see the section called “Commands”.
Using batch mode requires that you have previously saved the server host key on the client and set up a non-interactive method for user authentication (for example, host-based authentication or public-key authentication without a passphrase).
I'm guessing batch file is different than batch mode?
*I figured it out. You have to use the -B flag for every command you want to execute.
I figured it out. You have to use the -B flag for every command you want to execute.
sshg3 user#host -B dir -B ipconfig -B etc.cmd

Can't launch putty with remote command?

I'm attempting to launch putty via the command line in such a way that it runs a command on the server (I want to create a windows shortcut, to tail a log file)
So far I have a batch file containing this
"C:\Program Files (x86)\PuTTY\putty.exe" -ssh -t -pw -m tail_catalina_out -load "myprofile"
And within my server I have a file at the root directory named tail_catalina_out with the following contents.
tail -f /opt/tomcat/logs/catalina.out
Putty launches and my session starts successfully, but no command appears to be carried out despite this? Am I misunderstanding how this works?
You don't need -ssh with -load profile (and if you use a nonstandard port like my test it doesn't work at all); in fact you don't need it with [user#]host because it's the default
-pw -m tail_catalina_out uses -m as your password (which I hope is incorrect, so you should be reprompted unless publickey auth is set-up) and ignores tail_catalina_out
the file for -m must be local i.e. on the PuTTY machine not on the server (although the commands in it will be sent to, and must be valid on, the server)
Thus: "\path\to\putty" -t -m localcmdfile -load profile
You could also use plink which runs in the console and takes either -m localfile or the actual remote command on the command line after the last option (like the OpenSSH client ssh):
"\path\to\plink" -t -load profile tail -f remotefile
As usual, you can omit the quotes around the path if it contains no space. Personally I use \progra~2 instead of bothering with "\program files (x86)" but that's just me, and it may depend on a clean install (instead of upgrade).

URI Save Password inside the link

Is there a way to save the password of a ssh-connection inside an uri-link. AFAIK a uri can look like this username:password#domain/path. But the following example doesn't work on ubuntu:
ssh user:pass#domain/path
I always receive a "please enter password"-question. I know that it is not a quite secure way to save the password in plain text inside a link, but I have to work with other developers and what should I say... they are ex-Windows user, they don't like terminals and therefore I want to write a tiny shell script. this script should clone a remote git repo and create some specific stuff.
One click and I should do some magic!
You should use a ssh-key generated with ssh-keygen (man ssh-keygen). This is also available on the windows platform within the putty environment.
eval $(ssh-agent)
ssh-add ssh./yourkeyfilewithoutpassphrase
ssh user#sshserver "your remote command"
Befor you can use your ssh-key in the remotehost, you must insert the public key to the authorized_keys file. A convenient way is the command
ssh-copy-id -i ssh./yourkeyfilewithoutpassphrase.pub user#sshserver
or, if the key is already loaded by the ssh-agent
ssh-copy-id user#sshserver
After this point, you dont need any password for ssh connection to established remote hosts. You should use per user a different ssh-key, so you are able to enable and disable keys without bothering the other users.
You can't login with input password using ssh.
Another alternate way is setup a pair of ssh-keys, and login using ssh-key.
I follow the guide here: http://www.softwareprojects.com/resources/programming/t-ssh-no-password-without-any-private-keys-its-magi-1880.html

Using a variable's value as password for scp, ssh etc. instead of prompting for user input every time

AFAIK, the commands ssh or scp do not have/take a password parameter. Otherwise I could keep the password in a shell variable and probably get rid of the enter password prompt. If I write an scp command in my shell script, it prompts the user to input the password. I have multiple ssh and scp commands in my script and I do not want the user to enter the password every time. I would prefer to save the password in a shell variable in the beginning (by asking password once), then use it for every ssh or scp.
I read about "public key identification" in this question. Is it related to the solution I am looking for?
Update
I read in How to use ssh command in shell script? why it is unsafe to specify passwords on the commandline. Does using expect also store the password and is world visible (using ps aux)? Is that the security issue with using expect?
Further Explanation
To further make it clear, I am writing this shell script to automate code and database backup, do code upload, run necessary database queries, do all the things that are needed for a new version release of a LAMP project from a developer system to a remote live server. My shell script will be there inside the main codebase of the project in every developer instance.
Requirement
I want all developers (all may be working from different remote systems) knowing the SSH/FTP password to be able to use the shell by entering the ssh/ftp password same only at run-time once. I would prefer the password to be the ssh/ftp password
Note - I do not want other developers who don't know the SSH password to be able to use it (So I guess public key authentication will not work because it stores the passwords in the systems).
I do not want any command line solution which stores the password in some log in the system and can be world visible using ps aux or something.
Opening Bounty
From all the answers so far and my anaylsis of those solutions, it looks like other than public key authentication all others are insecure. I am not yet sure if using expect is insecure. I think it is otherwise the correct solution for me. In that case, I am getting command not found errors while trying to do that as already commented on one of the answers.
From http://www.debianadmin.com/sshpass-non-interactive-ssh-password-authentication.html -
First and foremost, users of sshpass
should realize that ssh’s insistance
on only getting the password
interactively is not without reason.
It is close to be impossible to
securely store the password, and users
of sshpass should consider whether
ssh’s public key authentication
provides the same end-user experience,
while involving less hassle and being
more secure.
So, is it not possible to securely run multiple ssh, scp commands by entering the ssh/ftp password (if only once at runtime? Please read my Requirement section again.
Also, can anyone explain this -
In particular, people writing programs
that satisfies are meant to
communicate the above points)password
programatically are encouraged to use
an anonymous pipe and pass the pipe’s
reading end to sshpass using the -d
option.
Does this mean anything is possible?
Indeed, you'll definitely want to look into setting up ssh keys, over saving a password in a bash script. If the key is passwordless, then no user input will be required to ssh/scp. You just set it up to use the key on both ends and voila, secured communication.
However, I'll get downvoted to hell if I don't say this. Many consider passwordless ssh keys to be a Bad Idea(TM). If anybody gets their hands on the keys, the have full access. This means that you are relying on other security measures such as file permissions to keep your password safe.
Also, look into ssh-agent. It allows you to set it up so that you have a password protected ssh-key, but you only need to type it in once and it will manage the password for the key for you and use it when necessary. On my linux box at home, I have ssh-agent set up to run in my .xinitrc file so that it prompts me once and then starts X. YMMV.
UPDATE:
With regards to your requirements, password protected public key authentication + ssh-agent still seems to fit. Only the developers privy to the SSH/FTP password could start up ssh-agent, type in the password and ssh-agent would manage the passwords for the public keys for the rest of the session, never requiring interaction again.
Of course, how it stores it is another matter entirely. IANASE, but for more information on security concerns of using ssh-agent, I found symantec's article to be pretty informative: http://www.symantec.com/connect/articles/ssh-and-ssh-agent
"The ssh-agent creates a unix domain
socket, and then listens for
connections from /usr/bin/ssh on this
socket. It relies on simple unix
permissions to prevent access to this
socket, which means that any keys you
put into your agent are available to
anyone who can connect to this socket.
[ie. root]" ...
"however, [..] they are only usable
while the agent is running -- root
could use your agent to authenticate
to your accounts on other systems, but
it doesn't provide direct access to
the keys themselves. This means that
the keys can't be taken off the
machine and used from other locations
indefinitely."
Hopefully you're not in a situation where you're trying to use an untrusted root's system.
The right way to do that is as follows:
Ensure that all your users are using ssh-agent (nowadays this is the default for most Linux systems). You can check it running the following command:
echo $SSH_AUTH_SOCK
If that variable is not empty, it means that the user is using ssh-agent.
Create a pair of authentication keys for every user ensuring they are protected by a non empty passphrase.
Install the public part of the authentication keys on the remote host so that users can log there.
You are done!
Now, the first time an user wants to log into the remote machine from some session it will have to enter the passphrase for its private key.
In later logins from the same session ssh-agent will provide the unlocked key for authentication in behalf of the user that will not be required to introduce the passphrase again.
Ugh. I hit the man pages hard for this. Here's what I got:
Use this code near the beginning of the script to silently get the ssh password:
read -p "Password: " -s SSHPASS # *MUST* be SSHPASS
export SSHPASS
And then use sshpass for ssh like so:
sshpass -e ssh username#hostname
Hope that helps.
You can Using expect to pass a password to ssh do this or as said already use public key authentication instead if that's a viable option.
For password authentication, as you mentioned in you description, you can use "sshpass". On Ubuntu, you can install as "sudo apt-get install sshpass".
For public/private key-pair base authentication,
First generate keys using, "ssh-keygen"
Then copy your key to the remote machine, using "ssh-copy-id username#remote-machine"
Once copied, the subsequent logins should not ask for password.
Expect is insecure
It drives an interactive session. If you were to pass a password via expect it would be no different from you typing a password on the command line except that the expect script would have retrieve the password from somewhere. It's typically insecure because people will put the password in the script, or in a config file.
It's also notoriously brittle because it waits on particular output as the event mechanism for input.
ssh-agent
ssh-agent is a fine solution if this is script that will always be driven manually. If there is someone who will be logged in to drive the execution of the script than an agent is a good way to go. It is not a good solution for automation because an agent implies a session. You usually don't initiate a session to automatically kick of a script (ie. cron).
ssh command keys
Ssh command keys is your best bet for an automated solution. It doesn't require a session, and the command key restricts what runs on the server to only the command specified in the authorized_keys. They are also typically setup without passwords. This can be a difficult solution to manage if you have thousands of servers. If you only have a few then it's pretty easy to setup and manage.
service ssh accounts
I've also seen setups with password-less service accounts. Instead of the command entry in tehh authorized_keys file, and alternative mechanism is used to restrict access/commands. These solutions often use sudo or restricted shells. However, I think these are more complicated to manage correctly, and therefore tend to be more insecure.
host to host automatic authentication
You can also setup host 2 host automatic authentication, but there are alot of things to get write to do this correctly. From setting up your network properly, using a bastion host for host key dissemination, proper ssh server configuration, etc. As a result this is not a solution a recommend unless you know what your doing and have the capacity and ability to set everything up correctly and maintain it as such.
For those for who setting up a keypair is not an option and absolutely need to perform password authentication, use $SSH_ASKPASS:
SSH_ASKPASS - If ssh needs a passphrase, it will read the passphrase from the current terminal if it was run from a terminal. If ssh does not have a terminal associated with it but DISPLAY and SSH_ASKPASS are set, it will execute the program specified by SSH_ASKPASS and open an X11 window to read the passphrase. This is particularly useful when calling ssh from a .xsession or related script. (Note that on some machines it may be necessary to redirect the input from /dev/null to make this work.)
E.g.:
$ echo <<EOF >password.sh
#!/bin/sh
echo 'password'
EOF
$ chmod 500 password.sh
$ echo $(DISPLAY=bogus SSH_ASKPASS=$(pwd)/password.sh setsid ssh user#host id </dev/null)
See also Tell SSH to use a graphical prompt for key passphrase.
Yes, you want pubkey authentication.
Today, the only way I was able to do this in a bash script via crontab was like that:
eval $(keychain --eval --agents ssh id_rsa id_dsa id_ed25519)
source $HOME/.keychain/$HOSTNAME-sh
This is with the ssh agent already running and to achieve that it was needed the passphrase.
ssh, ssh-keygen, ssh-agent, ssh-add and a correct configuration in /etc/ssh_config on the remote systems are necessary ingredients for securing access to remote systems.
First, a private/public keypair needs to be generated with ssh-keygen. The result of the keygen process are two files: the public key and the private key.
The public key file, usually stored in ~/.ssh/id_dsa.pub (or ~/.ssh/id_rsa.pub, for RSA encryptions) needs to be copied to each remote system that will be granting remote access to the user.
The private key file should remain on the originating system, or on a portable USB ("thumb") drive that is referenced from the sourcing system.
When generating the key pair, a passphrase is used to protect it from usage by non-authenticated users. When establishing an ssh session for the first time, the private key can only be unlocked with the passphrase. Once unlocked, it is possible for the originating system to remember the unlocked private key with ssh-agent. Some systems (e.g., Mac OS X) will automatically start up ssh-agent as part of the login process, and then do an automatic ssh-add -k that unlocks your private ssh keys using a passphrase previously stored in the keychain file.
Connections to remote systems can be direct, or proxied through ssh gateways. In the former case, the remote system only needs to have the public key corresponding to the available unlocked private keys. In the case of using a gateway, the intermediate system must have the public key as well as the eventual target system. In addition, the original ssh command needs to enable agent forwarding, either by configuration in ~/.ssh/config or by command option -A.
For example, to login to remote system "app1" through an ssh gateway system called "gw", the following can be done:
ssh -At gw ssh -A app1
or the following stanzas placed in the ~/.ssh/config file:
Host app1
ForwardAgent = yes
ProxyCommand = ssh -At gw nc %h %p 2>/dev/null
which runs "net cat" (aka nc) on the ssh gateway as a network pipe.
The above setup will allow very simple ssh commands, even through ssh gateways:
ssh app1
Sometimes, even more important than terminal sessions are scp and rsync commands for moving files around securely. For example, I use something like this to synchronize my personal environment to a remote system:
rsync -vaut ~/.env* ~/.bash* app1:
Without the config file and nc proxy command, the rsync would get a little more complicated:
rsync -vaut -e 'ssh -A gw' app1:
None of this will work correctly unless the remote systems' /etc/ssh_config is configured correctly. One such configuration is to remove "root" access via ssh, which improve tracking and accountability when several staff can perform root functions.
In unattended batch scripts, a special ssh key-pair needs to be generated for the non-root userid under which the scripts are run. Just as with ssh session management, the batch user ssh key-pair needs to be deployed similarly, with the public key copied to the remote systems, and the private key residing on the source system.
The private key can be locked with a passphrase or unlocked, as desired by the system managers and/or developers. The way to use the special batch ssh key, even in a script running under root, is to use the "ssh -i ~/.ssh/id_dsa" command options with all remote access commands. For example, to copy a file within a script using the special "batch" user access:
rsync -vaut -e 'ssh -i ~batch/.ssh/id_dsa -A gw' $sourcefiles batch#app2:/Sites/www/
This causes rsync to use a special ssh command as the remote access shell. The special-case ssh command uses the "batch" user's DSA private key as its identity. The rsync command's target remote system will be accessed using the "batch" user.

How do you use ssh in a shell script?

When I try to use an ssh command in a shell script, the command just sits there. Do you have an example of how to use ssh in a shell script?
Depends on what you want to do, and how you use it. If you just want to execute a command remotely and safely on another machine, just use
ssh user#host command
for example
ssh user#host ls
In order to do this safely you need to either ask the user for the password during runtime, or set up keys on the remote host.
First, you need to make sure you've set up password-less (public key login). There are at least two flavors of ssh with slightly different configuration file formats. Check the ssh manpage on your system, consult you local sysadmin or head over to How do I setup Public-Key Authentication?.
To run ssh in batch mode (such as within a shell script), you need to pass a command you want to be run. The syntax is:
ssh host command
If you want to run more than one command at the same time, use quotes and semicolons:
ssh host "command1; command2"
The quotes are needed to protect the semicolons from the shell interpreter. If you left them out, only the first command would be run remotely and all the rest would be run on the local machine.
You need to put your SSH public key into the ~/.ssh/authorized_keys file on the remote host. Then you'll be able to SSH to that host password-less.
Alternatively you can use ssh-agent. I would recommend against storing the password in the script.
You can use expect command to populate the username/password info.
The easiest way is using a certificate for the user that runs the script.
A more complex one implies adding to stdin the password when the shell command asks for it. Expect, perl libraries, show to the user the prompt asking the password (if is interactive, at least), there are a lot of choices.

Resources