I must create a Shell that when a user logs in, it will print on the terminal from which the connection was made how many users are logged in an their number of processes.
The second part ( the one with processes ) was easy, thanks you the following command
ps hax -o user | sort | uniq -c
But I can't go any further. I don't know how to automatically launch this script for every user, and even more, how to write on their terminal. ( I fount commands like msg, write but all require me to insert the username)
Your command ps hax -o user | sort | uniq -c does not show count of processes of logged in users but of every user (including system accounts) not necessarily currently logged in.
List of only logged in users can be get with who command.
To get count of processed per logged in user one can try:
for u in `who -u | cut -f1 -d' ' | sort -u`; do echo -n "$u "; ps hx -u $u | wc -l; done;
Message displayed on users terminal only at login time is set in /etc/motd test file. This is static file. What you need is dynamically generated motd file. This can be achieved with update-motd.
On Ubuntu/Debian update-motd configuration scripts can be found in /etc/update-motd.d/
I'm not sure if similar feature is available on RedHat like systems but you can search for update-motd or dynamic motd.
If you want the message to appear only each time the user opens the terminal, you can edit /etc/bash.bashrc and include the .sh script from there. This file basically contains commands that get executed every time a terminal is opened.
Related
I am a beginner in bash scripting and I have created a bash script to add users and remove users on Linux.
But since I am facing some issues with the script not really major issues but would be helpful if anyone could point me how to improve the script and the worst practice I am doing the script would be helpful
however the problem I have noticed is that the script takes -a to add a user -d to remove user and -h to get help the -a flag as 2 optional arguments -p for password and -s for shell so the command would be
./useradd.sh -a user -p password -s shell
this works as expected and the user is added to the system but the problem I am facing is that if I do not enter -a flag and specify the -s and -p flag the script is just exited I want to show a clear idea to the user why it exited and there is so many such errors I am assuming but I have not tested it out so much any help would be appreciated, so here is my script
https://github.com/abhijith7025/bash_scripts/blob/master/useradd.sh
... I have created a bash script to add users and remove users on Linux.
You might want to reconsider this, given that Linux has separate commands for these two operations.
There's a lot more to creating a user than there is is getting rid of one, so you may be asking for trouble trying to conjoin the two.
Anyway:
Your case statement has no "other" branch ("* )").
This may be why you're getting no errors when "misusing" your script.
case $opt in
a )
;;
d )
;;
h )
;;
* )
usage
exit 1
;;
esac
Other things to look out for:
useradd is, perhaps, a poor name for a script that can delete users.
You allow a shell to be specified as an argument, but you don't check to see if that exists.
It's conventional for Linux commands to operate on a "thing" or list of "things" and for that operation to be qualified by options that [usually] precede the thing(s). Thus, your script might be better invoked like this:
./manage_user -a -p password -s shell_exe user1
| | | |
| | | User name
| | Shell for User
| Password for User
Add a User
./manage_user -d user2
| |
| User name
Delete a User
Accessing the IP address of a connecting SSH client is possible via environment variables (such as SSH_CONNECTION), as described in
Find the IP address of the client in an SSH session
In a GNU screen session though, those environment variables are defined by whoever started the screen to begin with. Is there any way to also get hold of the SSH connection information, for someone who enters an already-existing screen session later, like from another host?
I can't think of a way to determine this, but this can be useful in cases where screen sessions are shared between different people, for example.
If the screen session is launched as root, you can but it won't be perfectly reliable
If two users type in the same screen window, they will both interact within the same shell. One can write a command. The other can press the <enter> key.
You have to get access to the environment variable SSH_CONNECTION (or better SSH_CLIENT) which is only possible if you are root, or if you use the same user inside the screen session.
Supposing you are root inside the screen session, you can know the last user active in a screen session by using the ps command and finding the last active session.
ps h -C screen katime -o pid,user
By using the pid, and accessing the /proc/<pid>/environ file, you can get the SSH_CLIENT variable.
sed -z '/SSH_CLIENT/p;d' /proc/`ps h -C screen katime -o pid |head -1`/environ
--> SSH_CLIENT=257.31.120.12
All of this suppose that your screen is executed as root
You can also chose to log all the active connections.
For such need, I would suggest you to store both the full list of connections and their last activity.
ps eh -C screen kstime -o pid,atime | while read pid stime; do echo -n "$stime: ";\
gawk -v 'RS=\0' -F= '$1=="SSH_CLIENT" {print $2}' /proc/$pid/environ; done
Result:
00:00:00: 257.31.120.12 61608 22
00:07:11: 258.1.2.3.4 49947 22
Note that you can also parse the result of the ps eh -C screen kstime -o args command if you find it easier.
EDIT:
This is a working Debian command to get all users currently connected to the same screen session:
find /var/run/screen/
-name $(pstree -sp $$ |sed 's/.*screen(\([0-9]*\)).*/\1/;q').*
-printf "%h\n"
| cut -f2 -d-
You can check the output of the last command that would list of all IP addresses or hostnames of all connection made if sshd is the only way to connect to server.
ec2-user]# last
ec2-user pts/0 115.250.185.183 Sun May 29 13:49 still logged in
ec2-user pts/0 115.250.140.241 Sat May 28 07:26 - 10:15 (02:48)
root pts/4 113.21.68.105 Tue May 3 10:15 - 10:15 (00:00)
Alternatively (on Linux), you can check /var/log/secure where sshd will usually log all details of all the connections made even if they don't result in successful logins.
If you're trying to support the multi-display mode ('screen -x'), then as someone said above you are likely out of luck.
One the other hand, if you could assume single-user mode, then you could create a wrapper/alias for the screen command that carries along an environment variable into screen (see 'screen -X stuff ...'); in this case you are just passing along SSH_CLIENT that will have the appropriate value.
If you can assume a given username comes from a single location (or, if more than one location, then simply choose most recent), then you can do some grep/sed on output of 'last' command.
client_ip=`last -ai | grep "still logged in" | grep "$USER " | grep -v '0.0.0.0' | tail -n 1 | sed 's/.* //g'`
echo "Hello $client_ip"
If your screen is starting usually in detached mode, then in your .screenrc, add the the following:
shell -$SHELL
Then your screen will have all the the variables.
For currently running screens that you are stuck with, simply run.
source ~/.bash_profile
Replace the path and the file name to match your environment.
I need to log ssh session of every user from the client side. I'm using the tee to do this
ssh abc#example.com | tee $(whoami).$(date).log
However, I only want to log user commands within the ssh session and skip the output of the command. For eg: If a user tailed a large file, I don't want to log the entire file.
I tried to grep for the command prompt and redirect the output to another file.
ssh abc#example.com | tee >(cat logfile) | grep "CMD_PROMPT_PATTTERN" >> $(whoami).$(date).log
But this does not work if the user changes the command prompt.
I wanted to know if there was a way to grep for linux commands from a text file.
Some related context:
I have read other posts which suggest adding a wrapper around ssh to do the logging.
But in this case, users can ssh to another host(say example2.com) from example.com and we need to log commands executed here as well from the starting host. I have also tried keystroke loggers but there is no way to distinguish commands executed by different users.
I'd appreciate any other suggestions to implement logging.
Why not tail -f user's .bash_history ? (or what shell they use), but 1st you will need to set "online" writing to it export PROMPT_COMMAND='history -a'
My problem is I need to monitor all the users that have logged on or logged out in real time. I know there is auth.log file, but I don't have permissions to it. Is there any way of displaying only the usernames and login/logout time?
To see which users are currently logged in, there are traditionally the commands who and w on Unix systems. Calling these is not restricted. Due to privacy reasons normal users should not be allowed to see when which users logged on or off.
That is the reason why what you want to do cannot be achieved properly with what is available to you. You will have to use workarounds each of which will have caveats.
The answer of Michael tries to achieve your goal by logging the list of current users (he's using ps but I would prefer who or w for this task). If this is done regularly (each minute or each hour or so) then later you can scan your log file to find out when who appeared and disappeared. I'd use it like this:
#!/bin/bash
log() {
line=$(who | cut -d' ' -f1 | sort -u)
echo "$(date): " $line # _NO_ quotes around $line!
}
while sleep 3600
do
log >> user.log
done & # do this in the background
Each hour this will log who is online into the file user.log.
You can use trace logged users with focus on running processes. Following scenario do it:
#!/bin/sh
mv current.log previous.log #Use two log file for compare users
ps aux | awk " {print $ 1}" |sort | uniq > current.log #Here unique users list
diff current.log previous.log | grep ">\|<" #comparring users lists
In result you can view next:
< avahi #logout user
> 123 #login user
> sfdfs #login user
Also, maybe the last command is what you can use.
I am trying to enforce a policy that logs an idle user out of a bash shell session, even when they are in an active process like a script-based menu, or vi session.
I have tried using "export TMOUT=x" where x is the number of seconds, but this only logs a user out if they are idle at the bash shell prompt.
Is there a bash script or any C code that I can run that will check what users have been idle for too long, and then stop all processes run by that user, and log them out?
Thanks
Ryan
in bash
w | tr -s " " | cut -d" " -f1,5 | tail -n+3
gives you a username/idletime pair for each shell. you can set up a cronjob using this information to logout the correct people.
The idletime is the time since the last keystroke directly in the shell (and not the applications).