Minihowto: Build a free shell server using FreeBSD
From SHellium Wiki
On this minihowto, I will try to explain how to build a free shell service using FreeBSD. The idea is to create a shell account on the system by means of logging into via ssh using username "newuser" and password "newuser". I'm using FreeBSD and 'sudo' on this example; To keep this minihowto short and simple we are not going to use 'jails', perhaps a modification to the script will allow it to work on Linux. Note: There are bunch of ways to do this, involving different levels of security and difficulty, keep in mind: this is a "MINIHOWTO", meaning is short and simple, you are welcome to add sugestions@remarks, This is not the "facto" method, use at your own risk. First we need to create our directories, groups, user, quotas, etc. as root: touch /sbin/newshell.sh # create newshell.sh chmod +x /sbin/newshell.sh # change mode eXecute echo "/sbin/newshell.sh" >> /etc/shells # we add newshell.sh to list of valid shells pw group add freeshell # we add our group freeshell cd /home # chdir to /home mkdir userexample # create user to be use as a example pw user add -n userexample -d /home/userexample -g freeshell -s /sbin/newshell.sh #create userexample chown userexample:freeshell /home/userexample # userexample:freeshell owns directory
Please define userexample quotas, it will be used as a template for new users, use: edquota userexample then: pw user add -n newuser -g wheel -s /sbin/newshell.sh # we create our main user passwd newuser # Enter 'newuser' as passwd (if you like) pkg_add -r sudo # install sudo. echo "wheel ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers # dont ask me for root password pkg_add -r bash # install bash if you dont have it
We are done, but there are some security issues I like to point out, I will not use jails at this point because like to keep it short and simple, here are some suggestions:
- If you planning a new install, suggest the following structure:
- /
- /swap
- /tmp
- /var
- /usr #after you tweak your box in /etc/fstab mount this as read only.
- /home #in /etc/fstab enable quotas for /home.
- Programs like: yes, ping, sudo, who, top and others should be denied to users in group 'freeshell'.
- Restrictions on number of running process's allowed.
- If you use PHP turn 'safe_mode'
- ...Others will apply.
Now all we need its the script, copy and paste the next code in /sbin and name it '/sbin/newshell.sh' Here is the code:
#!/usr/local/bin/bash #change this to where bash is located. # dzup ( zzerver [at] gmail.com ) # Dec 19 2008 echo "http://example.com" echo "Enter your MOTD here" echo "Example:" echo "Welcome to my free SSH service!" echo "to obtain a shell, please log in as:" echo "username: newuser" echo "password: newuser" num2=`echo $RANDOM` # create a ramdom number to avoid floods. echo "Magic Number: $num2" echo "What is the Magic Number?" read num1 if [ "$num2" != "$num1" ] ; then # Avoid Flows echo "Sorry, Wrong Magic Number, try again ..." read null exit fi echo "Please enter your username" echo "username: " read usuario if [ "$usuario" = "" ] ; then # username is null. echo "Invalid username, try again..." echo "Press Enter to exit." read null exit fi hacklogin=`echo "$usuario" | tr -d "|;\\\140<>\042\047\134\176$"` if [ ! "$usuario" == "$hacklogin" ] ; then # dangerous characters echo "Invalid Username, try again ...\n" echo "Press Enter to exit." read null exit fi # verify if username already exist. safelogin=`echo "$usuario"|tr -cd "[:alnum:]"` password=`echo $RANDOM` existe=`sudo cat /etc/master.passwd|sed 'y/[:]/[ ]/'|awk '{print $1}'|grep $safelogin` existe=`echo $?` if [ "$existe" = 0 ] ; then # username already in system. echo "Username: ' $safelogin ' already exists in our system, try again ... " echo "Press Enter to exit." read null exit fi respuesta="Y" echo "Ready to add $usuario in our system." echo "Confirm 'y' to yes, any other character to abort." echo "By answering 'y' you agree to our terms and policies." echo "Correct (y/n)?" read correcto if [ "$correcto" != "$respuesta" ] ; then # didn't accept our terms, so ...bye bye. echo "Aborting creation, thanks." echo "(if this is an error, we are expecting ' $respuesta ' to create your shell, try again)." echo "Press Enter to exit." read null exit fi # Lets create our new user. echo "Creating $usuario ..." sudo pw user add $safelogin -g -d /home/$safelogin -n $safelogin -s /usr/local/bin/bash -L freeshell sudo mkdir /home/$safelogin #create his/her home # lame way to get the new passwd, since its a minihowto wtf. # i will like to ask for passwd before create user, hmm I will fix that some other time. echo "Please enter your password (twice):" sudo passwd $safelogin #now lets create the enviroment. #note, at this time the user can enter blank passwds, which is a #security issue, will be fix later #comments are welcome. :) sudo mkdir /home/$safelogin/public_html #create his/her http space. sudo chown -R $safelogin:freeshell /home/$safelogin/ #he owns everything in his home. sudo chmod -R 705 /home/$safelogin #make sure nobody in our group can read my files sudo chmod -R 775 /home/$safelogin/public_html/ #make sure apache can read public_html sudo cp /etc/skel/.bash_profile /home/$safelogin #cp skel(modify /etcskel/.bash_profile) sudo chown -R $safelogin:freeshell /home/$safelogin/.bash_profile # he/her own this sudo edquota -p userexample $safelogin #Copy user quotas from our userexample sudo quotacheck -a #lets update quotas database echo "User succesfully created!" echo "Thank you for registering with us." echo "To login into your new shell use: ssh -l $safelogin example.com" echo -e "Press Enter to exit." read null exit
Save the above code in /sbin as newshell.sh, After you done that, you can ssh to your box using 'newuser'@'newuser' combination and it will create a shell for you. Notes: There are several ways to improbe this as you can see, this is the very basic idea, Remember to post your remarks/suggestions, they are always welcome. Thanks and good luck (adios) :)