简体   繁体   中英

SSH connections with PHP

I'm currently working on a project to make changes to the system with PHP (eg change the config file of Nginx / restarting services).

The PHP scripts are running on localhost. In my opinion the best (read: most secure) way is to use SSH to make a connection. I considering one of the following options:

Option 1: store username / password in php session and prompt for sudo

Using phpseclib with a username / password, save these values in a php session and prompt for sudo for every command.

Option 2: use root login

Using phpseclib with the root username and password in the login script. In this case you don't have to ask the user for sudo. (not really a safe solution)

<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('root', 'root-password')) {
    exit('Login Failed');
}
?>

Option 3: Authenticate using a public key read from a file

Use the PHP SSHlib with a public key to authenticate and place the pubkey outside the www root.

<?php

    $connection = ssh2_connect('shell.example.com', 22, array('hostkey' => 'ssh-rsa'));
    if (ssh2_auth_pubkey_file($connection, 'username', '/home/username/.ssh/id_rsa.pub', '/home/username/.ssh/id_rsa', 'secret')) {
        echo "Public Key Authentication Successful\n";
    } else {
        die('Public Key Authentication Failed');
    }
?>

Option 4: ?

I suggest you to do this in 3 simple steps:

First. Create another user (for example runner ) and make your sensitive data (like user/pass, private key, etc) accessible just for this user. In other words deny your php code to have any access to these data.

Second. After that create a simple blocking fifo pipe and grant write access to your php user.

Last. And finally write a simple daemon to read lines from the fifo and execute it for example by ssh command. Run this daemon with runner user.

To execute a command you just need to write your command in the file (fifo pipe). Outputs could be redirected in another pipe or some simple files if needed.

to make fifo use this simple command:

mkfifo "FIFONAME"

The runner daemon would be a simple bash script like this:

#!/bin/bash
while [ 1 ]
do
    cmd=$(cat FIFONAME | ( read cmd ; echo $cmd ) )
    # Validate the command
    ssh 192.168.0.1 "$cmd"
done

After this you can trust your code, if your php code completely hacked, your upstream server is secure yet. In such case, attacker could not access your sensitive data at all. He can send commands to your runner daemon, but if you validate the command properly, there's no worry.

:-)

Method 1

I'd probably use the suid flag . Write a little suid wrapper in C and make sure all commands it executes are predefined and can not be controlled by your php script. So, you create your wrapper and get the command from ARGV. so a call could look like this:

./wrapper reloadnginx

Wrapper then executes /etc/init.d/nginx reload .

Make sure you chown wrapper to root and chmod +s . It will then spawn the commands as root but since you predefined all the commands your php script can not do anything else as root.

Method 2

Use sudo and set it up for passwordless execution for certain commands. That way you achieve the same effect and only certain applications can be spawned as root. You can't however control the arguments so make sure there is no privilege escalation in these binaries.

You really don't want to give a PHP script full root access.

If you're running on the same host, I would suggest to either directly write the configuration files and (re)start services or to write a wrapper script.

The first option obviously needs a very high privilege level, which I would not recommend to do. However, it will be the most simple to implement. Your other named options with ssh do not help much, as a possible attacker still may easily get root privileges

The second option is way more secure and involves to write a program with high level access, which only takes specified input files, eg from a directory. The php-script is merely a frontend for the user and will write said input files and thus only needs very low privileges. That way, you have a separation between your high- and low privileges and therefore mitigate the risk, as it is much easier to secure a program, with which a possible attacker may only work indirectly through text files. This option requires more work, but is a lot more secure.

You can extend option 3 and use SSH Keys without any library

$command = sprintf('ssh -i%s -o "StrictHostKeyChecking no" %s@%s "%s"',
                $path, $this->getUsername(), $this->getAddress(), $cmd );
return shell_exec( $command );

I use it quite a lot in my project. You can have a look into SSH adapter I created.

The problem with above is you can't make real time decisions (while connected to a server). If you need real time try PHP extension called SSH2 .

ps. I agree with you. SSH seams to be the most secure option.

You can use setcap to allow Nginx to bind to port 80/443 without having to run as root. Nginx only has to run as root to bind on port 80/443 (anything < 1024). setcap is detailed in this answer .

There are a few cavets though. You'll have to chown the log files to the right user ( chown -R nginx:nginx /var/log/nginx ), and config the pid file to be somewhere else other than /var/run/ ( pid /path/to/nginx.pid ).

lawl0r provides a good answer for setuid/sudo.

As a last restort you could reload the configuration periodically using a cron job if it has changed.

Either way you don't need SSH when it's on the same system.

Dude that is totally wrong.

You do not want to change any config files you want to create new files and then include them in default config files .

Example for apache you have *.conf files and include directive. It is totally insane to change default config files. That is how I do it.

You do not need ssh or anything like that.

Belive me it is better and safer if you will.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM