Getting error in copying multiple files. Below command is copying only first file and giving error for rest of the files. Can someone please help me out.
Command:
scp $host:$(ssh -n $host "find /incoming -mmin -120 -name 2018*") /incoming/
Result:
user#host:~/scripts/OTA$ scp $host:$(ssh -n $host "find /incoming -mmin -120 -name 2018*") /incoming/
Password:
Password:
2018084session_event 100% |**********************************************************************************************************| 9765 KB 00:00
cp: cannot access /incoming/2018084session_event_log.195-10.45.40.9
cp: cannot access /incoming/2018084session_event_log.195-10.45.40.9_2_3
Your command uses Command Substitution to generate a list of files. Your assumption is that there is some magic in the "source" notation for scp that would cause multiple members of the list generated by your find command to be assumed to live on $host, when in fact your command might expand into something like:
scp remotehost:/incoming/someoldfile anotheroldfile /incoming
Only the first file is being copied from $host, because none of the rest include $host: at the beginning of the path. They're not found in your local /incoming directory, hence the error.
Oh, and in addition, you haven't escape the asterisk in the find command, so 2018* may expand to multiple files that are in the login directory for the user in question. I can't tell from here, it depends on your OS and shell configuration.
I should point out that you are providing yet another example of the classic Parsing LS problem. Special characters WILL break your command. The "better" solution usually offered for this problem tends to be to use a for loop, but that's not really what you're looking for. Instead, I'd recommend making a tar of the files you're looking for. Something like this might do:
ssh "$host" "find /incoming -mmin -120 -name 2018\* -exec tar -cf - {} \+" |
tar -xvf - -C /incoming
What does this do?
ssh runs a remote find command with your criteria.
find feeds the list of filenames (regardless of special characters) to a tar command as options.
The tar command sends its result to stdout (-f -).
That output is then piped into another tar running on your local machine, which extracts the stream.
If your tar doesn't support -C, you can either remove it and run a cd /incoming before the ssh, or you might be able to replace that pipe segment with a curly-braced command: { cd /incoming && tar -xvf -; }
The curly brace notation assumes a POSIX-like shell (bash, zsh, etc). The rest of this should probably work equally well in csh if that's what you're stuck with.
Limited warranty: Best Effort Only. Untested on animals or computers. Your milage may vary. May contain nuts.
If this doesn't work for you, poke at it until it does.
I read on man sshd one can add post-login processing when a user logs in using a particular key:
environment="FOO=BAR" ssh-rsa AAA... keytag
But when I try to ssh into the system, the target host does not register the line and instead asks for a password. What is the right way of adding this? I would like to do something like
command="echo|mail -s ${USER},${HOSTNAME} a.monitored.email#example.com" ssh-rsa AAA... keytag
I am using Suse SLE 11 SP2.
Thanks
Dinesh
First, according to the documentation command = "command":
That specifies the command is executed Whenever This key is used for authentication. The command supplied by the user (if any) is ignored. The command is run on a pty if the client requests a pty; Otherwise it is run without a tty. If an 8-bit clean channel is required, one must not request a pty or specify no-pty Should. A quote May be included in the command by quoting it with a backslash. This option might be useful to restrict Un certain public keys to perform just a specific operation. An example might be a key That Permits remote backups but nothing else. Note That May specify the client TCP and / or X11 forwarding Explicitly UNLESS they 'are prohibited. The command originally supplied by the client is available in the SSH_ORIGINAL_COMMAND environment variable. Note That This option Applies to shell, command or subsystem execution. Also note This command That May be superseded by Either a sshd_config (5) ForceCommand directive or a command embedded in a certificate.
Using this option, it is possible to enforce execution of a given command when this key is used for authentication and no other.This is not what you're looking for.
To run a command after login you can add in the file ~/bashrc something like this:
if [[ -n $SSH_CONNECTION ]] ; then
echo|mail -s ${USER},${HOSTNAME} a.monitored.email#example.com"
fi
Second, you need to verify the permissions of the authorized_keys file and the folder / parent folders in which it is located.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
For more information see: https://www.complang.tuwien.ac.at/doc/openssh-server/faq.html#3.14
Consider that I've successfully run these two commands in this order (but perhaps many commands ago):
~% ssh localhost echo
~% sshfs localhost:/ /media/copy-of-root
Now I would like to rerun the ssh command. My first instinct is to use !ssh, but this will match the sshfs command instead.
Is there a version of history expansion which will match entire first words instead of prefixes of commands? If not, is there some other robust way to choose the ssh command over the sshfs one?
well, if you search for ssh (with a trailing space) it will find it. IMO the best alternative is to bind up and down to up-line-or-search and down-line-or-search.
bindkey '^[[A' up-line-or-search # check the exact code for your UP key...
Then you would just use:
% ssh [UP]
which would search for ssh in your history. If that is not the history instance you want, just keep searching (i.e. hitting "UP").
It appears that in this question, the answer was to separate statements with semicolons. However that could become cumbersome if we get into complex scripting with multiple if statements and complex quoted strings. I would think.
I imagine another alternative would be to simply issue multiple SSH commands one after the other, but again that would be cumbersome, plus I'm not set up for public/private key authentication so this would be asking for passwords a bunch of times.
What I'd ideally like is much similar to the interactive shell experience: at one point in the script you ssh into#the_remote_server and it prompts for the password, which you type in (interactively) and then from that point on until your script issues the "exit" command, all commands in the script are interpreted on the remote machine.
Of course this doesn't work:
ssh user#host.com
cd some/dir/on/remote/machine
tar -xzf my_tarball.tgz
cd some/other/dir/on/remote
cp -R some_directory somewhere_else
exit
Is there another alternative? I suppose I could take that part right out of my script and stick it into a script on the remote host. Meh. Now I'm maintaining two scripts. Plus I want a little configuration file to hold defaults and other stuff and I don't want to be maintaining that in two places either.
Is there another solution?
Use a heredoc.
ssh user#host.com << EOF
cd some/dir/on/remote/machine
tar -xzf my_tarball.tgz
cd some/other/dir/on/remote
cp -R some_directory somewhere_else
EOF
Use heredoc syntax, like
ssh user#host.com <<EOD
cd some/dir/on/remote/machine
...
EOD
or pipe, like
echo "ls -al" | ssh user#host.com
I'd like to allow a user to set up an SSH tunnel to a particular machine on a particular port (say, 5000), but I want to restrict this user as much as possible. (Authentication will be with public/private keypair).
I know I need to edit the relevant ~/.ssh/authorized_keys file, but I'm not sure exactly what content to put in there (other than the public key).
On Ubuntu 11.10, I found I could block ssh commands, sent with and without -T, and block scp copying, while allowing port forwarding to go through.
Specifically I have a redis-server on "somehost" bound to localhost:6379 that I wish to share securely via ssh tunnels to other hosts that have a keyfile and will ssh in with:
$ ssh -i keyfile.rsa -T -N -L 16379:localhost:6379 someuser#somehost
This will cause the redis-server, "localhost" port 6379 on "somehost" to appear locally on the host executing the ssh command, remapped to "localhost" port 16379.
On the remote "somehost" Here is what I used for authorized_keys:
cat .ssh/authorized_keys (portions redacted)
no-pty,no-X11-forwarding,permitopen="localhost:6379",command="/bin/echo do-not-send-commands" ssh-rsa rsa-public-key-code-goes-here keyuser#keyhost
The no-pty trips up most ssh attempts that want to open a terminal.
The permitopen explains what ports are allowed to be forwarded, in this case port 6379 the redis-server port I wanted to forward.
The command="/bin/echo do-not-send-commands" echoes back "do-not-send-commands" if someone or something does manage to send commands to the host via ssh -T or otherwise.
From a recent Ubuntu man sshd, authorized_keys / command is described as follows:
command="command"
Specifies that the command is executed whenever this key is used
for authentication. The command supplied by the user (if any) is
ignored.
Attempts to use scp secure file copying will also fail with an echo of "do-not-send-commands" I've found sftp also fails with this configuration.
I think the restricted shell suggestion, made in some previous answers, is also a good idea.
Also, I would agree that everything detailed here could be determined from reading "man sshd" and searching therein for "authorized_keys"
You'll probably want to set the user's shell to the restricted shell. Unset the PATH variable in the user's ~/.bashrc or ~/.bash_profile, and they won't be able to execute any commands. Later on, if you decide you want to allow the user(s) to execute a limited set of commands, like less or tail for instance, then you can copy the allowed commands to a separate directory (such as /home/restricted-commands) and update the PATH to point to that directory.
Besides authorized_keys option like no-X11-forwarding, there actually is exactly one you are asking for: permitopen="host:port". By using this option, the user may only set up a tunnel to the specified host and port.
For the details of the AUTHORIZED_KEYS file format refer to man sshd.
My solution is to provide the user who only may be tunneling, without an interactive shell, to set that shell in /etc/passwd to /usr/bin/tunnel_shell.
Just create the executable file /usr/bin/tunnel_shell with an infinite loop.
#!/bin/bash
trap '' 2 20 24
clear
echo -e "\r\n\033[32mSSH tunnel started, shell disabled by the system administrator\r\n"
while [ true ] ; do
sleep 1000
done
exit 0
Fully explained here: http://blog.flowl.info/2011/ssh-tunnel-group-only-and-no-shell-please/
Here you have a nice post that I found useful:
http://www.ab-weblog.com/en/creating-a-restricted-ssh-user-for-ssh-tunneling-only/
The idea is: (with the new restricted username as "sshtunnel")
useradd sshtunnel -m -d /home/sshtunnel -s /bin/rbash
passwd sshtunnel
Note that we use rbash (restricted-bash) to restrict what the user can do: the user cannot cd (change directory) and cannot set any environment variables.
Then we edit the user's PATH env variable in /home/sshtunnel/.profile to nothing - a trick that will make bash not find any commands to execute:
PATH=""
Finally we disallow the user to edit any files by setting the following permissions:
chmod 555 /home/sshtunnel/
cd /home/sshtunnel/
chmod 444 .bash_logout .bashrc .profile
I'm able to set up the authorized_keys file with the public key to log
in. What I'm not sure about is the additional information I need to
restrict what that account is allowed to do. For example, I know I can
put commands such as:
no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding
You would want a line in your authorized_keys file that looks like this.
permitopen="host.domain.tld:443",no-pty,no-agent-forwarding,no-X11-forwardi
ng,command="/bin/noshell.sh" ssh-rsa AAAAB3NzaC.......wCUw== zoredache
If you want to do allow access only for a specific command -- like svn -- you can also specify that command in the authorized keys file:
command="svnserve -t",no-port-forwarding,no-pty,no-agent-forwarding,no-X11-forwarding [KEY TYPE] [KEY] [KEY COMMENT]
From http://svn.apache.org/repos/asf/subversion/trunk/notes/ssh-tricks
I made a C program which looks like this:
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
void sig_handler(int signo)
{
if (signo == SIGHUP)
exit(0);
}
int main()
{
signal(SIGINT, &sig_handler);
signal(SIGTSTP, &sig_handler);
printf("OK\n");
while(1)
sleep(1);
exit(0);
}
I set the restricted user's shell to this program.
I don't think the restricted user can execute anything, even if they do ssh server command, because the commands are executed using the shell, and this shell does not execute anything.
See this post on authenticating public keys.
The two main things you need to remember are:
Make sure you chmod 700 ~/.ssh
Append the public key block to authorized-keys
You will generate a key on the users machine via whatever ssh client they are using. pUTTY for example has a utility to do this exact thing. It will generate both a private and public key.
The contents of the public key file generated will be placed in the authorized_keys file.
Next you need to make sure that the ssh client is configured to use the private key that generated the public key. It's fairly straight forward, but slightly different depending on the client being used.