<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="https://www.w3.org/2005/Atom">
 <title><span>M</span>atteo <span>M</span>attei</title>
 <link href="https://www.matteomattei.com/atom.xml" rel="self"/>
 <link href="https://www.matteomattei.com/"/>
 <updated>2024-07-23T11:11:14+02:00</updated>
 <id>https://www.matteomattei.com</id>
 <author>
   <name>Matteo Mattei</name>
   <email>info@matteomattei.com</email>
 </author>
 
 <entry>
   <title>Full web server setup with Debian 12 (Bookworm)</title>
   <link href="https://www.matteomattei.com/full-web-server-setup-with-debian-12-bookworm/"/>
   <updated>2024-07-23T00:00:00+02:00</updated>
   <id>https://www.matteomattei.com/full-web-server-setup-with-debian-12-bookworm</id>
   <content type="html">&lt;h1 id=&quot;setup-bash-and-update-the-system&quot;&gt;Setup bash and update the system&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt update
apt dist-upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-hostname-correctly&quot;&gt;Configure hostname correctly&lt;/h1&gt;

&lt;p&gt;Make sure to have the following two lines (with the same format) at the top of your &lt;em&gt;/etc/hosts&lt;/em&gt; file&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;127.0.0.1       localhost.localdomain localhost
xxx.xxx.xxx.xxx web1.myserver.com web1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: &lt;em&gt;xxx.xxx.xxx.xxx&lt;/em&gt; is the public IP address assigned to your server.&lt;/p&gt;

&lt;p&gt;Add you full hostname (for example &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;web1.myserver.com&lt;/code&gt;) to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/hostname&lt;/code&gt; and apply it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hostname -F /etc/hostname
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then to validate that the FQDN is valid and correctly applied type this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;hostname -f
// the answer should be web1.myserver.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;install-all-needed-packages&quot;&gt;Install all needed packages&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt install wget vim git acl screen rsync net-tools pwgen mariadb-server mariadb-client nginx iptables shorewall php php-cli php-curl php-dev php-gd php-imagick php-imap php-memcache php-pspell php-tidy php-xmlrpc php-pear php-fpm php-mbstring php-mysql certbot phpmyadmin python3-pip python3-tld postfix ntp ca-certificates bsd-mailx tree
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Postfix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select &lt;strong&gt;Internet Site&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;System mail name: (insert here the FQDN, for example web1.myserver.com)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Web server to reconfigure automatically:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Do not select anything and continue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Configure database for phpmyadmin with dbconfig-common?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select &lt;strong&gt;Yes&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;MySQL application password for phpmyadmin:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Leave blank and press &lt;strong&gt;Ok&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;setup-nginx&quot;&gt;Setup Nginx&lt;/h1&gt;

&lt;p&gt;Stop Nginx web server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/nginx stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Backup Nginx configuration:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Add the following lines in &lt;em&gt;/etc/nginx/nginx.conf&lt;/em&gt; after &lt;em&gt;tcp_nopush on;&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tcp_nodelay on;
keepalive_timeout 65;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And the following lines after &lt;em&gt;gizp on;&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;gzip_disable &quot;msie6&quot;;

gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

# max body size
client_max_body_size 10M;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Copy some nginx configuration files:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir -p /etc/nginx/certs
ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/nginx/certs/server.crt
ln -s /etc/ssl/private/ssl-cert-snakeoil.key /etc/nginx/certs/server.key

mkdir -p /etc/nginx/global
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/nginx/global/codeigniter_production.conf &amp;gt; /etc/nginx/global/codeigniter_production.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/nginx/global/codeigniter_testing.conf &amp;gt; /etc/nginx/global/codeigniter_testing.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/nginx/global/common.conf &amp;gt; /etc/nginx/global/common.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/nginx/global/dokuwiki.conf &amp;gt; /etc/nginx/global/dokuwiki.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/nginx/global/phpmyadmin.conf &amp;gt; /etc/nginx/global/phpmyadmin.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/nginx/global/plainphp.conf &amp;gt; /etc/nginx/global/plainphp.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/nginx/global/ssl.conf &amp;gt; /etc/nginx/global/ssl.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/nginx/global/wordpress.conf &amp;gt; /etc/nginx/global/wordpress.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Restart Nginx:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/nginx restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-lets-encrypt&quot;&gt;Setup let’s encrypt&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;certbot register --agree-tos -m &amp;lt;your@email&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-mariadb&quot;&gt;Setup MariaDB&lt;/h1&gt;

&lt;p&gt;Secure MariaDB installation:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Enter current password for root (enter for none): &lt;strong&gt;[ENTER]&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Switch to unix_socket authentication [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Change the root password? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;New password: &lt;em&gt;MARIAB_ROOT_PASSWORD&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Re-enter new password: &lt;em&gt;MARIAB_ROOT_PASSWORD&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Remove anonymous users? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Disallow root login remotely? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Remove test database and access to it? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Reload privilege tables now? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Set MariaDB root password in a configuration file (the same password configured before!)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt; /root/.my.cnf
[client]
user = root
password = MARIADB_ROOT_PASSWORD
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Optional&lt;/em&gt; enable MySQL slow query logging (often useful during slow page load debugging):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sed -i &quot;{s/^#slow_query_log_file /slow_query_log_file /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#long_query_time /long_query_time /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log_slow_verbosity /log_slow_verbosity /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log-queries-not-using-indexes/log-queries-not-using-indexes/g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;MySQL is now configured, so restart it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/mariadb restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-shorewall-firewall-rules&quot;&gt;Configure Shorewall firewall rules&lt;/h1&gt;

&lt;p&gt;Copy the default configuration for one interface:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /usr/share/doc/shorewall/examples/one-interface
cp interfaces /etc/shorewall/
cp policy /etc/shorewall/
cp rules /etc/shorewall/
cp zones /etc/shorewall/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now open &lt;em&gt;/etc/shorewall/policy&lt;/em&gt; file and change the line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;net             all             DROP            info
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;removing &lt;em&gt;info&lt;/em&gt; directive given it fills the system logs:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;net             all             DROP
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now open &lt;em&gt;/etc/shorewall/rules&lt;/em&gt; and add the following rules at the bottom of the file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HTTP/ACCEPT     net             $FW
HTTPS/ACCEPT    net             $FW
SSH/ACCEPT      net             $FW
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;NOTE: in case you want to allow ICMP (Ping) traffic from a specific remote hosts you need to add a rule similar to the following where xxx.xxx.xxx.xxx is the remote IP address, before the &lt;strong&gt;Ping(DROP)&lt;/strong&gt; rule:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Ping(ACCEPT)    net:xxx.xxx.xxx.xxx       $FW
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now edit &lt;em&gt;/etc/default/shorewall&lt;/em&gt; and change &lt;strong&gt;startup=0&lt;/strong&gt; to &lt;strong&gt;startup=1&lt;/strong&gt;
You are now ready to start the firewall:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/shorewall start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-postfix&quot;&gt;Setup Postfix&lt;/h1&gt;

&lt;p&gt;Stop postfix server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/postfix stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Edit &lt;em&gt;/etc/mailname&lt;/em&gt; and set your server domain name, for example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;server1.mycompany.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Restart Postfix:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/postfix start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;select-correct-timezone&quot;&gt;Select correct timezone&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dpkg-reconfigure tzdata
# Select your timezone (for example Europe/Rome)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;log-rotation&quot;&gt;Log rotation&lt;/h1&gt;

&lt;p&gt;In order to correctly log files you need to adjust logrotate configuration for Nginx:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; /etc/logrotate.d/nginx
/home/*/*/logs/*.log {
        daily
        missingok
        rotate 14
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
        endscript
}
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;install-virtualhost-manager&quot;&gt;Install virtualhost manager&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/lemp_manager.py &amp;gt; /usr/local/sbin/lemp_manager.py
chmod 770 /usr/local/sbin/lemp_manager.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Download also the tools that will be used with cron:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir /root/cron_scripts
cd /root/cron_scripts
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/cron_scripts/backup_mysql.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian12/cron_scripts/mysql_optimize.sh
chmod 770 *.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-cron&quot;&gt;Configure CRON&lt;/h1&gt;

&lt;p&gt;Edit &lt;em&gt;/etc/crontab&lt;/em&gt; and add the following lines at the bottom:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# mysql optimize tables
3  4  *  *  7   root    /root/cron_scripts/mysql_optimize.sh

# mysql backup
32 4  *  *  *   root    /root/cron_scripts/backup_mysql.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;how-to-use-virtualhost-manager&quot;&gt;How to use virtualhost manager&lt;/h1&gt;

&lt;p&gt;You can use the virtualhost manager for adding or removing virtualhosts:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# lemp_manager

Usage:
/usr/local/sbin/lemp_manager -a|--action=&amp;lt;action&amp;gt; [-d|--domain=&amp;lt;domain&amp;gt;] [-A|--alias=&amp;lt;alias&amp;gt;] [options]

Parameters:
	-a|--action=ACTION
		it is mandatory
	-d|--domain=domain.tld
		can be used only with [add_domain, remove_domain, add_alias, get_certs, get_info]
	-A|--alias=alias.domain.tld
		can be used only with [add_alias, remove_alias, get_info]

Actions:
	add_domain	Add a new domain
	add_alias	Add a new domain alias to an existent domain
	remove_domain	Remove an existent domain
	remove_alias	Remove an existent domain alias
	get_certs	Obtain SSL certificate and deploy it
	get_info	Get information of a domain or a domain alias (username)

Options:
	-f|--fakessl	Use self signed certificate (only usable with [add_domain, add_alias])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
 <entry>
   <title>Full web server setup with Debian 11 (Bullseye)</title>
   <link href="https://www.matteomattei.com/full-web-server-setup-with-debian-11-bullseye/"/>
   <updated>2022-11-05T00:00:00+01:00</updated>
   <id>https://www.matteomattei.com/full-web-server-setup-with-debian-11-bullseye</id>
   <content type="html">&lt;h1 id=&quot;setup-bash-and-update-the-system&quot;&gt;Setup bash and update the system&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt-get update
apt-get dist-upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-hostname-correctly&quot;&gt;Configure hostname correctly&lt;/h1&gt;

&lt;p&gt;Make sure to have the following two lines (with the same format) at the top of your &lt;em&gt;/etc/hosts&lt;/em&gt; file&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;127.0.0.1       localhost.localdomain localhost
xxx.xxx.xxx.xxx web1.myserver.com web1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: &lt;em&gt;xxx.xxx.xxx.xxx&lt;/em&gt; is the public IP address assigned to your server.&lt;/p&gt;

&lt;h1 id=&quot;install-all-needed-packages&quot;&gt;Install all needed packages&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt install wget vim git acl screen rsync net-tools pwgen mariadb-server mariadb-client nginx iptables shorewall php php-cli php-curl php-dev php-gd php-imagick php-imap php-memcache php-pspell php-tidy php-xmlrpc php-pear php-fpm php-mbstring php-mysql certbot phpmyadmin python3-pip postfix ntp ca-certificates bsd-mailx tree
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Postfix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select &lt;strong&gt;Internet Site&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;System mail name: (insert here the FQDN, for example web1.myserver.com)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Web server to reconfigure automatically:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Do not select anything and continue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Configure database for phpmyadmin with dbconfig-common?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select &lt;strong&gt;Yes&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;MySQL application password for phpmyadmin:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Leave blank and press &lt;strong&gt;Ok&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;setup-nginx&quot;&gt;Setup Nginx&lt;/h1&gt;

&lt;p&gt;Stop Nginx web server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/nginx stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Backup Nginx configuration:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Add the following lines in &lt;em&gt;/etc/nginx/nginx.conf&lt;/em&gt; after &lt;em&gt;tcp_nopush on;&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;tcp_nodelay on;
keepalive_timeout 65;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And the following lines after &lt;em&gt;gizp on;&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;gzip_disable &quot;msie6&quot;;

gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

# max body size
client_max_body_size 10M;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Copy some nginx configuration files:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir -p /etc/nginx/certs
ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem /etc/nginx/certs/server.crt
ln -s /etc/ssl/private/ssl-cert-snakeoil.key /etc/nginx/certs/server.key

mkdir -p /etc/nginx/global
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/nginx/global/codeigniter_production.conf &amp;gt; /etc/nginx/global/codeigniter_production.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/nginx/global/codeigniter_testing.conf &amp;gt; /etc/nginx/global/codeigniter_testing.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/nginx/global/common.conf &amp;gt; /etc/nginx/global/common.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/nginx/global/dokuwiki.conf &amp;gt; /etc/nginx/global/dokuwiki.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/nginx/global/phpmyadmin.conf &amp;gt; /etc/nginx/global/phpmyadmin.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/nginx/global/plainphp.conf &amp;gt; /etc/nginx/global/plainphp.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/nginx/global/ssl.conf &amp;gt; /etc/nginx/global/ssl.conf
wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/nginx/global/wordpress.conf &amp;gt; /etc/nginx/global/wordpress.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Restart Nginx:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/nginx restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-lets-encrypt&quot;&gt;Setup let’s encrypt&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip3 install tld
certbot register --agree-tos -m &amp;lt;your@email&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-mariadb&quot;&gt;Setup MariaDB&lt;/h1&gt;

&lt;p&gt;Secure MariaDB installation:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Enter current password for root (enter for none): &lt;strong&gt;[ENTER]&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Switch to unix_socket authentication [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Change the root password? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;New password: &lt;em&gt;MARIAB_ROOT_PASSWORD&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Re-enter new password: &lt;em&gt;MARIAB_ROOT_PASSWORD&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Remove anonymous users? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Disallow root login remotely? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Remove test database and access to it? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Reload privilege tables now? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Set MariaDB root password in a configuration file (the same password configured before!)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt; /root/.my.cnf
[client]
user = root
password = MARIADB_ROOT_PASSWORD
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Optional&lt;/em&gt; enable MySQL slow query logging (often useful during slow page load debugging):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sed -i &quot;{s/^#slow_query_log_file /slow_query_log_file /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#long_query_time /long_query_time /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log_slow_verbosity /log_slow_verbosity /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log-queries-not-using-indexes/log-queries-not-using-indexes/g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;MySQL is now configured, so restart it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/mariadb restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-shorewall-firewall-rules&quot;&gt;Configure Shorewall firewall rules&lt;/h1&gt;

&lt;p&gt;Copy the default configuration for one interface:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /usr/share/doc/shorewall/examples/one-interface
cp interfaces /etc/shorewall/
cp policy /etc/shorewall/
cp rules /etc/shorewall/
cp zones /etc/shorewall/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now open &lt;em&gt;/etc/shorewall/policy&lt;/em&gt; file and change the line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;net             all             DROP            info
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;removing &lt;em&gt;info&lt;/em&gt; directive given it fills the system logs:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;net             all             DROP
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now open &lt;em&gt;/etc/shorewall/rules&lt;/em&gt; and add the following rules at the bottom of the file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HTTP/ACCEPT     net             $FW
HTTPS/ACCEPT    net             $FW
SSH/ACCEPT      net             $FW
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;NOTE: in case you want to allow ICMP (Ping) traffic from a specific remote hosts you need to add a rule similar to the following where xxx.xxx.xxx.xxx is the remote IP address, before the &lt;strong&gt;Ping(DROP)&lt;/strong&gt; rule:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Ping(ACCEPT)    net:xxx.xxx.xxx.xxx       $FW
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now edit &lt;em&gt;/etc/default/shorewall&lt;/em&gt; and change &lt;strong&gt;startup=0&lt;/strong&gt; to &lt;strong&gt;startup=1&lt;/strong&gt;
You are now ready to start the firewall:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/shorewall start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-postfix&quot;&gt;Setup Postfix&lt;/h1&gt;

&lt;p&gt;Stop postfix server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/postfix stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Edit &lt;em&gt;/etc/mailname&lt;/em&gt; and set your server domain name, for example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;server1.mycompany.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Restart Postfix:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/postfix start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;select-correct-timezone&quot;&gt;Select correct timezone&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;dpkg-reconfigure tzdata
# Select your timezone (for example Europe/Rome)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;log-rotation&quot;&gt;Log rotation&lt;/h1&gt;

&lt;p&gt;In order to correctly log files you need to adjust logrotate configuration for Nginx:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; /etc/logrotate.d/nginx
/home/*/*/logs/*.log {
        daily
        missingok
        rotate 14
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                invoke-rc.d nginx rotate &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
        endscript
}
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;install-virtualhost-manager&quot;&gt;Install virtualhost manager&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget -q -O - https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/lemp_manager.py &amp;gt; /usr/local/sbin/lemp_manager.py
chmod 770 /usr/local/sbin/lemp_manager.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Download also the tools that will be used with cron:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /root/cron_scripts
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/cron_scripts/backup_mysql.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian11/cron_scripts/mysql_optimize.sh
chmod 770 *.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-cron&quot;&gt;Configure CRON&lt;/h1&gt;

&lt;p&gt;Edit &lt;em&gt;/etc/crontab&lt;/em&gt; and add the following lines at the bottom:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# mysql optimize tables
3  4  *  *  7   root    /root/cron_scripts/mysql_optimize.sh

# mysql backup
32 4  *  *  *   root    /root/cron_scripts/backup_mysql.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;how-to-use-virtualhost-manager&quot;&gt;How to use virtualhost manager&lt;/h1&gt;

&lt;p&gt;You can use the virtualhost manager for adding or removing virtualhosts:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# lemp_manager

Usage:
/usr/local/sbin/lemp_manager -a|--action=&amp;lt;action&amp;gt; [-d|--domain=&amp;lt;domain&amp;gt;] [-A|--alias=&amp;lt;alias&amp;gt;] [options]

Parameters:
	-a|--action=ACTION
		it is mandatory
	-d|--domain=domain.tld
		can be used only with [add_domain, remove_domain, add_alias, get_certs, get_info]
	-A|--alias=alias.domain.tld
		can be used only with [add_alias, remove_alias, get_info]

Actions:
	add_domain	Add a new domain
	add_alias	Add a new domain alias to an existent domain
	remove_domain	Remove an existent domain
	remove_alias	Remove an existent domain alias
	get_certs	Obtain SSL certificate and deploy it
	get_info	Get information of a domain or a domain alias (username)

Options:
	-f|--fakessl	Use self signed certificate (only usable with [add_domain, add_alias])
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
 <entry>
   <title>List of some useful openssl commands</title>
   <link href="https://www.matteomattei.com/list-of-some-useful-openssl-commands/"/>
   <updated>2022-04-05T00:00:00+02:00</updated>
   <id>https://www.matteomattei.com/list-of-some-useful-openssl-commands</id>
   <content type="html">&lt;p&gt;This is a list of some useful openssl commands I used. Just a brief description of what you need to to and the actual command, no more!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Verify if a certificate belongs to a CA:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl verify -CAfile ca.pem certificate.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Verify if a certificate and a key matches (hashes must be equal):&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl x509 -noout -modulus -in certificate.pem | openssl md5
openssl rsa -noout -modulus -in key.pem | openssl md5
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Print certificate information&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl x509 -in certificate.pem -noout -text
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Check a CSR:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl req -text -noout -verify -in csr.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Check a private key:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl rsa -in key.pem -check
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Check a PKCS12:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl pkcs12 -info -in key.p12
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Generate key and certificate (CA)&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl req -new -x509 -days 365 -keyout ca-key.pem -out ca-cert.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Generate a randomic private key of 4096 bits&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl genrsa -out privkey.pem 4096
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Generate a CSR (certificate signing request):&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl req -new -sha256 -key privkey.pem -out csr.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Generate a certificate starting from CSR and sign it with the CA:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl x509 -req -days 365 -in csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out certificate.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Convert pkcs7 certificate to pem:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl pkcs7 -inform der -in certificate.p7c -print_certs -out certificate.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Convert pfx file to pem (certificate + private key):&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;openssl pkcs12 -in file.pfx -nocerts -out privkey.pem
openssl pkcs12 -in file.pfx -clcerts -nokeys -out cert.pem

// remove password from the private key
openssl rsa -in privkey.pem -out key.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
 <entry>
   <title>Convert old NodeJs applications to ES6 modules</title>
   <link href="https://www.matteomattei.com/convert-old-nodejs-application-to-es6-modules/"/>
   <updated>2021-12-23T00:00:00+01:00</updated>
   <id>https://www.matteomattei.com/convert-old-nodejs-applications-to-es6-modules</id>
   <content type="html">&lt;p&gt;Nowadays every Nodejs application should be converted to ES6 module because it brings several benefits:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Modules may be executed any number of times, but are loaded only once, thus improving performance.&lt;/li&gt;
  &lt;li&gt;Module scripts may be shared by multiple applications.&lt;/li&gt;
  &lt;li&gt;Modules help identify and remove naming conflicts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest difference between standard javascript library and an ES6 module is how we include a library (which can be either within your project or external).
The standard classic way is to use &lt;strong&gt;const library = require(‘library-name’)&lt;/strong&gt; but with ES6 modules we have to use &lt;strong&gt;import library from ‘library-name’&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In order to support the &lt;strong&gt;import&lt;/strong&gt; keyword you have to add the following line to the &lt;em&gt;package.json&lt;/em&gt; of your application:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&quot;type&quot;: &quot;module&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this way you are telling npm that your application is a pure ES6 module.&lt;/p&gt;

&lt;p&gt;Then you have to change all &lt;em&gt;require(xxx)&lt;/em&gt; statements with &lt;em&gt;import xxx from ‘yyy’&lt;/em&gt;.
In case you want to use an external library which is not a pure ES6 module you can always include it with this syntax:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import theNameYouWant from &apos;official-library-name&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In case you want to use a library which is placed inside your application you can use this syntax:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import theNameYouWant from &apos;./path/to/mylibrary.js&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mylibrary.js&lt;/code&gt; can export a default object with all functions like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import axios from &apos;axios&apos;;

export default {
	run: function(){
		console.log(&apos;run&apos;);
	},
	sum: function(x, y){
		console.log(`Sum is ${x+y}`);
	},
	get: async function(){
		return await axios.get(&apos;https://github.com/matteomattei/matteomattei.github.io/raw/master/public/logo_professtional.jpg&apos;);
	}
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And can be used in this way:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import mylib from &apos;./path/to/mylibrary.js&apos;

mylib.run(); // prints &apos;run&apos;
mylib.sum(2,3); // prints &apos;Sum is 5&apos;;
let getResult = await mylib.get();
console.log(Buffer.from(getResult.data).length); // prints the size of the image
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also export single functions from your library like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import axios from &apos;axios&apos;;

export function run() {
  console.log(&quot;run&quot;);
}
export function sum(x, y) {
  console.log(`Sum is ${x + y}`);
}
export async function get() {
  return await axios.get(
    &quot;https://github.com/matteomattei/matteomattei.github.io/raw/master/public/logo_professtional.jpg&quot;
  );
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this case you have to use it in this way:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import * as mylib from &apos;./path/to/mylibrary.js&apos;

mylib.run(); // prints &apos;run&apos;
mylib.sum(2,3); // prints &apos;Sum is 5&apos;;
let getResult = await mylib.get();
console.log(Buffer.from(getResult.data).length); // prints the size of the image
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Otherwise you can selectively import only the function you need:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import {run, sum, get} from &apos;./path/to/mylibrary.js&apos;

run(); // prints &apos;run&apos;
sum(2,3); // prints &apos;Sum is 5&apos;;
let getResult = await get();
console.log(Buffer.from(getResult.data).length); // prints the size of the image
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remember:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You have to add &lt;strong&gt;type: “module”&lt;/strong&gt; to your package.json file.&lt;/li&gt;
  &lt;li&gt;You can use &lt;strong&gt;await&lt;/strong&gt; directly in your main module without a wrap of an async function.&lt;/li&gt;
  &lt;li&gt;Your code must be implicitly &lt;em&gt;strict&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
 <entry>
   <title>Client and server SSL mutual authentication with NodeJs</title>
   <link href="https://www.matteomattei.com/client-and-server-ssl-mutual-authentication-with-nodejs/"/>
   <updated>2020-12-26T00:00:00+01:00</updated>
   <id>https://www.matteomattei.com/client-and-server-mutual-authentication-with-nodejs</id>
   <content type="html">&lt;p&gt;In order to communicate securely between server and client it is important not only to cipher the channel but also trust both endpoints. To do this, a common practice is to do mutual authentication between client and server.&lt;/p&gt;

&lt;p&gt;In this post I show you how to implement mutual authentication in Nodejs.&lt;/p&gt;

&lt;p&gt;Assume we want to create a mutual authentication channel between a server running on &lt;strong&gt;server.aaa.com&lt;/strong&gt; and a client running on &lt;strong&gt;client.bbb.com&lt;/strong&gt;.
Keep in mind the domain names because they are important in the certificates creation.&lt;/p&gt;

&lt;p&gt;First of all we need to generate certificates. Obviously you can use certificates released by any certification authority but for the purpose of the article I am going to create self signed certificates and related CA.&lt;/p&gt;

&lt;h2 id=&quot;step-1-create-a-working-folder-and-setup-hosts-file&quot;&gt;Step 1: Create a working folder and setup hosts file&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// AS USER
$ mkdir ~/mutual_authentication_example
$ cd ~/mutual_authentication_example

// AS ROOT
# echo &apos;127.0.0.1 server.aaa.com&apos; &amp;gt;&amp;gt; /etc/hosts
# echo &apos;127.0.0.1 client.bbb.com&apos; &amp;gt;&amp;gt; /etc/hosts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-2-generate-server-certificates&quot;&gt;Step 2: Generate server certificates&lt;/h2&gt;

&lt;p&gt;We are going to create a Certification Authority (CA) certificate for the server with 1 year validity and the related key.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl req -new -x509 -days 365 -keyout server-ca-key.pem -out server-ca-crt.pem
Generating a RSA private key
...........................................................................................+++++
.......................................+++++
writing new private key to &apos;ca-key.pem&apos;
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter &apos;.&apos;, the field will be left blank.
-----
Country Name (2 letter code) [AU]:IT
State or Province Name (full name) [Some-State]:Florence
Locality Name (eg, city) []:Campi Bisenzio
Organization Name (eg, company) [Internet Widgits Pty Ltd]:AAA Ltd
Organizational Unit Name (eg, section) []:DevOps
Common Name (e.g. server FQDN or YOUR name) []:aaa.com
Email Address []:info@aaa.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The PEM pass phrase is optional.
The other questions are not mandatory but it’s better if you answer all.
The most important question is the &lt;strong&gt;Common Name&lt;/strong&gt; which should be the server main domain (&lt;strong&gt;aaa.com&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Now we generate the actual server certificate which will be used in the ssl handshake.
First of all we have to generate a random key (4096 bit length in our example):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
.........++++
...................++++
e is 65537 (0x010001)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then generate a Certificate Signing Request (CSR) with the key we have generated:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl req -new -sha256 -key server-key.pem -out server-csr.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter &apos;.&apos;, the field will be left blank.
-----
Country Name (2 letter code) [AU]:IT
State or Province Name (full name) [Some-State]:Florence
Locality Name (eg, city) []:Campi Bisenzio
Organization Name (eg, company) [Internet Widgits Pty Ltd]:AAA Ltd
Organizational Unit Name (eg, section) []:DevOps
Common Name (e.g. server FQDN or YOUR name) []:server.aaa.com
Email Address []:info@aaa.com

Please enter the following &apos;extra&apos; attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pay attention to the &lt;strong&gt;Common Name&lt;/strong&gt; which must have the same name of the host will serve the application (&lt;strong&gt;server.aaa.com&lt;/strong&gt;).
As final step, generate the server certificate (validity 1 year) from the CSR previously created and sign it with the CA key:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl x509 -req -days 365 -in server-csr.pem -CA server-ca-crt.pem -CAkey server-ca-key.pem -CAcreateserial -out server-crt.pem
Signature ok
subject=C = IT, ST = Florence, L = Campi Bisenzio, O = AAA Ltd, OU = DevOps, CN = server.aaa.com, emailAddress = info@aaa.com
Getting CA Private Key
Enter pass phrase for server-ca-key.pem:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The password requested is the one inserted during CA key generation.
To verify the certificate signature against the CA you can issue the following command:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl verify -CAfile server-ca-crt.pem server-crt.pem
server-crt.pem: OK
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we have all the server certificates we need!&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;-rw-rw-r--  1 matteo matteo 1440 dic 26 12:52 server-ca-crt.pem
-rw-rw-r--  1 matteo matteo   41 dic 26 17:48 server-ca-crt.srl
-rw-------  1 matteo matteo 1854 dic 26 12:51 server-ca-key.pem
-rw-rw-r--  1 matteo matteo 1671 dic 26 17:48 server-crt.pem
-rw-rw-r--  1 matteo matteo 1785 dic 26 17:34 server-csr.pem
-rw-------  1 matteo matteo 3243 dic 26 17:30 server-key.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-3-generate-client-certificates&quot;&gt;Step 3: Generate client certificates&lt;/h2&gt;

&lt;p&gt;Now it’s time to do the same steps for the Client.
First of all create a Certification Authority (CA) certificate for the client with 1 year validity and the related key.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl req -new -x509 -days 365 -keyout client-ca-key.pem -out client-ca-crt.pem
Generating a RSA private key
..........................................................+++++
.............................................+++++
writing new private key to &apos;client-ca-key.pem&apos;
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter &apos;.&apos;, the field will be left blank.
-----
Country Name (2 letter code) [AU]:IT
State or Province Name (full name) [Some-State]:Rome
Locality Name (eg, city) []:Rome
Organization Name (eg, company) [Internet Widgits Pty Ltd]:BBB Ltd
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:bbb.com
Email Address []:info@bbb.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The PEM pass phrase is optional.
The other questions are not mandatory but it’s better if you answer all.
The most important question is the &lt;strong&gt;Common Name&lt;/strong&gt; which should be the client main domain (&lt;strong&gt;bbb.com&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;Now we generate the actual client certificate which will be used in the ssl handshake.
First of all we have to generate a random key (4096 bit length in our example):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl genrsa -out client-key.pem 4096
Generating RSA private key, 4096 bit long modulus (2 primes)
..............++++
........................................................................................++++
e is 65537 (0x010001)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then generate a Certificate Signing Request (CSR) with the key we have generated:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl req -new -sha256 -key client-key.pem -out client-csr.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter &apos;.&apos;, the field will be left blank.
-----
Country Name (2 letter code) [AU]:IT
State or Province Name (full name) [Some-State]:Rome
Locality Name (eg, city) []:Rome
Organization Name (eg, company) [Internet Widgits Pty Ltd]:BBB Ltd
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:client.bbb.com
Email Address []:info@bbb.com

Please enter the following &apos;extra&apos; attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Pay attention to the &lt;strong&gt;Common Name&lt;/strong&gt; which must have the same name of the host will serve the application (&lt;strong&gt;client.bbb.com&lt;/strong&gt;).
As final step, generate the client certificate (validity 1 year) from the CSR previously created and sign it with the CA key:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl x509 -req -days 365 -in client-csr.pem -CA client-ca-crt.pem -CAkey client-ca-key.pem -CAcreateserial -out client-crt.pem
Signature ok
subject=C = IT, ST = Rome, L = Rome, O = BBB Ltd, CN = client.bbb.com, emailAddress = info@bbb.com
Getting CA Private Key
Enter pass phrase for client-ca-key.pem:
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The password requested is the one inserted during CA key generation.
To verify the certificate signature against the CA you can issue the following command:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ openssl verify -CAfile client-ca-crt.pem client-crt.pem
client-crt.pem: OK
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we have all the client certificates we need!&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;-rw-rw-r--  1 matteo matteo 1350 dic 26 17:59 client-ca-crt.pem
-rw-rw-r--  1 matteo matteo   41 dic 26 18:06 client-ca-crt.srl
-rw-------  1 matteo matteo 1854 dic 26 17:58 client-ca-key.pem
-rw-rw-r--  1 matteo matteo 1586 dic 26 18:06 client-crt.pem
-rw-rw-r--  1 matteo matteo 1712 dic 26 18:04 client-csr.pem
-rw-------  1 matteo matteo 3243 dic 26 18:03 client-key.pem
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-4-run-the-code&quot;&gt;Step 4: Run the code!&lt;/h2&gt;

&lt;p&gt;Move all certificates in a folder called &lt;strong&gt;certs&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ mkdir ~/mutual_authentication_example/certs
$ mv ~/mutual_authentication_example/*.pem ~/mutual_authentication_example/certs/
$ mv ~/mutual_authentication_example/*.srl ~/mutual_authentication_example/certs/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now create a &lt;strong&gt;server.js&lt;/strong&gt; application:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;const fs = require(&quot;fs&quot;);
const https = require(&quot;https&quot;);
const options = {
  key: fs.readFileSync(`${__dirname}/certs/server-key.pem`),
  cert: fs.readFileSync(`${__dirname}/certs/server-crt.pem`),
  ca: [
    fs.readFileSync(`${__dirname}/certs/client-ca-crt.pem`)
  ],
  // Requesting the client to provide a certificate, to authenticate.
  requestCert: true,
  // As specified as &quot;true&quot;, so no unauthenticated traffic
  // will make it to the specified route specified
  rejectUnauthorized: true
};
https
  .createServer(options, function(req, res) {
    console.log(
      new Date() +
        &quot; &quot; +
        req.connection.remoteAddress +
        &quot; &quot; +
        req.method +
        &quot; &quot; +
        req.url
    );
    res.writeHead(200);
    res.end(&quot;OK!\n&quot;);
  })
  .listen(8888);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now create a &lt;strong&gt;client.js&lt;/strong&gt; application:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;const fs = require(&quot;fs&quot;);
const https = require(&quot;https&quot;);
const message = { msg: &quot;Hello!&quot; };

const req = https.request(
  {
    host: &quot;server.aaa.com&quot;,
    port: 8888,
    secureProtocol: &quot;TLSv1_2_method&quot;,
    key: fs.readFileSync(`${__dirname}/certs/client-key.pem`),
    cert: fs.readFileSync(`${__dirname}/certs/client-crt.pem`),
    ca: [
      fs.readFileSync(`${__dirname}/certs/server-ca-crt.pem`)
    ],
    path: &quot;/&quot;,
    method: &quot;GET&quot;,
    headers: {
      &quot;Content-Type&quot;: &quot;application/json&quot;,
      &quot;Content-Length&quot;: Buffer.byteLength(JSON.stringify(message))
    }
  },
  function(response) {
    console.log(&quot;Response statusCode: &quot;, response.statusCode);
    console.log(&quot;Response headers: &quot;, response.headers);
    console.log(
      &quot;Server Host Name: &quot; + response.connection.getPeerCertificate().subject.CN
    );
    if (response.statusCode !== 200) {
      console.log(`Wrong status code`);
      return;
    }
    let rawData = &quot;&quot;;
    response.on(&quot;data&quot;, function(data) {
      rawData += data;
    });
    response.on(&quot;end&quot;, function() {
      if (rawData.length &amp;gt; 0) {
        console.log(`Received message: ${rawData}`);
      }
      console.log(`TLS Connection closed!`);
      req.end();
      return;
    });
  }
);
req.on(&quot;socket&quot;, function(socket) {
  socket.on(&quot;secureConnect&quot;, function() {
    if (socket.authorized === false) {
      console.log(`SOCKET AUTH FAILED ${socket.authorizationError}`);
    }
    console.log(&quot;TLS Connection established successfully!&quot;);
  });
  socket.setTimeout(10000);
  socket.on(&quot;timeout&quot;, function() {
    console.log(&quot;TLS Socket Timeout!&quot;);
    req.end();
    return;
  });
});
req.on(&quot;error&quot;, function(err) {
  console.log(`TLS Socket ERROR (${err})`);
  req.end();
  return;
});
req.write(JSON.stringify(message));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s now time to test. Open a terminal and start the server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ node server.js
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Open another terminal and run the client:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ node client.js
TLS Connection established successfully!
Response statusCode:  200
Response headers:  {
  date: &apos;Sat, 26 Dec 2020 17:26:13 GMT&apos;,
  connection: &apos;close&apos;,
  &apos;transfer-encoding&apos;: &apos;chunked&apos;
}
Server Host Name: server.aaa.com
Received message: OK!

TLS Connection closed!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the first terminal (the server) will be logged a new connection:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ node server.js
Sat Dec 26 2020 18:26:13 GMT+0100 (Central European Standard Time) ::ffff:127.0.0.1 GET /
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;Basically you have to explicitly include the CA of the server in the connection object of the client and vice versa.
In this way the server will be able to verify the client certificate and the client will be able to verify the server certificate.&lt;/p&gt;

&lt;p&gt;I hope this example can help you implementing a mutual authentication between your endpoints in your applications.
You can download demo files from this &lt;a href=&quot;https://github.com/matteomattei/nodejs-ssl-mutual-authentication&quot;&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
 <entry>
   <title>Show Git branch name on shell prompt</title>
   <link href="https://www.matteomattei.com/show-git-branch-name-on-shell-prompt/"/>
   <updated>2020-12-24T00:00:00+01:00</updated>
   <id>https://www.matteomattei.com/git-branch-name-on-shell-prompt</id>
   <content type="html">&lt;p&gt;Maintaining multiple git repositories might became a mess specially if you often switch from one folder to another and if you are used to work on different branches. Basically you have to type every time &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git branch&lt;/code&gt; on the terminal to make sure to work on the correct working copy.&lt;/p&gt;

&lt;p&gt;If your OS is Linux (or MacOSx) and you have Bash installed, you can customize the Bash prompt to always show the current branch name in your working directory.&lt;/p&gt;

&lt;p&gt;First of all type ensure your default shell is &lt;strong&gt;/bin/bash&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;matteo@barracuda ~ $ echo $SHELL
/bin/bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then edit &lt;em&gt;~/.bashrc&lt;/em&gt; file and add the following lines at the bottom:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;parse_git_branch() {
     git branch 2&amp;gt; /dev/null | sed -e &apos;/^[^*]/d&apos; -e &apos;s/* \(.*\)/(\1)/&apos;
}

PS1=&quot;\u@\h \[\e[32m\]\w \[\e[91m\]\$(parse_git_branch)\[\e[00m\]$ &quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Basically we added the &lt;strong&gt;parse_git_branch()&lt;/strong&gt; function which prints out the current git branch (if you are in a git project) and then reset the PS1 variable (the Bash prompt) calling the previously function.&lt;/p&gt;

&lt;p&gt;Now you have to enable the new configuration just typing the following or doing a new login:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;matteo@barracuda ~ $ . ~/.bashrc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s try and see how it looks like:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;matteo@barracuda ~ $ cd src/myproject
matteo@barracuda ~/src/myproject (master)$
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s all! If you like to change colors or other PS1 parameters you can refer to the following resources:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://misc.flogisoft.com/bash/tip_colors_and_formatting&quot;&gt;Bash colors and formatting&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ss64.com/bash/syntax-prompt.html&quot;&gt;PS1 syntax variables&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
 <entry>
   <title>How to configure a secure SFTP chroot jail</title>
   <link href="https://www.matteomattei.com/how-to-configure-a-secure-sftp-chroot-jail/"/>
   <updated>2019-08-23T00:00:00+02:00</updated>
   <id>https://www.matteomattei.com/how-to-configure-a-secure-sftp-chroot-jail</id>
   <content type="html">&lt;p&gt;If you have a linux server, openssh is almost always already present, so without any other tool you can configure a super secure SFTP chroot jail to allow your users to access the server limiting the visibility to their home directory.&lt;/p&gt;

&lt;p&gt;Start creating a new linux system group called sftponly:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;groupadd --system sftponly
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We create a system group because we want an ID lower than 1000 so that every new user will take a sequential UID.
Now open &lt;em&gt;/etc/ssh/sshd_config&lt;/em&gt; and make sure to have the following lines:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PasswordAuthentication yes
ChallengeResponseAuthentication no
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now replace the line starting with &lt;strong&gt;Subsystem&lt;/strong&gt; with the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Subsystem sftp internal-sftp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This line tells SSH to use its internal sftp subsytem to mange SFTP connections.&lt;/p&gt;

&lt;p&gt;Now add the following lines at the bottom of the file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Match Group sftponly
    ChrootDirectory %h
    X11Forwarding no
    AllowTcpForwarding no
    ForceCommand internal-sftp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Basically the above section describes how to handle connections from users belonging to &lt;em&gt;sftponly&lt;/em&gt; group.
In particular we are telling SSH to chroot the users to their home directory, does not allow X11 and TCP forwarding and force to use the internal sftp interface.&lt;/p&gt;

&lt;p&gt;After do that, restart ssh server to make the changes active:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/ssh restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now the SFTP server is ready to be used but you must keep in mind some important rules otherwise it will not work!&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;every user home directory must belong to &lt;strong&gt;root:root&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;every user home directory must have &lt;strong&gt;0755&lt;/strong&gt; permissions&lt;/li&gt;
  &lt;li&gt;every user must belong to &lt;strong&gt;sftponly&lt;/strong&gt; group&lt;/li&gt;
  &lt;li&gt;every first level folder in user home directory must belong to &lt;strong&gt;${USER}:sftponly&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s do an example: create a new user &lt;em&gt;matteo&lt;/em&gt; with no login shell, assign it to &lt;em&gt;sftpgroup&lt;/em&gt; group and set a password:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;useradd --create-home --shell /usr/sbin/nologin --user-group matteo
usermod --groups sftponly matteo
passwd matteo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Assuming you want the following permissions:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir /home/matteo/pics    # write access by user matteo
mkdir /home/matteo/musics  # write access by user matteo
mkdir /home/matteo/logs    # read only access by user matteo
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Configure the folders in this way:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;chown root:root /home/matteo
chmod 755 /home/matteo
chown matteo:sftponly /home/matteo/pics
chown matteo:sftponly /home/matteo/musics
chown matteo:sftponly /home/matteo/logs
chmod 555 /home/matteo/logs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now try with &lt;em&gt;sftp&lt;/em&gt; command line client or with &lt;em&gt;filezilla&lt;/em&gt; and test your new SFTP server.
Files created from an SFTP session will belong to matteo:matteo.&lt;/p&gt;

&lt;p&gt;As you can understand, this configuration is very useful for web servers running with &lt;em&gt;PHP-FPM&lt;/em&gt; where every VirtualHost runs with its own user and privileges, so you can restrict the access by user with a secure SFTP connection and at the same time avoid all the problems related to the files permissions management and the configuration of a separated FTP/FTPS server.&lt;/p&gt;

&lt;p&gt;I hope you enjoy this article. If you like it please leave a comment!&lt;/p&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
 <entry>
   <title>Monitor SSH access and send email when someone logins</title>
   <link href="https://www.matteomattei.com/monitor-ssh-access-and-send-email-when-someone-logins/"/>
   <updated>2019-08-21T00:00:00+02:00</updated>
   <id>https://www.matteomattei.com/monitor-ssh-access-and-send-email-when-someone-logins</id>
   <content type="html">&lt;p&gt;In order to monitor SSH access we can rely on &lt;strong&gt;rsyslog&lt;/strong&gt; given all SSH accesses are recorded in /var/log/auth.log.
Start creating a custom rsyslog configuration &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/rsyslog.d/90-ssh.conf&lt;/code&gt; with the following content:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/matteomattei/ff1286c839775fb3ffb4a27a2de8d1f5.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Basically we are telling rsyslog to look for lines where the program name is &lt;strong&gt;sshd&lt;/strong&gt; and the message contains the &lt;strong&gt;session opened for user&lt;/strong&gt;.
Every time the above condition is matched, rsyslog will call the script we are going to create passing the entire log line as parameter.&lt;/p&gt;

&lt;p&gt;Assuming we want to receive an email with the user that have been logged, open your editor and create the file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/bin/log_access.py&lt;/code&gt;:&lt;/p&gt;

&lt;script src=&quot;https://gist.github.com/matteomattei/f2cc5a49e38894d81819322bb031cf4e.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Make the file executable:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;chmod +x /usr/local/bin/log_access.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remember to fill the SMTP data at the beginning of the script.
As you can see the above script also logs all logins to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/logins.log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Feel free to do what you want in the python script, the above it’s only an example!&lt;/p&gt;

&lt;p&gt;Now restart rsyslog and try if everything works as expected.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/rsyslog restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let me know your work cases and if this article can help you!&lt;/p&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
 <entry>
   <title>Full web server setup with Debian 10 (Buster)</title>
   <link href="https://www.matteomattei.com/full-web-server-setup-with-debian-10-buster/"/>
   <updated>2019-07-28T00:00:00+02:00</updated>
   <id>https://www.matteomattei.com/full-web-server-setup-with-debian-10-buster</id>
   <content type="html">&lt;h1 id=&quot;setup-bash-and-update-the-system&quot;&gt;Setup bash and update the system&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cp /etc/skel/.bashrc /root/.bashrc
apt-get update
apt-get dist-upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-hostname-correctly&quot;&gt;Configure hostname correctly&lt;/h1&gt;

&lt;p&gt;Make sure to have the following two lines (with the same format) at the top of your &lt;em&gt;/etc/hosts&lt;/em&gt; file&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;127.0.0.1       localhost.localdomain localhost
xxx.xxx.xxx.xxx web1.myserver.com web1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: &lt;em&gt;xxx.xxx.xxx.xxx&lt;/em&gt; is the public IP address assigned to your server.&lt;/p&gt;

&lt;h1 id=&quot;install-all-needed-packages&quot;&gt;Install all needed packages&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt install wget vim git acl screen rsync net-tools pwgen php mariadb-server mariadb-client apache2 iptables shorewall php php-cli php-curl php-dev php-gd php-imagick php-imap php-memcache php-pspell php-recode php-tidy php-xmlrpc php-pear php-fpm php-mbstring php-mysql postfix ca-certificates bsd-mailx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Postfix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select &lt;strong&gt;Internet Site&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;System mail name: (insert here the FQDN, for example web1.myserver.com)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;setup-chrooted-sftp-jail&quot;&gt;Setup chrooted SFTP jail&lt;/h1&gt;

&lt;p&gt;Create &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sftponly&lt;/code&gt; group:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;addgroup --system sftponly
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Edit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/ssh/sshd_config&lt;/code&gt; and make sure to have the following lines:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;PasswordAuthentication yes
ChallengeResponseAuthentication no
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then change the &lt;em&gt;Subsystem&lt;/em&gt; line with the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Subsystem sftp internal-sftp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And create the section to allow chrooted SFTP access to the users belonging to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sftponly&lt;/code&gt; group.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Match Group sftponly
    ChrootDirectory %h
    X11Forwarding no
    AllowTcpForwarding no
    ForceCommand internal-sftp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now restart ssh server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/sshd restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In order to have a working sftp jail, there are 4 rules to follow:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;every user home directory must belong to &lt;strong&gt;root:root&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;every user home directory must have &lt;strong&gt;0755&lt;/strong&gt; permissions&lt;/li&gt;
  &lt;li&gt;every user must belong to &lt;strong&gt;sftponly&lt;/strong&gt; group&lt;/li&gt;
  &lt;li&gt;every subfolder in user home directory must belong to &lt;strong&gt;${USER}:sftponly&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;setup-apache&quot;&gt;Setup Apache&lt;/h1&gt;

&lt;p&gt;Stop Apache web server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/apache2 stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Backup Apache configuration:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Edit the following lines in &lt;em&gt;/etc/apache2/apache2.conf&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;From &lt;strong&gt;Timeout 300&lt;/strong&gt; to &lt;strong&gt;Timeout 45&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;From &lt;strong&gt;KeepAliveTimeout 5&lt;/strong&gt; to &lt;strong&gt;KeepAliveTimeout 15&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create a configuration for phpmyadmin:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt; /etc/apache2/conf-available/phpmyadmin.conf
Alias /phpmyadmin /usr/share/phpmyadmin

&amp;lt;Directory /usr/share/phpmyadmin&amp;gt;
    Options SymLinksIfOwnerMatch
    DirectoryIndex index.php

    &amp;lt;IfModule mod_php5.c&amp;gt;
        &amp;lt;IfModule mod_mime.c&amp;gt;
            AddType application/x-httpd-php .php
        &amp;lt;/IfModule&amp;gt;
        &amp;lt;FilesMatch &quot;.+\.php$&quot;&amp;gt;
            SetHandler application/x-httpd-php
        &amp;lt;/FilesMatch&amp;gt;

        php_value include_path .
        php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
        php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/php/php-php-gettext/:/usr/share/javascript/:/usr/share/php/tcpdf/:/usr/share/doc/phpmyadmin/:/usr/share/php/phpseclib/
        php_admin_value mbstring.func_overload 0
    &amp;lt;/IfModule&amp;gt;
    &amp;lt;IfModule mod_php.c&amp;gt;
        &amp;lt;IfModule mod_mime.c&amp;gt;
            AddType application/x-httpd-php .php
        &amp;lt;/IfModule&amp;gt;
        &amp;lt;FilesMatch &quot;.+\.php$&quot;&amp;gt;
            SetHandler application/x-httpd-php
        &amp;lt;/FilesMatch&amp;gt;

        php_value include_path .
        php_admin_value upload_tmp_dir /var/lib/phpmyadmin/tmp
        php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/share/php/php-gettext/:/usr/share/php/php-php-gettext/:/usr/share/javascript/:/usr/share/php/tcpdf/:/usr/share/doc/phpmyadmin/:/usr/share/php/phpseclib/
        php_admin_value mbstring.func_overload 0
    &amp;lt;/IfModule&amp;gt;

&amp;lt;/Directory&amp;gt;

# Authorize for setup
&amp;lt;Directory /usr/share/phpmyadmin/setup&amp;gt;
    &amp;lt;IfModule mod_authz_core.c&amp;gt;
        &amp;lt;IfModule mod_authn_file.c&amp;gt;
            AuthType Basic
            AuthName &quot;phpMyAdmin Setup&quot;
            AuthUserFile /etc/phpmyadmin/htpasswd.setup
        &amp;lt;/IfModule&amp;gt;
        Require valid-user
    &amp;lt;/IfModule&amp;gt;
&amp;lt;/Directory&amp;gt;

# Disallow web access to directories that don&apos;t need it
&amp;lt;Directory /usr/share/phpmyadmin/templates&amp;gt;
    Require all denied
&amp;lt;/Directory&amp;gt;
&amp;lt;Directory /usr/share/phpmyadmin/libraries&amp;gt;
    Require all denied
&amp;lt;/Directory&amp;gt;
&amp;lt;Directory /usr/share/phpmyadmin/setup/lib&amp;gt;
    Require all denied
&amp;lt;/Directory&amp;gt;
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Configure the proper Apache modules and configurations:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;a2dismod mpm_worker
a2dismod mpm_prefork

a2enmod mpm_event
a2enmod ssl
a2enmod rewrite
a2enmod headers
a2enmod deflate
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_fcgi
a2enmod http2
a2enmod setenvif

a2enconf security
a2enconf php7.3-fpm
a2enconf phpmyadmin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now restart Apache:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-mariadb&quot;&gt;Setup MariaDB&lt;/h1&gt;

&lt;p&gt;Secure MariaDB installation:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Enter current password for root (enter for none): &lt;strong&gt;[ENTER]&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Set root password? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Write your &lt;em&gt;MARIAB_ROOT_PASSWORD&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Remove anonymous users? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Disallow root login remotely? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Remove test database and access to it? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Reload privilege tables now? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instruct MariaDB to use native password:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql -u root mysql -e &quot;update user set plugin=&apos;mysql_native_password&apos; where user=&apos;root&apos;; flush privileges;&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Set MariaDB root password in a configuration file (the same password configured before!)&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt; /root/.my.cnf
[client]
user = root
password = MARIADB_ROOT_PASSWORD
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Enable MySQL slow query logging (often useful during slow page load debugging):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sed -i &quot;{s/^#slow_query_log_file /slow_query_log_file /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#long_query_time /long_query_time /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log_slow_rate_limit /log_slow_rate_limit /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log_slow_verbosity /log_slow_verbosity /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log-queries-not-using-indexes/log-queries-not-using-indexes/g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;MySQL is now configured, so restart it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/mysql restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;install-phpmyadmin&quot;&gt;Install phpMyAdmin&lt;/h1&gt;

&lt;p&gt;The version of phpmyadmin coming with the distribution is not updated so I prefer to install the latest manually:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export VER=&quot;5.0.4&quot;
cd /tmp
wget https://files.phpmyadmin.net/phpMyAdmin/${VER}/phpMyAdmin-${VER}-all-languages.tar.gz
tar xvf phpMyAdmin-${VER}-all-languages.tar.gz
rm -f phpMyAdmin-${VER}-all-languages.tar.gz
mv phpMyAdmin* /usr/share/phpmyadmin
mkdir -p /var/lib/phpmyadmin/tmp
chown -R www-data:www-data /var/lib/phpmyadmin
mkdir /etc/phpmyadmin/
cp /usr/share/phpmyadmin/config.sample.inc.php  /usr/share/phpmyadmin/config.inc.php
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now edit the file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/share/phpmyadmin/config.inc.php&lt;/code&gt; and set secret passphrase and temporary directory:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;// https://www.devglan.com/online-tools/bcrypt-hash-generator
$cfg[&apos;blowfish_secret&apos;] = &apos;SECRET_HERE&apos;;
[...]
$cfg[&apos;TempDir&apos;] = &apos;/var/lib/phpmyadmin/tmp&apos;;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-shorewall-firewall-rules&quot;&gt;Configure Shorewall firewall rules&lt;/h1&gt;

&lt;p&gt;Copy the default configuration for one interface:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /usr/share/doc/shorewall/examples/one-interface
cp interfaces /etc/shorewall/
cp policy /etc/shorewall/
cp rules /etc/shorewall/
cp zones /etc/shorewall/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now open &lt;em&gt;/etc/shorewall/policy&lt;/em&gt; file and change the line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;net             all             DROP            info
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;removing &lt;em&gt;info&lt;/em&gt; directive given it fills the system logs:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;net             all             DROP
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now open &lt;em&gt;/etc/shorewall/rules&lt;/em&gt; and add the following rules at the bottom of the file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HTTP/ACCEPT     net             $FW
HTTPS/ACCEPT    net             $FW
SSH/ACCEPT      net             $FW
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;NOTE: in case you want to allow ICMP (Ping) traffic from a specific remote hosts you need to add a rule similar to the following where xxx.xxx.xxx.xxx is the remote IP address, before the &lt;strong&gt;Ping(DROP)&lt;/strong&gt; rule:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Ping(ACCEPT)    net:xxx.xxx.xxx.xxx       $FW
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now edit &lt;em&gt;/etc/default/shorewall&lt;/em&gt; and change &lt;strong&gt;startup=0&lt;/strong&gt; to &lt;strong&gt;startup=1&lt;/strong&gt;
You are now ready to start the firewall:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/shorewall start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-postfix&quot;&gt;Setup Postfix&lt;/h1&gt;

&lt;p&gt;Stop postfix server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/postfix stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Edit &lt;em&gt;/etc/mailname&lt;/em&gt; and set your server domain name, for example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;server1.mycompany.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Restart Postfix:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/postfix start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;lets-encrypt&quot;&gt;Let’s encrypt&lt;/h1&gt;

&lt;p&gt;In order to get SSL free certificates with let’s encrypt install the powerful (and simple) dehydrated tool:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /root
git clone https://github.com/lukas2511/dehydrated.git
cd dehydrated
touch domains.txt
cp docs/examples/config .
/root/dehydrated/dehydrated --register --accept-terms
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Prepare Apache2 configuration for letsencrypt:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt; /etc/apache2/conf-available/dehydrated.conf
Alias /.well-known/acme-challenge /var/www/dehydrated
&amp;lt;Directory /var/www/dehydrated&amp;gt;
        Options None
        AllowOverride None

        # Apache 2.x
        &amp;lt;IfModule !mod_authz_core.c&amp;gt;
                Order allow,deny
                Allow from all
        &amp;lt;/IfModule&amp;gt;

        # Apache 2.4
        &amp;lt;IfModule mod_authz_core.c&amp;gt;
                Require all granted
        &amp;lt;/IfModule&amp;gt;
&amp;lt;/Directory&amp;gt;
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Enable new config and reload Apache&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;a2enconf dehydrated
systemctl reload apache2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;log-rotation&quot;&gt;Log rotation&lt;/h1&gt;

&lt;p&gt;In order to correctly log files you need to adjust logrotate configuration for Apache:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; /etc/logrotate.d/apache2
/var/www/vhosts/*/logs/access*.log
{
    rotate 30
    missingok
    size 10M
    compress
    delaycompress
    sharedscripts
    postrotate
        /etc/init.d/apache2 reload &amp;gt; /dev/null
    endscript
}

/var/www/vhosts/*/logs/error*.log
{
    rotate 3
    missingok
    compress
    delaycompress
    size 2M
    sharedscripts
    postrotate
        /etc/init.d/apache2 reload &amp;gt; /dev/null
    endscript
}
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;prepare-environment&quot;&gt;Prepare environment&lt;/h1&gt;

&lt;p&gt;Create all needed directories and files&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir /root/cron_scripts
mkdir -p /var/www/vhosts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now download all tools to manage the server locally:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/ADD_ALIAS.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/ADD_DOMAIN.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/ADD_SSL.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/ALIAS_LIST.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/DEL_ALIAS.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/DEL_DOMAIN.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/DOMAIN_LIST.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/MYSQL_CREATE.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/UPDATE_SFTP_PASSWORD.sh
chmod 770 *.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Download also the tools that will be used with cron:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /root/cron_scripts
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/cron_scripts/backup_mysql.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian10/LAMP/cron_scripts/mysql_optimize.sh
chmod 770 *.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Edit &lt;em&gt;/root/ADD_DOMAIN.sh&lt;/em&gt; and change &lt;strong&gt;ADMIN_EMAIL&lt;/strong&gt; variable with your email address.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;configure-cron&quot;&gt;Configure CRON&lt;/h1&gt;

&lt;p&gt;Edit &lt;em&gt;/etc/crontab&lt;/em&gt; and add the following lines at the bottom:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# mysql optimize tables
3  4  *  *  7   root    /root/cron_scripts/mysql_optimize.sh

# mysql backup
32 4  *  *  *   root    /root/cron_scripts/backup_mysql.sh

# letsencrypt
50 2 * * *      root    /root/dehydrated/dehydrated -c &amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
 <entry>
   <title>Full web server setup with Debian 9 (Stretch)</title>
   <link href="https://www.matteomattei.com/full-web-server-setup-with-debian-9-stretch/"/>
   <updated>2017-12-31T00:00:00+01:00</updated>
   <id>https://www.matteomattei.com/full-web-server-setup-with-debian-9-stretch</id>
   <content type="html">&lt;h1 id=&quot;setup-bash-and-update-the-system&quot;&gt;Setup bash and update the system&lt;/h1&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cp /etc/skel/.bashrc /root/.bashrc
apt-get update
apt-get dist-upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-hostname-correctly&quot;&gt;Configure hostname correctly&lt;/h1&gt;
&lt;p&gt;Make sure to have the following two lines (with the same format) at the top of your &lt;em&gt;/etc/hosts&lt;/em&gt; file&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;127.0.0.1       localhost.localdomain localhost
xxx.xxx.xxx.xxx web1.myserver.com web1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: &lt;em&gt;xxx.xxx.xxx.xxx&lt;/em&gt; is the public IP address assigned to your server.&lt;/p&gt;

&lt;h1 id=&quot;install-all-needed-packages&quot;&gt;Install all needed packages&lt;/h1&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt-get install vim git acl screen rsync net-tools php mysql-server mysql-client apache2 iptables phpmyadmin varnish shorewall vsftpd php-cli php-curl php-dev php-gd php-imagick php-imap php-memcache php-pspell php-recode php-tidy php-xmlrpc php-pear postfix apg ca-certificates bsd-mailx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;MariaDB/PhpMyAdmin:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;web server to reconfigure automatically: &lt;strong&gt;apache2&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;configure database for phpmyadmin with dbconfig-common? &lt;strong&gt;Yes&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;MySQL application password for phpmyadmin: [blank]&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Postfix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Select &lt;strong&gt;Internet Site&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;System mail name: (insert here the FQDN, for example web1.myserver.com)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;setup-ftp&quot;&gt;Setup FTP&lt;/h1&gt;
&lt;p&gt;Stop VSFTP server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/vsftpd stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Create backup configuration:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mv /etc/vsftpd.conf /etc/vsftpd.conf.backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Add new configuration:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; &quot;EOF&quot; &amp;gt; /etc/vsftpd.conf
listen=YES
listen_port=21
anonymous_enable=NO
local_enable=YES
guest_enable=YES
guest_username=nobody
user_sub_token=$USER
local_root=/var/www/vhosts/$USER
virtual_use_local_privs=YES
user_config_dir=/etc/vsftpd/users
pam_service_name=vsftpd_local_and_virtual
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
ftpd_banner=Welcome to my ftp server
write_enable=YES
download_enable=YES
dirlist_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
xferlog_file=/var/log/xferlog
connect_from_port_20=YES
connect_timeout=60
data_connection_timeout=300
idle_session_timeout=300
local_max_rate=0
max_clients=0
max_per_ip=3
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Create an empty chroot_list file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir /etc/vsftpd
touch /etc/vsftpd/chroot_list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Install PAM module for virtual users:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt-get install libpam-pwdfile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And configure it creating the file &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/pam.d/vsftpd_local_and_virtual&lt;/code&gt; with this content:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Standard behaviour for ftpd(8).
auth    required        pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed

# first try to authenticate local users
auth    sufficient      pam_unix.so

# if that failed, login with virtual user
auth    required        pam_pwdfile.so  pwdfile /etc/vsftpd/passwd

# pam_pwdfile doesn&apos;t come with account, so we just permit on success
account required        pam_permit.so
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Start VSFTP server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/vsftpd start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-apache&quot;&gt;Setup Apache&lt;/h1&gt;
&lt;p&gt;Stop Apache web server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/apache2 stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Backup Apache configuration:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cp /etc/apache2/apache2.conf /etc/apache2/apache2.conf.backup
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Edit the following lines in &lt;em&gt;/etc/apache2/apache2.conf&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;From &lt;strong&gt;Timeout 300&lt;/strong&gt; to &lt;strong&gt;Timeout 45&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;From &lt;strong&gt;KeepAliveTimeout 5&lt;/strong&gt; to &lt;strong&gt;KeepAliveTimeout 15&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Edit &lt;em&gt;/etc/apache2/mods-enabled/mpm_prefork.conf&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;IfModule mpm_prefork_module&amp;gt;
        StartServers             5
        MinSpareServers          5
        MaxSpareServers          10
        MaxRequestWorkers        150
        MaxConnectionsPerChild   10000
&amp;lt;/IfModule&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Edit &lt;em&gt;/etc/apache2/ports.conf&lt;/em&gt; and change the port &lt;strong&gt;80&lt;/strong&gt; with &lt;strong&gt;8080&lt;/strong&gt; since we are going to use Varnish:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Listen 8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Change the port (from &lt;strong&gt;80&lt;/strong&gt; to &lt;strong&gt;8080&lt;/strong&gt;) also in the default virtual host &lt;em&gt;/etc/apache2/sites-enabled/000-default.conf&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Enable useful Apache modules:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;a2enmod ssl
a2enmod rewrite
a2enmod headers
a2enmod deflate
a2enmod proxy
a2enmod proxy_http
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now restart Apache:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-varnish&quot;&gt;Setup Varnish&lt;/h1&gt;
&lt;p&gt;Stop Varnish daemon:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/varnish stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Backup your &lt;em&gt;/etc/varnish/default.vcl&lt;/em&gt; and create a new one with this content:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vcl 4.0;
import std;

# Default backend definition. Set this to point to your content server.
backend default {
    .host = &quot;127.0.0.1&quot;;
    .port = &quot;8080&quot;;
    .connect_timeout = 600s;
    .first_byte_timeout = 600s;
    .between_bytes_timeout = 600s;
}

sub vcl_recv {
    # Happens before we check if we have this in cache already.
    #
    # Typically you clean up the request here, removing cookies you don&apos;t need,
    # rewriting the request, etc.

    if (req.url ~ &quot;^/phpmyadmin&quot;) {
        return (pass);
    }

    if ((client.ip != &quot;127.0.0.1&quot; &amp;amp;&amp;amp; std.port(server.ip) == 80) &amp;amp;&amp;amp;
        (
          (req.http.host ~ &quot;localhost&quot;)
          # ENSURE HTTPS - DO NOT REMOVE THIS LINE
        )
    ){
        set req.http.x-redir = &quot;https://&quot; + req.http.host + req.url;
        return (synth(750, &quot;&quot;));
    }
}

sub vcl_synth {
  # Listen to 750 status from vcl_recv.
  if (resp.status == 750) {
    # Redirect to HTTPS with 301 status.
    set resp.status = 301;
    set resp.http.Location = req.http.x-redir;
    return(deliver);
  }
}

sub vcl_backend_response {
    # Happens after we have read the response headers from the backend.
    #
    # Here you clean the response headers, removing silly Set-Cookie headers
    # and other mistakes your backend does.
}

sub vcl_deliver {
    # Happens when we have all the pieces we need, and are about to send the
    # response to the client.
    #
    # You can do accounting or modifying the final object here.
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now edit &lt;em&gt;/etc/default/varnish&lt;/em&gt; and set the &lt;strong&gt;DAEMON_OPTS&lt;/strong&gt; variable like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;DAEMON_OPTS=&quot;-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we have to make some changes also to systemd scripts (this step is mandatory for Debian Stretch!) since systemd does not consider /etc/default/varnish settings.&lt;/p&gt;

&lt;p&gt;Edit &lt;em&gt;/lib/systemd/system/varnish.service&lt;/em&gt; and change port 6081 with port 80:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[Unit]
Description=Varnish HTTP accelerator
Documentation=https://www.varnish-cache.org/docs/4.1/ man:varnishd

[Service]
Type=simple
LimitNOFILE=131072
LimitMEMLOCK=82000
ExecStart=/usr/sbin/varnishd -j unix,user=vcache -F -a :80 -T localhost:6082 -f /etc/varnish/default.vcl -S /etc/varnish/secret -s malloc,256m
ProtectSystem=full
ProtectHome=true
PrivateTmp=true
PrivateDevices=true

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Restart Varnish:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;systemctl daemon-reload
systemctl restart varnish.service
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-mariadb&quot;&gt;Setup MariaDB&lt;/h1&gt;

&lt;p&gt;Secure MariaDB installation:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql_secure_installation
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Enter current password for root (enter for none): &lt;strong&gt;[ENTER]&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Set root password? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Write your &lt;em&gt;MARIAB_ROOT_PASSWORD&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Remove anonymous users? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Disallow root login remotely? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Remove test database and access to it? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Reload privilege tables now? [Y/n] &lt;strong&gt;Y&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instruct MariaDB to use native password:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mysql -u root mysql -e &quot;update user set plugin=&apos;mysql_native_password&apos; where user=&apos;root&apos;; flush privileges;&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Set MariaDB root password in a configuration file (the same password configured before!)&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt; /root/.my.cnf
[client]
user = root
password = MARIADB_ROOT_PASSWORD
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Enable MySQL slow query logging (often useful during slow page load debugging):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sed -i &quot;{s/^#slow_query_log_file /slow_query_log_file /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#long_query_time /long_query_time /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log_slow_rate_limit /log_slow_rate_limit /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log_slow_verbosity /log_slow_verbosity /g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
sed -i &quot;{s/^#log-queries-not-using-indexes/log-queries-not-using-indexes/g}&quot; /etc/mysql/mariadb.conf.d/50-server.cnf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;MySQL is now configured, so restart it:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/mysql restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;fix-for-phpmyadmin-redirecting-to-port-8080&quot;&gt;Fix for PhpMyAdmin redirecting to port 8080&lt;/h1&gt;
&lt;p&gt;If you try to access to &lt;em&gt;http://yoursitename/phpmyadmin&lt;/em&gt; you are redirected to &lt;em&gt;http://yoursitename:8080/phpmyadmin&lt;/em&gt; that will not work unless you open the firewall rule for port 8080 as described below. This because the web server is actually running on port 8080. To workaround this and have the PhpMyAdmin working on port 80 you need to force the redirect:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; &quot;EOF&quot; &amp;gt; /etc/phpmyadmin/conf.d/fix-redirection.php
&amp;lt;?php
$cfg[&apos;PmaAbsoluteUri&apos;] = $_SERVER[&apos;REQUEST_SCHEME&apos;].&apos;://&apos;.$_SERVER[&apos;SERVER_NAME&apos;].&apos;/phpmyadmin&apos;;
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;configure-shorewall-firewall-rules&quot;&gt;Configure Shorewall firewall rules&lt;/h1&gt;
&lt;p&gt;Copy the default configuration for one interface:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /usr/share/doc/shorewall/examples/one-interface
cp interfaces /etc/shorewall/
cp policy /etc/shorewall/
cp rules /etc/shorewall/
cp zones /etc/shorewall/

cd /usr/share/doc/shorewall6/examples/one-interface
cp interfaces /etc/shorewall6/
cp policy /etc/shorewall6/
cp rules /etc/shorewall6/
cp zones /etc/shorewall6/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now open &lt;em&gt;/etc/shorewall/policy&lt;/em&gt; file and change the line:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;net             all             DROP            info
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;removing &lt;em&gt;info&lt;/em&gt; directive given it fills the system logs:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;net             all             DROP
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now open &lt;em&gt;/etc/shorewall/rules&lt;/em&gt; and add the following rules at the bottom of the file:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HTTP/ACCEPT     net             $FW
HTTPS/ACCEPT     net             $FW
SSH/ACCEPT      net             $FW
FTP/ACCEPT      net             $FW

# real apache since varnish listens on port 80
#ACCEPT         net             $FW             tcp             8080
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;NOTE: in case you want to allow ICMP (Ping) traffic from a specific remote hosts you need to add a rule similar to the following where xxx.xxx.xxx.xxx is the remote IP address, before the &lt;strong&gt;Ping(DROP)&lt;/strong&gt; rule:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Ping(ACCEPT)    net:xxx.xxx.xxx.xxx       $FW
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now edit &lt;em&gt;/etc/default/shorewall&lt;/em&gt; and change &lt;strong&gt;startup=0&lt;/strong&gt; to &lt;strong&gt;startup=1&lt;/strong&gt;
You are now ready to start the firewall:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/shorewall start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;setup-postfix&quot;&gt;Setup Postfix&lt;/h1&gt;
&lt;p&gt;Stop postfix server:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/postfix stop
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Edit &lt;em&gt;/etc/mailname&lt;/em&gt; and set your server domain name, for example:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;server1.mycompany.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, in order to monitor mail traffic coming from PHP you need to edit &lt;em&gt;/etc/php/7.0/apache2/php.ini&lt;/em&gt;. Go to &lt;strong&gt;[mail function]&lt;/strong&gt; section and set the following two options:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sendmail_path = /usr/local/bin/sendmail-wrapper
auto_prepend_file = /usr/local/bin/env.php
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now create the two files above in &lt;em&gt;/usr/local/bin&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sendmail-wrapper&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#!/bin/sh
logger -p mail.info sendmail-wrapper.sh: site=${HTTP_HOST}, client=${REMOTE_ADDR}, script=${SCRIPT_NAME}, pwd=${PWD}, uid=${UID}, user=$(whoami)
/usr/sbin/sendmail -t -i $*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;env.php&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;?php
putenv(&quot;HTTP_HOST=&quot;.@$_SERVER[&quot;HTTP_HOST&quot;]);
putenv(&quot;SCRIPT_NAME=&quot;.@$_SERVER[&quot;SCRIPT_NAME&quot;]);
putenv(&quot;SCRIPT_FILENAME=&quot;.@$_SERVER[&quot;SCRIPT_FILENAME&quot;]);
putenv(&quot;DOCUMENT_ROOT=&quot;.@$_SERVER[&quot;DOCUMENT_ROOT&quot;]);
putenv(&quot;REMOTE_ADDR=&quot;.@$_SERVER[&quot;REMOTE_ADDR&quot;]);
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now make they both have executable flag:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;chmod +x /usr/local/bin/sendmail-wrapper
chmod +x /usr/local/bin/env.php
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Add also &lt;em&gt;/usr/local/bin/&lt;/em&gt; to the open_basedir php list in &lt;em&gt;/etc/apache2/conf-enabled/phpmyadmin.conf&lt;/em&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;php_admin_value open_basedir /usr/share/phpmyadmin/:/etc/phpmyadmin/:/var/lib/phpmyadmin/:/usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Restart Postfix:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/init.d/postfix start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;lets-encrypt&quot;&gt;Let’s encrypt&lt;/h1&gt;
&lt;p&gt;In order to SSL free certificates with let’s encrypt install the powerful (and simple) dehydrated tool:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /root
git clone https://github.com/lukas2511/dehydrated.git
cd dehydrated
touch domains.txt
cp docs/examples/config .
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Prepare Apache2 configuration for letsencrypt:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt; /etc/apache2/conf-available/dehydrated.conf
Alias /.well-known/acme-challenge /var/www/dehydrated
&amp;lt;Directory /var/www/dehydrated&amp;gt;
        Options None
        AllowOverride None

        # Apache 2.x
        &amp;lt;IfModule !mod_authz_core.c&amp;gt;
                Order allow,deny
                Allow from all
        &amp;lt;/IfModule&amp;gt;

        # Apache 2.4
        &amp;lt;IfModule mod_authz_core.c&amp;gt;
                Require all granted
        &amp;lt;/IfModule&amp;gt;
&amp;lt;/Directory&amp;gt;
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Enable new config and reload Apache&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;a2enconf dehydrated
systemctl reload apache2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;log-rotation&quot;&gt;Log rotation&lt;/h1&gt;
&lt;p&gt;In order to correctly log files you need to adjust lograte configuration for Apache:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt; EOF &amp;gt;&amp;gt; /etc/logrotate.d/apache2
/var/www/vhosts/*/logs/access*.log
{
    rotate 30
    missingok
    size 10M
    compress
    delaycompress
    sharedscripts
    postrotate
        /etc/init.d/apache2 reload &amp;gt; /dev/null
    endscript
}

/var/www/vhosts/*/logs/error*.log
{
    rotate 3
    missingok
    compress
    delaycompress
    size 2M
    sharedscripts
    postrotate
        /etc/init.d/apache2 reload &amp;gt; /dev/null
    endscript
}
EOF
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;prepare-environment&quot;&gt;Prepare environment&lt;/h1&gt;
&lt;p&gt;Create all needed directories and files&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir /root/cron_scripts
mkdir -p /var/www/vhosts
mkdir -p /etc/vsftpd/users
touch /etc/vsftpd/passwd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now download all tools to manage the server locally:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ADD_ALIAS.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ADD_DOMAIN.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ADD_FTP_VIRTUAL_USER.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ADD_SSL.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/ALIAS_LIST.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/CLEAN_VARNISH_CACHE.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/DEL_ALIAS.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/DEL_DOMAIN.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/DEL_FTP_VIRTUAL_USER.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/DOMAIN_LIST.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/MYSQL_CREATE.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/UPDATE_ALL_FTP_PASSWORD.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/UPDATE_FTP_PASSWORD.sh
chmod 770 *.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Download also the tools that will be used with cron:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;cd /root/cron_scripts
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/cron_scripts/backup_mysql.sh
wget https://raw.githubusercontent.com/matteomattei/servermaintenance/master/Debian9/LAMP/cron_scripts/mysql_optimize.sh
chmod 770 *.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Edit &lt;em&gt;/root/ADD_DOMAIN.sh&lt;/em&gt; and change &lt;strong&gt;ADMIN_EMAIL&lt;/strong&gt; variable with your email address.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1 id=&quot;configure-cron&quot;&gt;Configure CRON&lt;/h1&gt;
&lt;p&gt;Edit &lt;em&gt;/etc/crontab&lt;/em&gt; and add the following lines at the bottom:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# mysql optimize tables
3  4  *  *  7   root    /root/cron_scripts/mysql_optimize.sh

# mysql backup
32 4  *  *  *   root    /root/cron_scripts/backup_mysql.sh

# letsencrypt
50 2 * * *      root    /root/dehydrated/dehydrated -c &amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</content>
   <author>
     <name>Matteo Mattei</name>
     <uri>https://www.matteomattei.com/about</uri>
   </author>
 </entry>
 
</feed>
