20

My son received a new laptop this past christmas, primarily for usage at his new school... And now that he has his own laptop, he's stoked to have Steam installed.

But the wife wants me to remove Steam, because the laptop is primarily for school usage... I'd rather not do that, if I don't have to.

Is there a way I can restrict or otherwise limit access to Steam? Perhaps a password on Steam itself, or set times during which it can be run?

Ideally, it has to be something pretty simple to use because my work often keeps me away from home (and computers, and telecommunications and...) for long periods of time and whilst my wife is not as comfortable around computers as I am, easier to use is far, far better.

Surely there's something out there that can achieve this task?

4
  • You could use the child-proof lock in your router to limit the access to steam, e.g. 1h a day. Steam uses the ports UDP 27000 - 27015 for the client traffic. If you limit these ports in your router your son won't be able to log into steam.
    – Kev Inski
    Jan 28, 2016 at 6:47
  • The simplest solution is to create a user profile on your Ubuntu on which you install Steam. Create a password for the new user profile that will be used by your son.
    – user284234
    Jan 28, 2016 at 6:47
  • @Begueradj Kids can be smart. And physical access to a machine means possible root access, which means you could bypass everything except maybe encryption. You would need to encrypt that user's home directory to securely protect it then.
    – Byte Commander
    Jan 28, 2016 at 7:56
  • @Gregory How smart is your son with computers? Do you need a 100% safe thing, or is it enough if accessing Steam is just made non-trivial?
    – Byte Commander
    Jan 28, 2016 at 7:57

5 Answers 5

5

Set a time- limit on a process or application

With a small background script, you can set a time- limit on a process or application.
As long as your user does not know the administrator's password, it is not surpassed too easily.

The solution below

Is such 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.

The script

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

#--- set the time limit below (minutes)
minutes = 1
#--- set the process name to limit below
app = "gedit"

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

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

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

    try:
        # if the pid of the targeted process exists, add a "tick" to the used quantum
        pid = subprocess.check_output(["pgrep", app]).decode("utf-8").strip()
        n = read(uselog)
        n = n + 1 if n != None else 0
        # when time exceeds the permitted amount, kill the process
        if n > minutes*6: 
            subprocess.Popen(["kill", pid])
        open(uselog, "wt").write(str(n))
    except subprocess.CalledProcessError:
        pass

    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 process name to limit, and the maximum number of allowed minutes. In the example:

    #--- set the time limit below (minutes)
    minutes = 1
    #--- set the process name to limit below
    app = "gedit"
    
  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 &
    

That's it

When someone tries to kill the background script:

enter image description here

(action not allowed)

Explanation; how it works

  • Once per 10 seconds, the script looks if the targeted process is running. If so, it "adds" one "point" to a total usage, to be recorded in a file (/opt/limit/uselog). If the dayly limit is reached, the script no longer allows the process to run, killing it 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 again, you'd need the sudo password to do so.




EDIT

Although the script above should provide a reasonably secure way of limiting an application's usage, as mentioned by @Bytecommander, it can be surpassed, although not very easily. The combination with the measure below will make it very unlikely that this will happen, unless your son knows the setup, and is quite experienced with Linux/Ubuntu.

Additional measure

A bit further from a "simple solution", but still not too difficult to set up is the additional measure below. If our suspected delinquent would find out the script is called from /etc/rc.local, would manage to become root, and remove the line in /etc/rc.local, or would be able to stop the script that way, we can confront him with the next problem: the screen blacks out after log in. Additionally, the solution checks if the background script is running after 5 minutes after restart, blacking out if not.

The extra measure is a startup- check if the line /opt/limit/limit_use & is present in /etc/rc.local, and a check after 5 minutes if the script still runs. Since the script runs from a (hidden from Startup Applications) launcher in /etc/xdg/autostart it will be quite difficult to find out what is happening, unless you know how it is done. The combination of these two measures makes it unlikely your son will find out, and if he does, probably nothing will stop him.

How to set up

Two simple steps are involved:

  1. Copy the code below into an empty file, save it as blackout.desktop on your desktop:

    [Desktop Entry]
    Name=not allowed
    Exec=/bin/bash -c "sleep 15 && /usr/local/bin/blackout.py"
    Type=Application
    Terminal=false
    NoDisplay=true
    

    Copy the file to /etc/xdg/autostart:

    sudo cp /path/to/blackout.desktop /etc/xdg/autostart
    
  2. Copy the script below into an empty file, save it as blackout.py on your desktop, make it executable and copy it to /usr/local/bin:

    cp /path/to/blackout.py /usr/local/bin
    

    The script

    #!/usr/bin/env python3
    import subprocess
    import time
    
    def dim_screen():
        screen = [
            l.split()[0] for l in subprocess.check_output(["xrandr"]).decode("utf-8").splitlines()\
            if " connected" in l
            ]
        for scr in screen:
            subprocess.Popen(["xrandr", "--output", scr, "--brightness", "0"])
    
    if not "/opt/limit/limit_use &" in open("/etc/rc.local").read():
        dim_screen()
    
    time.sleep(300)
    
    try:
        pid = subprocess.check_output(["pgrep", "limit_use"]).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        dim_screen()
    

Explanation

Launchers in /etc/xdg/autostart will launch an application (in this case the extra security check- up) for all users. This could be overwritten locally, but you have to know the check up runs. By putting the line NoDisplay=true into our launcher, it will not appear locally in Startup Applications, so without knowing it exists, it is unlikely to be discovered.

Furthermore, your son has only 15 seconds to find out (then the screen is blacked out) so he would have a serious problem, unless he is a genious, has a lot of experience with Ubuntu and a creative mind.

7
  • But if his son can log in to the system using the root password then won't he able to edit the rc.local?
    – Raphael
    Jan 28, 2016 at 17:49
  • 1
    @Raphael that's why I mentioned as long as the user is no administrator. But if he is, practically nothing will stop him from surpassing eventually if he is smart enough. Jan 28, 2016 at 17:57
  • Ikr, if he is well versed in linux or if he knows how to use google efficiently, eventually none of the answers would work anyway.
    – Raphael
    Jan 28, 2016 at 18:00
  • 1
    @ByteCommander true of course. Nevertheless it seems a reasonable balance of the requested simple solution, a restricted time and a reasonable level of security, given the interest in question (limiting the time, spent gaming). Jan 28, 2016 at 20:26
  • 1
    @JacobVlijm Yes, of course. I'm just pointing out that they may keep their 8 year old kid out this way, but when it becomes a teen with some technical knowledge, they have to know that there's no 100% security. (Not that I wouldn't like to grand the teen some freedom)
    – Byte Commander
    Jan 28, 2016 at 20:31
4

From my own experience restricting access to computer games is one of the most challenging tasks in educating our kids. Of course we parents want them to use their computers mainly for school but this heavily conflicts with the kid's intentions. They will hate us for giving them hardware usable for school only.

And of course we also want them to learn how to use their computer in a sensible way, including how to use it not only for work but also for leisure. This includes gaming and watching videos.

Unfortunately, well maintained and working parental controls to restrict the kid's computing is almost non-available for Ubuntu. Another major issue is that as soon as they are smart kids all measures we took become in vain. They will always find ways to overcome our restrictions, in case they are really smart without us even being able to notice.

Any blocking software or PAM-restrictions running on the kid's computer will be temporary only, and may sooner or later be overcome very easily. Therefore we decided to let the password-protected router do the job, where physical access can be controlled much easier.

So what we do here to somewhat limit gaming at the moment is a combination of all of the following:

  • Talk to them to educate them how and when to use computers for leisure, and when to use them for school. This is a constantly ongoing, rather tedious process leading to endless discussions and arguments. But it is what we feel is the only thing that will last in the long term.
  • No administrator permissions on their account. This is a temporary thing. We do know that they will be able to put themselves in the sudo group sooner or later. The plan is that they will ask us for that rather than making this in hiding.
  • Make a contract for clearly defined computing times. They need to know what for and how long they are allowed to use their machines. They need to learn how to split up this time for school and for leisure.
  • Hard-block all internet during sleep hours.

To ease fulfilling the contract on computer usage for both, the kids, and us we installed the following restrictions:

  • Use a password-protected router that allows restriction of internet access on a combination of a hardware (MAC) and a time-table basis. As long as they don't know about MAC-spoofing this will work quite well. It will also restrict access through their smart phones and tablets. This of course won't work if there was an open wireless network in your neighbourhood.
  • Install an SSH server on the kid's computers to pull the plug in case they got lost in their own intentions. This is for emergency cases we are glad we had not needed much.
  • Installed a DNS blacklist (through the router, not the computer!) which should block access to the worst.

Blocking internet access will effectively disable gaming if that game needs internet access such as Steam, Minecraft, or other gamig servers. It will however be of no effect for games running off line.

3
  • Are you referring to shutdown using ssh or just closing the application?
    – Raphael
    Jan 28, 2016 at 11:00
  • Depends on the situation... SSH can do it all, shutdown, kill user, kill app, revert hacks, remove users from sudoers, ... for SSH we have a parent admin account on all kid's boxes.
    – Takkat
    Jan 28, 2016 at 11:04
  • Nice, you're the first one who has an additional layer of security except all the local stuff which one can revert if they become root (which is not preventable if they have physical access).
    – Byte Commander
    Jan 28, 2016 at 19:49
1

This can be achieved by using shell scripts.

First script is to kill Steam as soon as it is run:

#!/bin/bash

while true
do
    pkill steam
    sleep 1
done

exit 0

Save it as /path/to/anyname.sh and add it to the list of start-up applications.

What this script will do is that it will check any open process named steam every second and if it finds any then it will kill it.

But, you need a solution where steam can be run at a specific time right so that your son can play games during that interval. To do that you have to write another script:

#!/bin/bash

    echo "pkill anyname.sh" | at 10:00

exit 0

Save it as /path/to/anyname2.sh and also add this to your list of start-up applications.

This script will kill the first script at 10:00 hrs. So, when your son runs Steam at 10:00 hrs. He will be able to play it now.

The third script is to re-initiate the first script at another point of time so that it kills Steam after a time interval and your son won't be able to play games through Steam anymore.

#!/bin/bash

    echo "bash /path/to/anyname.sh" | at 12:00

exit 0

Save it as /path/to/anyname3.sh and add it to your list of startup-applications.

Make sure to keep those paths hidden, so that your son doesn't find out.

5
  • isn't there a way by which we can stop it from starting instead of killing it after every time it starts?
    – Alex Jones
    Jan 28, 2016 at 7:50
  • @edwardtorvalds - I do not know of any, so I posted this solution.
    – Raphael
    Jan 28, 2016 at 7:51
  • I upvote your answer, but the OP needs a SIMPLE/EASY and not TOO technical method
    – user284234
    Jan 28, 2016 at 8:01
  • Its simple and easy, all the op needs to do is copy and paste the scripts save those files and add those to startup applications, then forget about it.
    – Raphael
    Jan 28, 2016 at 8:06
  • kill loop - dirtiest i can imagine.
    – Croll
    Jan 28, 2016 at 19:29
0

Why not use new User Account (via System Settings). This is the only one method on Linux for "permissions".

  1. New user "SteamUser" should not be in sudoers (just a limited account).
  2. Then create second account called "SuperAdmin" and make it sudoers account (root access). But keep its password only with you.
  3. Then remove your son's account from sudoers. (sudo group). Then this account will not have root access, it will not be able to install or remove software, change system-wide settings.
  4. Login to your "SuperAdmin" account and change ownership of steam binaries and steam games folder to prevent them from running by anyone except "SteamUser". This includes removing read+write+execute access from anyone except "SteamUser"

Few notes..

  • There is no abillity to leave a root access with your son's account, otherwise permissions control is bypassed easily with chown/chmod.
  • Other suggestions based on background scripts are just unstable mess. This means they are not promising. However, they're easy to set up maybe.
  • Folder paths to transfer to "SteamAccount" are: /home/son/.steam and of course the binary file /usr/games/steam
  • To play steam, "SteamUser" password is required (you will need to login with "SteamUser" and them run steam. You can try looking for methods to expire session after some time with locking it, to prevent playing too long time. I am not sure if there are tools like that, but it's technically possible to set time limits, but for sessions, not programs.
6
  • Ah, I believe I found my downvoter... Jan 28, 2016 at 19:43
  • This is not really secure, because smart enough kids (being able to use google and follow a step-by-step guide is already enough) can easily bypass user restrictions if they have physical access.
    – Byte Commander
    Jan 28, 2016 at 19:48
  • @ByteCommander at least it's more reliable than background scripts. But yeah you are right. Just like on Windows. Like anywhere.
    – Croll
    Jan 28, 2016 at 19:51
  • No offense, but how is this more secure? Jan 28, 2016 at 19:53
  • And how do you want to specify a time limit for how long the kid may use Steam? And what about the allowed school stuff? Another account for that? I personally hate systems with too many accounts per person, because they're a pain to use because of not shared settings etc.
    – Byte Commander
    Jan 28, 2016 at 19:55
0

Just adding on to Jacob Vlijm's answer. His solution is for setting a time limit on particular apps (2 hours a day etc.) Just pasting some code below for people who want to limit app use during particular periods. (eg. No VLC from 9 am to 8 pm).

You'll need to save the script somewhere, make it executable and run it every minute from cron.

#!/usr/bin/python3

import subprocess
import datetime


# get current date, time and day
dt = datetime.datetime.now().astimezone()
day_integer = dt.weekday()

# limit use from 9 am onwards
start_time = datetime.time(9, 0, 0, 0)

# this is if you want to set different end times for different days
# 20 stands for 2000 or 8 pm. I've set 17 for 1700 or 5 pm for Sat
end_time_dict = {
                0 : 20,
                1 : 20,
                2 : 20,
                3 : 20,
                4 : 20,
                5 : 17,
                }

# add names of processes you want to limit below
app_list = [
            'vlc',
            ]

if day_integer != 6: # not a sunday. Use or !=5 if you want to add Sat too
    end_time_fragment = end_time_dict[day_integer]
    end_time = datetime.time(end_time_fragment, 0, 0, 0)

    if ((dt.time() >= start_time) and (dt.time() < end_time)):
        for app in app_list:
            try:
                pid = subprocess.check_output(["pgrep", app]).decode("utf-8").strip()
                subprocess.Popen(["kill", pid])
            except subprocess.CalledProcessError:
                pass

# below is line to add to cron script, this will run script every minute
# * * * * * cd /absolute/path/folder && /usr/bin/python3 ./limit_app_time.py

You must log in to answer this question.

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