I would like to create a php script that creates keys for ssh-authentication.
I've started with a
exec("ssh-keygen -b 1024 -t dsa -N *pwd* -f *path-to-file* -q");
to create the private and public-key-pair. No problem till here ;)
Now I've to convert the OpenSSL-Key to the ppk-format of PuTTY (in the cmd, not in the GUI). If anyone have an Idea on how to manage that, please let me know.
Thanks
If you were working with RSA keys you could do this (requires phpseclib):
<?php
include('Crypt/RSA.php');
$rsa = new Crypt_RSA();
$rsa->setPassword('password');
$rsa->loadKey('...');
//$rsa->setPassword(); // clear the password if there was one
echo $rsa->getPrivateKey(CRYPT_RSA_PRIVATE_FORMAT_PUTTY);
?>
You have not specified, what OS you run at. On *nix, you can use PuTTYgen (from PuTTY):
puttygen openssl-key -o mykey.ppk
For details see: https://linux.die.net/man/1/puttygen
On Windows, PuTTYgen is a GUI application only. Though, you can use WinSCP, it has PuTTYgen-compatible command-line interface:
winscp.com /keygen openssl-key -o mykey.ppk
Related
Im using Gnupg to decrypt a file:
gpg --decrypt -o file.xml file.gpg
You need a passphrase to unlock the secret key for
user: "TEST-COMPANY (DAM Key) <test#test.de>"
4096-bit RSA key, ID 257C2D21, created 2018-04-23
Enter passphrase:
Then I write this passphrase and then works.
And now I want to make it automatic using this command on PHP:
$command = 'gpg --decrypt -o file.xml file.gpg'
exec($command);
The problem came when system ask for phassphrase.
I tried this:
$command = 'gpg --decrypt -o file.xml file.gpg | [Passphrase]'
but doesn't work.
Any idea about this?
Thank you
Just adding the answer that the OP and #CD001 figured out in the comments, because it helped me immensely (thanks!), and seems like a common issue (secret key was generated with passphrase, and generating new keys isn't an option). I was pulling my hair out trying to decrypt with the GnuPG functions, before learning that as of GnuPG 2.1, it can't decrypt a file with passphrase-generated key (as noted in comment here). Configuring gpg-agent with a preset passphrase may work fine, but I much prefer what the OP here did.
$encrypted_file = "file.csv.pgp";
$path_to_file = $_SERVER["DOCUMENT_ROOT"]."/dir1/dir2";
$passphrase = "passphrase";
$command = "echo {$passphrase} | gpg --passphrase-fd 0 --batch --yes {$path_to_file}/{$encrypted_file}";
exec($command);
If successful, the decrypted file will be in the same directory, without the .pgp extension. So make sure it was successful...
$decrypted_file = str_replace(".pgp", "", $encrypted_file );
if (file_exists("{$path_to_file}/{$decrypted_file}")) {
echo "Successfully decrypted $encrypted_file to $decrypted_file";
}
I try use php exec function to encrypt an given string like
exec("echo test | /usr/local/bin/gpg -e -a -r name#host.local --trust-model always", $output, $encrypted);
echo $encrypted;
That same command works fine in command line and outputs the encrypted message. But for whatever reason I get always 2 as exit code when running in PHP. I figured out that it could be a permission problem. But how to solve it? I read about setting --homedir but without success :(
BIG thanks in advance!
PS: I cannot simply use the gnupg php module…
I've setup proftpd with a tutorial in an Ubuntu Server machine with MySQL user access. Now I've created some users (user01, user02, user03) and created a cyphered password with this command:
/bin/echo "{md5}"`/bin/echo -n "mypassword" | openssl dgst -binary -md5 | openssl enc -base64`
{md5}NIGde+6ruSYKXIVLyFs+RA==
I'm not ashamed to say I did not understand anything of this command, but I would like to, and make the same command line work in a PHP code.
I know there is an OpenSSL library in PHP, but I don't really know how to get the same result.
I've found it out my self (and I feel proud about)
`//php
$dgst = openssl_digest('mypassword', 'md5', TRUE);
echo "{md5}" . base64_encode($dgst); `
This will give as result '{md5}NIGde+6ruSYKXIVLyFs+RA=='
echo base64_encode(md5('mypassword', true));
No need to even use the openssl extension.
I'm using phpseclib and need to make a couple of php functions that enable someone to programmatically ssh into their server and change the root password and also change the password of a user that may have forgotten their password (so have to be logged in as root).
I tried using libssh2, but found it a bit nasty to use. I'm now looking at phpseclib which seems more robust. But when I tried to use the 'su' command like so:
echo $ssh->exec('su');
I get the reply:
su: must be run from a terminal
and when I try to use sudo:
echo $ssh->exec('sudo passwd root');
I get the error:
sudo: no tty present and no askpass program specified
Anyway, it turns out that su is disabled for direct ssh access, but after having a look at this article, it turns out you can do it with the following command:
ssh -t -t -l 'username' 'host' 'su -'
That's what finally worked for me anyway when entering into a terminal from my laptop (running ubuntu), and then I entered my password and then the root password to finish off.
Quoting from the site linked to above:
Ssh commands (using -t) the remote sshd to establish a 'pseudo-terminal' pipe to the worker process when -t is given.
. ssh does this as long as its stdin is a terminal.
. But if ssh's stdin is a non-terminal, ssh won't direct sshd to establish a
pseudo-terminal unless TWO -t's are given:
echo password | ssh -t -t -l username remote_host
. So with -t -t (from ssh) sshd sets up a pseudo-terminal to the client process.
. The client, whether it be 'tty' or 'su' cannot tell it is connected to a ficticious >terminal:
echo dummystr | ssh -t -t -l username host.com -c ''tty'
echo password | ssh -t -t -l username host.com -c 'su -'
So there is the answer. Use double -t if you are 'su root'ing' on a linux box through an >interactive client ssh like the one from OpenBSD.
So, it actually worked from the terminal as I said above using:
ssh -t -t -l 'username' 'host' 'su -'
but I really want to be able to execute this command using phpseclib. Only thing is I don't know how to put in any flags into the exec() function. Specifically, I need to put in the -t flags (twice).
I've looked for ages and can't find anything. Be really grateful for some help on this. Sorry about the length of this post as well. :)
Cheers
Joe
If sudo passwd root requires a tty try read() / write() in phpseclib. eg.
<?php
include('Net/SSH2.php');
$ssh = new Net_SSH2('localhost', 22);
$ssh->login('username', 'password');
$ssh->read('[prompt]');
$ssh->write("sudo passwd root\n");
$ssh->read('Password:');
$ssh->write("Password\n");
echo $ssh->read('[prompt]');
?>
Actually, I'm just copy / pasting from your other post: php ssh2_exec not executing 'su' command
Looks like you were getting some help there and then stopped following up? Someone suggested you need to add new lines to your commands. Did you try that? They also suggested posting on the phpseclib support forums. Seems like a good bit of advice to me...
You can enable the pseudoterminal by calling
$ssh->enablePTY();
after you login, but before the exec. This will prevent it from complaining about the missing tty.
I looked into phpseclib's Net_SSH2 for the time being. It looks like it uses sockets to connect to the server. So there's no way to pass in -t twice. It's not an ssh call.
Since you mentioned libssh2 in your question, there's a PEAR wrapper which supports it, might make things easier, the code is only in SVN currently. The PEAR wrapper is called Net_SSH2 as well, but is different from phpseclib's Net_SSH2 (confusing).
Check out the code here:
http://svn.php.net/viewvc/pear/packages/Net_SSH2/trunk/
To download it, do an svn checkout out with:
svn co http://svn.php.net/repository/pear/packages/Net_SSH2/trunk/ ./Net_SSH2
Small example:
<?php
require_once './Net_SSH2/Net/SSH.php';
$ssh = new Net_SSH2::factory('LibSSH2', array(
'login_name' => 'user',
'password' => 'pass',
'hostname' => 'example.org',
'command' => 'su -',
));
$ssh->sshExec($std_output, $std_error);
var_dump($std_output, $std_error);
Would that help?
I'm trying to establish an interactive SSH connection to a remote server using PHP via the command line on Mac OS X 10.6. I'm currently using PHP's proc_open function to execute the following command:
ssh -t -t -p 22 user#server.com
This almost works. The -t -t options are supposed to force a pseudo terminal which they almost do. I am able to enter the SSH password and press enter. However, after pressing enter the terminal appears to simply hang. No output, no nothing - it's as if the SSH session has failed. I can't run commands or anything and have to kill the whole thing using Ctrl+C. I know the login is successful because I can execute a command like ssh -t -t -p 22 user#server.com "ls -la" and get the correct output.
I thought the problem must be related to the fact that I was using standard pipes in my proc_open call, so I replaced them with pty. I get the following error: "pty pseudo terminal not supported on this system..."
Does Mac OS X simply not support pty or pseudo terminals? (I'm pretty new at using all this shell terminology).
Here's the PHP code:
$descriptorspec = array(0 => array("pty"), 1 => array("pty"), 2 => array("pty"));
$cwd = getcwd();
$process = proc_open('ssh -t -t -p 22 user#server.com', $descriptorspec, $pipes, $cwd);
if (is_resource($process))
{
while (true)
{
echo(stream_get_contents($pipes[1]));
$status = proc_get_status($process);
if (! $status["running"])
break;
}
}
(Sorry - cannot for the life of me figure out SO's formatting instructions...)
What am I doing wrong? Why can't I use pty? Is this just impossible on Mac OS X? Thanks for your help!
You should use public key authentication rather than trying to programmatically bypass interactive password authentication.
The password prompt is supposed to be used from a tty and I believe it was made intentionally difficult to use otherwise. Also the -t -t argument only takes effect once you are connected to the remote host. And I don't believe the PHP function proc_open() can run a command inside a virtual terminal.
To setup public key authentication:
# Generate keypair
ssh-keygen -t rsa
# Copy public key to server
scp ~/.ssh/id_rsa.pub example.com:.ssh/authorized_keys
# Now you shouldn't be prompted for a password when connecting to example.com
# from this host and user account.
ssh example.com
# Since the web server (and thus PHP) probably has its own user account...
# Copy the ~/.ssh/id_rsa file somewhere else
cp ~/.ssh/id_rsa /some_path/id_rsa
# Change ownership of the file to the web server account
chown www-data:www-data /some_path/id_rsa
# Fix the file permissions (ssh ignore the keyfile if it is world readable)
chown 600 /some_path/id_rsa
# Try connecting to the server through the web server account
su -c "ssh -i /some_path/id_rsa -o UserKnownHostsFile=/some_path/known_hosts example.com" www-data
# Add the host to the known hosts file when prompted
Alternately, you could use plink (part of PuTTY for Linux) instead of OpenSSH as it can take the password on the command line plink -pw password example.com. But doing so presents a security risk as anyone who runs ps aux on the server can see the password in the process list.
There is also a program called sshpass that takes the password from an environment variable or command argument and passes it to ssh.
It looks like the problem is best solved using PHP's passthru() function. After alot more (rather painful) research I was able to issue a command through this function and could interact with the remote server through the terminal as if I had run ssh and svn export by hand (they both require passwords, therefore were good tests). What I'm going to have to do is construct a (potentially very long) string of commands separated by && and attach them to the end of the ssh command: ssh -t -t -p 22 hostname command1 && command2 ... The output will be sent to my terminal in Mac OS X even though the commands are being executed on the remote server. Looks like this is the solution I was looking for the whole time - pretty simple really! Thanks to everyone who helped me with this. I gave Alexandre the "green checkmark" because he was the only one who kept responding and was quite helpful in deducing the final answer to the problem. Thanks Alexandre!
This is old, but for any googlers out there, here is an actual solution using proc_open:
Pty descriptors are available in PHP, but have to be configured during compilation (see this 10yr old bug report https://bugs.php.net/bug.php?id=33147)
But in python however, we don't have that problem. So instead of running the ssh command directly, run this python script:
import sys
import pty
args = " ".join(sys.argv[1:])
pty.spawn(['/usr/bin/ssh', args])
About pty.spawn from python docs:
Spawn a process, and connect its controlling terminal with the current
process’s standard io. This is often used to baffle programs which
insist on reading from the controlling terminal.
Have you tried the PHP SSH2 extension?
Have you tried phpseclib, a pure PHP SSH implementation?:
<?php
include('Net/SSH2.php');
$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('username', 'password')) {
exit('Login Failed');
}
echo $ssh->read('username#username:~$');
$ssh->write("ls -la\n");
echo $ssh->read('username#username:~$');
?>
I wrote a ssh client on php with ssh2 extension, you can take a look to the source code on the github page https://github.com/roke22/PHP-SSH2-Web-Client
Please send some feedback.