I built this deployment script which runs when my debian 6.0 server is deployed. I have shown it here before (this is a linode stackscript incase anyone else is wondering):
#!/bin/bash
#
# Install PostgreSQL
#
# Copyright (c) 2010 Filip Wasilewski <en#ig.ma>.
#
# My ref: http://www.linode.com/?r=aadfce9845055011e00f0c6c9a5c01158c452deb
function postgresql_install {
aptitude -y install postgresql postgresql-contrib postgresql-dev libpq-dev
}
function postgresql_create_user {
# postgresql_create_user(username, password)
if [ -z "$1" ]; then
echo "postgresql_create_user() requires username as the first argument"
return 1;
fi
if [ -z "$2" ]; then
echo "postgresql_create_user() requires a password as the second argument"
return 1;
fi
echo "CREATE ROLE $1 WITH LOGIN ENCRYPTED PASSWORD '$2';" | sudo -i -u postgres psql
}
function postgresql_create_database {
# postgresql_create_database(dbname, owner)
if [ -z "$1" ]; then
echo "postgresql_create_database() requires database name as the first argument"
return 1;
fi
if [ -z "$2" ]; then
echo "postgresql_create_database() requires an owner username as the second argument"
return 1;
fi
sudo -i -u postgres createdb --owner=$2 $1
}
postgresql_install
postgresql_create_user(username, password)
postgresql_create_database(dbname, username)
I deployed my server with this script, which was built on top of Filip's version, but then when I try to see if postgresql is running by typing pg_ctl it says command not found.
Where I have I gone wrong on this? Since it deploys when the server runs I am not able to see where it is going wrong.
As people say it looks like you don't have the PostgreSQL bin directory on your path. In my experience on Ubuntu with PostgreSQL 9.1/9.2 on install from apt, the postgres user is created but it doesn't properly set up your environment, so pg_ctl and initdb etc are not on your PATH.
I can't see what PostgreSQL version you're using, but my 9.1 & 9.2 instances store the binaries in /usr/lib/postgresql/9.2/bin
Check that directory to see if it contains pg_ctl and other binaries. If it does,
try running:
export PATH=$PATH:/usr/lib/postgresql/9.2/bin
and see if that allows you to run pg_ctl. If so, you'll need to execute that at login from .bashrc or similar
Related
I am creating a restricted user without shell for port forwarding only and I need to execute a script on login via pubkey, even if the user is connected via ssh -N user#host which doesn't asks SSH server for a shell.
The script should warn admin on connections authenticated with pubkey, so the user connecting shouldn't be able to skip the execution of the script (e.g., by connecting with ssh -N).
I have tried to no avail:
Setting the command at /etc/ssh/sshrc.
Using command="COMMAND" in .ssh/authorized_keys (man authorized_keys)
Setting up a script with the command as user's shell. (chsh -s /sbin/myscript.sh USERNAME)
Matching user in /etc/ssh/sshd_config like:
Match User MYUSERNAME
ForceCommand "/sbin/myscript.sh"
All work when user asks for shell, but if logged only for port forwarding and no shell (ssh -N) it doesn't work.
The ForceCommand option runs without a PTY unless the client requests one. As a result, you don't actually have a shell to execute scripts the way you might expect. In addition, the OpenSSH SSHD_CONFIG(5) man page clearly says:
The command is invoked by using the user's login shell with the -c option.
That means that if you've disabled the user's login shell, or set it to something like /bin/false, then ForceCommand can't work. Assuming that:
the user has a sensible shell defined,
that your target script is executable, and
that your script has an appropriate shebang line
then the following should work in your global sshd_config file once properly modified with the proper username and fully-qualified pathname to your custom script:
Match User foo
ForceCommand /path/to/script.sh
If you only need to run a script you can rely on pam_exec.
Basically you reference the script you need to run in the /etc/pam.d/sshd configuration:
session optional pam_exec.so seteuid /path/to/script.sh
After some testing you may want to change optional to required.
Please refer to this answer "bash - How do I set up an email alert when a ssh login is successful? - Ask Ubuntu" for a similar request.
Indeed in the script only a limited subset on the environment variables is available:
LANGUAGE=en_US.UTF-8
PAM_USER=bitnami
PAM_RHOST=192.168.1.17
PAM_TYPE=open_session
PAM_SERVICE=sshd
PAM_TTY=ssh
LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
PWD=/
If you want to get the user info from authorized_keys this script could be helpful:
#!/bin/bash
# Get user from authorized_keys
# pam_exec_login.sh
# * [ssh - What is the SHA256 that comes on the sshd entry in auth.log? - Server Fault](https://serverfault.com/questions/888281/what-is-the-sha256-that-comes-on-the-sshd-entry-in-auth-log)
# * [bash - How to get all fingerprints for .ssh/authorized_keys(2) file - Server Fault](https://serverfault.com/questions/413231/how-to-get-all-fingerprints-for-ssh-authorized-keys2-file)
# Setup log
b=$(basename $0| cut -d. -f1)
log="/tmp/${b}.log"
function timeStamp () {
echo "$(date '+%b %d %H:%M:%S') ${HOSTNAME} $b[$$]:"
}
# Check if opening a remote session with sshd
if [ "${PAM_TYPE}" != "open_session" ] || [ $PAM_SERVICE != "sshd" ] || [ $PAM_RHOST == "::1" ]; then
exit $PAM_SUCCESS
fi
# Get info from auth.log
authLogLine=$(journalctl -u ssh.service |tail -100 |grep "sshd\[${PPID}\]" |grep "${PAM_RHOST}")
echo ${authLogLine} >> ${log}
PAM_USER_PORT=$(echo ${authLogLine}| sed -r 's/.*port (.*) ssh2.*/\1/')
PAM_USER_SHA256=$(echo ${authLogLine}| sed -r 's/.*SHA256:(.*)/\1/')
# Get details from .ssh/authorized_keys
authFile="/home/${PAM_USER}/.ssh/authorized_keys"
PAM_USER_authorized_keys=""
while read l; do
if [[ -n "$l" && "${l###}" = "$l" ]]; then
authFileSHA256=$(ssh-keygen -l -f <(echo "$l"))
if [[ "${authFileSHA256}" == *"${PAM_USER_SHA256}"* ]]; then
PAM_USER_authorized_keys=$(echo ${authFileSHA256}| cut -d" " -f3)
break
fi
fi
done < ${authFile}
if [[ -n ${PAM_USER_authorized_keys} ]]
then
echo "$(timeStamp) Local user: ${PAM_USER}, authorized_keys user: ${PAM_USER_authorized_keys}" >> ${log}
else
echo "$(timeStamp) WARNING: no matching user in authorized_keys" >> ${log}
fi
I am the author of the OP; I came to the conclusion that what I need to achieve is not possible using SSH only to the date (OpenSSH_6.9p1 Ubuntu-2, OpenSSL 1.0.2d 9 Jul 2015), but I found a great piece of software that uses encrypted SPAuthentication to open SSH port and it's new version (to the date of this post, it's GitHub master branch) has a feature to execute a command always that a user authorizates successfully.
FWKNOP - Encrypted Single Packet Authorization
FWKNOP set iptables rules that allow access to given ports upon a single packet encrypted which is sent via UDP. Then after authorization it allow access for the authorized user for a given time, for example 30 seconds, closing the port after this, leaving the connection open.
1. To install on an Ubuntu linux:
The current version (2.6.0-2.1build1) on Ubuntu repositories to the date still doesn't allow command execution on successful SPA; (please use 2.6.8 from GitHub instead)
On client machine:
sudo apt-get install fwknop-client
On server side:
sudo apt-get install fwknop-server
Here is a tutorial on how to setup the client and server machines
https://help.ubuntu.com/community/SinglePacketAuthorization
Then, after it is set up, on server side:
Edit /etc/default/fwknop-server
Change the line START_DAEMON="no" to START_DAEMON="yes"
Then run:
sudo service fwknop-server stop
sudo service fwknop-server start
2. Warning admin on successful SPA (email, pushover script etc)
So, as stated above the current version present in Ubuntu repositories (2.6.0-2.1build1) cannot execute command on successful SPA. If you need this feature as of the OP, but it will be released at fwknop version (2.6.8), as can it is stated here:
https://github.com/mrash/fwknop/issues/172
So if you need to use it right now you can build from github branch master which have the CMD_CYCLE_OPEN option.
3. More resources on fwknop
https://help.ubuntu.com/community/SinglePacketAuthorization
https://github.com/mrash/fwknop/ (project on GitHub)
http://www.cipherdyne.org/fwknop/ (project site)
https://www.digitalocean.com/community/tutorials/how-to-use-fwknop-to-enable-single-packet-authentication-on-ubuntu-12-04 (tutorial on DO's community)
I am the author of the OP. Also, you can implement a simple logwatcher as the following written in python3, which keeps reading for a file and executes a command when line contains pattern.
logwatcher.python3
#!/usr/bin/env python3
# follow.py
#
# Follow a file like tail -f.
import sys
import os
import time
def follow(thefile):
thefile.seek(0,2)
while True:
line = thefile.readline()
if not line:
time.sleep(0.5)
continue
yield line
if __name__ == '__main__':
logfilename = sys.argv[1]
pattern_string = sys.argv[2]
command_to_execute = sys.argv[3]
print("Log filename is: {}".format(logfilename))
logfile = open(logfilename, "r")
loglines = follow(logfile)
for line in loglines:
if pattern_string in line:
os.system(command_to_execute)
Usage
Make the above script executable:
chmod +x logwatcher.python3
Add a cronjob to start it after reboot
crontab -e
Then write this line there and save it after this:
#reboot /home/YOURUSERNAME/logwatcher.python3 "/var/log/auth.log" "session opened for user" "/sbin/myscript.sh"
The first argument of this script is the log file to watch, and the second argument is the string for which to look in it. The third argument is the script to execute when the line is found in file.
It is best if you use something more reliable to start/restart the script in case it crashes.
My rvm is not working, probably due to an error. When I open new console, it says:
-bash: /Users/amorfis/.rvm/scripts/cd: line 14: syntax error near unexpected token `('
-bash: /Users/amorfis/.rvm/scripts/cd: line 14: ` cd() { __zsh_like_cd cd "$#" ; }'
It's hard to say where the script .rvm/scripts/cd is called. When I remove this line from ~/.bash_profile:
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*
there is no error. But when I issue source $HOME/.rvm/scripts/rvm... still there is no error.
My system is Mac OS X 10.9.4
rvm --version:
rvm 1.25.29 (stable) by Wayne E. Seguin <wayneeseguin#gmail.com>, Michal Papis <mpapis#gmail.com> [https://rvm.io/]
UPDATE
Other scripts in ~/.rvm/scripts:
alias
aliases
autolibs
base
cd
cleanup
cli
completion
cron
db
disk-usage
docs
env
extras
fetch
fix-permissions
functions
gemsets
group
hash
help
hook
info
initialize
install
irbrc
irbrc.rb
list
maglev
manage
migrate
monitor
mount
notes
osx-ssl-certs
override_gem
patches
pkg
prepare
repair
requirements
rtfm
rubygems
rvm
set
snapshot
tools
upgrade
version
wrapper
zsh
My ~/.bash_profile looks like this:
#...not important stuff
source ~/.bashrc
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*
And in my ~/.bashrc I have this line (and few others):
[ -s "/Users/amorfis/.scm_breeze/scm_breeze.sh" ] && source "/Users/amorfis/.scm_breeze/scm_breeze.sh"
When I remove this line, the error is also gone. And again, it still doesn't show when I run source ~/.scm_breeze/scm_breeze.sh
Scm breeze is installed from here: https://github.com/ndbroadbent/scm_breeze
In source ~/.scm_breeze/scm_breeze.sh there is such piece of code:
if ! type ruby > /dev/null 2>&1; then
echo "Now in if"
# If Ruby is not installed, fall back to the
# slower bash/zsh implementation of 'git_status_shortcuts'
source "$scmbDir/lib/git/fallback/status_shortcuts_shell.sh"
fi
I expected the "if" statement is the problem. So I did this. Added such code before the if:
echo "Now lets try"
if ! type ruby > /dev/null 2>&1; then
echo "trying"
fi
echo "tried"
and inside if, as the first line in the block:
echo "Now in if"
This was the output:
Now lets try
tried
-bash: /Users/amorfis/.rvm/scripts/cd: line 14: syntax error near unexpected token `('
-bash: /Users/amorfis/.rvm/scripts/cd: line 14: ` cd() { __zsh_like_cd cd "$#" ; }'
So it looks like scm_breeze.sh is ok. The problem must be in .rvm, but only when scm_breeze.sh is run.
UPDATE 2:
The beginning of the .rvm/scripts/cd script looks like this:
#!/usr/bin/env bash
# Source a .rvmrc file in a directory after changing to it, if it exists. To
# disable this feature, set rvm_project_rvmrc=0 in /etc/rvmrc or $HOME/.rvmrc
case "${rvm_project_rvmrc:-1}" in
1|cd)
# clonned from git#github.com:mpapis/bash_zsh_support.git
source "$rvm_scripts_path/extras/bash_zsh_support/chpwd/function.sh"
# not using default loadign to support older Zsh
[[ -n "${ZSH_VERSION:-}" ]] &&
__rvm_version_compare "$ZSH_VERSION" -gt 4.3.4 ||
{
cd() { __zsh_like_cd cd "$#" ; }
popd() { __zsh_like_cd popd "$#" ; }
pushd() { __zsh_like_cd pushd "$#" ; }
}
I'd add this in as a comment, but I don't have the reputation to do so. I tried the answer from blob, but it didn't work.
I don't see the "scm_breeze-line", that Riaan Burger was talking about. Has anyone figured out an answer to this?
My error is pretty much the same:
/Users/myusername/.rvm/scripts/cd:14: defining function based on alias `cd' [ruby-2.3.3]
/Users/myusername/.rvm/scripts/cd:14: parse error near `()'
and line #14 says the same:
11 [[ -n "${ZSH_VERSION:-}" ]] &&
12 __rvm_version_compare "$ZSH_VERSION" -gt 4.3.4 ||
13 {
14 cd() { __zsh_like_cd cd "$#" ; }
15 popd() { __zsh_like_cd popd "$#" ; }
16 pushd() { __zsh_like_cd pushd "$#" ; }
17 }
I just ran into the same problem. The solution was to ensure the scm_breeze line executes after all the rvm ones.
Hit the same problem today, but the problem had nothing to do with scm_breeze in my case. If anyone stumbled onto this answer from google or some other place, maybe it'll help you.
Shortly after switching to OSX from Win7 I've been happily modifying anything and everything without necessarily understanding what I'm doing. Amongst other things, I've edited .bashrc as root (not the one from profile, rather the one located in /etc/.bashrc) and aliased cd like that:
alias cd='cd -P'
Never had problems with it before installing RVM, so if you were as root-happy as I once was, it might be worth checking whether you left yourself such a gift in the past.
I've moved said line into ~/.bash_profile and since then RVM happily runs without errors.
So basically what I did,
Step 1) Get a clone from SCM_BREEZE :-
git clone https://github.com/scmbreeze/scm_breeze.git
Step 2) Get a reference from Author's Doc (Link for Docs) and wrote few commands inside my local git repository's terminal,
. "$HOME/.scm_breeze/scm_breeze.sh"
update_scm_breeze
gs
It will update you scm breeze from github and patch your files if any
Your Git Status Command
N you are good to go...
Hope so it would help you now :)
I am a root user and in a shell script I would like to change user to oracle than run a sql script, I tried following;
#!/bin/sh
portStatus=`lsof -ni:5060`
if [ ${#portStatus} -ne 0 ]
then
sudo -u oracle << EOF
/oracle/product/102/db/bin/sqlplus -s a513s6p4/a513s6p4 #/oracle/product/102/db/GW_EP_List.sql;
EOF
else
exit
fi
it gives me following error;
./deneme2.sh: syntax error at line 12: `end of file' unexpected
Can you please let me know what might be the problem?
Thanks,
Halit
When using here documents the closing string MUST be at the beginning of the line!
Try
#!/bin/sh
portStatus=`lsof -ni:5060`
if [ ${#portStatus} -ne 0 ]
then
sudo -u oracle << EOF
/oracle/product/102/db/bin/sqlplus -s a513s6p4/a513s6p4 #/oracle/product/102/db/GW_EP_List.sql;
EOF
else
exit
fi
You can use su. Remember get environment with su -:
COMMAND="/oracle/product/102/db/bin/sqlplus -s a51... "
su - oracle -c $COMMAND
A nice sample oracle-base site, Automating Database Startup and Shutdown on Linux Post:
case "$1" in
'start')
# Start the Oracle databases:
# The following command assumes that the oracle login
# will not prompt the user for any values
su - $ORA_OWNER -c "$ORA_HOME/bin/lsnrctl start"
su - $ORA_OWNER -c $ORA_HOME/bin/dbstart
touch /var/lock/subsys/dbora
;;
sudo -u oracle /oracle/product/102/db/bin/sqlplus -s a513s..........
You don't need EOF here. Execute your sqlplus command like above. In this case your oracle user must be a sudo user.
If oracle is a normal user
su - oracle -c "/oracle/product/102/db/bin/sqlplus -s a513s.........."
A little more about su command (From man page):
The su command is used to become another user during a login session.
Invoked without a username, su defaults to becoming the superuser.
The optional argument - may be used to provide an environment similar
to what the user would expect had the user logged in directly.
Additional arguments may be provided after the username, in which case
they are supplied to the user's login shell. In particular, an
argument of -c will cause the next argument to be treated as a command
by most command interpreters. The command will be executed by the
shell specified in /etc/passwd for the target user.
I've installed RVM in Mixed Mode and have Phusion Passenger running in stand alone mode.
I've found this init script to start my Phusion Passenger standalone server on startup: http://memcloud.com/note/show/167
Modifying only the prescribed values, it was giving me the following error, but would still run
-su: /home/myuser/.rvm/bin/rvm: No such file or directory
I ran which rvm in myuser and found out that RVM is in /usr/local/rvm/bin/rvm. So I updated the RVM variable to reflect that, and changed RVM="$USER_HOME/.rvm/bin/rvm" to RVM="/usr/local/rvm/bin/rv". Now it's giving me the following message, but it still runs.
RVM is not a function, selecting rubies with 'rvm use ...' will not work.
Not really sure if it's a problem if the system is running, but I'd just like to be sure.
I would say this script is wrong, you should use something more like this:
#!/usr/bin/env bash
### BEGIN INIT INFO
# Provides: my-app passenger in standalone
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/stop my-app web site
### END INIT INFO
# BEGIN MINIMAL CHANGES
USER=www-data
USER_HOME=/var/www
APP_PATH=/var/www/my-app/current
GEM_SET=ruby-1.8.7-p330#my-app
ADDRESS=127.0.0.1
PORT=3000
ENVIRONMENT=production
# END MINIMAL CHANGES
RVM="/usr/local/rvm/bin/rvm"
PASSENGER="$USER_HOME/.rvm/gems/$GEM_SET/bin/passenger"
PASSENGER="cd $APP_PATH; $RVM $GEM_SET do $PASSENGER"
CMD_START="$PASSENGER start -a $ADDRESS -p $PORT -e $ENVIRONMENT -d"
CMD_STOP="$PASSENGER stop -p $PORT"
. /lib/lsb/init-functions
case "$1" in
start)
echo "Starting myapp passenger"
echo $CMD_START
su - $USER -c "$CMD_START"
;;
stop)
echo "Stopping myapp passenger"
echo $CMD_STOP
su - $USER -c "$CMD_STOP"
;;
*)
echo "Usage: $0 start|stop" >&2
exit 3
;;
esac
you could also replace GEM_SET=. to make rvm use ruby stored in .rvmrc but this requires that $USER trusted that .rvmrc ... which could be also done in this script with:
su - $USER -c "rvm rvmrc trust $APP_PATH"
called as first line in start)
I want to make a shellscript to install Wine on a Mac
and i want the user to enter his/her password so the script can use it later on to make the installation unattended by automatically entering the password on "sudo" commands. This is what i got for now:
clear
echo Wine Installer v1.0
echo -------------------
echo by Sydcul
sleep 4
clear
echo "Please enter your OS X user password."
echo "It is needed in some parts of the installation."
read PASSWORD
echo "Wine installation starting."
echo "Please do not shut down your system."
mkdir winetmp
cd winetmp
curl -O https://distfiles.macports.org/MacPorts/MacPorts-2.0.3.tar.bz2
tar xjvf MacPorts-2.0.3.tar.bz2
cd MacPorts-2.0.3
echo $PASSWORD | ./configure && make && sudo make install
echo $PASSWORD | sudo port -v selfupdate
echo $PASSWORD | sudo port -v install xorg
echo $PASSWORD | sudo port -v install wine
rm -rf ~/winetmp
clear
echo "Wine is successfully installed and ready for use!"
But at a certain point is still asks for the password.
How can i fix this?
Honestly, I would drop all that $PASSWORD stuff and remove the sudo from all your commands. You are writing an installation script, which should be run with elevated privileges. Have your users execute your script with sudo ./installwine.sh, and then run the commands in the script without sudo. All your port -v stuff will inherit the elevated privileges.
If you'd like to offer your user a nice error message if they forget to run the script with sudo (rather than just having your first call to port fail cryptically), you could check to see if the effective user ID ($EUID) is 0, and print the error message and exit otherwise. See https://askubuntu.com/questions/30148/how-can-i-determine-whether-a-shellscript-runs-as-root-or-not.
You can prompt the user for the password for the first time and then save it in a file (and don't forget to encrypt it).
The next time when you need it you can easily read it from the same file and store it in a variable and then use this command
echo $variablename | sudo -S command
Actually I think sudo doesn't accept password from stdin (you need to specify -S parameter to enable this).
As workaround you can execute sudo su to gain root privileges for all commands.
UPD: I'm not recommend to save password to file cause it is very bad solution from security point.
UPD2: You forget about Xcode, if it is not installed this script fails on compile stage :)
Why don't you just use the custom prompt option for sudo, and let it ask for the password if it needs it?
You start by checking if they're already root or not like this:
SUDO=""
if [[ 0 == $(id -u) ]]
then
SUDO="sudo "
fi
$SUDO command 1
$SUDO command arg arg arg
and then optionally combine that with the ability to customize the sudo prompt using the -p option.
then
SUDO="sudo -p \"I need elevated access for this part. Please enter %u's password:\" "
fi
You still get control over the interface, but don't prompt for a password unless you need it. Some people may have sudo set up for nopassword operation, for example. Others might run your installer as root. Or maybe their pasword is already cached with sudo. Etc. It's best to let sudo manage prompting, possibly using an askpass program (see the -A option) if necessary.