NTP permission issue - linux

I gave everyone in my team a copy of a centos 7 virtual machine. The time can get out of sync. I found that I can manually update the time by using the command below:
[no_sudo#rolling ~]$ ntpdate pool.ntp.org
26 Apr 18:10:11 ntpdate[25928]: bind() fails: Permission denied
[no_sudo#rolling ~]$
However I can only update it as sudo. One of the commands I made for the team runs some automated testing, and uses the date.time as a name.
How can I ether automate the updating of time on the virtual machine, or alter the permissions of that service, so anyone can run it regardless or permissions.
Thanks!

"How can I ether automate the updating of time on the virtual machine"
The ntp daemon, ntpd, should take care of this. Sure it's running?
# start the ntp daemon
/etc/init.d/ntpd start
You could also add a daily or hourly entry in root's crontab that updates the time:
# To edit root's crontab
sudo crontab -e
# Add this line to run the command every day at noon (change as needed):
* 12 * * * /usr/sbin/ntpdate
"alter the permissions of that service, so anyone can run it"
This undermines the security model. However, if the users are allowed to use sudo already, you could allow password-less execution of that single executable so it won't block your script:
# To edit the sudoers file:
sudo visudo
# Then add something like this depending on the location of ntpdate:
username ALL= NOPASSWD: /usr/sbin/ntpdate

You should configure and use ntpd instead of ntpdate.

\#!/bin/sh
\#script to set the time using google - my ISP is blocking access to ntp server! major bummer!! :(
HOST="www.google.co.ke"
ping -q -c 2 $HOST > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "----\`date\`---------------------FAILURE----------------------------------"
echo "Failure: \`date\` -- $HOST is is DOWN! >>> better luck next time!"
else
echo "****\`date\`*********************BEGIN: SUCCESS*********************************"
mydateold="\`date\`"
echo "Success: \`date\` -- $HOST is UP >>> set the time!"
date -s "$(date -d "\`curl http://www.google.co.ke -v 2>&1 | grep "Date: " | awk '{ print $3 " " $5 " " $4 " " $7 " " $6 " GMT"}'\`")"
mynewdate="\`date\`"
echo "Success: \`date\` >>> Date updated: OLD DATETIME: $mydateold and NEW DATETIME:
$mynewdate"
echo "****\`date\`*********************END: SUCCESS***********************************"
fi
\#EOF
\#Powered By Slackware Linux :)

Related

Cron script to restart memcached not working

I have a script in cron to check memcached and restart it if it's not working. For some reason it's not functioning.
Script, with permissions:
-rwxr-xr-x 1 root root 151 Aug 28 22:43 check_memcached.sh
Crontab entry:
*/5 * * * * /home/mysite/www/check_memcached.sh 1> /dev/null 2> /dev/null
Script contents:
#!/bin/sh
ps -eaf | grep 11211 | grep memcached
if [ $? -ne 0 ]; then
service memcached restart
else
echo "eq 0 - memcache running - do nothing"
fi
It works fine if I run it from the command line but last night memcached crashed and it was not restarted from cron. I can see cron is running it every 5 minutes.
What am I doing wrong?
Do I need to use the following instead of service memcached restart?
/etc/init.d/memcached restart
I have another script that checks to make sure my lighttpd instance is running and it works fine. It works a little differently to verify it's running but is using the init.d call to restart things.
Edit - Resolution: Using /etc/init.d/memcached restart solved this problem.
What usually causes crontab problems is command paths. In the command line, the paths to commands are already there, but in cron they're often not. If this is your issue, you can solve it by adding the following line into the top of your crontab:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
This will give cron explicit paths to look through to find the commands your script runs.
Also, your shebang in your script is wrong. It needs to be:
#!/bin/bash
I suspect the problem is with the grep 11211 - it's not clear the meaning of the number, and that grep may not be matching the desired process.
I think you need to log the actions of this script - then you see what's actually happening.
#!/bin/bash
exec >> /tmp/cronjob.log 2>&1
set -xv
cat2 () { tee -a /dev/stderr; }
ps -ef | cat2 | grep 11211 | grep memcached
if [ $? -ne 0 ]; then
service memcached restart
else
echo "eq 0 - memcache running - do nothing"
fi
exit 0
The set -xv output is captured to a log file in /tmp. The cat2 will copy the stdin to the log file, so you can see what grep is acting upon.
Save below code as check_memcached.sh
#!/bin/bash
MEMCACHED_STATUS=`systemctl is-active memcached.service`
if [[ ${MEMCACHED_STATUS} == 'active' ]]; then
echo " Service running.... so exiting "
exit 1
else
service memcached restart
fi
And you can schedule it as cron.

how to create a script for checking if ssh is running and if not restart it

I'm running a headless system with a raspberry pi and after a while of not connecting via ssh the system will stop responding to ssh, it is not the Wi-Fi dongle falling asleep, I have checked, seeing I have a piglow running piglow-sysmon, and the part of the pi glow that monitors network activity does show activity when the pi stops responding to ssh. I found a nice script for checking if Wi-Fi is up and if not restart it, although im not that great with bash scripting, and cannot figure out how or if i can mod it to work with ssh instead of Wi-Fi, if anyone can help me mod it, or provide a small quick one, I'm using cron to run it (once I can get it modded) every few minutes
here the script I'm trying to mod
#!/bin/bash
LOGFILE=/home/pi/network-monitor.log
if ifconfig wlan0 | grep -q "inet addr:" ;
then
echo "$(date "+%m %d %Y %T") : Wifi OK" >> $LOGFILE
else
echo "$(date "+%m %d %Y %T") : Wifi connection down! Attempting reconnection." >> $LOGFILE
ifup --force wlan0
OUT=$? #save exit status of last command to decide what to do next
if [ $OUT -eq 0 ] ; then
STATE=$(ifconfig wlan0 | grep "inet addr:")
echo "$(date "+%m %d %Y %T") : Network connection reset. Current state is" $STATE >> $LOGFILE
else
echo "$(date "+%m %d %Y %T") : Failed to reset wifi connection" >> $LOGFILE
fi
fi
Try the following script. It makes a few assumptions:
1) Your account has its own ssh key in the authorized_keys file, so that "ssh localhost" essentially just gives you another shell, without prompting for a password
2) If the ssh command does not complete in three seconds, it would be safe to assume that the ssh daemon is up, but stuck for some reason:
#! /bin/bash
ssh localhost /bin/true &
sleep 3; kill -9 $!
if wait $!
then
echo Up
else
echo Down
fi
A bit crude, but should be effective. It's up to you to figure out how to restart the ssh service in an optimum way, here. Fill in the blanks.
You may also want to discard all standard error here, as it'll likely to have some unimportant noise...
If, on the other hand, this script reports that the ssh service is running, but you still can't connect from the outside, the problem is not the ssh service, but it lies elsewhere, so it's back to the drawing board for you.

How to display current time on welcome message/MOTD?

echo "Current date and time: $(date)" >> /etc/motd
The above code displays the current time that was added to /etc/motd.
I want the user to see the actual current time and date after the login. Is there a way to do this?
Rather than a one-shot time how about if the user sees the current time at each command line prompt?
Try this first from the command line prompt:
PS1="\# \w$bk"
The prompt will look like: 11:41 AM ~
More information for the user might be to add the username and local machine name with the time. With the user "DrPete" on a local machine named "LittleSorrel" the prompt:
PS1="\u on \h \# \w$bk "
Looks like: DrPete on LittleSorrel 10:34 AM ~
To reset the prompt to default to "# ":
PS1="# "
To make the prompt permanently available, add the prompt construction of your choice, i.e.,
export PS1="\# \w$bk "
To ~/.profile.
From this guide
https://ownyourbits.com/2017/04/05/customize-your-motd-login-message-in-debian-and-ubuntu/
sudo mkdir -p /etc/update-motd.d
sudo cat > /etc/update-motd.d/10date <<'EOF'
#!/bin/sh
echo
echo echo "Current date and time: $(date)"
EOF
sudo chmod a+x /etc/update-motd.d/*
It will show up in the next login.
For Centos 7 I suggest using dynamic MOTD with my updated PAM package to have update-motd.d feature from Ubuntu.
Install with:
yum install https://github.com/gdubicki/centos-pam-with-update-motd/releases/download/1.1.8-1022.3/pam-1.1.8-1022.el7.x86_64.rpm
Use with:
Delete the default static /etc/motd.
Make SSHD not show the static MOTD with lines PrintMotd no, Banner none, UsePAM yes (and optionally PrintLastLog no) in your /etc/ssh/sshd_config & reload sshd service.
Add this line to your /etc/pam.d/sshd: session optional pam_motd.so motd=/run/motd.dynamic.
Add your script to /etc/update-motd.d:
#!/bin/bash
echo "Current date and time: $(date)"
...as /etc/update-motd.d/10time file for example, with permissions to be read and executed by root.
Please see https://github.com/gdubicki/centos-pam-with-update-motd for the most up to date info.

Running bash script in cron

I have the following bash script:
!/bin/bash
# script to send simple email
#Wait 5 seconds
#sleep 05
# email subject
SUBJECT="SUBJECT"
# Email To ?
EMAIL="EMAIL"
# Email text/message
MYIP=$(curl http://ipecho.net/plain)
LASTIP=$(head -n 1 /home/ubuntu/myip.txt)
echo "Last IP:" $LASTIP
echo "Current IP:" $MYIP
#Check if IPs are the same
if [[ "$MYIP" == "$LASTIP" ]]; then
echo "IP hasn't changed. Do nothing."
else
sendemail -f $EMAIL -t $EMAIL -u $SUBJECT -m $MYIP -s smtp.gmail.com -o tls=yes -xu username -xp password
echo $MYIP > myip.txt
fi
When I try to run it in the command line, it works perfectly. The problem starts when I include it in "crontab -e" like this: "* * * * * /home/ubuntu/myip.sh".
Then it does not work. Seem to be that the sendmail is not functioning properly.
When I do a: tail -f /var/log/syslog
Sep 18 21:48:02 gpuserver sendmail[18665]: r8J1m1gO018665: from=ubuntu, size=314, class=0, nrcpts=1, msgid=<201309190148.r8J1m1gO018665#gpuserver>, relay=ubuntu#localhost
Sep 18 21:48:02 gpuserver sendmail[18665]: r8J1m1gO018665: to=ubuntu, ctladdr=ubuntu (1000/1000), delay=00:00:01, xdelay=00:00:00, mailer=relay, pri=30314, relay=[127.0.0.1] [127.0.0.1], dsn=4.0.0, stat=Deferred: Connection refused by [127.0.0.1]
Any ideas?
When you run a script from the command line you are utilizing your current environment. Cron doesn't have that info ... So what you should do from the command line is:
env > me
Then edit the script and include ./me at the start of the script. That way your cron task will run with the same environment.
When a cron prints something to stdout or stderr, cron itself tries to send a report by e-mail. Since you probably don't have system-wide e-mail configured, this is probably where the error message in syslog is coming from.
To prevent cron from sending any mail, make sure your script and any commands it spawns don't output anything to stdout or stderr. An easy way to do this is to add "&>/dev/null" to your cron line.
You can also add 'MAILTO=""' at the beginning of your crontab.
This all documented in the man pages for cron/crontab (man -k cron).

Perform action when user logs in via SSH from a particular host

I have a quesiton that puzzles me and I wonder if anyone has attempted to achieve the following:
Let's assume that this is the result of my 'last' command in a Linux environment:
root pts/1 192.168.1.10 Wed Feb 10 07:04 - 07:57 (00:52)
root pts/2 Tue Feb 9 22:00 - 00:13 (02:13)
How can I setup a particular action (say for example a modified MOTD or sending an email) if the the 'root' user has logged in from 192.168.1.10. Is there a way of capturing this information?
The second part of this question is that how can I make the above check a bit more robust - i.e. if I have the following:
mary pts/1 192.168.1.10 Wed Feb 10 07:04 - 07:57 (00:52)
bob pts/2 Tue Feb 9 22:00 - 00:13 (02:13)
Now I'd like to perform an action if the username is equal to 'mary' and the host is 192.168.1.10.
Any suggestions are welcomed.
Thank you in advance.
There's a special file /etc/ssh/sshrc where you can put some commands that will runs each time someone connect by ssh. I wrote that for you :
#!/bin/bash
mail=user#domain.tld
monitored_user=root
monitored_ip=x.x.x.x
hostname=$(hostname)
# add a welcome message:
printf >&2 "\nWelcome on $hostname $USER\n"
read -d " " ip <<< $SSH_CONNECTION
[[ $ip == $monitored_ip && $USER == $monitored_user ]] || exit 0
date=$(date "+%d.%m.%Y %Hh%M")
reverse=$(dig -x $ip +short)
mail -s "Connexion of $USER on $hostname" $mail <<EOF
IP: $ip
Reverse: $reverse
Date: $date
EOF
Put this script in a file, then put the full path of the script in /etc/ssh/sshrc
In man ssh :
/etc/ssh/sshrc :
Commands in this file are executed by ssh when the user
logs in, just before the user's shell (or command) is started. See the
sshd(8) manual page for more information.
Thanks for all your replies. Eventually I managed to find a solution which does work for the time being but it does have one flaw which I'll point out in a minute.
I have added the following to my /etc/bashrc file (or /etc/bash.bashrc whatever environment you're using):
HOST="192.168.0.1"
RHOST=`who am i | sed -n 's/.*(\([^) ]*\).*/\1/p; 1q'`
if [ "$RHOST" == "$HOST" ]; then
echo "SAY WHAT!"
#add further actions here if needed
fi
The flaw that I was talking about before may actually not be a flaw. If you're already SSH-ed into the system, and you want to SSH to a host which lives on the same IP, say ssh root#your-host who am i would then print 'your-host' but I think that's the way it should be.
Needless to say that the above sed statement can be modified so you can capture the username as well, and you can extend the if/else statement to suite your needs.
Thank you again for all your replies.
You can add something to /etc/profile or equivalent that does something depending on the value of $SSH_CLIENT.
It looks like you are using last because it reads /var/log/wtmp by default which is a record of logins. The who command also allows you to read the same file but with an interface more to your needs.
For example:
$ who --ips /var/log/wtmp | grep '^msw.*127.0.0.1'
msw pts/2 2012-10-07 15:52 127.0.0.1
msw pts/3 2012-10-07 15:55 127.0.0.1
where neither of those sessions were active, but rather historic and logged.
In ubuntu i put a script in
/etc/profile.d
and when someone(user ssh) log in, it send an email to my mail
#/etc/profile.d/run_on_loggin.sh
echo $(who i am) | mail -s 'SSH Login Notification' mymail#hotmail.com
I want to create a php file with smtp, to send email with my mail to me...
some times hotmail saved in spam...
if i have the php file i will run like this...
if i want to pass var to file php run like this...
excuse my english :3
note: i think this command run from user, be carefully if the user doen't has permission to use some command or send email.
One way would be to run a simple script periodically:
#!/bin/bash
users=$(last | sed -ne '/192\.168\.1\.10/ s/\([^ ]*\).*/\1/p')
for user in $users; do
sendmail "$user" < email.txt
done
This would pipe the last command into sed to extract a user list and save it into the variable $users. The sed command uses the -n flag so it only prints what we tell it to. First, we select lines that contain the specified IP, with the /192\.168\.1\.10/ "address". On those lines, we attempt to extract the characters before a space, and if we succeed we print the result.
Then, we can loop through the $users variable and act accordingly.
One way to call this repeatedly would be through cron, and a simpler way would be to do while true; do ./my_script.bash; sleep 60; done.

Resources