restart apache server by ssh command in perl php - apache

I am trying to restart the Apache server through ssh command in perl - php.
Below is code I tried. It works through PuTTY. Though if I run through browser it does not run at line : $output = $ssh->exec("systemctl status apache2");
use Net::SSH::Expect;
my $ssh = Net::SSH::Expect->new (
host => "xx.xx.xx.xx",
password=> 'adsd#21',
user => 'root',
raw_pty => 1
);
print("\n");
my $output = $ssh->login();
print($output);
if ($output !~ /Welcome/) {
die "Login has failed. Login output was $login_output";
}
$output = $ssh->exec("systemctl status apache2");
The Error:
"WARNING: terminal is not fully functional"

Though Net::SSH is an elegant module, I would suggest using the system tools available to you by default.
You have ssh available and using ssh-keys are more secure, especially due to the fact that you currently display passwords in a script. If you are unsure of how to setup ssh-keys, let me know and I will add it to the answer.
Effectively your entire script can purely be:
use strict;
use warnings;
my $apache_status = `ssh username\#servername systemctl status apache2`;
print $apache_status;

Related

Connect via ssh with a single .bat script to multiple Adresses

I have a environment of 27 Mikrotik Routers and I want to add a user on each one with same credentials.
Normally I had to connect on every Router and click through the GUI to add the user, but now I found a way to use SSH connection via cmd.
I wrote this - which connects on a single Router and performs the Add-User process
ssh admin#10.1.2.3 -password "Passw0rd!" "user add name=customer-support password=#F0ry0u! group=full"
But now I want to make a script which maybe reads in a csv file with the ip adresses of all the routers I want to perform the change on and connect on each Router to execute the command.
Is this possible?
Since SSH is available for MikroTik router, you can indeed read their addresses from a file.
For example, use bash (which you can execute even on Windows through WSL/WSL2 or Git for Windows which includes a MinGW bash)
See for example "Bash Read Comma Separated CSV File on Linux / Unix", here adapted to your case
#!/bin/bash
# Purpose: Read Comma Separated CSV File
# Author: Vivek Gite under GPL v2.0+
# ------------------------------------------
INPUT=data.cvs
OLDIFS=$IFS
IFS=','
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read maddress
do
echo "Address : $maddress"
# do your SSH call here
done < $INPUT
IFS=$OLDIFS
But if you really need a bat script, see for instance "Help in writing a batch script to parse CSV file and output a text file".

How to check SSH credentials are working or not

I have a large number of devices around 300
I have different creds to them
SSH CREDS, API CREDS
So as I cannot manually SSH to all those devices and check the creds are working or not
I am thinking of writing a script and pass the device IP's to the script and which gives me as yes as a result if the SSH creds are working and NO if not working.
I am new to all this stuff! details will be appreciated!
I will run this script on a server from where I can ssh to all the devices.
Your question isn't clear as to what sort of credentials you use for connecting to each host: do all hosts have the same connection method, for instance?
Let's assume that you use ssh's authorised keys method to log in to each host (i.e. you have a public key on each host within the ~/.ssh/authorized_keys file). You can run ssh with a do nothing command against each host and look at the exit code to see if the connection was successful.
HOST=1.2.3.4
ssh -i /path/to/my/private.key user#${HOST} true > /dev/null 2>&1
if [ $? -ne 0]; then echo "Error, could not connect to ${HOST}"; fi
Now it's just a case of wrapping this in some form of loop where you cycle through each host (and choose the right key for each host, perhaps you could name each private key after the name or IP address of the target host). The script will go out all those hosts for which a connection was not possible. Note that this script assumes that true is available on the target host, otherwise you could use ls or similar. We pipe all output to /dev/null/ as we're only interested in the ability to connect.
EDIT IN RESPONSE TO OP CLARIFICATION:
I'd strongly recommend not using username/password for login, as the username and password will likely be held in your script somewhere, or even in your shell history, if you run the command from the command line. If you must do this, then you could use expect or sshpass, as detailed here: https://srvfail.com/how-to-provide-ssh-password-inside-a-script-or-oneliner/
The ssh command shown does not spawn a shell, it literally logs in to the remote server, executes the command true (or ls, etc), then exits. You can use the return code ($? in bash) to check whether the command executed correctly. My example shows it printing out an error message for non-zero return codes, but to print out YES on successful connection, you could do this:
if [ $? -eq 0]; then echo "${HOST}: YES"; fi

Why am I getting a "permission denied" error with this Perl CGI script?

I am trying to make a Perl script that takes a remote host's IP address when they visit a certain website. However I can't seem to get past this apache error:
Permission denied at path_to_perl_script line 19
I am running a website on an Ubuntu server and I have configured Apache2 and CGI properly.
Here is the login.pl script:
#!/usr/bin/perl -T
use CGI;
use DBI;
use strict;
use warnings;
use Path::Class;
use autodie;
# read the CGI params
my $cgi = CGI->new;
my $username = $cgi->param("username");
my $password = $cgi->param("password");
my $port = $cgi->remote_host();
my $dir = dir("var/www/html");
my $file = dir->file("testingPerl.txt");
my $file_handle = $file->openw();
$file_handle->print($port);
I am fairly new to Perl and I don't quite understand why I am getting this error.
You are getting a "permission denied" error because of this statement:
my $dir = dir("var/www/html");
The path var/www/html is relative to the script's current working directory and it is unlikely that it exsits. What you likely want is /var/www/html.
However, your script runs with the privileges of the user id under which the web server is running. In normal configurations, that user often is not allowed to write to /var/www/html. So, fixing that may not fix your problem.
Further, note that you don't need or want autodie if you use Path::Class or Path::Tiny: They both croak on error.
You can try this simple script to see if everything is working:
#!/path/to/perl -T
use strict;
use warnings;
use CGI;
my $cgi = CGI->new;
print $cgi->header('text/plain'), $cgi->remote_host, "\n";
Finally, it looks like you are going to overwrite the output file for each visitor.

Apprtc with coturn STUN/TURN server

Simply, I am going run locally popular example of WEBRTC app:
github.com/webrtc/apprtc
The apprtc installed, and even works locally without turn server ( "Same origin policy" don't allow use Google TURN server, which works only from apprtc.appspot.com: access-control-allow-origin:"https://apprtc.appspot.com").
But I know that in real internet world (nats and firewalls) I need turn server. So I have decided to use own STUN/TURN server:
code.google.com/p/coturn/
I am trying integrate my apprtc with coturn:
+apprtc: http://localhost:8080/?wstls=false
+coturn: http://localhost: 3478
and I have questions:
a) Do I need execute some turnadmin commands, which are described in INSTALL guide?
Or it will be enaugh to run turnserver from example:
my_name#my_machine:~/WEBRTC/turnserver-4.4.5.2/examples/scripts/restapi$ ./secure_relay_secret.sh
which contains:
if [ -d examples ] ; then
cd examples
fi
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
export DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}:/usr/local/lib/:/usr/local/mysql/lib/
PATH="./bin/:../bin/:../../bin/:${PATH}" turnserver -v --syslog -a -L 127.0.0.1 -L ::1 -E 127.0.0.1 -E ::1 --max-bps=3000000 -f -m 3 --min-port=32355 --max-port=65535 --use-auth-secret --static-auth-secret=logen --realm=north.gov --cert=turn_server_cert.pem --pkey=turn_server_pkey.pem --log-file=stdout -q 100 -Q 300 --cipher-list=ALL $#
b) When I open localhost: 3478 in browser I see:
"TURN Server
use https connection for the admin session:
What uri is for rest API?
c) In rest API I need pass some parameters: username and key. Is it enough?
Will be enough to simply add extra -u switch to turnserver command? Need I some extra configurations?
e) How solve "Same origin policy"? I am not going experiment with the same ports and nginx, but simply set "access-control-allow-origin" header to turnserver response. How do it without nginx proxy? Or maby some others solutions?
d) Are some other important issues, which person running apprtc app and coturn server should know?
edit
For me the most problem was thinking that Coturn has own api method which return TURN servers - but has not. So it is requird to do it myself - on own http server. Below is example in python/django:
from hashlib import sha1
import hmac
TURN_SERVER_SECRET_KEY = 'my_pass'
def get_turn_servers(request):
if 'username' not in request.GET.keys():
return HttpResponseForbidden()
unix_timestamp_tomorrow = int(time()) + (24*60*60)
new_username = str(unix_timestamp_tomorrow)+':'+request.GET['username']
hashed = hmac.new(TURN_SERVER_SECRET_KEY, new_username, sha1)
password = hashed.digest().encode("base64").rstrip('\n')
turn_udp_uri = 'turn:%s:3478?transport=udp' % settings.DOMAIN.split(':')[0] #bez portu
turn_tcp_uri = 'turn:%s:3478?transport=tcp' % settings.DOMAIN.split(':')[0]
return JsonResponse({
'username':new_username,
'password':password,
'uris':[turn_udp_uri,
turn_tcp_uri,
]
})
Helpful will be groups:
https://groups.google.com/forum/#!forum/turn-server-project-rfc5766-turn-server
https://groups.google.com/forum/#!forum/discuss-webrtc
If sombody needs webrtc in django code, please write to me.

Tcl Expect fails spawning SSH to server but SSH from command line works

I have some code that I'm using to connect to a server and perform some commands. The code is as follows:
#!/usr/bin/expect
log_file ./log_std.log
proc setPassword {oldPass newPass} {
send -- "passwd\r"
expect "* Old password:"
send -- "$oldPass\r"
expect "* New password:"
send -- "$newPass\r"
expect "* new password again:"
send -- "$newPass\r"
}
set server [lindex $argv 0]
spawn /bin/ssh perfgen#$server
# Increase buffer size to support large text responses
match_max 100000
# Conditionally expects a prompt for host authenticity
expect {
"*The authenticity of host*" {
send -- "yes\r"
}
}
What I find very strange is that when I SSH from my command line the SSH command works no problem. However, when I SSH from the shell script I get the following error:
spawn /bin/ssh perfgen#192.168.80.132
ssh: Could not resolve hostname 192.168.80.132
: Name or service not known
The same script runs against 3 servers, but 2 of the 3 servers always fail. However, if I try logging into the servers manually do do the work all three servers pass.
Any idea what might be happening here? I'm completely stumped. This code was working up until about 2 weeks ago and according to the server administrator nothing has changed on the server-side config.
Trimming any whitespace seemed to solve the issue:
set serverTrimmed [string trim $server]