69

Access to our computer (not only to the internet) needs to be restricted for the accounts of my kids (7, 8) until they are old enough to manage this by themselves. Until then we need to be able to define the following:

  • the hours of the day when computing is o.k. (e.g. 5 - 9 pm)
  • the days of the week when computing is not o.k. (e.g. mondays to fridays)
  • the amount of time allowed per day (e.g. 2 hours)

In 11.10 all of the following that used to do the job don't work any more:

  • Timekpr: for > 11.10 no more available through the ppa.
  • Timeoutd: command line alternative, but from 11.10 removed from the repositories.
  • Gnome Nanny: Looks great but repeatedly crashes to force restarting X-server. So we can't use or recommed this program at the moment.

Are there any other alternatives?

10
  • Hmmm... if there isn't anything that does this, it would probably be easy to hack it together with shell scripts / cron jobs. Aug 21, 2010 at 2:24
  • 14
    EEK. Can't let my parents see this one. BUT, I'd get around it because I've got awesome root access. :P
    – jrg
    Oct 21, 2011 at 19:34
  • The interest is in "still being developed", but I don't think it merits a new question. Mar 9, 2013 at 19:36
  • Other than the timekpr developer promising he may or may not have time to continue development there is no such application afaik. But from my own experience I know now that we can do well (better even?) without but it then needs smart kids and smart parents.
    – Takkat
    Mar 9, 2013 at 20:10
  • @jrg or just a live usb ;) May 25, 2015 at 10:05

12 Answers 12

45
+150

Ubuntu <= 11.10 User's follow this guide for Ubuntu User's >= 11.10 read the Bottom page notice :

Yes all of those programs are out of date and all your questions are answered here and good look with your parent control.....

When we talk about forcing a user to log off, what we’re really talking about is implementing time restrictions on the account for system access or services. The easiest way I’ve found to implement time restrictions is using a plug-in module called Linux-PAM.

Pluggable Authentication Module (PAM) is a mechanism for authenticating users. Specifically, we’re going to use the pam_time module to control timed access for users to services.

Using the pam_time module, we can set access restrictions to a system and/or specific applications at various times of the day as well as on specific days or over various terminal lines. Depending on the configuration, you can use this module to deny access to individual users based on their name, the time of day, the day of week, the service they’re applying for, and their terminal from which they’re making the request.

When using pam_time, you must terminate the syntax of each line (or rule) in the /etc/security/time.conf file with a newline. You can comment each line with the pound sign [#], and the system will ignore that text until the newline.

Here’s the syntax for a rule:

services;ttys;users;times

The first field —  services — is a logic list of PAM service names.
The second field — tty — is a logic list of terminal names.
The third field — users — is a logic list of users or a netgroup of users.
The fourth field — times — indicates the applicable times.

Here’s an example of a typical set of rules:

login ; * ; !bobby ; MoTuWeThFr0800-2000
login ; * ; !root ; !Al0000-2400
http ; * ; !bobby ; MoTuWeThFr0800-2000
http ; * ; !root; !Al0000-2400

These rules restrict user bobby from logging on between the hours of 0800 and 2000, and they also restrict Internet access during these hours. Root would be able to logon at any time and browse the Internet during all times as well.

Note: The system logs errors with these rules as syslog(3).


With Ubuntu Linux, it is possible to assign to your computer time restrictions, to prevent the connection of one or more users to your system. With the time restrictions, you can, for example, limit access to the computer for your children (a kind of parental control, in short), or even protect the connection to your server during certain hours.

Manual Configuration

Understand what you will do

Throughout this tutorial, we will use PAM (Pluggable Authentication Modules, English Pluggable Authentication Modules). It allows you to control user authentication when they connect. Then, we will use the security configuration files to define logon hours allowed. These manipulations can be performed on any version of Ubuntu, and require only a simple text editor (vim, emacs, nano, gedit, kate, to name a few). Enable Restrictions hours via the PAM Module

First of all, first go to the /etc/pam.d/, where is all configurable services:

$ Ls /etc/pam.d/
atd common-account common-session gdm login ppp sudo
chfn common-auth cron gdm-autologin Other samba
chsh common-cupsys gnome-screensaver password passwd su

If we want to block the connection to the computer, we will have to change the gdm service. Edit the file so gdm and add this line of code (at the end of file):

account required pam_time.so

GDM is the login screen distributions Ubuntu, Edubuntu and Xubuntu. For Kubuntu, which uses KDE, kdm service is called, it will be the file it will open. And you're done for configuring the PAM! This will enable the control of hours on this service.

If you have a server, you probably do not have no GUI. In this case, GDM / KDM not installed and the connection will not be blocked. To prevent connection to TTY, you must modify the login of the same file, and add the same line of code than previously acknowledged. This action also applies to people who have installed a GUI and want to block access to the login screen and terminals.

Configure Access Hours

Now that the PAM service has been activated, we only have to configure access times. Open the /etc/security. Several configuration files are available:

$ Ls /etc/security/
access.conf namespace.conf pam_env.conf
group.conf namespace.init time.conf
limits.conf opasswd time.conf.bak

Edit the file time.conf. Some explanations and examples (English) introducing the. To set access schedules, copy and paste the following line of code (at the end of the file, as always):

*;*;user;scheduler

Instead of the user field, enter the login account you want to block.

If you want to block multiple users, enter their login in a row, separated by the | operator. For example, if I want to freeze the accounts of Patrick, John and Emily:

*;*;Patrick|jean|emilie;scheduler

By cons, if you want to block access to the system for all users but one in particular, use the! before the person concerned. For example, if I want access to the computer is denied to all users, except Nicolas and Xavier:

Nicolas *;*;!|xavier;scheduler

Turning now to the field zones. In this field that the selection of days and hours will be allowed connection possible. You must first specify the day of the week, using the following abbreviations:

Mo : Monday     Fr : Friday     Wd : Sa/Su
Tu : Tuesday    Sa : Saturday   wk : Mo/Tu/We/Th/Fr
We : Wenesday   Su : Sunday
Th : Thursday   Al : All Days

Be careful not to confuse the abbreviations Wk and Wd are misleading! particularly poorly identified on the Internet: you can easily find conflicting information!

Then, we specify the deadlines. These should be formatted 24H, consisting of 4 digits. For example, to restrict 3:17 p.m. to 6:34 p.m., we write: 1517-1834. To allow Marie to connect only on Tuesday, from 3:17 p.m. to 6:34 p.m., we obtain the result:

*;*;marie;Tu1517-1834

Connections outside of these hours will be banned. As for users, it is possible to use the operators | and! to indicate several times (the! then indicate that all logon hours are allowed, except those to be shown).

The two stars (wildcards) at the beginning of the line of code are, respectively, and tty services fields. Since you want to block all access to the system, it is unnecessary to specify what service or what tty you want to block. However, if you want to prevent the use of a particular service, simply specify it as the following example:

login;tty1|tty4|tty5;marie;!Wd0000-2400

Thus, the user marry can not connect to a TTY, 4 and 5 during the weekend.

Some Examples of Restrictions Schedule

mathilde is allowed to connect every day from 1:20 p.m. to 3:20 p.m. and from 4:00 p.m. to 8:30 p.m.:

*;*;mathilde;Al1320-1520|Al1600-2030

Stone, Frank and Florian are allowed to connect to 2:00 p.m. to 6:45 p.m. during the weekdays, and 2:00 p.m. to 10:15 p.m. for the weekend:

*;*;Stone|franck|florian;Wk1400-1845|Wd1400-2215

Olive is never allowed to connect. jessica can log on Wednesday from 1:00 p.m. to 4:00 p.m.:

*;*;olivier;!Al0000-2400
*;*;jessica;We1300-1600

2 different lines, for two different time for each user Expiration of a Session

When a session expires (it exceeds the time while the user is already connected), the PAM can reach the user. While mathilde connects during the hours of time allowed, it is perfectly free to exceed these hours! For this, we will use a new program: ´cron´. This application executes commands at intervals of time. In our case, we will make use of command ´skill-KILL-u´ to disconnect the user when the session expires. Handling is very simple. Simply edit the file ´/etc/crontab´. Then add the following line of code:

Minute Hour Day * * (s) root skill -KILL -u User

As before, replacing the Minute field schedules and time desired. Then fill in the day (s) by (s) day (s) banned (s), or simply type an asterisk (*) to indicate all days of the week. Finally, change the field used by the login account to be blocked, and voila!

Days do not notice the same way with the cron jobs! Here is the list of abbreviations to be used with this program:

mon : monday    fri : friday
tue : tuesday   sat : saturday
wed : wednesady sun : sunday
thu : thursday   *  : all hours

Some Examples of cron jobs (with examples of times in the previous section)

jessica can log on Wednesday from 1:00 p.m. to 4:00 p.m.

-> Disconnect: Tuesday at 4:00 p.m..

00 16 * root * wed skill -KILL -u jessica

mathilde is allowed to connect every day from 1:20 p.m. to 3:20 p.m. and from 4:00 p.m. to 8:30 p.m..

-> Disconnecting: Daily, 8:30 p.m. to 3:20 p.m. ET.

20 15 * * * root skill -KILL -u mathilde
30 20 * * * root skill -KILL -u mathilde

Stone, Frank and Florian are allowed to connect to 2:00 p.m. to 6:45 p.m. during the weekdays, and 2:00 p.m. to 10:15 p.m. for the weekend

-> Disconnect (1): Monday, Tuesday, Wednesday, Thursday and Friday, at 18:45. -> Disconnect (2): Saturday and Sunday at 10:15 p.m..

45 18    * * mon,tue,wed,thu,fri   root    skill -KILL -u stone && skill -KILL -u franck && skill -KILL -u florian
15 22    * * sat,sun               root    skill -KILL -u stone && skill -KILL -u franck && skill -KILL -u florian

The command skill-KILL-u disconnects the user from the GUI, as well as TTY. It is perfectly usable for server administrators. However, this command is immediate and the disconnection will be made without notice. It would therefore be preferable to prevent the installation of this device users of the computer or network in question!

It is possible to prevent users with a wall command launched by cron few minutes before the end of the timeframe, that will be displayed in the terminals of all users.

40 18 * * Mon,Tue,wed,thu,fri root echo "end of session in 5 minutes" | wall

To prevent users from GUI can be used in place of the wall command notify-send is in the package libnotify-bin Install X

40 18 * * Mon,Tue,wed,thu,fri stone DISPLAY=:0 notify-send "end of session in 5 minutes"

Ubuntu 11.10 User's

I've seen around user having problems with Pam and i saw alot of bug about that so Why is the reason??? is so simple Ubuntu 11.10 doens't support GDM anymore the new display manager is lightGDM the problem is the follow where store this directive account required pam_time.so i think is in /etc/pam.d/lightdm or /etc/pam.d/lightdm-autologin but bug how ???

so for just around you can check this 2 LightGdm log files :

  • /var/log/lightdm/lightdm.log
  • /var/log/lightdm/x-0.log

or run LightGdm in debug mode :

LightDM --debug

or report a bug :

ubuntu-bug lightdm

I report the Bug's here so cross your finger and wait....

4
  • 4
    This is - wow - great - I am impressed! Esp. the notify bit is very much to my liking because we don't want our kids to be kicked off without warning. That'd be too evil even for an evil dad like me ;)
    – Takkat
    Oct 21, 2011 at 17:50
  • Unfortunately with lightdm this seems not to work (bugs.launchpad.net/lightdm/+bug/880313).
    – Takkat
    Oct 23, 2011 at 11:57
  • wow, it's great and long explanation .. Oct 25, 2011 at 13:07
  • The case for openSUSE 11.4 is exactly like Ubuntu 11.10.
    – TonySalimi
    Dec 15, 2017 at 22:07
11

TimeKpr

I guess it has everything you need. Limit access time per day per user, easy gui for configuration, abitlity to bypass for a day, add some "reward time", notification of remaining time for users, etc.

The project page is here. They also have a PPA for ubuntu which you can add to your Software Sources: deb http://ppa.launchpad.net/timekpr-maintainers/ppa/ubuntu lucid main. And install via Software Center or via CLI: sudo apt-get install timekpr.

2
  • Can TimeKpr set time limits for individual applications (such as games?) Dec 7, 2012 at 16:37
  • I'm sorry, the question is from 2011, but this answer predate to 2010 ? Is this a bug?
    – Liso
    Nov 14, 2021 at 4:02
10

Auto-logoff is extremely frustrating if you are in the middle of something. It's violent, it's brutal, it's plain rude. And it doesn't matter how old you are. It's one thing when you are just computer addicted and it's very different when you are tracking time and get kicked out 5 seconds before you managed to click that submit button or save your document. I suggest you to consider using an auto-reminder instead of an auto-kicker. That will teach your kids to respect each other and allow each other to use the computer willingly.

There's even a lighter alternative. Start by tracking the amount of time that each kid spends using the computer and make the gathered data available for all of them so they can see it. This incredibly simple thing alone (applied to internet bandwidth spent) has saved my life when I was being the network admin in an office full of adults. The public stats about bandwidth usage for each computer (just the amount of bytes, not deanonymizing info like lists of visited sites etc) turned the situation from "me - the evil greedy admin against them - the poor abused office users" to "man, you downloaded 5 times more than me, that's bad!" "sorry, I downloaded indeed, I watched a lot of youtube during lunch breaks, won't do it anymore at this rate" - I was simply excluded from the confrontation scenario.

0
8

Timekpr

can be used in 11.10 running LightDM to setup restrictions for users by adding the following line to /etc/pam.d/lightdm

account required pam_time.so

We may need to remove libpam-smbpass to enable user switching until bug #835310 is fixed.

All restrictons defined in the application window work as defined in the timekpr GUI.

To display the timekpr-client icon in Unity we need to whitelist 'timekpr'in Unity panel settings, and in addition we need to add Unity to the following line in /etc/xdg/autostart/timekpr-client.desktop:

OnlyShowIn=GNOME;XFCE;KDE;Unity;

To start the countdown of the time granted we may have to start the timekpr daemon with

/etc/init.d/timekpr start

for 14.04:

A newer release/fork of timekpr was published for Ubuntu 14.04 by Eduards Bezverhijs in his ppa:mjasnik/ppa.

1
  • Great but i think is a temporary solution ... because is you are using timepkr and samba at the same time for sharing with other computers (see what ClaudeD (claude-d) wrote) about possible error....
    – hhlp
    Oct 27, 2011 at 19:11
7

I had this issue too. So I wrote the kidtimer script, which lets you define usage times and totals. The project can be found on Github at the following location:

This is how to install it and use it:

  1. Copy and paste the code into a file called kidtimer.install.

    #!/bin/bash
    # Restrict kids computer access to specific hours and total time.
    # By: Michael Groves - grover66_at_gmail_dot_com
    
    #variables
    basedir="/usr/local/kidtimer"
    configdir="/etc/kidtimer"
    Cdate=`/bin/date | awk '{ print $2" "$3 }'`
    TUI=0
    HOUR=`/bin/date +%H`
    DOW=`/bin/date +%u`
    WEEKEND="no"
    [ "$DOW" == "6" ] && WEEKEND="yes"
    [ "$DOW" == "7" ] && WEEKEND="yes"
    
    #arguments
    [ $# -eq 0 ] && TUI=1
    [ $# -eq 1 ] && COMMAND=$1
    [ $# -eq 2 ] && COMMAND=$1 && KID=$2
    [ $# -eq 3 ] && COMMAND=$1 && KID=$2 && Time=$3
    
    ################# Subroutines ##################
    ################################################
    
    go_check_install () {
    if [ ! -e $basedir ]; then
        go_initialize
    fi
    }
    
    
    go_initialize () {
    /bin/mkdir -p $basedir/time
    /bin/mkdir -p $basedir/schedule
    /bin/cp $0 /usr/local/bin/kidtimer && chmod +x /usr/local/bin/kidtimer
    echo "0 * * * *     root    /usr/local/bin/kidtimer hourly" > /etc/cron.d/kidtimer
    echo "0 0 * * *     root    /usr/local/bin/kidtimer daily" >> /etc/cron.d/kidtimer
    echo "* * * * *     root    /usr/local/bin/kidtimer check" >> /etc/cron.d/kidtimer
    echo "@reboot       root    /usr/local/bin/kidtimer daily" >> /etc/cron.d/kidtimer
    echo "@reboot       root    /usr/local/bin/kidtimer hourly" >> /etc/cron.d/kidtimer
    /bin/mkdir $configdir
    /usr/bin/touch $configdir/kid.list
    go_create_message_files
    echo "Kidtimer is now installed. Run /usr/local/bin/kidtimer to configure."
    }
    
    
    go_create_message_files () {
    cat << EOF > $basedir/send5.sh
    #!/bin/bash
    Name=\$1
    /bin/su -s /bin/bash -c 'DISPLAY=:0 /usr/bin/notify-send -i \
        /usr/share/pixmaps/gnome-set-time.png "ALERT" \
        "You will be logged out in 5 minutes."' \$Name
    EOF
    chmod +x $basedir/send5.sh
    cat << EOF > $basedir/send4.sh
    #!/bin/bash
    Name=\$1
    /bin/su -s /bin/bash -c 'DISPLAY=:0 /usr/bin/notify-send -i \
            /usr/share/pixmaps/gnome-set-time.png "ALERT" \
            "You will be logged out in 4 minutes."' \$Name
    EOF
    chmod +x $basedir/send4.sh
    cat << EOF > $basedir/send3.sh
    #!/bin/bash
    Name=\$1
    /bin/su -s /bin/bash -c 'DISPLAY=:0 /usr/bin/notify-send -i \
            /usr/share/pixmaps/gnome-set-time.png "ALERT" \
            "You will be logged out in 3 minutes."' \$Name
    EOF
    chmod +x $basedir/send3.sh
    cat << EOF > $basedir/send2.sh
    #!/bin/bash
    Name=$1
    /bin/su -s /bin/bash -c 'DISPLAY=:0 /usr/bin/notify-send -i \
            /usr/share/pixmaps/gnome-set-time.png "ALERT" \
            "You will be logged out in 2 minutes."' \$Name
    EOF
    chmod +x $basedir/send2.sh
    cat << EOF > $basedir/send1.sh
    #!/bin/bash
    Name=\$1
    /bin/su -s /bin/bash -c 'DISPLAY=:0 /usr/bin/notify-send -i \
            /usr/share/pixmaps/gnome-set-time.png "ALERT" \
            "You will be logged out in 1 minute."' \$Name
    EOF
    chmod +x $basedir/send1.sh
    cat << EOF > $basedir/logout.sh
    #!/bin/bash
    Name=\$1
    /usr/bin/pkill -KILL -u \$Name
    rm -rf /tmp/kidtimer.shutdown.\$Name
    EOF
    chmod +x $basedir/logout.sh
    cat << EOF > $basedir/schedule/blank
    #hour weekday weekend (y/n)
    00 n n
    01 n n
    02 n n
    03 n n
    04 n n
    05 n n
    06 n n
    07 n n
    08 y y
    09 y y
    10 y y
    11 y y
    12 y y
    13 y y
    14 y y
    15 y y
    16 y y
    17 y y
    18 y y
    19 y y
    20 n n
    21 n n
    22 n n
    23 n n
    #minutes weekday weekend
    MAX 120 240
    EOF
    }
    
    
    go_check () {
    for I in `cat $configdir/kid.list`; do
            /usr/bin/users | grep -q $I
            if [ $? -eq 0 ]; then
                    if [ -e $basedir/time/$I.ttl ]; then
                            C=`cat $basedir/time/$I.ttl`
                            C=$((C + 1))
                            echo $C > $basedir/time/$I.ttl
                    else
                            echo 1 > $basedir/time/$I.ttl
                            C=1
                    fi
            else
            go_clean_jobs $I
            exit 0
        fi
            # check total time.
            W="no"
            [ $DOW -eq 6 ] && W="yes"
            [ $DOW -eq 7 ] && W="yes"
            [ "$W" == "no" ] && TIME_LIMIT=`cat $basedir/schedule/$I | grep ^MAX | awk '{ print $2 }'`
            [ "$W" == "yes" ] && TIME_LIMIT=`cat $basedir/schedule/$I | grep ^MAX | awk '{ print $3 }'`
            if [ $C -ge $TIME_LIMIT ]; then
                    if [ ! -e /tmp/kidtimer.shutdown.$I ]; then
                            /usr/bin/passwd $I -l
                            go_logout $I
                    fi
            fi
    done
    }
    
    
    go_clean_jobs () {
    K=$1
    for I in `/usr/bin/atq | awk '{ print $1 }' | sort`; do
        /usr/bin/at -c $I | grep kidtimer | grep -q $K
        [ $? -eq 0 ] && /usr/bin/at -d $I
    done
    [ -e /tmp/kidtimer.shutdown.$K ] && rm -rf /tmp/kidtimer.shutdown.$K
    }
    
    
    go_daily () {
    for I in `cat $configdir/kid.list`; do
        ls -l $basedir/time/$I.ttl | grep -q "$Cdate"
        if [ ! $? -eq 0 ]; then
            echo "0" > $basedir/time/$I.ttl
        fi
    done
    }
    
    
    go_hourly () {
    if [ -s $configdir/kid.list ]; then
        for I in `cat $configdir/kid.list`; do
            if [ -e $basedir/schedule/$I ]; then
                [ "$WEEKEND" == "no" ] && TL=`cat $basedir/schedule/$I | grep ^MAX | awk '{ print $2 }'`
                [ "$WEEKEND" == "yes" ] && TL=`cat $basedir/schedule/$I | grep ^MAX | awk '{ print $3 }'`
                [ -e $basedir/time/$I.ttl ] && C=`cat $basedir/time/$I.ttl`
                [ $C -ge $TL ] && /usr/bin/passwd $I -l && exit 0
                [ "$WEEKEND" == "no" ] && R=`grep ^$HOUR $basedir/schedule/$I | awk '{ print $2 }'`
                [ "$WEEKEND" == "yes" ] && R=`grep ^$HOUR $basedir/schedule/$I | awk '{ print $3 }'`
                if [ "$R" == "y" ]; then
                    /usr/bin/passwd $I -u
                else
                    /usr/bin/passwd $I -l
                    /usr/bin/users | grep -q $I && /usr/local/bin/kidtimer shutdown $I
                fi
            fi
        done
    fi
    }
    
    
    go_logout () {
    K=$1
    echo "$basedir/send5.sh $K" | at now + 1 minutes
    echo "$basedir/send4.sh $K" | at now + 2 minutes
    echo "$basedir/send3.sh $K" | at now + 3 minutes
    echo "$basedir/send2.sh $K" | at now + 4 minutes
    echo "$basedir/send1.sh $K" | at now + 5 minutes
    echo "$basedir/logout.sh $K" | at now + 6 minutes
    touch /tmp/kidtimer.shutdown.$K
    }
    
    
    go_addtime () {
    U=$KID
    A=$Time
    if [ "$KID" == "reset" ]; then
        echo "0" > $basedir/time/$U.ttl
        echo "Done."
        exit 0
    elif [ "$KID" == "" ]; then
        echo "Error."
        echo "Syntax: addtime <user> <minutes|reset>"
        exit 1
    else    
        C=`cat $basedir/time/$KID.ttl`
        C=$((C - Time))
        echo $C > $basedir/time/$KID.ttl
        echo "New total minutes is "$C"."
        echo "Done."
    fi
    
    /usr/bin/passwd $KID -u
    }
    
    
    go_tui () {
    go_command_list
    echo -n "Choose: "; read -e X
    case "$X" in
    1) go_setup_user
            ;;
    2) go_modify_user
            ;;
    3) go_remove_user
            ;;
    4) go_list_users
        ;;
    5) exit 0
            ;;
    esac
    go_tui
    }
    
    
    go_command_list () {
    echo
    echo "1) Setup user limits."
    echo "2) Modify user limits."
    echo "3) Remove user limits."
    echo "4) List configured users."
    echo "5) Quit."
    echo
    }
    
    
    go_list_users () {
    echo
    echo "Users configured for kidtimer:"
    if [ -s $configdir/kid.list ]; then
        cat $configdir/kid.list
    else
        echo "No configured users."
    fi
    }
    
    go_setup_user () {
    echo
    echo -n "Username: "; read -e U
    /usr/bin/id $U > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        /bin/cp $basedir/schedule/blank $basedir/schedule/$U
        echo "0" > $basedir/time/$U.ttl
        echo $U >> $configdir/kid.list
        echo "Done."
        echo
        echo -n "Modify limits now ?(y/n): "; read -e M
        if [ "$M" == "y" ]; then
            if [ -e /usr/bin/nano ]; then
                        /usr/bin/nano $basedir/schedule/$U
                        echo "Done."
                else
                        /usr/bin/vi $basedir/schedule/$U
                        echo "Done."
                fi
        fi
    else
        echo "Error. User does not exist. Please create user using the useradd command first."
    fi
    }
    
    
    go_modify_user () {
    echo
    echo -n "Username: "; read -e U
    grep -q ^$U $configdir/kid.list
    if [ $? -eq 0 ]; then
        if [ -e /usr/bin/nano ]; then
            /usr/bin/nano $basedir/schedule/$U
            echo "Done."
        else
            /usr/bin/vi $basedir/schedule/$U
            echo "Done."
        fi
    else
        echo "Error. User not setup. Please setup user first."
    fi
    }
    
    
    go_remove_user () {
    echo
    echo -n "Username: "; read -e U
    grep -q ^$U $configdir/kid.list
    if [ $? -eq 0 ]; then
        grep -v ^$U $configdir/kid.list > /tmp/kidtimer.tmp
        cat /tmp/kidtimer.tmp > $configdir/kid.list
        echo "Done."
    else
        echo "Error. User is not setup."
    fi
    }
    
    
    go_help () {
    echo
    echo "Commands:"
    echo "--------------------------------------------------------------------------------"
    echo "addtime <user> <minutes> ... Increases allowed time for the day."
    echo "logout <user>            ... Starts logout sequence for user."
    echo "hourly                   ... Enables/disables user access based on the schedule."
    echo "daily                    ... Resets time for the new day."
    echo "help                     ... This list."
    echo "--------------------------------------------------------------------------------"
    }
    
    ###################### Code ####################
    ################################################
    
    go_check_install
    [ $TUI -eq 1 ] && go_tui
    
    case "$COMMAND" in
    addtime) go_addtime
        ;;
    logout) go_logout $KID
        ;;
    initialize) go_initialize
        ;;
    hourly) go_hourly
        ;;
    daily) go_daily
        ;;
    check)  go_check
        ;;
    -h) go_help
        ;;
    help) go_help
        ;;
    esac
    exit 0
    
  2. Execute it:

    sudo ./kidtimer.install
    
  3. Run it:

    sudo kidtimer
    
  4. Setup a existing user account.

  5. Done.

For help:

sudo kidtimer help

Add time to a user's account (for that day only):

sudo kidtimer addtime user minutes

Features:

  • Allow your kid specific hours of the day to access the computer, both weekday and weekend.
  • Set maximum amount of time, both weekday and weekend.

Key files:

/etc/kidtimer/kid.list
/etc/cron.d/kidtimer
/usr/local/kidtimer/schedule/<user>
/usr/local/kidtimer/time/<user>.ttl
/usr/local/bin/kidtimer

Cronjobs:

  • Check every minute to see if user is logged in. If so, increment total time. If hit max time, disable account and start logoff sequence (5 mins total).
  • Check hourly to see if user is allowed to login. If so, enable account.
  • At midnight, reset time.

Note:

The application uses notify-send to alert user time is running out. When time runs out, all user processes are terminated, so please prepare user.

5

timekpr - This program will track and control the computer usage of your user accounts. You can limit their daily usage based on a timed access duration and configure periods of day when they can or cannot log in. With this application, administrators can limit account login time duration or account access hours. The application works as a parental time control, and will be useful to parents who want to limit child access time.

Even Nedberg proposed the following answer:
Just started copying into the 11.10 version for the PPA. Should finish
in a few minutes.

You can update your system with unsupported packages from this untrusted PPA by adding ppa:timekpr-maintainers/ppa to your system's Software Sources.

deb http://ppa.launchpad.net/timekpr-maintainers/ppa/ubuntu oneiric main 
deb-src http://ppa.launchpad.net/timekpr-maintainers/ppa/ubuntu oneiric main 

This package is available in :

PROBLEM :

I report the Bug's here so cross your finger and wait....

2
  • Oh that is good news. We used to use timekpr here. Hope it will work - it's still installed on my 11.10 box, runs well but doesn't lock my kid's accounts.
    – Takkat
    Oct 24, 2011 at 21:11
  • and for 14.04 does it work?
    – rogerdpack
    Jun 23, 2014 at 14:15
3

Introduction

We can check if a user is logged in by the command:

who -u

which gives us an output like:

$ who -u
jacob    :0           2016-03-17 20:48   ?          2557 (:0)
newuser  :1           2016-03-17 20:50   ?          4466 (:1)

In the output we get the pid of the targeted user, that needs to be halted if the time exceeds the limit.

The solution

Assuming your user does not have sudo privileges:

This solution is a small background script. It limits the usage per day to a defined number of minutes, to set in the head of the script. Once set up (which is not too difficult) it runs very easy, and no additional action is needed afterwards.

To prevent unwanted data loss of possibly opened files, 60 seconds before the targeted user's time limit expires, a message will appear on his or her DISPLAY:

enter image description here

The script

#!/usr/bin/python3
import subprocess
import os
import sys
import time


#--- set the time limit below (minutes)
minutes = 120
#--- set the user name to limit below
user = "newuser"

uselog = "/opt/limit/uselog"
datefile = "/opt/limit/currdate"

def read(f):
    try:
        return int(open(f).read().strip())
    except FileNotFoundError:
        pass

def message(disp, user):
    return "DISPLAY="+disp+" su - "+user+" -c "+'"'+\
      "notify-send 'User "+user+\
      " will be logged off in 60 seconds'"+'"'


currday1 = read(datefile)

while True:
    time.sleep(10)
    currday2 = int(time.strftime("%d"))
    # check if the day has changed, to reset the used quantum
    if currday1 != currday2:
        open(datefile, "wt").write(str(currday2))
        try:
            os.remove(uselog)  
        except FileNotFoundError:
            pass
    # if the pid of the targeted process exists, add a "tick" to the used quantum
    check = subprocess.check_output(["who", "-u"]).decode("utf-8")
    pid = [l.split() for l in check.splitlines() if user in l]
    if pid:
        n = read(uselog)
        n = n + 1 if n != None else 0
        open(uselog, "wt").write(str(n))
        # when time exceeds the permitted amount, kill the process
        if n > minutes*6:
            disp = [d for d in [d[1] for d in pid] if all([":" in d, not "." in d])][0]
            subprocess.Popen(["/bin/bash", "-c", message(disp, user)])
            time.sleep(60)
            pids = [p[-2] for p in pid]
            for p in pids:
                subprocess.Popen(["kill", p])  

    currday1 = currday2

How to use

  1. On your desktop (or anywhere else), create a folder named: limit
  2. Copy the script into an empty file, save it as limit_use (no extension) inside the folder and make it executable
  3. Edit in the head of the script the user name to limit, and the maximum number of allowed minutes. In the example:

    #--- set the time limit below (minutes)
    minutes = 1
    #--- set the user name to limit below
    user = "jacob"
    
  4. Copy the folder to the directory /opt:

    cp -r /path/to/limit /opt
    
  5. Now edit /etc/rc.local to make the script run it as root on startup:

    sudo -i gedit /etc/rc.local
    

    Just before the line

    exit 0
    

    another line:

    /opt/limit/limit_use &
    

Explanation; how it works

  • Once per 10 seconds, the script looks if the targeted user is logged in. If so, it "adds" one "point" to a total usage, to be recorded in a file (/opt/limit/uselog). If the daily limit is reached, the script no longer allows the user to be logged in, kills its process if it exists.
  • On the day change (the date is recorded in a file, so reboot won't help), the log file is deleted, allowing a new amount of usage time to build up.
  • Since the script runs on boot up, from rc.local only user(s) with sudo privileges can stop the script, even then only if the user knows the process name.

Stop the script

In case you'd like to stop the script, use the command:

sudo kill "$(pgrep limit_use)"

But you'd need the sudo password to do so.

2

Lock Screen Timer

systray.gif

Create your own Screen Lock Timer instead of 3rd Party applications

Although there are 3rd Party applications to do this, you can create your own. Summary of steps:

  • Use gedit to create script lock-screen-timer
  • Copy and paste code from this window to lock-screen-timer
  • Mark lock-screen-timer as an executable
  • Test it!
  • Configure Nautilus to execute bash scripts
  • Create desktop shortcut link
  • Monitor time remaining

Use gedit to create script lock-screen-timer

Open the Terminal using Ctrl+Alt+T and type:

gedit lock-screen-timer

Copy and paste code from window below to lock-screen-timer

Toggle back to this screen and copy the following code by highlighting it and pressing Ctrl+C:

#!/bin/bash

# NAME: lock-screen-timer
# PATH: $HOME/bin
# DESC: Lock screen in x minutes
# CALL: Place on Desktop or call from Terminal with "lock-screen-timer 99"
# DATE: Created Nov 19, 2016. Last revision Nov 13, 2021.

# UPDT: Updated to support WSL (Windows Subsystem for Linux)
#       Remove hotplugtv. Replace ogg with paplay.
#       May 30 2018 - Cohesion with multi-timer. New sysmonitor indicator style.
#       Nov 13 2021 - Wrap long lines with \ continuation. Shorten comments.

# NOTE: Time defaults to 30 minutes.
#       If previous version is sleeping it is killed.
#       Zenity is used to pop up entry box to get number of minutes.
#       If zenity is closed with X or Cancel, no screen lock timer is launched.
#       Pending lock warning displayed at set intervals.
#       Write time remaining to ~/.lock-screen-timer-remaining

MINUTES="$1" # Optional parameter 1 when invoked from terminal.

# if no parameters set default MINUTES to 30
if [ $# == 0 ]; then
    MINUTES=30
fi

DEFAULT="$MINUTES" # When looping, minutes count down to zero. 
                   # Save deafult for subsequent timers.

# Check if lock screen timer already running
pID=$(pgrep -f "${0##*/}") # All PIDs matching lock-screen-timer name
PREVIOUS=$(echo "$pID" | grep -v ^"$$") # Strip out this running copy ($$$)
if [ "$PREVIOUS" != "" ]; then
    kill "$PREVIOUS"
    rm ~/.lock-screen-timer-remaining
    zenity --info --title="Lock screen timer already running" \
        --text="Previous lock screen timer has been terminated."
fi

# Running under WSL (Windows Subsystem for Linux)?
if cat /proc/version | grep Microsoft; then
    WSL_running=true
else
    WSL_running=false
fi


while true ; do # loop until cancel

    # Get number of minutes until lock from user
    MINUTES=$(zenity --entry --title="Lock screen timer" \
        --text="Set number of minutes until lock" --entry-text="$DEFAULT")

    RESULT=$? # Zenity return code
    if [ $RESULT != 0 ]; then
        break ; # break out of timer lock screen loop and end this script.
    fi

    DEFAULT="$MINUTES" # Save deafult for subsequent timers.
    if [[ $MINUTES == 0 ]] || [[ $MINUTES == "" ]]; then
        break ; # zero minutes considered cancel.
    fi

    # Loop for X minutes, testing each minute for alert message.
    (( ++MINUTES )) 
    while (( --MINUTES > 0 )); do
        case $MINUTES in 1|2|3|5|10|15|30|45|60|120|480|960|1920)
            notify-send --urgency=critical \
            --icon=/usr/share/icons/gnome/256x256/status/appointment-soon.png \
            "Locking screen in ""$MINUTES"" minute(s)." ;
            if [[ $WSL_running == true ]]; then  
                powershell.exe -c '(New-Object Media.SoundPlayer \
                "C:\Windows\Media\notify.wav").PlaySync();'
            else
               paplay /usr/share/sounds/freedesktop/stereo/complete.oga ;
            fi
           ;;
        esac;

        # Record number of minutes remaining to file other processes can read.
        echo "Lock screen in: $MINUTES Minutes" > ~/.lock-screen-timer-remaining

        sleep 60

    done

    rm ~/.lock-screen-timer-remaining # Remove countdown work file

    if [[ $WSL_running == true ]]; then  
        # Call lock screen for Windows 10
        rundll32.exe user32.dll,LockWorkStation
    else
        # Call screen saver lock for Unbuntu versions > 14.04.
        dbus-send --type=method_call --dest=org.gnome.ScreenSaver \
            /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock
    fi

done # End of while loop getting minutes to next lock screen

exit 0 # Closed dialog box or "Cancel" selected.

Then toggle back to the empty gedit window and paste the code using Ctrl+V. Save the file and exit the editor back to the command prompt.

Mark lock-screen-timer as an executable

Now we need to make the script executable by typing:

chmod +x lock-screen-timer

Test It!

Before calling the script from the GUI, we'll call it from the terminal so we can see if any error messages are displayed:

~/lock-screen-timer

You are prompted for the number of minutes:

Lock Screen Timer

Set the desired number of minutes and click OK to start the timer. When there are 15, 10, 5, 3, 2 and 1 minute(s) left a system sound is heard and a message bubble appears advising when the screen will be locked. After the screen is locked you need to enter your password to unlock the screen.

Configure Nautilus to execute bash scripts

Nautilus defines what happens when we double click on an executable script when it's the files display window or a link on on the desktop. Normal behavior is to edit the script using gedit. We want to change this behavior such that it is executed.

Start Nautilus and navigate to directory containing lock-screen-timer. Left click on it once to give it focus. Hover mouse over top menu bar until "File Edit..." menu appears, use:

  1. Click Edit drop-down menu
  2. Click Properties option
  3. Click Behavior tab
  4. Observe the radio option buttons under Executable Text Files
  5. Check radio button Run executable text files when they are opened

Create desktop shortcut link

From previous section lock-screen-timer still has focus. If not, navigate to the script and left click on it once to give it focus. Then use:

  • Right click on the file and the context-menu options appear.
  • From the menu select Make Link.
  • A new icon appears called Link to lock-screen-timer.
  • Left click on the new icon and drag it from Nautilus to your desktop.

Now you can double click on the desktop shortcut link and the script is run. A dialog box appears to get the number minutes. Two buttons are presented Cancel and OK. If you click the X to close the window it is the same as selecting Cancel.

After the timer is running and you double click on it again the first running copy is "killed". You can now start a new scren lock countdown or click Cancel for no countdown.

Display Time Remaining in systray / notification area

While lock screen timer is running it records how many minutes are remaining into the file ~/.lock-screen-timer-remaining. You can look at this file with the watch command or display it on Ubuntu's system tray / application indicator bar as shown at the top of this answer. To display time remaining in the notification area, follow the instructions in this Q&A: Can BASH display in systray as application indicator?.

2

I tried timekpr but did not got it working. Then made a variant of it which works on my Ubuntu. This is what one needs to do for this variant:

  1. Add time limit in /var/lib/timelimit/user_to_be_limited.limit file with root rights only. e.g. 1800 for 1800 seconds (30 minutes) daily limit.

  2. Create /usr/local/bin/timelimit.sh with root rights with following:

    #!/bin/bash
    
    pollTime=30
    export DISPLAY=:0
    
    while(true); do
        sleep $pollTime
        usersLogedIn=$( users|sed -e 's/\s\+/\n/g'|sort|uniq )
        for userName in $usersLogedIn; do
            if [[ -e "/var/lib/timelimit/$userName.limit" ]]
            then
                if [[ ! -e "/var/lib/timelimit/$userName.time" || `( stat -c '%z'  /var/lib/timelimit/$userName.time|cut -c9,10 )` != `date +%d` ]]
                then 
                    echo $pollTime > /var/lib/timelimit/$userName.time
                else
                    timeUsed=$(( `cat /var/lib/timelimit/$userName.time` + $pollTime ))
                    echo $timeUsed > /var/lib/timelimit/$userName.time
                fi
                if [[ `cat /var/lib/timelimit/$userName.time` -gt `cat /var/lib/timelimit/$userName.limit` ]]
                then
                    export XAUTHORITY=/home/$userName/.Xauthority
                    notify-send --icon=gtk-dialog-warning --urgency=critical -t 30000 "$userName" "You have 60 seconds left!"
                    sleep 60
                    pkill -u $userName
                fi
            fi
        done
    done
    
  3. Add to /etc/rc.local:

    sudo /usr/local/bin/timelimit.sh &
    
  4. Restart Ubuntu

2

I just made an answer available easily. Code is explained on thread http://forums.linuxmint.com/viewtopic.php?f=213&t=77687 . In short: a limit configured in minutes per day, a cron job every minute, a message to user to keep him informed and a forced logoff.

To download and install this, open a Terminal and run the commands below:

cd /tmp/
git clone https://github.com/Thomas-Baeckeroot/ParentalControl.git
cd ParentalControl/
./install.sh

Administrator password will be requested during the installation process (to install the cron job, to copy the script, …). From there you will be guided for all. There is also an ./uninstall.sh at the same place just in case. It is build to work with all Ubuntu based distro (Mint, etc… probably all debian also). If any issue occurs please let me know, including system version and graphical environment in comments:

uname -a
echo $XDG_CURRENT_DESKTOP

Thomas Baeckeroot

2

I've just released a beta version of my new application LittleBrother that is able to monitor play time on Linux machines. Test users are welcome to try the Debian package. Instructions on how to download and use it can be found here: https://github.com/marcus67/little_brother. The installation may still be a little rough, though. These are the features of the application:

  • Any number of users can be monitored.
  • Each user can have a specific set of rules defining the permitted playtime.
  • Rules can be adapted to "contexts", such as the day of the week and/or a vacation schedule (currently only the German schedules are supported).
  • Play time can be restricted to a time window (from, to).
  • A maximum play time per day can be defined.
  • Users can be forced to take a break after a certain maximum session time.
  • Users can be forced to wait for a miniumum break time after their activity.
  • Any number of Linux client hosts can be monitored (currently this requires users to have the same login on all machines).
  • There is a master host with a history of the activities of all users. This master host checks the rule sets and prompts the client hosts to terminate processes if required.
  • The master host offers a simple web interface for viewing the user activity over a configured history length (e.g. 7 days) and an administration page to dynamically define rule exceptions for a configured number of days into the future.
  • The web application can be run behind a proxy so that it will be accessible from away allowing remote administration after receiving calls from young users begging for more play time.
  • The application has international language support. Currently English and German translations are provided. Users are invited to provide translations for other languages.
  • The application uses voice generation to inform the user over impending forced logouts. Also these spoken messages are internationalized.
  • In addition to the time spent on Linux hosts the application can also monitor activity time on other devices such as smart phones or tables. It takes advantage of the fact that most modern operating systems put devices in some kind of power saving mode while they are not being used. This way, the network response (by pinging) can be used to determine the activity on those devices. In contrast to the Linux hosts, the application will not be able the terminate the activity. The play time, however, will be added to the overall playtime and hence will have an impact on the time allowed and also on the break time rules on the Linux hosts.

Some screenshots:

Status Page Administration Page

2
1

Sample parental timeout script

Create cron job with the following bash script

sudo vi /root/timeout.sh

sample script content (scheduled Monday to Friday 18:00-20:00, Saturday, Sunday 08:00-22:00 )

#!/bin/bash
#==========================================
#              Timeout script
#==========================================

# */1 * * * * /root/timeout.sh

USER="test"

TIMEOUT_USER=$(who | grep $USER)
TIMEOUT_DHM=$(date +"%u%H%M")

if [ ! -z "$TIMEOUT_USER" ] \
        && [[ ! (\
                  ($TIMEOUT_DHM -ge 11800 && $TIMEOUT_DHM -le 12200) || \
                  ($TIMEOUT_DHM -ge 21800 && $TIMEOUT_DHM -le 22200) || \
                  ($TIMEOUT_DHM -ge 31800 && $TIMEOUT_DHM -le 32200) || \
                  ($TIMEOUT_DHM -ge 41800 && $TIMEOUT_DHM -le 42200) || \
                  ($TIMEOUT_DHM -ge 51800 && $TIMEOUT_DHM -le 52200) || \
                  ($TIMEOUT_DHM -ge 60800 && $TIMEOUT_DHM -le 62200) || \
                  ($TIMEOUT_DHM -ge 00800 && $TIMEOUT_DHM -le 02200) \
                )]];
then
  echo "$(date +"%Y-%m-%d %H:%M:%S") - $USER timeout" >> /var/log/timeout.log
  skill -KILL -u $USER
fi

Edit root contab

sudo crontab -e

and add this schedule running every minute

*/1 * * * * /root/timeout.sh

restart cron and list crontab

sudo systemctl restart cron
sudo crontab -l

You could edit any time /root/timeout.sh

Manually check script using

sudo /root/timeout.sh

Timed outed sessions are logged into /var/log/timeout.log

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .