Deploying, configuring, and managing lots of virtual servers on a daily basis is time consuming. As a sysadmin's to-do-list becomes overpopulated with low level tasks, he cannot spare time for higher level tasks requiring his knowledge and expertise. Hence, his full potential is lost.
In this blog post, I will recommend another way to do so with a simple example. The proposed solution is not really innovative, and it is not supposed to be a substitute for existing solutions. However, I see this method as a valid alternative since you can do one-click-configurations for simple tasks without installing or learning any other software.
The idea behind one-click-configuration
The idea behind a one-click-configuration is, upon submitting a form in PHP, if properly authenticated, you can connect to a remote instance using SSH, execute commands, open a text file, and append to/replace text in that file. As I've said there is nothing really innovative with this idea, but it can save you from a learning curve to do automation for simplest tasks. You should be able to write your own code in PHP and deploy it in a trusted server though! You are submitting your password or private key for authentication.
For experimental purposes, we are automating this blog post here. This method allows us to connect to a remote server just like we connect to an Amazon EC2 instance. You can also use languages other than PHP.
This one-click-configuration tool does the following:
- Creates public/private keypairs in server
- Grabs the private key from server and provides a link to download the key
- Adds public key to authorized keys file in the server
- Checks if private key can be used to connect to server
- Removes password requirement for sudoers
- Disables plain text password logins
- Works for multiple operating systems: Ubuntu 14.04/16.04 and CentOS 7
Simplest bootstrap theme
For user interface, just use the simplest bootstrap theme to obtain something looking like this:
This user interface contains fields for you to type ip address, port number, username, and password for your remote instance, as well as an operating system selector. For different operating systems, we need to customize the code a little.
What's happening in the backend?
This section explains what is happening in the backend. I use phpseclib library to connect to a server via SSH and sFTP.
According to requirements of different operating systems, our code changes a little bit. Sometimes you will have to do something like this:
if($system == "ubuntu1404" || $system == "ubuntu1604") .. else if($system == "centos7") ..
After an SSH command is sent, we wait to read for an expected string. For example, in order to create keys,
$ssh->write("ssh-keygen -t rsa\n"); $ssh->read('/.ssh/id_rsa):'); $ssh->write("\n"); $ssh->read('Enter passphrase (empty for no passphrase):'); $ssh->write("\n"); $ssh->read('Enter same passphrase again:'); $ssh->write("\n"); $ssh->read($expectedStr.'$');
where the variable expectedStr is set to
$expectedStr = ":~"; //For Ubuntu if($system == "centos7") $expectedStr = "]";
As you see, expectedStr can differ according to the underlying operating system.
In order to retrieve the private key from server, an sFTP connection is used:
$sftp = new Net_SFTP($ip,$port); if (!$sftp->login($username, $password)) exit("Login Failed"); $date = new DateTime(); $keyname = md5($ip."".$port."".$date->getTimestamp()); $sftp->get('.ssh/id_rsa', 'temp/'.$keyname);
To run a command requiring password authorization:
$ssh->write("sudo service ssh restart\n"); //For Ubuntu $ssh->read(':'); $ssh->write($password."\n"); $ssh->read($expectedStr.'$');
To append a line at the end of a text file:
$ssh->write("echo 'PasswordAuthentication no' | sudo tee --append /etc/ssh/sshd_config\n"); $ssh->read($expectedStr.'$');
To find and change a line in a text file:
$ssh->write("sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config\n"); $ssh->read($expectedStr.'$');
Echo sexy text outputs for debugging
I like to color code my text outputs I use for debugging or informative purposes. You can use bootstrap theme's paragraph styles for this purpose.
echo "<p class='text-info'>Initiating remote connection with ".$host."</p>"; $ssh = new Net_SSH2($ip,$port); if (!$ssh->login($username, $password)) exit("<p class='text-danger'>Login failed</p>"); .. echo "<p class='text-warning'>Do not forget to download your private key file before closing this page.</p>";
Outputs will look like this:
What do you think of this post? What are other alternative methods? Let me know by commenting below.