ITCooky Recipes

Lets cooky it yammy things!

Installing http2 site on cloude(VPS) hosting HETZNER in Germany!

дата October 9, 2020

It is time to move on, towards to progress, towards to Europe! I don’t expect everything to go well there, but I am sure that the best technologies and specialists are already there; therefore, European hosting is cheaper, more powerful and more technologically advanced than Russian! Germany, if I am correctly mistaken, is the largest data center in Europe, where a huge digital infrastructure was built up for the World Cup.

Why HETZNER – I did not have much time to choose, I was relying on the images on the site, those words are not even known by Russian hosting companies – AMD Epyc, NVme and really “unique prices”.

First you must register, with a real name, address and card, the euro will be withdrawn from it for verification (as in Netflix), and until now they have not returned it, maybe it will be returned later (do not laugh, one euro is nothing in Russia, but in Germany its 10 days of hosting !!!). I take the cheapest cx11 rate: 2 gig, 1 core, 20 gb and for only 3 euros, in rubles it is now 270RUR. I look at the old hoster (RUVDS) how much the same cost 770RUR …

HETZNER says that the traffic is given by 20 terabytes, then more for 1.5 euros per terabyte. The Russian hosters do not count the traffic, so it is not known how much traffic I have on my projects (I did not count it for them by myself), but when seeing the traffic per day on this site, 20 terabytes is a LOT impossible to spend in a month!

As you can see in other rates, there are no problems with memory and space in Europe, only the cores remain in deficit. Memory and cores can be increased at any time, but not disk. It’s a big surprise, but the Germans say this is so that at any time you can go back to the old rate!

Lets configure the VPS
I chose centOS8, but there were also 7, I was afraid that 8 would differ from 7 as 6 from 7, but no, it does not differ at all!
A couple of seconds to install the image, a password is received in the email of your personal account, the first time you enter it, you are immediately asked to change it and enter it again. I use ssh, but my personal account on the site has a beautiful console!

First of all, I check what we have
uname -a

Linux itcooky 4.18.0-193.14.2.el8_2.x86_64 #1 SMP Sun Jul 26 03:54:29 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

See how many bits the operating system is
uname -m


64 good

lets check cores


One as ordered

yum update
and reboot

Also, the usual practice, when root does not directly login via ssh, you first login as user then you get super rights.
useradd user1
passwd user1

We give this user the right to log in via ssh (although it already has it, we prohibit it to others)
vi /etc/ssh/sshd_config
add line

AllowUsers user1

and we prohibit entering the root, find this line and write

PermitRootLogin no

Restart ssh
service sshd restart
And now you can enter with ssh only under user1
and then we elevate permissions with the command

install the minimum apps required
yum install wget
yum install tar

for compilation
yum group install 'Development Tools'
yum install pcre-devel
yum install gd-devel
yum install zlib-devel
yum install openssl-devel

Preparing the web server for http2
First you need to update openssl
openssl version

OpenSSL 1.1.1c FIPS  28 May 2019

This version would work, but we need source so I’ll install the newest one.

We go to the folder where you are going to download everything
cd /usr/local/src
tar -xf openssl-1.1.1h.tar.gz

Go to the folder and run the build
cd openssl-1.1.1h
make install


openssl version

OpenSSL 1.1.1h  22 Sep 2020 (Library: OpenSSL 1.1.1c FIPS  28 May 2019

new version installed

Install nginx with http2
It must also be the most recent version, compiled with parameters
cd /usr/local/src
tar -xf nginx-1.19.3.tar.gz
cd nginx-1.19.3

And the compilation command itself, and at the end it indicates the path for openssl /usr/local/src/openssl-1.1.1h/
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/ --lock-path=/var/run/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-openssl=/usr/local/src/openssl-1.1.1h/
make install

See version
nginx -v

nginx version: nginx/1.19.3

Add a user (maybe it already exists) and grant rights to the nginx folder
useradd nginx
chown -R nginx:nginx /etc/nginx/

I must also created a file that will help start and stop nginx
vi /usr/lib/systemd/system/nginx.service
add text

Description=nginx - high performance web server

ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/conf/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID


systemctl start nginx
systemctl enable nginx

I have not edited the firewall, but for record
firewall-cmd --zone=public --permanent --add-service=http
firewall-cmd --zone=public --permanent --add-service=https
firewall-cmd --reload

In the browser, we write the IP and look: the minimum site works

Install Mysql
We install the version what is in the CentOS repository
yum install mysql-server
systemctl start mysqld
systemctl enable mysqld

Next, we change the root password to ours, it must be complex with special characters and change other settings

Install PHP
I need 7.4, since the site is currently running on 7.4, WordPress won’t run on a lower version!
We get version 7.4
dnf install
dnf install
dnf module reset php
dnf module enable php:remi-7.4

and install
yum install php php-fpm php-mysqlnd php-xml php-gd php-mbstring

php-xml: required for phpBB
php-gd: for a plugin with images in the theme list
php-mbstring: phpBB works best with this module, so does Sphinx search
And for the new installed modules to work you need to reload php-fpm

edir php-fpm settings
vi /etc/php-fpm.d/www.conf
switch to nginx, there was apache ha

user = nginx
group = nginx


listen.owner = nginx = nginx 
listen.mode = 0660

and change (for compatibility with my nginx configurations)

listen = /var/run/php.sock
mkdir /var/lib/php/session
chown -R nginx:nginx /var/lib/php/session

but it may not be necessary

to start
systemctl start php-fpm.service
systemctl enable php-fpm.service

First website launch
Make a folder for future sites
mkdir /usr/local/www
I copied an example from nginx
cp -r /etc/nginx/html /usr/local/www
make a file there
vi /usr/local/www/html/info.php


And change the nginx settings
right here
vi /etc/nginx/conf/nginx.conf

#user nobody;
worker_processes 1;

error_log /dev/null crit;

events {
worker_connections 1024;

http {
include mime.types;
default_type application/octet-stream;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

include /etc/nginx/conf/conf.d/*.conf;

Create a folder where we will put the site settings
mkdir /etc/nginx/conf/conf.d
make file
vi /etc/nginx/conf/conf.d/default.conf

# The default server
server {
listen 80;
server_name localhost;

location / {
root /usr/local/www/html;
index index.php index.html index.htm;

# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/local/www/html;

location ~ \.php$ {
root /usr/local/www/html;
fastcgi_pass unix:/var/run/php.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;

# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /\.ht {
deny all;

service nginx restart
service php-fpm restart

And according to the idea, it should work, but it never works, but it worked for me – I wrote all the steps here for myself, the most part, of course!

Website transfer
On the old server, archive the folder with the site and the database
tar -cvf itc.tar ./
mysqldump --user=root --password --host=localhost wpita > ./wpita.sql

I download these files on the new server
scp user@ ./
scp user@ ./

The file can be immediately unzipped in the folder/usr/local/www/
tar -xvf itc.tar
And for the base, you must first create it and make a user for it

Let’s go to mysql
mysql -u root -p
We make a user with the name
CREATE USER 'wpita'@'localhost' IDENTIFIED BY 'QWErty123!';
GRANT ALL PRIVILEGES ON wpit.* TO 'wpita'@'localhost';
ALTER USER 'wpita'@'localhost' IDENTIFIED WITH mysql_native_password BY 'QWErty123!';

If the MySQL database password contains #, Sphinx will not be able to read it, so it is best not to type # in the password.

After that, you can add the base.
mysql -u root -p wpita < wpita.sql
For Letsencrypt, you need to transfer certificates from the old server, but first install it on the new one
chmod a+x certbot-auto
./certbot-auto --nginx

And now the certificates, we do on old server
cd /home/user
tar -cvf lc.tar /etc/letsencrypt

on new server
cd /usr/local/src
scp user@ ./
tar -xvf lc.tar

And we will transfer everything to the /etc/letsencrypt folder for now this is enough, then it will be necessary to configure the renewal of certificates
If the site folder in server has changed, this should be reflected in the letsencrypt files in the /etc/letsencrypt/renewal folder; otherwise certifiers will refuse to update
To update the certificates themselves, I add
crontab -e

19 6 9,18,27 * * /usr/local/src/certbot-auto renew -q&&/usr/sbin/service nginx reload

On the new server I make settings for the site
vi /etc/nginx/conf/conf.d/it.conf
I add text: everything that requests http via ip4 and ip6 is forwarted to https

server {
    listen 80;
    listen [::]:80;
    return 301 https://$host$request_uri;
access_log  off;

vi /etc/nginx/conf/conf.d/itSSL.conf
I add the text: here http2 appeared on the second line if everything was done correctly before then the site will start serving content to browsers in h2

server {
listen       443 ssl http2;
listen [::]:443 ssl http2;
    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;
    ssl_trusted_certificate /etc/letsencrypt/live/;
    ssl_stapling on;
    ssl_stapling_verify on;
    add_header Strict-Transport-Security "max-age=31536000";
    add_header Content-Security-Policy "img-src https: data:; upgrade-insecure-requests";

access_log  off;
location / {
        root   /usr/local/www/;
        index  index.php index.html index.htm;

    error_page  404              /404.html;
location = /404.html {
     root   /usr/local/www/;
error_page 500 /500.html;
location = /500.html {
        root   /usr/local/www/;
error_page 502 /502.html;
location = /502.html {
        root   /usr/local/www/;
error_page 503 /503.html;
location = /503.html {
        root   /usr/local/www/;
error_page 504 /504.html;  
location = /504.html {
        root   /usr/local/www/;

    # pass the PHP scripts to FastCGI server listening on
    location ~ \.php$ {
        root           /usr/local/www/;
        fastcgi_pass   unix:/var/run/php.sock; 
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;

location ~ .(gif|png|jpeg|jpg|svg)$ {
root           /usr/local/www/;
     valid_referers none blocked *;
     if ($invalid_referer) {
        return   403;
    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    location ~ /\.ht {
        deny  all;

I also add so that nothing is shown on IP
vi /etc/nginx/conf/conf.d/ipnull.conf

server {
    listen      80 default_server;
    listen [::]:80 default_server; 
    return      444;

in 443 there will already be a certificate error, I don't know how to make it more beautiful ...

Restart nginx
service nginx restart

Now go to your domain registrar's personal account and change the A records to IP4 of the new server, as well as the AAAA records to IP6! For the RU zone, the changes are activated instantly, for COM in one hour.

CAUTION: Before adding AAAA records, you must make sure that your domain's NS server supports IP6. If it is not supported and you have added AAAA records, that may cause some internet services that have IP6 in priority to malfunction, for example FeedBurner or renewal of LetsEncrypt certificates. This is my case, the R01 (RU-CENTER Group) registrar allowed to add AAAA records on its NS server, but it doesn't work with IP6!

Well, I still want IP6, Hertzner gives his DNS in my personal account, let's go.
The process of adding your domain is more or less clear, all records will be copied automatically, you just need to add AAAA records, and I got confused here

The personal account indicates
IPv6 2a01:4f8:c2c:96ca::/64
This is a range, DNS will not accept this record

Add to DNS
it will also be wrong

I look at the server what IP6 is on the interface

I indicate it in DNS Hertzner. Here one more difference was found, to refer to a domain without everything (without www) it is necessary to write instead of the empty space @ , the Russian registrar had an empty space!

In total that's the number of records I have

After that, you need to add in your domain registrar account, the Hetzner NS server and after 12 hours the site will start to be approved for IP6
Lets checked if everything worked, yes of course it worked, I've already done it a hundred times!

IP6 verification was faster on this site

This is how you can verify that http2 works on the site

One Response to “Installing http2 site on cloude(VPS) hosting HETZNER in Germany!”

  1. […] is not my first migration, of course, and in Hetzner is the second, here is the first described Installing http2 site on cloude(VPS) hosting HETZNER in Germany! I won’t write in detail about how to create a VPS there, I created a VPS just the same and […]

Leave a Reply

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