I am working in a team that have just completed building a prototype system for controlling machines (multiple c++ programs with some IPC, networking and device I/O running on Ubuntu Server 16.04). Everything is started and managed by systemd on boot and is pretty much self-regulating with no real need for user intervention.

We now want to try secure the system from people attempting to inspect, copy or steal our system (they will be able to get access to the computers if they really want to). One of the ways we were thinking of doing this is to remove the shell/terminal from linux since it is not needed and will make it more difficult for hackers to navigate the system. We are mostly application programmers with only a moderate level of experience administrating linux systems so we have the following questions:

  1. Firstly, if it is actually possible to do. To clarify, we want to remove any terminal that allows users to run commands such as cd, cat, ls, apt-get, scp.

  2. If it is possible, then is it advisable and will it actually increase the security of the system. Are there any other advantages or disadvantages to doing this? Are there any alternatives?

  3. How can it be achieved.

  • On the presumption that these are your machines, rather than someone else's: How are you going to administer the machines once they are deployed in the field? Your plan for that affects the answers to this. – JdeBP Dec 22 '17 at 11:16
  • 1
    Without a shell you'll have to rewrite all the scripts (starting with the init scripts) to use some other language, perhaps even using binaries. – Murphy Dec 22 '17 at 12:41
  • 1
    Running a system without a shell at all is an interesting idea from a technical point of view, but bringing security/hardening into it seems to attract answers that are beside the point. I wonder if the question would be better without the security part, or if the main point could be emphasized more (whichever one it is). – ilkkachu Dec 22 '17 at 12:46
  • 2
    An interesting experiment might be to change (edit source + recompile) dash and bash so that they refuse to read/execute arbitrary commands from stdin, and can only run scripts and whatever is passed to them with -c , and see how far a system can boot and run that way. – Mark Plotnick Dec 22 '17 at 20:56
  • 2
    At best, this will be security by obscurity. You're better off securing the machines to prevent unauthorised access than removing the shell to make it slightly more difficult for an unauthorised user to do anything (someone who can access it can easily use whatever method they used to gain access to install a statically linked shell and whatever other tools they might want). – cas Dec 23 '17 at 7:10

While disabling the shell might limit attack surface it'd be far easier to limit read access in /usr/bin. For limiting shell access to users setting ones login shell to /sbin/nologin works. If the idea is to limit what you can do at the terminal then:

  • Use efistub with secure boot.

This should already be the case with Ubuntu.

  • Disable the rescue shell in initram.

This involves extracting the initram editing the init script and removing the shell call in the rescue function.

  • Disable ttys on system.

Because you're using systemd just

systemctl disable getty@tty1.service

You will have no way of interacting with the system at all. You can use a second system enabled with secure boot that allows remote or local maintenance or you'll have to rip out the harddrive and make modifications on another system with chroot.

This doesn't prevent the creation of pttys which means SSH will still work.


Well, technically Linux is just the kernel, it doesn't need a shell for anything. But to do anything useful, you need something running in userspace. If you managed to integrate everything you need into one process, you could drop it in place of /sbin/init and have no other userspace processes on the system.

In practice you might want the equivalent of udev and other plumbing, possibly a DHCP client. (Static IPv4 configuration can be set on the kernel command line.)

With the traditional sysvinit style initialization, everything depended on shell scripts (the ones in /etc/init.d/, with links from /etc/rc*.d), so using that is right out. But one of the points of systemd is that it doesn't rely on the shell as much, so that might be doable, if all services you're running have systemd unit files (instead of init.d scripts), and they don't use shell scripts for anything else.

On one Ubuntu system (17.10) I have, at least console-setup, keyboard-setup and Postfix seem to have shell scripts in their unit files. The first two aren't probably important since you not logging in on a console without a shell, but there might be others that need it...

If a shell-less system was really wanted, I'd probably start from scratch or from something more minimal than a full-blown system like Ubuntu. It would be an interesting experiment to remove /bin/sh and see how far the system gets, though.

You mentioned security as one motivation for this. Without a shell, any shellcode that relies on starting a shell would fail, which might thwart simpler attackers. But in principle, when we get to the point where the attacker can run arbitrary code, there's nothing to stop them from doing what they want manually, without a shell, or from just loading a shell on the system and running it. It's just a question of how much time your attackers are prepared to use.

An obvious disadvantage of a shell-less system would be that configuring it would be harder, since you couldn't just log in to start an editor, or restart services. You'd need to boot the system from a "rescue disk" or rebuild it completely to make changes.

Note that disabling the usual ways of logging in to the system (gettys on virtual consoles, SSH, whatever) don't do much to stop attackers. They're more likely to exploit bugs in any services you're running, than to ask nicely if your system would please let them log in.


My first choice would be to disable the ttys on screen and disable/restrict ssh, so there will be basically nothing to log in: https://askubuntu.com/questions/357039/how-do-i-disable-virtual-consoles-tty1-6

Another possibility would be to disable the login of the user(s) themselves: Disable user shell for security reasons

Not the answer you're looking for? Browse other questions tagged or ask your own question.