I need to implement an SCP handler which would allow me to save files to a specific directory. For example, if user typed scp [source] [destination], script would copy [source] at temp/[destination].
So, all I need to do is to change [destination] adding temp/ as a prefix.
I have decided to implement custom process handler, which, as you can guess, accepts asyncssh.SSHServerProcess. The problems I have faced are:
When I try to access process.command attribute, I get scp -t [destination], whereas I typed scp [source] [destination] at the clientside (note, [source] does not appear in process.command). I doubt whether it is a proper way to obtain command or not.
After I have transformed command, how can I apply scp command? Consider I have scp -t temp/[destination], how can I run this command?
Related
I would like to execute a "git push" command using Python script. I was hoping to achieve this by using python's subprocess.Popen() method. However when I invoke the "git push" command, the ssh agent asks me for my passphrase in order to be able to push any changes to the repository.
And here is my question - is there any way for me to be able to pass my passphrase which is an input expected by the ssh process not the git itself?
process = subprocess.Popen("git push", stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False)
pin = process.stdin.write("Passphrase")
I acknowledge that it might be easier to get rid of this ssh-agent's passphrase message everytime I git push or pull, however just for the sake of knowing I was curious is there a way to achieve it this way.
Note that GitPython issue 559 mentioned in 2016:
As far as I know, it is not possible to use keys with passphrases with GitPython due to the way git is invoked by it.
It simply does not connect standard input, which usually would be required to read the passphrase. The preferred way to do it would be to use a specific key without passphrase.
If that is not an option, git will also invoke the program pointed to by GIT_ASKPASS to read a password for use with the ssh key.
There is however a possible workaround, initially applied to GPG:
How to sign commits using the GitPython package
See 03_sign_commit_using_the_gitpython_package.py.
But again, for GPG. Check if that can be adapted for SSH.
I'm at a loss for what to think, here. There must be something I'm missing since I'm able to execute this perfectly fine in another, similar context, but not here. I am trying to run the following console command via Robot Framework for the sake of testing my system's reaction to a network outage: ssh it#128.0.0.1 sudo ifconfig ens192 down (the user & host ip are modified for posting here.)
To accomplish this, I'm using the following line of code:
Run Process 'ssh it#128.0.0.1 sudo ifconfig ens192 down' shell=True stdout=stdout stderr=stderr
Now, I've executed this myself in console and saw that the result was an inability to ping the ip, which is what I want. So I know for certain that the command itself isn't a problem. What is a problem is the fact that I get the following result: /bin/sh: ssh it#128.0.0.1 sudo ifconfig ens192 down: command not found
That's fine, though, because I believe this is a simple issue of the ssh instance not having the it user's $PATH. For reasons described below, I'm going to guess its $PATH variable is empty. Thus, I modified the keyword call as such:
Run Process 'ssh it#128.0.0.1 PATH\=/usr/sbin sudo ifconfig ens192 down' shell=True stdout=stdout stderr=stderr
The result of this command is as follows: /bin/sh: ssh it#128.0.0.1 PATH=/usr/sbin sudo ifconfig ens192 down: No such file or directory, which I believe to be referring to the items in the PATH attribute. I've tried several different things to determine what the problem could be, such as why it would be unable to find these files in an instance where, executed manually in the console, these directories are indeed present.
Given that I have less than a year's worth of experience with Robot Framework, I'm certain that there's just something I'm not understanding about the Process library. Could I have an explanation as to what I am missing for this execution and, if possible, an explanation as to how I should be executing an ssh command via Robot Framework?
A few extra things worth pointing out:
The it user is brand new, having been created via useradd it and copying the home directory contents into its new space.
I have already added an entry into the device's sudoers file to allow the it user to execute ifconfig without requiring password entry.
On that note, I've sent the executing user's ssh keys over to the device such that it does not require a password to log into it as that user.
I have attempted to execute several basic commands. I have intermittently gotten ls to work but have been unable to get a greater sense of what $PATH the Robot Framework ssh instance has because echo doesn't seem to work.
I'm pulling and pushing to a github repository with a python script. For the github repository, I need to use a ssh key.
If I do this manually before running the script:
eval $(ssh-agent -s)
ssh-add ~/.ssh/myprivkey
everything works fine, the script works. But, after a while, apparently the key expires, and I have to run those 2 cmds again
The thing is, if I do that inside the python script, with os.system(cmd), it doesn't work, it only works if I do that manually
I know this must be a messy way to use the ssh agent, but I honestly don't know how it works, and I just want the script to work, that's all
The script runs once an hour, just in case
While the normal approach would be to run your Python script in a shell where the ssh agent is already running, you can also consider an alternative approach with sshify.py
# This utility will execute the given command (by default, your shell)
# in a subshell, with an ssh-agent process running and your
# private key added to it. When the subshell exits, the ssh-agent
# process is killed.
Consider defining the ssh key path against a host of github.com in your ssh config file as outlined here: https://stackoverflow.com/a/65791491/14648336
If Linux then at this path ~/.ssh/ create a file called config and input something similar to in the above answer:
Host github.com
HostName github.com
User your_user_name
IdentityFile ~/.ssh/your_ssh_priv_key_file_name
This would save the need for starting an agent each time and also prevent the need for custom environment variables if using GitPython (you mention using Python) as referenced in some other SO answers.
These are the things I need to do:
Open putty.exe
Enter username and password.
Run a shell script.
I am using UFT (VB Scripting). I am able to open PuTTY but not able to enter username and password or run any commands using UFT.
Is there any other way I can achieve this? I have searched it and found that we can use Plink. Then the problem would be that the whole team will have to install Plink for that purpose. And that is not possible.
Thanks in advance.
PuTTY has the -m switch, that you can use to provide a path to a file with a list of commands to execute:
putty.exe user#example.com -m c:\local\path\commands.txt
Where the commands.txt will, in your case, contain a path to your shell script, like:
/home/user/myscript.sh
Though for automation, your better use the Plink command-line connection tool, instead of the GUI PuTTY application, as you have already found out. The Plink is a part of PuTTY package, so everyone who has PuTTY should have Plink too.
The Plink (plink.exe) has the same command-line arguments as PuTTY. And in addition to those, you can specify your command directly on its command like:
plink.exe user#example.com /home/user/myscript.sh
or using its standard input
plink.exe user#example.com < c:\local\path\command.txt
(of course, you will use redirection mechanism of your language, instead of the <).
Note that providing a command using the -m switch or directly on command-line implies a non-interactive mode, while using the standard input uses an interactive mode by default. So the results or behavior may differ. Use the -t and -T switches to force the interactive and the non-interactive mode, respectively.
You can add cmd arguments when you launch putty directly;
start C:\Users\putty.exe -load "server" -l userID -pw Password -m commands.txt
Can you not request the user name and pass prior and pass this along to the executable?
To run a single remote command or short series of commands is even easier by using the plink -batch flag instead of needing a script file. For example to show the OS name and a directory listing, do this:
plink user#host -pw password -batch uname;ls
I have a python script which is performing some nagios configuration. The script is running as a user which has full sudo rights (the user can run any command with sudo, without password prompt). The final step in the configuration is this:
open(NAGIOS_COMMAND_FILE, 'a').write(cmdline)
The NAGIOS_COMMAND_FILE is only writable by root, so this command should be run by root. I can think of two ways of achieving this (both unsatisfactory):
Run the whole script as root. I do not like doing this, since any error in my script will be executed with full root rights.
Put the open(NAGIOS_COMMAND_FILE, 'a').write(cmdline) command in a separate script, and use the subprocess library to call that script, with sudo. I do not like creating an extra script just to run a single command.
I suppose there is no way of changing the running user just for a single command, in my current script, or am I wrong?
Why don't you give write permission on NAGIOS_COMMAND_FILE to your user who have all sudo rights?
Never, ever run a web server as root or as a user with full sudo privileges. This isn't a pythonic thing, it is a "keep my server from being pwned" thing.
Look at os.seteuid, the "principle of least privilege", and man sudoers and run your server as regular "httpd-server" where "httpd-server" has sudoer permission to write to NAGIOS_COMMAND_FILE. And then be sure that what you write to the command file is as clean as you can make it.
It is actually possible to change user for a single command.
Fabric provides a way to log in as any user to a server. It relies on ssh connections I believe. So you could connect to localhost with a different user in your python script and execute the desired command.
http://docs.fabfile.org/en/1.4.3/api/core/decorators.html
Anyway, as others have already precised, it is best to allow the user running the script permission to execute this one command and avoid relying on root for execution.
I would agree with the post above, either give your user write perms to the NAGIOS_COMMAND_FILE or add that use to a group that has those permissions, like nagcmd.