IP:3.239.109.55 Location:United States Status:Insecure
Setups Collection

Collection of setups

In this guide we will install LEMP Stack (Nginx, MySQL, PHP) and configure a web server on Ubuntu Server 20.04.

Choose Vultr (Affiliate link) to host your server.

Prerequisites
You should use a non-root user account with sudo privileges.

1. Install Nginx
The first step in creating a LEMP stack on Ubuntu 20.04 is by updating the package lists and installing Nginx. Type y and ENTER if prompted.

sudo apt update && sudo apt install nginx

Once installed, check to see if the Nginx service is running.

sudo service nginx status

If Nginx is running correctly, you should see a green Active state below.

● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-04-27 23:05:58 UTC; 2min 26s ago
Docs: man:nginx(8)
Main PID: 2433 (nginx)
Tasks: 2 (limit: 1137)
Memory: 5.1M
CGroup: /system.slice/nginx.service
├─2433 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
└─2434 nginx: worker process

Apr 27 23:05:58 ubuntu systemd[1]: Starting A high performance web server and a reverse proxy server...
Apr 27 23:05:58 ubuntu systemd[1]: Started A high performance web server and a reverse proxy server.

You may need to press q to exit the service status.

2. Configure Firewall
If you haven’t already done so, it is recommended that you enable the ufw firewall on Ubuntu 20.04 and add a rule for Nginx. Before enabling ufw firewall, make sure you add a rule for SSH, otherwise you may get locked out of your server if you’re connected remotely.

sudo ufw allow OpenSSH

If you get an error “ERROR: could find a profile matching openSSH”, this probably means you are not configuring the server remotely and can ignore it.

Now add a rule for Nginx.

sudo ufw allow 'Nginx Full'

Output:

Rule added
Rule added (v6)

Enable ufw firewall.

sudo ufw enable

Press y when asked to proceed.

Now check the firewall status.

sudo ufw status

Status: active

To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx Full ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx Full (v6) ALLOW Anywhere (v6)

The Nginx component of your LEMP Stack on Ubuntu 20.04 should now be ready to serve web pages.

3. Test Nginx
Go to your web browser and visit your domain or IP. If you don’t have a domain name yet and don’t know your IP, you can find out by running:

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'

Welcome to Nginx test page
You can find this Nginx default welcome page in the document root directory /var/www/html. To edit this file in nano text editor:

sudo nano /var/www/html/index.nginx-debian.html

To save and close nano, press CTRL + X and then press y and ENTER to save changes.

Your Nginx web server is ready to go. You can now add your own html files and images the the /var/www/html directory as you please.

4. Install MySQL
The next component of the LEMP Stack on Ubuntu 20.04 is MySQL.

Let’s begin by updating the repository and installing the MySQL package using apt.

sudo apt update && sudo apt install mysql-server

Press y and ENTER when prompted to install the MySQL package.

Once the package installer has finished, we can check to see if the MySQL service is running.

sudo service mysql status

If running, you will see a green Active status like below.

● mysql.service - MySQL Community Server
Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-04-02 02:40:59 CEST; 2min 47s ago
Main PID: 18476 (mysqld)
Status: "Server is operational"
Tasks: 27 (limit: 4915)
CGroup: /system.slice/mysql.service
└─18476 /usr/sbin/mysqld

Apr 02 02:40:59 ubuntu2004 systemd[1]: Starting MySQL Community Server...
Apr 02 02:40:59 ubuntu2004 systemd[1]: Started MySQL Community Server.

You may need to press q to exit the service status.

5. Configure MySQL Security
You should now run mysql_secure_installation to configure security for your MySQL server.

sudo mysql_secure_installation

5.1. Validate Password Component (Optional)
You will be asked if you want to set up the Validate Password Plugin. It’s not really necessary unless you want to enforce strict password policies for some reason.

Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No:

Press ENTER if you don’t want to set up the validate password plugin.

5.2. Create Root Password
If you didn’t create a root password in Step 1, you must now create one here.

Please set the password for root here.

New password:

Re-enter new password:

Generate a strong password and enter it. Note that when you enter passwords in Linux, nothing will show as you are typing (no stars or dots).

5.3. Remove Anonymous Users
You will next be asked to remove anonymous users.

By default, a MySQL installation has an anonymous user,
allowing anyone to log into MySQL without having to have
a user account created for them. This is intended only for
testing, and to make the installation go a bit smoother.
You should remove them before moving into a production
environment.

Remove anonymous users? (Press y|Y for Yes, any other key for No) :

Press y and ENTER to remove anonymous users.

5.4. Disable Remote Root Login
Normally, root should only be allowed to connect from
'localhost'. This ensures that someone cannot guess at
the root password from the network.

Disallow root login remotely? (Press y|Y for Yes, any other key for No) :

Press y and ENTER to disallow root login remotely.

5.5. Remove Test Database
By default, MySQL comes with a database named 'test' that
anyone can access. This is also intended only for testing,
and should be removed before moving into a production
environment.

Remove test database and access to it? (Press y|Y for Yes, any other key for No) :

Press y and ENTER to remove the test database.

5.6. Reload Privilege Tables
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.

Reload privilege tables now? (Press y|Y for Yes, any other key for No) :

Press y and ENTER to reload the privilege tables.

You’re all done!

5.7. Test MySQL Service
You can now log into the MySQL server. Because you are running this command as sudo, this will automatically log into MySQL using the MySQL root account. If you are prompted for a password, enter your Linux root account password, not the MySQL one.

sudo mysql

Output:

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 8.0.19-0ubuntu5 (Ubuntu)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

To exit MySQL, type exit and press ENTER.

exit

You have now successfully installed and secured the MySQL component of your LEMP Stack on Ubuntu 20.04.

6. Install PHP
The final component of your LEMP Stack on Ubuntu 20.04 is PHP.

Unlike Apache, Nginx does not contain native PHP processing. For that we have to install PHP-FPM (FastCGI Process Manager). FPM is an alternative PHP FastCGI implementation with some additional features useful for heavy-loaded sites.

You should add Ubuntu’s universe repository before installing php-fpm to ensure you get the correct package.

sudo add-apt-repository universe

Now update the package lists and install PHP-FPM on Ubuntu 20.04. We will also install php-mysql to allow PHP to communicate with the MySQL database. Press y and ENTER when asked to continue.

sudo apt update && sudo apt install php-fpm php-mysql

Once installed, check the PHP version.

php --version

If PHP was installed correctly, you should see something similar to below.

PHP 7.4.3 (cli) (built: Mar 26 2020 20:24:23) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies

Above we are using PHP version 7.4, though this may be a later version for you depending on which package was in the repository.

Depending on what version of Nginx and PHP you install, you may need to manually configure the location of the PHP socket that Nginx will connect to.

List the contents for the directory /var/run/php/

ls /var/run/php/

You should see a few entries here.

total 4
lrwxrwxrwx 1 root root 30 Apr 27 23:28 php-fpm.sock -> /etc/alternatives/php-fpm.sock
-rw-r--r-- 1 root root 5 Apr 27 23:28 php7.4-fpm.pid
srw-rw---- 1 www-data www-data 0 Apr 27 23:28 php7.4-fpm.sock

Above we can see the socket is called php7.4-fpm.sock. Remember this as you may need it for the next step.

7. Configure Nginx for PHP
We now need to make some changes to our Nginx server block.

The location of the server block may vary depending on your setup. By default, it is located in /etc/nginx/sites-available/default.

Edit the file in nano.

sudo nano /etc/nginx/sites-available/default

7.1. Prioritize index.php
Press CTRL + W and search for index.html.

Now add index.php before index.html

/etc/nginx/sites-available/default
index index.php index.html index.htm index.nginx-debian.html;

7.2. Server Name
Press CTRL + W and search for the line server_name.

Enter your server’s IP here or domain name if you have one.

/etc/nginx/sites-available/default
server_name YOUR_DOMAIN_OR_IP_HERE;

7.3. PHP Socket
Press CTRL + W and search for the line location ~ \.php.

You will need to uncomment some lines here by removing the # signs before the four lines marked in red below.

Also ensure value for fastcgi_pass socket path is correct. For example, if you installed PHP version 7.4, the socket should be: /var/run/php/php7.4-fpm.sock

If you are unsure which socket to use here, exit out of nano and run ls /var/run/php/

/etc/nginx/sites-available/default

location ~ \.php$ {
include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
}

Make sure to remove the # sign before the closing bracket } in red above.

7.4. Save and Test
Once you’ve made the necessary changes, save and close (Press CTRL + X, then press y and ENTER to confirm save)

Now check the config file to make sure there are no syntax errors.

sudo nginx -t

Output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If no errors, you can reload the Nginx config.

sudo service nginx reload

8. Test PHP
To see if PHP is working correctly on Ubuntu 20.04, create a new PHP file called info.php in the document root directory. By default, this is located in /var/www/html/, or if you set up multiple domains in a previous guide, it may be located in somewhere like /var/www/mytest1.com/public_html

Once you have the correct document root directory, use the nano text editor to create a new file info.php

sudo nano /var/www/html/info.php

Type or paste the following code into the new file.

/var/www/html/info.php
phpinfo();

Save and exit (press CTRL + X, press Y and then press ENTER)

You can now view this page in your web browser by visiting your server’s domain name or public IP address followed by /info.php: http://your_domain_or_IP/info.php

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'

phpinfo() outputs a large amount of information about the current state of PHP. This includes information about PHP compilation options and extensions, the PHP version and server information.

PHP LEMP Stack Nginx Ubuntu 20.04
You have now successfully installed PHP-FPM for Nginx on Ubuntu 20.04.

Make sure to delete info.php as it contains information about the web server that could be useful to attackers.

sudo rm /var/www/html/info.php


ENJOY and please send us your feedback!
You can always save your time by asking us to help you to set it up.

In this guide we will install PhpMyAdmin for Nginx on Ubuntu Server 20.04.

Choose Vultr (Affiliate link) to host your server.

Prerequisites
You should use a non-root user account with sudo privileges.

1. Install phpMyAdmin
Let’s begin by updating the package lists and installing phpMyAdmin for Nginx on Ubuntu 20.04.

sudo apt update && sudo apt install phpmyadmin

Press y and ENTER when asked to continue.

1.1. Select Nothing
If you are prompted to choose a web server like below, as there is no option for Nginx, press TAB and then ENTER to continue without selecting a web server.

Install and secure phpMyAdmin for Nginx on Ubuntu 20.04
1.2. Configure Database
Select Yes and press ENTER to install and configure the database.

1.3. Application Password
The MySQL application password is used internally by phpMyAdmin to communicate with MySQL and it is not recommended that you use it to log into phpMyAdmin. You can leave this blank and a password will be generated automatically.

Press ENTER to continue.

2. Create Symbolic Link
In order for Nginx to serve the phpMyAdmin files correctly, we must create a symbolic link from the phpMyAdmin directory /usr/share/phpmyadmin to the Nginx document root directory.

The default location of the Nginx document root in Ubuntu 20.04 should be /var/www/html/, though it could be different depending on your setup. If you followed a previous guide for setting up multiple domains for Nginx, your document root may be located in somewhere like /var/www/example.com/public_html.

Once you have confirmed your document root, let’s create a symbolic link from the phpMyAdmin directory to your document root. Here we will assume your document root is /var/www/html/ and we will simply add phpmyadmin to the end of it. This will allow us to access phpMyAdmin at example.com/phpmyadmin.

sudo ln -s /usr/share/phpmyadmin /var/www/html/phpmyadmin

3. Test phpMyAdmin
You should now be able to access the phpMyAdmin web interface by visiting your server’s domain name or public IP address followed by /phpmyadmin. e.g. http://example.com/phpmyadmin or http://192.168.1.10/phpmyadmin

If you don’t have a domain name yet or don’t know your IP, you can find out with:

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'

MySQL root Account and phpMyAdmin
In MySQL 5.7 and above, you will not be able to log into phpMyAdmin using the MySQL root account and will get an error “Access denied for user ‘root’@’localhost'”. Instead, you should create a new superuser account just for phpMyAdmin. If you want force MySQL to allow root login via phpMyAdmin, see: Can’t log into phpMyAdmin with root

4. Create MySQL Superuser
In terminal, log into MySQL using your MySQL root password.

You may have created a root password when you installed MySQL for the first time or the password could be blank. If you have forgotten your MySQL root password, see: Reset MySQL Root Password

sudo mysql -u root -p

Once logged in, add a new MySQL superuser with the username of your choice. In this example we are calling it pmauser. Click here to generate a strong password and replace password_here below with it.

CREATE USER 'pmauser'@'localhost' IDENTIFIED BY 'password_here';

Now grant superuser privileges to our new user pmauser.

GRANT ALL PRIVILEGES ON *.* TO 'pmauser'@'localhost';

Exit MySQL.

exit

You should now be able to access phpMyAdmin using this new user account.

phpMyadmin login Ubuntu 20.04
It is strongly recommended that you set up some additional security for phpMyAdmin in the steps below.

5. Obscure phpMyAdmin URL (Recommended)
Bots and attackers continuously scan web servers for the phpMyAdmin login page, so it is recommended that you change the URL to something else.

In this example we are going to change it from example.com/phpmyadmin to example.com/pma_hidden, though you can change it to whatever you want.

In step 2, we created a symbolic link in the document root /var/www/html/phpmyadmin

All we need to do is to rename this symbolic link, in this example, to: pma_hidden. Make sure you enter the correct document root here. The default is /var/www/html though it may be something like /var/www/example.com/public_html/ on your server.

sudo mv /var/www/html/phpmyadmin /var/www/html/pma_hidden

You should now be able to access phpMyAdmin at example.com/pma_hidden

6. Secure phpMyAdmin (Recommended)
To provide an additional layer of security, we can set up authentication in Nginx.

We will now install apache2-utils, which can generate the .htpasswd file that works with both Nginx and Apache.

sudo apt install apache2-utils

Once installed, we can generate the .htpasswd file. Simply change username to whatever username you want. Generate a password and keep it safe.

sudo htpasswd -c /etc/nginx/.htpasswd username

There should now be a .htpasswd file containing your username and encrypted password. You can check with:

cat /etc/nginx/.htpasswd

You should see something like username:$apr1sdfsdf4435sdtskLfWmmg1sfdsdgg4

We now need to add two directives to our Nginx configuration file. The location of the config file may vary depending on your setup, though the default is usually in /etc/nginx/sites-available/default. If you set up multiple domains in a previous guide, your config file may be located in somewhere like /etc/nginx/sites-available/example.com

This this example, we will assume the config file is in /etc/nginx/sites-available/default. Open the file to edit.

sudo nano /etc/nginx/sites-available/default

Scroll down and look for the location blocks and paste in a new block underneath them with the name of your obscured phpMyAdmin folder, in this example pma_hidden.

/etc/nginx/sites-available/default
location /pma_hidden {
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
}

Save file and exit (press CTRL + X, press Y and then press ENTER).

Check that the Nginx config file is valid, otherwise the server could crash on restart.

sudo nginx -t

If valid, reload Nginx config.

sudo service nginx reload

Now when visiting example.com/pma_hidden, you should be presented with an authentication window.


ENJOY and please send us your feedback!
You can always save your time by asking us to help you to set it up.

In this guide we will install PhpMail on Ubuntu Server 20.04.

Choose Vultr (Affiliate link) to host your server.

Prerequisites
You should use a non-root user account with sudo privileges.

1. Install Postfix
Let’s update the package database first.

sudo apt-get update
Install mailutils, which will automatically install Postfix.

sudo apt install -y mailutils
On the first Postfix configuration screen, select OK by pressing TAB and ENTER

Select Internet Site and press ENTER.

System mail name should be your domain name eg. example.com, press ENTER.

Package should now be installed.

2. Configure Postfix
For security reasons, you should instruct Postfix only to process requests to send emails from the server on which it is running.

Edit the Postfix configuration file.

sudo nano /etc/postfix/main.cf
Towards the bottom of the file, find the line inet_interfaces = all. (Press CTRL + W to search)
Change it to:

/etc/postfix/main.cf
inet_interfaces = loopback-only
Save file and exit. (Press CTRL + X, press Y and then press ENTER)

Lastly, let’s restart Postfix.

sudo systemctl restart postfix
If you intend on sending email to your own domain, Postfix requires some additional configuration. For example, I want my PHP app to send emails to info@devanswers.co. This will fail if you don’t make some additional changes to your main.cf file.

Can’t send mail to own domain. Postfix: status=bounced (unknown user: “user”)
3. Test Postfix
We’ll now send a test email message. Make sure to replace test@example.com with your own email address.

echo "Test Email message body" | mail -s "Email test subject" test@example.com
Don’t forget to check your spam folder.

If you still haven’t received any mail after a few minutes, check the mail error log.

sudo tail /var/log/mail.log
If the mail log is empty or doesn’t give enough information, try parsing the syslog. This will return the last 50 entries for postfix.

sudo tail -f -n 50 /var/log/syslog | grep postfix
If the syslog is empty and you still haven’t received any test email, it’s possible that the test email was rejected by the recipient server. You should check to see if anything has bounced back to your mail folder.

sudo less /var/mail/$(whoami)
Press uppercase G to scroll to the bottom of the file and lowercase q to quit. The $(whoami) variable returns the currently logged in user.

Update Feb 2020: If you are sending to Gmail, Outlook or other large email providers, you may get a bounce error similar to “This message does not have authentication information or fails”. If so, please see article:

Postfix Gmail Bounce: This message does not have authentication information or fails to 550-5.7.26 pass authentication checks.
4. Test PHP mail()
If Postfix is working correctly, you should now be able to send mail via PHP mail().

$to = 'nobody@example.com';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: webmaster@example.com' . "\r\n" .
'Reply-To: webmaster@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);
?>
Mail Never Received / Spam Issues
If emails are being rejected by the remote mail provider (such as Gmail), or mail is going straight to your email client’s spam folder, you may need to do some additional configuration on your domain (SPF, DKIM, DMARC records) to get past spam filters. Please see:

Postfix Gmail Bounce: This message does not have authentication information or fails to 550-5.7.26 pass authentication checks.
Alternatively, you could relay messages through an external SMTP server of your choice or through Gmail’s SMTP server.


ENJOY and please send us your feedback!
You can always save your time by asking us to help you to set it up.

In this guide we will install Postfix GMAil SMTP on Ubuntu Server 20.04.

Choose Vultr (Affiliate link) to host your server.

Prerequisites
You should use a non-root user account with sudo privileges.
If you’re not using 2-Step Verification, please ensure that your Gmail account is configured to allow less secures apps.

1. Install Postfix
If you’ve already installed Postfix, skip to step 2.

Let’s update the package database first.

sudo apt-get update
Install mailutils, which will automatically install Postfix.

sudo apt install -y mailutils
On the first Postfix configuration screen, select OK by pressing TAB and ENTER

Select Internet Site and press ENTER.

System mail name should be your domain name eg. example.com, press ENTER.

Package should now be installed.

2. Configure Postfix
Edit the Postfix configuration file.

sudo nano /etc/postfix/main.cf
Find the following line relayhost = about 6 lines up from the bottom of the file and delete it.

Add the following to the end of the file.

/etc/postfix/main.cf
relayhost = [smtp.gmail.com]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_tls_CAfile = /etc/postfix/cacert.pem
smtp_use_tls = yes
Save file and exit. (Press CTRL + X, press Y and then press ENTER)

3. Create Password and DB Files
Create the sasl_passwd file which will store our credentials.

sudo nano /etc/postfix/sasl_passwd
Insert the following:

/etc/postfix/sasl_passwd
[smtp.gmail.com]:587 username@gmail.com:password
Replace username and password with your own.

Save file and exit. (Press CTRL + X, press Y and then press ENTER)

Create a hash database file for Postfix with the postmap command.

sudo postmap /etc/postfix/sasl_passwd
There should now be a file called sasl_passwd.db in the /etc/postfix/ directory.

For added security, we will only allow root user to read and write to sasl_passwd and sasl_passwd.db

sudo chown root:root /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db
sudo chmod 0600 /etc/postfix/sasl_passwd /etc/postfix/sasl_passwd.db

4. Sign Certificate
Now we are going to create the certificate.

cat /etc/ssl/certs/thawte_Primary_Root_CA.pem | sudo tee -a /etc/postfix/cacert.pem
There should now be a certificate file called cacert.pem in /etc/postfix

5. Send a Test Mail
We’ll now send a test email message. Make sure to replace test@example.com with your own email address.

echo "Test Email message body" | mail -s "Email test subject" test@example.com
Don’t forget to check your spam folder.

If you still haven’t received any mail, check the mail error log.

sudo tail /var/log/mail.log
If the mail log is empty or doesn’t exist, try parsing the syslog. This will return the last 50 entries for postfix.

sudo tail -f -n 50 /var/log/syslog | grep postfix
If the syslog is empty and you still haven’t received any test email, it’s possible that the test email was rejected by the recipient server. You should check to see if anything has bounced back to your mail folder.

sudo less /var/mail/$(whoami)
Press uppercase G to scroll to the bottom of the file and lowercase q to quit. The $(whoami) variable returns the currently logged in user.

6. Allow Less Secure Apps
If Gmail is not allowing postfix to connect via SMTP, you may need to enable “Allow Less Secure Apps” on your Gmail account.

Please see: Allow less secure apps to access your Gmail account

Note: Sending Mail to Your Own Domain
If you ever intend to send email from postfix to your own domain, webmaster@example.com for example, postfix may need some further configuration.


ENJOY and please send us your feedback!
You can always save your time by asking us to help you to set it up.

In this guide we will change Postfix configuration on Ubuntu Server 20.04.

Choose Vultr (Affiliate link) to host your server.

Prerequisites
You should use a non-root user account with sudo privileges.

Having problems sending email to your own domain? You may need to change your postfix configuration.

I was experiencing a problem sending mail to an address at my own domain. I wanted my PHP app to send notification emails to info@devanswers.co but they kept bouncing with “status=bounced (unknown user: “user”)”.

Accessing the log:

sudo tail /var/log/mail.log -n 200
This will return the last 200 lines of the log.

Log output:

/var/log/mail.log
May 24 12:28:04 example postfix/pickup[30776]: DC48FC0927: uid=33 from=
May 24 12:28:04 example postfix/cleanup[32746]: DC48FC0927: message-id=<7662c91b0e00d2a3eb28eb1dbee01d98@178.62.26.57>
May 24 12:28:04 example postfix/qmgr[1711]: DC48FC0927: from=, size=9136, nrcpt=1 (queue active)
May 24 12:28:04 example postfix/local[32748]: DC48FC0927: to=, relay=local, delay=0.06, delays=0.03/0.01/0/0.01, dsn=5.1.1, status=bounced (unknown user: "user")
May 24 12:28:04 example postfix/cleanup[32746]: E7413C0928: message-id=<20170524122804.E7413C0928@example.com>
May 24 12:28:04 example postfix/qmgr[1711]: E7413C0928: from=<>, size=10993, nrcpt=1 (queue active)
May 24 12:28:04 example postfix/bounce[32749]: DC48FC0927: sender non-delivery notification: E7413C0928
May 24 12:28:04 example postfix/qmgr[1711]: DC48FC0927: removed
May 24 12:28:04 example postfix/local[32748]: E7413C0928: to=, relay=local, delay=0.01, delays=0/0/0/0, dsn=2.0.0, status=sent (delivered to mailbox)
May 24 12:28:04 example postfix/qmgr[1711]: E7413C0928: removed
May 24 12:28:04 example postfix/pickup[30776]: EBC48C0927: uid=33 from=
May 24 12:28:04 example postfix/cleanup[32746]: EBC48C0927: message-id=
May 24 12:28:04 example postfix/qmgr[1711]: EBC48C0927: from=, size=8898, nrcpt=1 (queue active)
I’m not sure if others have experienced this issue, but if your email server is hosted on another domain and you use postfix and SMTP to send local emails from a PHP web form for example, then you need to setup the following in your postfix configuration.

Open your Postfix config file.

sudo nano /etc/postfix/main.cf
Scroll down and look for the entries for myhostname and mydestination. Change them so they look like this.

/etc/postfix/main.cf
. . .
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = localhost
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
. . .
This forces postfix to always use the external email server, even in a case the email recipient is under your local domain name, like myself@mydomain.com.

Lastly, let’s restart Postfix.

sudo systemctl restart postfix
You can send a test email to see if it works.

echo "Test Email message body" | mail -s "Email test subject" example@example.com


ENJOY and please send us your feedback!
You can always save your time by asking us to help you to set it up.

In this guide we will install SFTP server on Ubuntu Server 20.04.

Choose Vultr (Affiliate link) to host your server.

Prerequisites
You should use a non-root user account with sudo privileges.
Before you begin…
It’s surprising how many web developers are still unaware of SFTP and the advantages over FTP/FTPS. SFTP comes with Linux Server preinstalled and works just like normal FTP, but is more secure and less hassle to set up. If your FTP client supports SFTP, you should use it!

How to configure SFTP for a web server document root

1. Install vsftpd
Let’s begin by updating the package lists and installing vsftpd on Ubuntu 20.04.

Below we have two commands separated by &&. The first command will update the package lists to ensure you get the latest version and dependencies for vsftpd. The second command will then download and install vsftpd. Press y and ENTER when asked to continue.

sudo apt update && sudo apt install vsftpd

Once installed, check the status of vsftpd

sudo service vsftpd status

● vsftpd.service - vsftpd FTP server
Loaded: loaded (/lib/systemd/system/vsftpd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2020-04-27 19:35:30 IST; 13s ago
Main PID: 54532 (vsftpd)
Tasks: 1 (limit: 1137)
Memory: 652.0K
CGroup: /system.slice/vsftpd.service
└─54532 /usr/sbin/vsftpd /etc/vsftpd.conf

Apr 27 19:35:30 ubuntu systemd[1]: Starting vsftpd FTP server...
Apr 27 19:35:30 ubuntu systemd[1]: Started vsftpd FTP server.

Above we can see our FTP server is now up and running.

2. Configure Firewall
If you haven’t already done so, it is recommended that you enable the ufw firewall for Ubuntu 20.04. Before enabling ufw firewall, make sure you add a rule for SSH, otherwise you may get locked out of your server if you’re connected remotely. If you don’t want to set up a firewall, skip to Step 3.

sudo ufw allow OpenSSH

Let’s open ports 20 and 21 for FTP, and ports 40000-50000 for passive FTP. We’ll also open port 990 for TLS, which we will set up later.

sudo ufw allow 20/tcp

sudo ufw allow 21/tcp

sudo ufw allow 40000:50000/tcp

sudo ufw allow 990/tcp

Now, enable the firewall if it isn’t already. Press y and ENTER if warned about disrupting the SSH connection.

sudo ufw enable

To check the status of the firewall, run:

sudo ufw status

If the firewall is running, you should see Status: active and the firewall rules we just added.

Status: active

To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Apache Full ALLOW Anywhere
3306 ALLOW Anywhere
20/tcp ALLOW Anywhere
21/tcp ALLOW Anywhere
40000:50000/tcp ALLOW Anywhere
990/tcp ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Apache Full (v6) ALLOW Anywhere (v6)
3306 (v6) ALLOW Anywhere (v6)
20/tcp (v6) ALLOW Anywhere (v6)
21/tcp (v6) ALLOW Anywhere (v6)
40000:50000/tcp (v6) ALLOW Anywhere (v6)
990/tcp (v6) ALLOW Anywhere (v6)

3. Create FTP User
We will now create a new user that we will use to log into FTP. In this example, we will create a new user called ftpuser.

sudo adduser ftpuser

Generate a strong password and keep it safe.

You may also be asked to enter some contact information. You can just press ENTER to each of these.

If you only want ftpuser to log in via FTP, you should disable their SSH access by blacklisting their username in the SSH config file. Otherwise, skip to Step 4.

Open the SSH config in nano.

sudo nano /etc/ssh/sshd_config

Add the following to the bottom of the file replacing ftpuser with the user you want to deny SSH and SFTP access. You can add multiple users here separated by a single space. (To paste in nano, press the right mouse button). /etc/ssh/sshd_config

DenyUsers ftpuser

To save file and exit, press CTRL + X, press Y and then press ENTER.

Restart the SSH service.

sudo service sshd restart

4. Directory Permissions
You now need to decide where this new FTP user is allowed to view and upload files.

vsftpd uses chroot jails to restrict users to their home directories and requires that the home directory is not writable. For that reason, we have to set up some directories and permissions.

If you plan on using this FTP user account to upload files to a web server, continue to Step 4.1. If you just want to upload to a home folder, skip to Step 4.2.

Method 1. Upload to a Web Server
In many cases, you want to be able to upload files to the document root on the web server.

If you followed a previous guide here for setting up multiple domains, your document root may be located in somewhere like /var/www/test1.com/public_html – in that case, you would need to set the home folder for ftpuser to the folder above the document root: /var/www/test1.com (substituting test1.com for your own domain).

If you are not using multiple domains, we will assume you are using the default document root /var/www/html for both Apache and Nginx in Ubuntu 20.04. In this scenario, we have to make /var/www/ the home directory for our user ftpuser.

Let’s set the folder above the document root as the home directory for ftpuser.

sudo usermod -d /var/www ftpuser

Now set ownership of the document root directory to ftpuser. (The default is /var/www/html, though it may be /var/www/test1.com/public_html on your server.)

This will allow our FTP user to write and alter files in the document root directory.

sudo chown ftpuser:ftpuser /var/www/html

Now skip to Step 5 to configure vsftpd.

Method 2: Upload to a Home Folder
If instead you want this user to upload files to the home directory, create a new directory called ftp in the user’s home directory and another within it called files. In this example below our user is called ftpuser.

sudo mkdir /home/ftpuser/ftp

Set the ownership of the ftp directory to no nobody:nogroup.

sudo chown nobody:nogroup /home/ftpuser/ftp

Set permissions for the ftp directory using chmod so that it is not writable by anyone, otherwise vsftpd will not allow you to log in. a-w means a = all/everyone - = remove w = write permission, so, remove write permissions for everyone.

sudo chmod a-w /home/ftpuser/ftp

Next we will create a new directory within /ftp where the user can view and upload files.

sudo mkdir /home/ftpuser/ftp/files

Assign ownership of this directory to our new FTP user otherwise they will not be able to write to it.

sudo chown ftpuser:ftpuser /home/ftpuser/ftp/files

5. Configure vsftpd
There are a few changes we have to make to the vsftpd configuration file before you can start using FTP on Ubuntu 20.04.

Rename the config file.

sudo mv /etc/vsftpd.conf /etc/vsftpd.conf.bak

Create a new config file with nano editor.

sudo nano /etc/vsftpd.conf

Paste in the following:

/etc/vsftpd.conf
listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=vsftpd
force_dot_files=YES
pasv_min_port=40000
pasv_max_port=50000

If you followed Method 2 previously and only want this user to upload files to the home folder, we must tell vsftpd that the local_root is the /ftp folder we created earlier. Don’t add these two lines if you want the user to upload to the web document root!.

etc/vsftpd.conf
user_sub_token=$USER
local_root=/home/$USER/ftp

We are done with vsftpd.conf

To save file and exit, press CTRL + X, press Y and then press ENTER.

Restart vsftpd.

sudo systemctl restart vsftpd

6. Test FTP
We can now test vsftpd to see if we can log in as the user we created earlier. We recommend FileZilla, which works on Windows, Mac and Linux.

Enter your server’s IP, your FTP username and password you created earlier, and click Quickconnect.

Above we can see we have connected successfully and the web root directory html is displayed, though this may be different on your server.

Try uploading, creating and editing folders and files within the web root directory to ensure permissions are working correctly.

You will notice we have a warning in FileZilla “Status: Insecure server, it does not support FTP over TLS.” It is highly recommended that you now configure TLS so that login credentials and traffic are encrypted over the FTP connection.

If you are having problems logging in to the FTP server, try checking the vsftpd log. To view the last 200 entries using tail:

sudo tail /var/log/vsftpd.log -n 200

7. Secure FTP with TLS (Recommended)
It’s important to keep a few things in mind when using FTP – it is not encrypted by default meaning your credentials and files that you send are vulnerable to interception. To address this you should connect to vsftpd using FTPS (FTP over SSL/TLS).

Let’s begin by creating a new certificate with the openssl tool.

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem

You will be asked to enter some details like country, etc. You don’t have to fill these in. You can just press ENTER for defaults.

Now that your private key has been created, there are a few changes we have to make to the vsftpd configuration file.

Open the config file in nano editor.

sudo nano /etc/vsftpd.conf

Paste in the following beneath it.

/etc/vsftpd.conf
ssl_enable=YES
rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH

Save and exit (press CTRL + X, press Y and then press ENTER)

Restart vsftpd.

sudo systemctl restart vsftpd

8. Testing TLS with FileZilla
We can now test TLS. We recommend FileZilla, which works on Windows, Mac and Linux.

Enter your server’s IP, your FTP username and password you created earlier, and click Quickconnect.

You may be presented with an Unknown Certificate warning. Click Always trust this certificate in future sessions and click OK.

If you are connected over TLS, it will tell you in the connection log. You will also see a padlock in the bottom right corner.


ENJOY and please send us your feedback!
You can always save your time by asking us to help you to set it up.

© Copyright 2017-2020 Secureme.
All Rights Reserved.