Configure Shell In A Box, LShell and Nginx in Debian 8


Shell In A Box is a very useful tool when it comes to access your server via web. It provides you the total power of shell via web. One can ask, why we need a webshell? One answer can be, we can access the server shell without using any ssh client. That includes, you can manage and maintain your server with anything that has an active internet connection and a web-browser.

On the other hand, LShell, developed in python, stands for Limited Shell, is also very popular when it comes to limit an user’s shell activity and interaction.

Both of the projects are matured, widely used and well maintained that can be relied on.

Today our experiment will be to configure shellinabox and lshell in Debian based Linux system. This way we can also apply webshell in Raspberry Pi also.

Expected outcome

  • We should be able to access the shell of a Server via web securely.


  • Server/PC/VM with Debian 8 (Jesse) and active internet connection or Rasbian 8 on Raspberry Pi 3 Model B.

Let’s Start

We will need to install couple of applications, shellinabox, lshell and nginx. We will need nginx to handle the web requests and connections is the best possible way, as nginx is also very reliable in this business.

# apt-get update && apt-get upgrade
# apt-get install lshell shellinabox openssl nginx sudo sshd

One thing, we should consider that, shellinabox doesn’t allow accessing root by default. So, we are gonna add a new user, dev1core, in the system –

# adduser dev1core
# useradd -G root dev1core
# chsh -s /usr/bin/lshell dev1core

We have bound dev1core user to use lshell as his/her default shell. Let’s set a password for the user by –

# passwd dev1core

Now we need to configure these applications one by one. Let’s configure lshell first.

# cp /etc/lshell.conf /etc/lshell.conf.default
# echo>/etc/lshell.conf
# nano /etc/lshell.conf

The sample lshell.conf configuration will be like –

## log directory (default /var/log/lshell/) 
#logpath                        : /var/log/lshell/
## set log level to 0, 1, 2, 3 or 4 (0: no logs, 1: least verbose, 4: log all commands) 
#loglevel               : 2
## configure log file name (default is %u i.e. username.log) 
#logfilename    : %y%m%d- % u 
#logfilename    : syslog 

## in case you are using syslog, you can choose your logname 
#syslogname             : myapp 

## a list of the allowed commands or ' all ' to allow all commands in user's PATH 
allowed                 : ['']

## a list of forbidden character or commands 
forbidden               : [';','&','|','`','>','<','$(','${','history']

## a list of allowed command to use with sudo (8) 
sudo_commands   : ['ifconfig','ping']

## number of warnings when user enters a forbidden value before getting 
## exited from lshell, set to-1 to disable. 
warning_counter : 10

## command aliases list (similar to bash's alias directive) 
#aliases                        : {'ll':'ls-l','vi ':'vim'}

## introduction text to print (when entering lshell) 
intro                   : "Type '? ' or ' help ' to get the list of allowed commands" 

## configure your promt using %u or %h (default: username) 
#prompt                 : "%u %h" 

## a value in seconds for the session timer 
#timer                  : 30

## list of path to restrict the user geographically
path            : ['']

## set the home folder of your user. If not specified the home_path is set to 
## the $HOME environment variable 
home_path               : '/home/dev1core'

## update the environment variable $PATH of the user 
env_path                : ':/usr/bin:/usr/sbin' 

## add environment variables 
#env_vars: {' foo ':1, ' bar ':'helloworld '} 

## allow or forbid the use of scp (set to 1 or 0) 
scp                     : 0

## forbid scp upload 
scp_upload              : 0

## forbid scp download 
scp_download            : 0

## allow of forbid the use of sftp (set to 1 or 0) 
sftp                    : 0

## list of command allowed to execute over ssh (e.g. rsync, rdiff-backup, etc.) 
#overssh: ['ls','rsync']

## logging strictness. If set to 1, any unknown command is considered as 
## forbidden, and user's warning counter is decreased. If set to 0, command is 
## considered as unknown, and user is only warned (i.e. *** unknown synthax) 
strict                  : 1

## force files sent through scp to a specific directory 
#scpforce               : '/home/bla/uploads/'

## history file maximum size 
#history_size: 100 

## set history file name (default is/home / % u/.lhistory) 
#history_file: "/home / % u/.lshell_history"

Now we will configure shellinabox with –

# nano /etc/default/shellinabox

The sample shellinabox configuration will be like –

# sample config
# Should shellinaboxd start automatically

# TCP port that shellinboxd's webserver listens on

# Parameters that are managed by the system and usually should not need
# changing:
# SHELLINABOX_DATADIR=/var/lib/shellinabox
# SHELLINABOX_USER=shellinabox

# Any optional arguments (e.g. extra service definitions).  Make sure
# that that argument is quoted.
#   Beeps are disabled because of reports of the VLC plugin crashing
#   Firefox on Linux/x86_64.
#   localhost-only makes shellinabox to be browsed by the localhost only.

SHELLINABOX_ARGS="--no-beep --disable-ssl --localhost-only"
#SHELLINABOX_ARGS="--no-beep -s /terminal:LOGIN --disable-ssl --localhost-only"

At this point, we need to configure the permission for sudoers, for that –

# visudo

and the modification will be like –

# disallow all commands
dev1coe ALL=(ALL) !ALL
# allow specific commands
dev1core ALL=NOPASSWD: /usr/sbin/ifconfig, /usr/sbin/ping

Here, we are allowing only ifconfig and ping to be executed by the user: dev1core.

At this point we will configure nginx will self-signed ssl certificate so all the web rules and traffic can be handled by nginx.

# cd /etc/nginx/ssl
# openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout nginx.key -out nginx.crt

Please fill up the necessary information ant at the end a certificate file will be created as nginx.crt. We consider the default site configuration file is available at /etc/nginx/conf.d/default and port 90 is available. So, let’s create a config file –

# nano /etc/nginx/conf.d/1-shellinabox.conf

– and configure it like –

 listen 90;

 ssl on;
 ssl_certificate /etc/nginx/ssl/nginx.crt;
 ssl_certificate_key /etc/nginx/ssl/nginx.key;

 location / 
 proxy_redirect default;

 proxy_set_header Host $host;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 client_max_body_size 10m;
 client_body_buffer_size 128k;

 proxy_connect_timeout 90;
 proxy_send_timeout 90;
 proxy_read_timeout 90;

 proxy_buffer_size 4k;
 proxy_buffers 4 32k;
 proxy_busy_buffers_size 64k;
 proxy_temp_file_write_size 64k;

 #auth_basic "Restricted";
 #auth_basic_user_file /etc/nginx/.htpasswd;

We have almost come to the end of this integration. We just need to restart the applications –

# /etc/init.d/shellinabox restart
# /etc/init.d/nginx restart

– and the integrated system should be ready to use.


The result is as expected. Browsing www://{system_ip}:90 prompts up login pop-up and we can login using the username and password of dev1core. we get the lshell environment and we can execute ifconfig and ping command only with the help of sudo.

You can now play with the webshell in your server securely. Please share your experience and we will be glad to hear that 🙂

Useful links

One comment

  1. Hey there! Would you mind if I share your blog with my zynga group? There’s a lot of people that I think would really appreciate your content. Please let me know. Cheers|


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

<span>%d</span> bloggers like this: