15

An introductory C++ course is offered every year in our university. In order for students to code in C++ and submit their assignments, we give them shell access to a Linux server. They use ssh to log in to the server with their accounts, do the coding and keep the compiled code in their home directories. However, giving shell access brings in a number of vulnerabilities with it. My question is, Is there any other way, apart from giving shell access to students, in which we can fulfil the above mentioned purpose? Any server side tool/application that can provide an interface to students for doing their c++ assignments without compromising server security?

Steve Dodier-Lazaro
  • 6,798
  • 29
  • 45
Soban
  • 289
  • 1
  • 5
  • 1
    Is it required that they code on the server? – RoraΖ May 22 '15 at 11:12
  • 12
    Have you considered using VMs to fully isolate the students from each other? Disk space, especially for relatively ephemeral data, is relatively cheap, and cloning a pre-provisioned VM can reduce the on-disk footprint, but 30+ VMs do need a reasonable chunk of RAM to work well. – user May 22 '15 at 12:04
  • 14
    What makes you believe that "giving shell access brings in a number of vulnerabilities with it."? – Karalga May 22 '15 at 15:33
  • Is one of the problems that students submit their assignments by leaving compiled code in the appropriate place in their home directory? Then the marker must have read access to every student's home directory. – emory May 22 '15 at 16:51
  • @Karalga I think the consideration is standard shells which aren't jailed or sandboxed into their own little niches with no other access... – Thomas Ward May 22 '15 at 17:41
  • 3
    Why not just have them use Github or something of that nature? Source control is something they need to learn anyway. – Kevin Krumwiede May 22 '15 at 22:49
  • Why give them server access? Why not just specify the environment their assignments will be tested against? You could even provide a VM image for their testing. Then it's up to the student how they want actually build. They can use the image or do something else and then test on the image. – jpmc26 May 23 '15 at 00:49
  • @MichaelKjörling yes setting up VMs is a good idea but we don't have the amount of RAM needed for that kind of setup. – Soban May 23 '15 at 10:37
  • @KevinKrumwiede how can github be used in this scenario? Please explain a bit if possible – Soban May 23 '15 at 10:41
  • 1
    I don't think it would be appropriate for an entire course, but there are browser-based services like ideone.com that work pretty well if all you want to do is let people write some code and execute it. I've used ideone.com in a physics course where I had the students learn a tiny bit of python in order to do simple simulations. The advantage is that it requires zero setup or resources from me, and there is zero security risk. –  May 23 '15 at 13:36
  • @Soban The basic requirement is a place to put assignments, right? They're not going to "do the coding" over SSH; they'll write it in an IDE and upload it. Not only would Github provide a place to store their projects, but the use of services like Github is something they need to be taught anyway. And you don't need to set up or host anything. – Kevin Krumwiede May 23 '15 at 17:59
  • 1
    Instead of GitHub, use Gogs. It's a full-fledged self-hosted GitHub clone but would be completely under your control. If you want to automatically test the student's code, you can set up a post-commit hook that pulls the code into a small VM, compiles the code, runs it (killing it off if it takes too long), and saves and e-mails the results to the student. By doing that, you get a history of code changes AND a pass/fail grading system all in one. – CubicleSoft May 24 '15 at 00:15
  • Actually, you don't need a separate VM. It would just be more secure that way. The code can still be pulled into an account with no privileges to do anything bad on the system and you could recreate the user account for each new program pulled in from Gogs. With a VM, you would just reload it (programmatically) from a snapshot - that way, even if the VM was compromised, it would only be compromised for a few moments. – CubicleSoft May 24 '15 at 00:42
  • @Soban The vast majority of modern computers can handle a single virtual machine running Linux. I was suggesting that the students host their own VMs, rather than trying to have a server side VM per user. – jpmc26 May 28 '15 at 01:11

4 Answers4

28

What you need is relatively simple: you need to ensure that your students' unprivileged accounts are well confined. If you don't have a graphical environment involved, your situation is relatively simple. You should start by implementing the following actions:

  • ensure users are created without administrative privileges (no sudo, no admin or wheel group)
  • ensure users are unable to emulate a login screen to spoof your login screen (a classic for university, which I've seen happen)
  • ensure proper polkitd policy which prevents users from suspending/shutting down the host
  • ensure you don't run vulnerable/outdated suid/sgid services on the host (see how to list them)
  • ensure no individual user can deplete the resources of the system (by configuring Systemd.cgroup to impose resource usage limits on the entire session of each user)
  • strengthen your mandatory access control by installing and configuring properly SELinux (to limit students to a student role where they can only write in their home and in /tmp)
  • expire accounts when necessary to avoid lingering accounts with eventually compromised passwords (see this question on the Unix site)
  • you can even run students' sessions in separate containers using Systemd.nspawn which is designed to run fully working systems independently from one another, using Linux namespaces. This is the proper way to jail a session, not chroot

You might then notice that students use the machines for other purposes than those allowed. You can limit access to machines to specific times using pam_time though that might get in the way of students getting their work done and should be balanced against the benefits it provides. Also, make sure that your network administrators know what traffic to expect on this host so they can detect undesirable traffic.


All of this being said, I don't see the point in white-listing specific binaries (useless since students can compile and run their own code) as it may get in the way of students using legitimate development tools, e.g. alternative compilers, building toolchains, code analysis tools, code versioning tools, etc.

As long as users can only harm themselves and you've got strong guarantees of that, the job is done. This isn't exactly a long-term production system anyway, students are only using it to fool around with educational code.

Steve Dodier-Lazaro
  • 6,798
  • 29
  • 45
  • 3
    Your right that a Systemd.nspawn is better than a chroot, its just not available on all systems. chroot is on almost all. Security wise your awnser is better than my suggestion of chroot. It is however also a lot harder to setup (a lot more work). I believe my suggestion of just using a continous integration setup is even better. but is also a lot of work. – LvB May 22 '15 at 11:58
  • The problem with `chroot` is that if you want to `chroot` an entire session, you'll have to code support for that in your `logind`. – Steve Dodier-Lazaro May 22 '15 at 11:58
  • you do know that chroot support for that is inside openssh? or am I missing something? – LvB May 22 '15 at 12:00
  • 1
    Ah! I actually didn't! I would still prefer a container-based solution, as the goal of confining would be to prevent a privilege escalation that breaks the AC model of the system. User namespaces provide tangible protection against `root` privilege escalations (unlike `chroot`). – Steve Dodier-Lazaro May 22 '15 at 12:09
  • True that, its all about effort / protection balance that is needed. (OP needs to decide that) – LvB May 22 '15 at 12:15
  • One thing that I would try is to set a server with (around) 8GB of RAM, just for simple VMs. By simple, I mean Debian VMs or Arch Linux, running with only 5% of CPU available for the machine, and only 256MB of RAM, with 4MB of graphical memory. This would be really just enough for them to connect to one of those VMs to compile and run the code. – Ismael Miguel May 22 '15 at 18:40
  • @SteveDL Thank you for a detailed answer. I think I will go with your suggestions. I have a question though: "ensure users are unable to emulate a login screen to spoof your login screen (a classic for university, which I've seen happen)" How do u achieve this? – Soban May 23 '15 at 10:56
  • @LawrivanBuël Thanks for your suggestion of chroot. I think it will be easier to chroot ssh users to their home directories; i have done that once previously but its been a while. Haven't tried Systemd.nspawn before – Soban May 23 '15 at 11:05
  • @Soban that targets more generally shared machines in lab rooms. I assume your users log in into a TTY and *then* SSH to the coding machine, right? So, if you use a plain-text login UI (e.g. the TTY's default UI with some custom header), anyone can set up a script and run it that emulates the look of the UI, catch SIGINT, refresh the whole screen when the victim types a password character to hide the input, etc. – Steve Dodier-Lazaro May 23 '15 at 11:14
  • You can do either of: use a X-based login UI and prevent non-root users from running X; automatically close inactive user sessions; prevent (via SELinux) `student_r` users from `su`-ing so they can't transparently log a victim in into the victim's shell (making the attack at least visible). – Steve Dodier-Lazaro May 23 '15 at 11:15
  • If you log your users into a graphical shell, you can't do anything at the moment since X11 has no access control capabilities. In the future you might be able to prevent full-screen apps depending on the Wayland compositor you use. – Steve Dodier-Lazaro May 23 '15 at 11:16
  • One more thing. Would setting quotas be a good idea too? – Soban May 23 '15 at 11:16
  • Let us [continue this discussion in chat](http://chat.stackexchange.com/rooms/24053/discussion-between-steve-dl-and-soban). – Steve Dodier-Lazaro May 23 '15 at 11:17
3

It's far from complete, but a group of teammates from my University are developing Mumuki. The English version seems to be broken doesn't have English content at the moment, but you can read it's intention there. You can also join the project and make it run C++ (I've started with C).

The idea of the platform is to create exercises with unit tests that check them.

We have started thinking about how to run the code in isolated ways, but up to now there's nothing implemented.

mgarciaisaia
  • 157
  • 1
  • 7
  • 1
    This seems harsh, but, in what way does that answer the question? The execution still isn't isolated and there is still no way to solve the O.P.'s issue. – Ismael Miguel May 22 '15 at 18:40
  • It's an application that provides an intrrface for students to upload their assignments without having `ssh` (part of what the OP is asking) and that doesn't solve the isolation at the moment but is intended to. – mgarciaisaia May 22 '15 at 18:51
  • @IsmaelMiguel: ie, it's not an out-of-the box solution at the moment, but the tool is intended _exactly_ for what the user is trying to do. – mgarciaisaia May 22 '15 at 18:54
  • That's a pretty convincing argument. +1 on that! – Ismael Miguel May 22 '15 at 19:14
1

Yes there are. For a start, it's not a bad idea to use SSH but to improve security you can do the following:

  • Use chroot jails to lock all 'student' users who log in via SSH into a limited environment.
  • Do not give them sudo access, instead use specific scripts / commands in the sudoers list to allow a limited subset of the administration commands.
  • Make the server not publicly accessible on any port > 1024. (run ssh on a high port number to prevent script-kiddie access).
  • While you're at it, encourage them to use ssh-keys to log in. These are from a security standpoint far superior to username / password access (provided there encrypted with a password).
  • As an alternative you could use git and continuous integration for this. (Gitlab and Jenkins combo for example) this has the added bonus of being able to only give them access through a safe web environment (when you use a TLS setup so 'https',use a proper certificate!) And all access is auditable.
Steve Dodier-Lazaro
  • 6,798
  • 29
  • 45
LvB
  • 8,217
  • 1
  • 26
  • 43
  • 5
    *encourage them to use ssh-keys* no, don't encourage them. Force them. Make them learn good practices right from the beginning. They shouldn't even be given the possibility to get a passing grade if they can't bother respecting basic security practices. –  May 22 '15 at 20:04
  • 1
    by encourage I anot also mean force, but also motivate them to use ssh-keys (so more than just forcing) – LvB May 22 '15 at 23:26
  • Where do you propose they will connect from? Lab machines on which they've already authenticated (then use ssh-keys)? Or do they connect via their own PCs/laptops? In the latter case, SSH keys will have a higher support cost because CS undergrads are quite good at bricking/reinstalling their OS ruthlessly and at changing computers. You'll have to spend time explaining them how to migrate their keys, or helping them add a newly made key to their authorized_keys. Keep in mind unis often have ~200 undergrads in a CS course, and academics are pretty busy people :-) – Steve Dodier-Lazaro May 23 '15 at 10:19
  • The students use both Lab PCs and their personal laptops; whatever is convenient for them. They just need to connect to the server and start working on their assignments. Each user is given a username which is the same as his/her university student ID – Soban May 23 '15 at 11:11
  • I guess learning how to backup is important... to learn sooner rather than later. – LvB May 24 '15 at 00:15
0

Yes, there are alternative approaches. However, I think your question is based on flawed assumptions. While allowing shell logins to more people will obviously have security impacts, it doesn't necessarily mean by definition that the security of the resulting system cannot be effectively managed. These systems are designed to be multi-user systems and have the facility to manage this access in ways which will not compromise security (or at least, manage the level of risk to an acceptable point). The real challenge in these envrionments is that you typically don't have the resources to do this. For example, it is unlikely that a single student profile would be adequate - you would need profiles to reflect the different needs. An introductory programming course probably doesn't need the same access as a course on network programming or systems programming. The problem then becomes one of having sufficient time to administer all these different profiles and ensure they are appropriate.

Having said all that, I do think in this day and age, there are alternative approaches which are likely to be both more manageable and more appropriate. For example, using virtual machines can be very productive. These can be setup so that each student is isolated from each other and can be done so that they can 'refresh' their virtual environment to a known 'good state'. Then there are solutions based around things like Docker or Vagrant, which can be used to allow students to create a standard and consistent environment on their own machines. Instead of your server being a platform which students log into to do their work, your server becomes a distribution mechanism which allows the students to download a working environment which they can run themselves. This also allows the possibility of creating customised environments which have been tweaked to suit the specific course requirements.

Tim X
  • 3,242
  • 13
  • 13