Soren Dam
  • Blog
  • Contact

Set up LAMP stack with suPHP and SFTP on Ubuntu 14.04 LTS

January 20, 2015

By Søren Friis Dam

This tutorial shows how to install a LAMP stack with suPHP on a clean Ubuntu 14.04 LTS

Update your VPS

Update and upgrade your server by running these commands

sudo apt-get update
sudo apt-get upgrade

Save the file and you are done.

Install Apache

Install Apache by running the following command

sudo apt-get install apache2

After doing so visit the public IP address and you should see something like this

Ubuntu with Apache just installed

Right now, all pages will be under the /var/www/html/ folder.

Create localhost user and default directory skeleton

Run the following commands that creates the user localhost as well as set home directory and password for it.

sudo useradd -d /var/www/localhost -m localhost
sudo passwd localhost

Create default directory

cd /var/www/localhost
sudo mkdir public_html
sudo mkdir logs
sudo chown -Rv localhost:localhost /var/www/localhost

Disable shell access as we only want these users to have access via SFTP – see more on this later

sudo usermod localhost -s /bin/false

Create additional users

Run the following commands to add new user with a home directory that is a copy of the /var/www/localhost directory

sudo useradd -d /var/www/sub-one.example.com -m -k "/var/www/localhost" sub-one.example.com
sudo passwd sub-one.example.com
sudo usermod sub-one.example.com -s /bin/false

Add Virtual Host

With a virtual host you tell Apache to host different sites on different places on your server.

To set up a virtual host copy the default virtual host file. I like to have one for each of my domains but you should be fine if you like to have all your setup in the same file

sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/sub-one.example.com.conf

The default file in my case i called 000-default.conf. It might just be called default.conf in other environments.

Now go and edit the file

sudo nano /etc/apache2/sites-available/sub-one.example.com.conf

It should look something like this – just replace the domain everywhere it occurs. If you wish to allow .htaccess files be sure to set AllowOverride to All in you home directory (in this case /var/www/sub-one.example.com/public_html)

<VirtualHost *:80>
        ServerName sub-one.example.com
        #ServerAlias example.com - change this if you wish to map example.com to www.example.com
        ServerAdmin webmaster@example.com
        DocumentRoot /var/www/sub-one.example.com/public_html

        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/sub-one.example.com/public_html>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog /var/www/sub-one.example.com/logs/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /var/www/sub-one.example.com/logs/access.log combined
</VirtualHost>

For other domains you can now copy this file like this

sudo cp /etc/apache2/sites-available/sub-one.example.com.conf /etc/apache2/sites-available/sub-two.example.com.conf

…and then edit the newly created file to change everywhere the domain name occurs.

To enable each site enter this command for each domain like this

sudo a2ensite sub-one.example.com

Now restart Apache

sudo service apache2 restart

You should now be able to access your sites on the domains you have made virtual host files for. In my case sub-one.example.com and sub-two.example.com. But currently, there is nothing on these sites so go on, and create an index.html in each of the public_html folders like this

sudo nano /var/www/sub-one.example.com/public_html/index.html

write something in each of the – e.g. <h2>sub-one.example.com</h2>. There is no need to write <html> <body> etc. as any modern browser will automatically do so for you. Remeber to create af file like this for each of your domains including localhost.

For the localhost (which shows the site when the public IP is entered in the browser) user it seems like Apache takes the first enabled site. You can either make a 000-localhost.conf file or edit the 000-default.conf file. I have chosen to make a 000-localhost.conf file

sudo cp /etc/apache2/sites-available/sub-one.example.com.conf /etc/apache2/sites-available/000-localhost.conf

Open the file and change all occurrences of sub-one.example.com with localhost. Furthermore, comment out or remove the ServerName so the document looks like this

<VirtualHost *:80>
        #ServerName localhost
        #ServerAlias example.com
        ServerAdmin webmaster@example.com
        DocumentRoot /var/www/localhost/public_html

        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/localhost/public_html>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog /var/www/localhost/logs/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /var/www/localhost/logs/access.log combined
</VirtualHost>

Once you have saved the document you should enabled it using the a2ensite command

sudo a2ensite 000-localhost.conf

Now you want to disable the 000-default.conf file

sudo a2dissite 000-default.conf

Once you have completed the above steps and reloaded Apache using sudo service apache2 reload  you should be able to visit the site on it’s IP and see the content of the file you have made on /var/www/localhost/public_html/index.html. Likewise, you should be able to visit the individual sites you have made using their URL.

Enable or disable Apache moduels

Apache comes with a bunch of modules that just need to be enabled. To see available modules type this command

ls /etc/apache2/mods-available

To see what is already enabled type this

ls /etc/apache2/mods-enabled

We need the rewrite module so let’s go on and enable that

sudo a2enmod rewrite

Once completed restart Apache

sudo service apache2 restart

Likewise, you can disable a module. Remember to restart Apache for the change to become effective

udo a2dismod mod_name

Chroot users and enable SFTP

If you try to use SSH to access the site you should be denied. That’s good. Now it is time to set up SFTP so it works with suPHP and gives the files you upload the correct permissions.

SFTP is a secure way of transferring your files to and from your server. It should work out of the box but you need to change a some things to get the right file permissions when using suPHP. Open the sshd_config file

sudo nano /etc/ssh/sshd_config

…and find the line

Subsystem sftp /usr/libexec/openssh/sftp-server

Change the line so i reads

Subsystem sftp internal-sftp

…and finally add this block to the end of the file (where sftp is the name of the group that restricts the users to SFTP access)

Match group sftp
    ChrootDirectory %h
    X11Forwarding no
    AllowTcpForwarding no
    ForceCommand internal-sftp -u 22

Save the file and reload the SSH service to

sudo service ssh reload

After modifying OpenSSH we need to modify our chrooted web user accounts to have the sftp group as a secondary group. But first, we need to add that group

sudo addgroup --system sftp

Modify the web user accounts to have the sftp group as a secondary group

sudo usermod -G sftp localhost

If the chroot environment is in a user’s home directory both /var/www and /var/www/username must be owned by root and should have permissions along the lines of 755 or 750.

To change this execute the this

sudo chown root:root /var/www/localhost

…and this

sudo chmod 755 /var/www/localhost

These users will now be unable to create files anywhere in the system but in subfolders to /var/www/username, since these directory are now owned by the root user.

Just to make sure that the correct owner and group is set for the files and folders below the user run this query

sudo chown localhost:localhost /var/www/localhost/*

This will make sure that the user is able to upload to all folders below /var/www/username/ – in our case the folders logs and not least public_html

You should now be all set and be able to upload/download using SFTP.

You might need to disconnect your SFTP connection and reconnect to make the right file permission come through.

SSH and SFTP on different ports

Our SSH access is is behind a firewall and so we need to connect to a VPN before we can access our servers via SSH. However, we need to be able to give users outside our organisation – who don’t have access to connect to our VPN – access to use SFTP. To solve this, we decided to run two instances of SSH with different configuration.

1. First step is to make a copy of the contents of the /etc/ssh/ directory. We have chosen to call the copy ssh-sftp throughout this example.

sudo cp -r /etc/ssh /etc/ssh-sftp

Open the sshd_config file en the newly duplicated folder.

sudo nano /etc/ssh-sftp/sshd_config

Change the port to something high that is not on this list of know port search numbers. In our example we change it to port 25468. You will also need to add a reference to PidFile so the changes in the sshd_config looks like this.

Port 25468
PidFile /var/run/ssh-sftp.pid

While you have that file open you also want to allow only the group sftp. This is done by entering the following just below the above.

AllowGroups sftp

Lastly, append the following lines to the files if they are not already there (from a previous step)

Match group sftp
    ChrootDirectory %h
    X11Forwarding no
    AllowTcpForwarding no
    ForceCommand internal-sftp -u 22

Save the file.

2. (This step might be obsolete) Make a copy of the /etc/default/ssh file and name the copy ssh-sftp.

sudo cp /etc/default/ssh /etc/default/ssh-sftp

Open the file…

sudo nano /etc/default/ssh-sftp

…and append ‘-f /etc/ssh-sftp/sshd_config’ to the SSHD_OPTS so the file looks like this.

# Default settings for openssh-server. This file is sourced by /bin/sh from
# /etc/init.d/ssh.

# Options to pass to sshd
SSHD_OPTS='-f /etc/ssh-sftp/sshd_config'

Save the file.

3. Copy the /etc/init/ssh.conf file and name the copy ssh-sftp.conf

sudo cp /etc/init/ssh.conf /etc/init/ssh-sftp.conf

Open the file…

sudo nano /etc/init/ssh-sftp.conf

…and change all instances of ssh with ssh-sftp. Furthermore, comment the line that says exec /usr/sbin/sshd -D  and replace it with exec /usr/sbin/sshd-sftp -D -f /etc/ssh-sftp/sshd_config  so the file looks like this (first part of the file is omitted).

#___CODE ABOVE OMITTED___
pre-start script
    test -x /usr/sbin/sshd || { stop; exit 0; }
    test -e /etc/ssh-sftp/sshd_not_to_be_run && { stop; exit 0; }

    mkdir -p -m0755 /var/run/sshd
end script

# if you used to set SSHD_OPTS in /etc/default/ssh, you can change the
# 'exec' line here instead
#exec /usr/sbin/sshd -D
exec /usr/sbin/sshd-sftp -D -f /etc/ssh-sftp/sshd_config

Save the file.

4. Make a symbolic link from /usr/sbin/sshd-sftp to /user/sbin/sshd by executing this command.

sudo ln -s /usr/sbin/sshd /usr/sbin/sshd-sftp

5. Copy the file /etc/init.d/ssh and name it ssh-sftp.

sudo cp /etc/init.d/ssh /etc/init.d/ssh-sftp

Open the file…

sudo nano /etc/init.d/ssh-sftp

…and replace all sshd with sshd-sftp as well as all ssh with ssh-sftp. The file should look somewhat similar to this.

#! /bin/sh

### BEGIN INIT INFO
# Provides:		sshd-sftp
# Required-Start:	$remote_fs $syslog
# Required-Stop:	$remote_fs $syslog
# Default-Start:	2 3 4 5
# Default-Stop:		
# Short-Description:	OpenBSD Secure Shell server
### END INIT INFO

set -e

# /etc/init.d/ssh-sftp: start and stop the OpenBSD "secure shell(tm)" daemon

test -x /usr/sbin/sshd-sftp || exit 0
( /usr/sbin/sshd-sftp -? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0

umask 022

if test -f /etc/default/ssh-sftp; then
    . /etc/default/ssh-sftp
fi

. /lib/lsb/init-functions

if [ -n "$2" ]; then
    SSHD_OPTS="$SSHD_OPTS $2"
fi

# Are we running from init?
run_by_init() {
    ([ "$previous" ] && [ "$runlevel" ]) || [ "$runlevel" = S ]
}

check_for_upstart() {
    if init_is_upstart; then
	exit $1
    fi
}

check_for_no_start() {
    # forget it if we're trying to start, and /etc/ssh-sftp/sshd_not_to_be_run exists
    if [ -e /etc/ssh-sftp/sshd_not_to_be_run ]; then 
	if [ "$1" = log_end_msg ]; then
	    log_end_msg 0 || true
	fi
	if ! run_by_init; then
	    log_action_msg "OpenBSD Secure Shell server not in use (/etc/ssh-sftp/sshd_not_to_be_run)" || true
	fi
	exit 0
    fi
}

check_dev_null() {
    if [ ! -c /dev/null ]; then
	if [ "$1" = log_end_msg ]; then
	    log_end_msg 1 || true
	fi
	if ! run_by_init; then
	    log_action_msg "/dev/null is not a character device!" || true
	fi
	exit 1
    fi
}

check_privsep_dir() {
    # Create the PrivSep empty dir if necessary
    if [ ! -d /var/run/sshd-sftp ]; then
	mkdir /var/run/sshd-sftp
	chmod 0755 /var/run/sshd-sftp
    fi
}

check_config() {
    if [ ! -e /etc/ssh-sftp/sshd_not_to_be_run ]; then
	/usr/sbin/sshd-sftp $SSHD_OPTS -t || exit 1
    fi
}

export PATH="${PATH:+$PATH:}/usr/sbin:/sbin"

case "$1" in
  start)
	check_for_upstart 1
	check_privsep_dir
	check_for_no_start
	check_dev_null
	log_daemon_msg "Starting OpenBSD Secure Shell server" "sshd-sftp" || true
	if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd-sftp.pid --exec /usr/sbin/sshd-sftp -- $SSHD_OPTS; then
	    log_end_msg 0 || true
	else
	    log_end_msg 1 || true
	fi
	;;
  stop)
	check_for_upstart 0
	log_daemon_msg "Stopping OpenBSD Secure Shell server" "sshd-sftp" || true
	if start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/sshd-sftp.pid; then
	    log_end_msg 0 || true
	else
	    log_end_msg 1 || true
	fi
	;;

  reload|force-reload)
	check_for_upstart 1
	check_for_no_start
	check_config
	log_daemon_msg "Reloading OpenBSD Secure Shell server's configuration" "sshd-sftp" || true
	if start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/sshd-sftp.pid --exec /usr/sbin/sshd; then
	    log_end_msg 0 || true
	else
	    log_end_msg 1 || true
	fi
	;;

  restart)
	check_for_upstart 1
	check_privsep_dir
	check_config
	log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd-sftp" || true
	start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /var/run/sshd-sftp.pid
	check_for_no_start log_end_msg
	check_dev_null log_end_msg
	if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd-sftp.pid --exec /usr/sbin/sshd-sftp -- $SSHD_OPTS; then
	    log_end_msg 0 || true
	else
	    log_end_msg 1 || true
	fi
	;;

  try-restart)
	check_for_upstart 1
	check_privsep_dir
	check_config
	log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd-sftp" || true
	RET=0
	start-stop-daemon --stop --quiet --retry 30 --pidfile /var/run/sshd-sftp.pid || RET="$?"
	case $RET in
	    0)
		# old daemon stopped
		check_for_no_start log_end_msg
		check_dev_null log_end_msg
		if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd-sftp.pid --exec /usr/sbin/sshd-sftp -- $SSHD_OPTS; then
		    log_end_msg 0 || true
		else
		    log_end_msg 1 || true
		fi
		;;
	    1)
		# daemon not running
		log_progress_msg "(not running)" || true
		log_end_msg 0 || true
		;;
	    *)
		# failed to stop
		log_progress_msg "(failed to stop)" || true
		log_end_msg 1 || true
		;;
	esac
	;;

  status)
	check_for_upstart 1
	status_of_proc -p /var/run/sshd-sftp.pid /usr/sbin/sshd-sftp sshd-sftp && exit 0 || exit $?
	;;

  *)
	log_action_msg "Usage: /etc/init.d/ssh-sftp {start|stop|reload|force-reload|restart|try-restart|status}" || true
	exit 1
esac

exit 0

6. Start the new ssh-sftp service

sudo service ssh-sftp start

You should now be able to use SFTP externally on port 25468 with your users that are a member of the sftp group (remember to open that port in the firewall if you have one). These users will not be able to get shell access but only have SFTP access.

Install PHP

We are now going to install PHP

sudo apt-get install libapache2-mod-php5

This will install and enable PHP as an Apache module.

You now might want to install additional PHP modules. In this case we are going to install MySQL and cURL

sudo apt-get install php5-mysql php5-curl

Restart Apache

sudo service apache2 restart

You should now be able to execute PHP scripts in your /var/www/[user]/public_html directories. To test, add a file named phpinfo.php to /var/www/localhost/public_html

sudo nano /var/www/localhost/public_html/phpinfo.php

…and enter the following in the file and save it

<?php phpinfo(); ?>

Visit the site on its IP or the domain mapped to localhost and type /phpinfo.php after the IP/domain. You should now get some info about your system.

You should remove this file once you are done testing. This can be done by executing

sudo rm /var/www/localhost/public_html/phpinfo.php

Install and set up suPHP

If you wish to run different sites under different users, suPHP is the answer. Furthermore, it gives an additional layer of security.

To install and enable suPHP execute the following

sudo apt-get install suphp-common libapache2-mod-suphp

Executing a PHP file now will return a 500 error. Don’t worry; we will fix this below.

Open each of your virtual host files. I’ll start with 000-localhost.conf

sudo nano /etc/apache2/sites-available/000-localhost.conf

In each host file add the following lines

php_admin_flag engine off
suPHP_Engine on

…so the file will look like this

<VirtualHost *:80>
        #ServerName localhost
        #ServerAlias localhost
        ServerAdmin webmaster@example.com
        DocumentRoot /var/www/localhost/public_html

        php_admin_flag engine off
        suPHP_Engine on

        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>        <Directory /var/www/localhost/public_html>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog /var/www/localhost/logs/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /var/www/localhost/logs/access.log combined
</VirtualHost>

Do the same for your other virtual host files

Edit the suPHP cofing file

sudo nano /etc/suphp/suphp.conf

Where it says

umask=0077

change it to

umask=0022

While you are there you might also want to change the loglevel from info to warn so it looks like this. Otherwise your suPHP log file will be flooded very quickly.

loglevel=warn

The full file should look something like this (I have uncommented the lines instead of replacing them with the above)

[global]
;Path to logfile
logfile=/var/log/suphp/suphp.log

;Loglevel
loglevel=warn

;User Apache is running as
webserver_user=www-data

;Path all scripts have to be in
docroot=/var/www:${HOME}/public_html

;Path to chroot() to before executing script
;chroot=/mychroot

; Security options
allow_file_group_writeable=false
allow_file_others_writeable=false
allow_directory_group_writeable=false
allow_directory_others_writeable=false

;Check wheter script is within DOCUMENT_ROOT
check_vhost_docroot=true

;Send minor error messages to browser
errors_to_browser=false

;PATH environment variable
env_path="/bin:/usr/bin"

;Umask to set, specify in octal notation
;umask=0077
umask=0022

; Minimum UID
min_uid=100

; Minimum GID
min_gid=100


[handlers]
;Handler for php-scripts
application/x-httpd-suphp="php:/usr/bin/php-cgi"
#application/x-httpd-php="php:/usr/bin/php-cgi"

;Handler for CGI-scripts
x-suphp-cgi="execute:!self"

You should now be able to execute PHP files again. But now Apache should use the respective user for the execution. To check it out create the following file

sudo nano /var/www/localhost/public_html/whoami.php

Enter the following in the file and save it

<?php echo exec('/usr/bin/whoami'); ?>

If you visit the site with your IP or domain and whoami.php it should write “localhost”

If you still get a 500 error there can be several reasons.

Check your file permissions. suPHP requires them to be atmost 755. Execute the following to correct the permissions

sudo chmod -Rv og-w /var/www/localhost/public_html/

Also, make sure you have set umask 0022 in

sudo nano /var/www/localhost/.bashrc

You could also have user id issues. This can be fixed by running

sudo chown -R localhost:localhost /var/www/localhost/public_html/

If you have PHP OPCode caching disable it and restart your server

If you are still experiencing issues check the Apache error log at

nano /var/www/localhost/logs/error.log

You might also want to check the suPHP log at

sudo nano /var/log/suphp/suphp.log

You might also want to change the default upload limit on 2048KiB. To do this edit the php.ini file. (if you cannot find the loaded php.ini file look in the phpinfo.php file.)

sudo nano /etc/php5/cgi/php.ini

Find an change the following lines to the desired size

; Maximum allowed size for uploaded files.
upload_max_filesize = 128M

; Must be greater than or equal to upload_max_filesize
post_max_size = 128M

Install MySQL

This is pretty straight forward. Just run

sudo apt-get install mysql-server

Then run the installation scripts…

sudo mysql_install_db

…and…

sudo mysql_secure_installation

When prompted make sure to set a secure root password. You can safely answer yes to all the questions.

Install phpMyAdmin

Even though phpMyAdmin is in the Ubuntu repository we are going to download it from source and upload it manually to the server.

Go to the phpMyAdmin downloads page and download the latest version of phpMyAdmin

Once downloaded unpack it and upload the folder (which in this example is named phpmyadmin) to your public_html using your localhost user (created in a previous step)

You should now be able to access phpMyAdmin at either the IP followed by /phpmyadmin or any domain assigned to the 000-localhost.conf (in /etc/apache2/sites-available/000-localhost.conf) followed by /phpmyadmin.

Once you confirmed it working change the url to something else so it is more difficult to guess for bots.

sudo mv /var/www/localhost/public_html/phpmyadmin /var/www/localhost/public_html/my-new-phpmyadmin-name

Instead of accessing phpMyAdmin on /phpmyadmin you should now access it on /my-new-phpmyadmin-name.

Finally you probably want to make access further secure – e.g. limiting access by IP or a second password. There is a great tutorial on securing phpMyAdmin on Digital Ocean (which is, by the way, a great hosting company)

Send emails with SMTP

For sending emails there is an excellent transactional email service called Mandrill by the folks at MailChimp. It is very simple to use and we only need to install SSMTP as a gateway.

sudo apt-get install ssmtp

Once installed open SSMTP settings…

sudo nano /etc/ssmtp/ssmtp.conf

…and make the content look like this

# ---- basic config
root=your@email.com
UseTLS=YES
UseSTARTTLS=YES
hostname=fqdn_of_your_server.example.com
FromLineOverride=NO
# ---- mandrill config
mailhub=smtp.mandrillapp.com:587
AuthUser=your_mandrill_email@example.com
AuthPass=mandrill_api_key

Run CRON jobs and send emails with result

Now that we are able to send emails we should be able to mail the results for CRON jobs. To make a CRON job for a specific user (in this case the user named sub-one.example.com) run the crontab command

sudo crontab -e -u sub-one.example.com

Append the following lines

MAILTO=your@email.com
5 20 7,16,26 * * php /var/www/sub-one.example.com/public_html/my-job-to-execute.php

This will execute the my-job-to-execute.php file at five minutes past 8 p.m. every 7th, 16th and 26th of every month and email the result to the designated email.


If you are having issues or suggestions for improvements don’t hesitate to make a comment.

Resources

http://www.intechgrity.com/install-apache-with-virtual-host-concept-on-ubuntu-vps/

https://www.linode.com/docs/tools-reference/tools/limiting-access-with-sftp-jails-on-debian-and-ubuntu

https://bensmann.no/restrict-sftp-users-to-home-folder/

http://sysadmin.circularvale.com/server-config/setting-a-umask-for-chrooted-sftp-users/

https://www.linuxquestions.org/questions/blog/anomie-152469/running-an-sftp-only-daemon-on-rhel5-3495/

https://stackoverflow.com/questions/3889377/set-umask-for-a-sftp-account

http://ubuntuforums.org/showthread.php?t=1497376

http://www.unixlore.net/articles/five-minutes-to-even-more-secure-ssh.html

https://www.sebel.ch/2013/12/using-mandrill-with-ssmtp/

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

  • Contact
  • © 2025 Søren Friis Dam