---
# System prepended metadata

title: Server Deploing Sheet
tags: [deploy]

---

---
title: Server Deploing Sheet
tags: deploy
description: 
---
#### *VPS*
<!-- Put the link to this slide here so people can follow -->

---


## 

### Initial managment
```typescript=
apt update & apt upgrade
useradd -m user & usermod -aG sudo user
passwd user
mkdir config && cd config
mkdir iptables vpn uwsgi nginx fail2ban manuals docker wireguard
user=[username]
```
### SSH 
#### Configure 
```bash=
cd ~/config/ssh/
ln -s /home/$user/config/ssh/sshd_config /etc/ssh/sshd_config.d/ssh_config
ssh-keygen -A
```
#### SSHD config (sed '/^ *#/d; /^ *$/d' clean_conf)
```bash=
Port [port]
AddressFamily inet
ListenAddress [ip]
Protocol 2 
HostKey /etc/ssh/ssh_host_rsa_key
RekeyLimit 1G
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 1m
PermitRootLogin no
StrictModes yes
AllowUsers $user
MaxAuthTries 5
MaxSessions 4
PubkeyAuthentication yes
AuthorizedKeysFile	/home/$user/.ssh/authorized_keys /home/$user/.ssh/authorized_keys2
IgnoreRhosts yes
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
X11Forwarding no
PrintMotd no
PrintLastLog yes
Compression no
ClientAliveInterval 60
ClientAliveCountMax 3
TCPKeepAlive no
AcceptEnv LANG LC_*
Subsystem sftp	/usr/lib/openssh/sftp-server
DenyGroups no-ssh
```

```bash=

# check config
/usr/sbin/sshd -t
sudo systemctl restart sshd
sudo systemctl status sshd
```

#### Edit ssh welcome message
```bash=
sudo apt install update-motd
echo "" > /snap/core18/2066/motd
```

### Iptables
#### Iptables params explanation
```bash= 
# The order of passing the tables
https://ittricks.ru/administrirovanie/linux/531/iptables-poryadok-proxozhdeniya-tablic-i-cepochek
```

####
```bash=
# create main iptables conf file 
cd configs/iptables/
nano ~/config/iptables/iptables_rules.ipv4
sudo apt-get install iptables-persistent
```

#### Disable TOR nodes and IPtables config
```bash=
# https://bozza.ru/art-297.html
# https://losst.ru/upravlenie-sluzhbami-linux
# https://losst.ru/kak-dobavit-skript-v-avtozagruzku-ubuntu
```
apt update & apt -y install ipset


```bash=
systemctl edit --force --full tornodescollector
```
```bash=
[Unit]
After=iptables.service
After=ip6tables.service
Description=TOR nodes collector
After=multi-user.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/root/tornodescollector.sh

[Install]
WantedBy=basic.target

#systemctl edit --force tornodescollector
```

```bash=
nano /root/tornodescollector.sh
```
```bash=
#!/bin/bash
# Block Tor Exit nodes
 EXTERNAL_IP="IP"
# EXTERNAL_IP=$(curl ident.me) - DANGEROUS!

ipset -N TORSET iphash 2> /dev/null
# curl "https://check.torproject.org/torbulkexitlist?ip=${EXTERNAL_IP}" | xargs -n 1 ipset -A TORSET 
/usr/bin/curl -sSL "https://check.torproject.org/torbulkexitlist?ip=${EXTERNAL_IP}" 2> /dev/null | xargs -n 1 ipset -A TORSET 2> /dev/null
systemctl restart iptables
```
```bash=
sudo systemctl daemon-reload
```
```bash=
sudo systemctl enable tornodescollector
```


#### /etc/iptables/rules.v4 for IPv4
```bash=
# Generated by iptables-save v1.6.0 on Sat Jun  1 11:06:45 2019
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -j MASQUERADE
COMMIT
# Completed on Sat Jun  1 11:06:45 2019
# Generated by iptables-save v1.6.0 on Sat Jun  1 11:06:45 2019
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
# Completed on Sat Jun  1 11:06:45 2019
# Generated by iptables-save v1.6.0 on Sat Jun  1 11:06:45 2019
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:SRV-Firewall-1-INPUT - [0:0]:TOR - [0:0]
-A INPUT -j TOR
-A TOR -m set --match-set TORSET src -j DROP
-A INPUT -j VPN-Firewall-1-INPUT
-A FORWARD -j VPN-Firewall-1-INPUT
-A VPN-Firewall-1-INPUT -s 127.0.0.1/32 -p icmp -m icmp --icmp-type any -j ACCEPT
-A VPN-Firewall-1-INPUT -s 109.252.0.0/16 -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A VPN-Firewall-1-INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A VPN-Firewall-1-INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A VPN-Firewall-1-INPUT -p tcp -m tcp --dport 44300 -j ACCEPT
-A VPN-Firewall-1-INPUT -s 109.252.0.0/16 -p udp -m udp --dport 51820 -j ACCEPT
-A VPN-Firewall-1-INPUT -s 176.59.0.0/16 -p udp -m udp --dport 51820 -j ACCEPT
-A VPN-Firewall-1-INPUT -s 212.3.128.0/19 -p udp -m udp --dport 51820 -j ACCEPT
-A VPN-Firewall-1-INPUT -s 94.25.0.0/16 -p udp -m udp --dport 51820 -j ACCEPT
-A VPN-Firewall-1-INPUT -s 109.252.0.0/16 -p tcp -m tcp --dport 44327 -j ACCEPT
-A VPN-Firewall-1-INPUT -s 176.59.0.0/16 -p tcp -m tcp --dport 44327 -j ACCEPT
-A VPN-Firewall-1-INPUT -s 212.3.128.0/19 -p tcp -m tcp --dport 44327 -j ACCEPT
-A VPN-Firewall-1-INPUT -s 94.26.0.0/16 -p tcp -m tcp --dport 44327 -j ACCEPT
-A VPN-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A VPN-Firewall-1-INPUT -s 109.252.0.0/16 -p tcp -m state --state NEW -m tcp --dport 43900 -j ACCEPT
-A VPN-Firewall-1-INPUT -s 109.252.0.0/16 -p udp -m state --state NEW -m udp --dport 44000 -j ACCEPT
-A VPN-Firewall-1-INPUT -i tun+ -j ACCEPT
-A VPN-Firewall-1-INPUT -i lo -j ACCEPT
-A VPN-Firewall-1-INPUT -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m multiport --dports 80,443,44327 -m connlimit --connlimit-above 10 --connlimit-mask 9 --connlimit-sad>
-A VPN-Firewall-1-INPUT -p icmp -m icmp --icmp-type 8 -j DROP
-A VPN-Firewall-1-INPUT -i eth0 -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP
-A VPN-Firewall-1-INPUT -i eth0 -p tcp -j DROP
-A VPN-Firewall-1-INPUT -i eth0 -p udp -j DROP


# Completed on Sat Jun  1 11:06:45 2019
```
#### /etc/iptables/rules.v6 for IPv6.
```bash=
# Generated by ip6tables-save v1.8.7 on Sun Jun  6 01:25:37 2021
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p ipv6-icmp -j DROP
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -j DROP
-A INPUT -p udp -j DROP
COMMIT
# Completed on Sun Jun  6 01:25:37 2021

#ip6tables rules
ip6tables -P INPUT DROP
ip6tables -P FORWARD DROP
ip6tables -P OUTPUT ACCEPT

ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
ip6tables -I INPUT 1 -i lo -j ACCEPT
ip6tables -A INPUT -p icmpv6 -j ACCEPT

ip6tables -A INPUT -p tcp --dport http -j ACCEPT
ip6tables -A INPUT -p tcp --dport https -j ACCEPT
ip6tables-save > /etc/ip6tables.conf

# manual mode
iptables-resotre < /etc/iptables/rules.v4
```

#### Disable ipv6
```bash
sudo nano /etc/sysctl.conf 
#add at the end of the config file
net.ipv6.conf.all.disable_ipv6 = 1
sudo sysctl -p
sudo systemctl restart iptables
```


```bash=
/etc/iptables/rules.v4
# all other version are depricated
#nano ~/config/iptables/iptables_restore.ipv4
## -->
###!/bin/sh
##/sbin/iptables-restore < /home/$user/config/iptables/iptables_rules.ipv4
## --
#sudo ln -s sudo ln -s /home/$user/config/iptables/iptables_restore.ipv4 /etc/network/if-pre-up.d/iptables_restore 
```

### Wireguard install
```bash=
sudo add-apt-repository ppa:wireguard/wireguard
sudo apt install wireguard
```

### Rkhunter install

```bash=
# https://habr.com/ru/company/first/blog/242865/

# by root
sudo apt -y install rkhunter mailutils  

# optional (errors)
nano /etc/rkhunter.conf
MIRRORS_MODE=1 ---> MIRRORS_MODE=0
UPDATE_MIRRORS=0 ---> UPDATE_MIRRORS=1
WEB_CMD="/bin/false" ---> WEB_CMD=""
MAIL_CMD=echo "Rkhunter warnings were received" | mail -s "rkhunter status message" mail -aFrom:mail

# Add mail for alerts
nano /etc/rkhunter.conf 
MAIL-ON-WARNING="mail.com"


# manual launch
rkhunter -c --enable all --disable none --rwo

# collect hashes of sys files
rkhunter --propupd 

# add to crontab job
sudo nano /etc/cron.daily/rkhunters

#!/bin/sh
(
/usr/bin/rkhunter --versioncheck
/usr/bin/rkhunter --update
/usr/bin/rkhunter -c --sk --rwo) | mail -s "rkhunter scan status from $(date)" $mail -aFrom:$mail

chmod +x /etc/cron.daily/rkhunters

# or
@daily /usr/bin/rkhunter --cronjob --update --quiet

# parse rkhunter log file
sudo cat /var/log/rkhunter.log | grep -A5 "\[ Warning \]"

# for false-positive 
# SCRIPTWHITELIST="/sbin/ifup /sbin/ifdown /usr/bin/groups /usr/bin/ldd /usr/bin/whatis"

# for hidden files and folders
# ALLOWHIDDENDIR="/etc/.java"
# ALLOWHIDDENFILE="/etc/.java"

# add mail newsletter
## https://www.dmosk.ru/miniinstruktions.php?mini=postfix-over-yandex
sudo nano /etc/postfix/main.cf    
---
relayhost =
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/private/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_type = cyrus
smtp_sasl_mechanism_filter = login
smtp_sender_dependent_authentication = yes
sender_dependent_relayhost_maps = hash:/etc/postfix/private/sender_relay
smtp_tls_CAfile = /etc/postfix/ca.pem
smtp_use_tls = yes
---

# create private config files 
mkdir /etc/postfix/private

sudo nano /etc/postfix/private/sender_relay
---
@[domain]    smtp.yandex.ru
---
sudo nano /etc/postfix/private/sasl_passwd
---
[smtp.yandex.ru]:587 $mailName@$domain:$pass
---
postmap /etc/postfix/private/{sasl_passwd,sender_relay}

# get certificate of the smtp server
openssl s_client -starttls smtp -crlf -connect smtp.yandex.ru:587

#to file
/etc/postfix/ca.pem

# restart postfix service
sudo systemctl restart postfix

# test mail server
echo "Test text" | mail -s "Test title" $toWhomEmail -aFrom:$FromWhoEmail

# set default hashes
sudo rkhunter --propupd

```
#### Replace OpenSSH header

```bash=
sshd -V
cp /usr/sbin/sshd /tmp & cd /tmp
strings -t d -a -n 7 sshd | grep OpenSSH
dd if=./sshd bs=1 skip= [address] count=[count] | od -A n -c
dd if=./sshd bs=1 count=[address] of=sshd.1
dd if=./sshd bs=1 skip=[address] count=[count] of=sshd.2
dd if=./sshd bs=1 skip=[address] count=999999999 of=sshd.3
od -A n -c sshd.2
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' sshd.2 

#nano sshd.2
#tr -d '\n' < title > sshd.2
cat sshd.* > sshd.new
strings -t d -a -n 7 sshd.new | grep OpenSSH
chmod 755 ./sshd.new
cp /usr/sbin/sshd /usr/sbin/sshd.bak
rm /usr/sbin/sshd
cp /tmp/sshd.new /usr/sbin/sshd

# Example
sshd -V
strings -t d -a -n 7 sshd | grep OpenSSH
dd if=./sshd bs=1 skip=526539 count=29 | od -A n -c
dd if=./sshd bs=1 count=526539 of=sshd.1
dd if=./sshd bs=1 skip=526539 count=30 of=sshd.2
dd if=./sshd bs=1 skip=526569 count=999999999 of=sshd.3

#SGCMS Fingerprint: X64_vsd12d
#SGCMS FGPT:X64_St24aDr49zRms2

# check the title
dd if=./sshd.2  bs=1 skip=0 count=999999999 | d -A n -c
sed -i 's/OpenSSH_8.4p1 Ubuntu-5ubuntu1/SGCMS FGPT:X64_St24aDr49zRms2/g' sshd.2 
cat sshd.* > sshd.new
chmod 755 ./sshd.new
strings -t d -a -n 7 sshd.new | grep OpenSSH
chmod +x sshd.new
cp /tmp/sshd.new /user/sbin/sshd

# explanation (with errors! wrong indents!)
# https://poweruser.guru/questions/782382/%D1%81%D0%BA%D1%80%D1%8B%D1%82%D1%8C-%D0%B2%D0%B5%D1%80%D1%81%D0%B8%D1%8E-ssh 
```

### Fail2ban

#### Manual
```
#https://www.dmosk.ru/instruktions.php?object=fail2ban
```

#### Configure application
```bash=
sudo apt install fail2ban
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
# /etc/fail2ban/fail2ban.conf
# /etc/fail2ban/jail.conf - jail config


# port configs
# SSH
#sudo nano /etc/fail2ban/jail.d/ssh.conf
cd ~/config/fail2ban
nano ssh.conf
# ---
[ssh]
enabled = true
port = ssh
filter = sshd
action = iptables[name=sshd]
logpath = /var/log/auth.log

# NGINX
# sudo nano /etc/fail2ban/jail.d/nginx.conf
# ---
[nginx]
enabled = true
port = http,https
filter = nginx-http-auth
action = iptables-multiport[name=nginx, port="http,https", protocol=tcp]
logpath = /var/log/nginx/error.log

#create symlinks to configs
sudo ln -s /home/$user/config/fail2ban/ssh.conf /etc/fail2ban/jail.d/ssh.conf 
sudo ln -s /home/$user/config/fail2ban/nginx.conf /etc/fail2ban/jail.d/nginx.conf

sudo systemctl restart fail2ban.service
```
#### fail2ban commands
```bash=
# Check rules and configs are being used
fail2ban-client status 

# Check details and ban statistic of the current rules
fail2ban-client status ssh

# Check /var/log/auth.log for IP
sudo cat auth.log | grep -E  -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}"

# Check /var/log/auth.log for IPv6
sudo cat auth.log | grep -E  -o "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))"
```

### DJANGO

```bash=
sudo apt update
sudo apt install python3-pip
sudo -H pip3 install --upgrade pip
sudo pip3 install virtualenv virtualenvwrapper
#echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc
echo "export WORKON_HOME=home/$user/config/environment" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
export PYTHONPATH='/home/$user/config/django/lib/python3.4'
source ~/.bashrc
cd ~/config/django/ 
mkvirtualenv [project_name]
pip3 install django
# test django server
sudo `which python3` manage.py runserver 0.0.0.0:8080
#deactivate env
deactivate
#activate env
source bin/activate

```

#### UWSGI (I)
```bash=
sudo apt-get install python3-dev
sudo -H pip3 install uwsgi
# test UWSGI
#sudo uwsgi --http :8080 --home /home/$(whoami)/config/environment/$(whoami) --chdir /home/$(whoami)/config/djanago/$project/ -w $project.wsgi
cd ~/config/uwsgi
sudo mkdir -p /etc/uwsgi/sites
sudo ln -s /home/$(whoami)/config/uwsgi/$project.ini /etc/uwsgi/sites/
```

#### UWSGI project config file
```bash=

[uwsgi]
uid             = $user
project         = $project
base            = /home/%(uid)/config/django
chdir           = %(base)/%(project)
module          = %(project).wsgi:application
master          = true
callable        = $project
pidfile         = /run/uwsgi/%(project).pid

env             = LANG=en_US.UTF-8
env             = DJANGO_SETTINGS_MODULE=$project.settings
pythonpath      = %(base)/%(project)
plugins         = python3
virtualenv      = /home/$user/config/environment/$project

socket          = /run/uwsgi/%(project).socket
chmod-socket    = 660
chown-socket    = %(uid):www-data

processes       = 5
enable-threads  = true
vacuum          = true
no-orphans      = true
autoload        = true
#touch-reload    = %(base)/%(porject)/touch.reload
harakiri        = 30
buffer-size     = 32768
```

```bash=
# uwsgi service config creating
sudo ln -s /home/$(whoami)/config/uwsgi/uwsgi.service /etc/systemd/system/uwsgi.service
```

#### UWSGI service config file
```bash=
[Unit]
Description=uWSGI Emperor service

[Service]
ExecStartPre=/bin/bash -c 'mkdir -p /run/uwsgi; chown $user:www-data /run/uwsgi'
ExecStart=/usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
Restart=always
KillSignal=SIGQUIT
Type=notify
NotifyAccess=all

[Install]
WantedBy=multi-user.targe
```

### NGINX

#### Configure server
```bash=
server=[server_url]

sudo apt-get install nginx -y
sudo nano /etc/nginx/nginx.conf
cd ~/config/nginx
sudo ln -s /home/$(whoami)/config/nginx/nginx.conf /etc/nginx/sites-available/$(echo $project)
sudo ln -s /etc/nginx/sites-available/$(echo $project) /etc/nginx/sites-enabled
sudo usermod -a -G www-data $(whoami)
sudo mkdir -p /var/www/$project/static
sudo chown -R $(whoami):www-data /var/www/$project
sudo chmod -R 755 /var/www/$project

```

#### NGINX server config
```bash=
server {
    client_body_buffer_size 1K; 
    client_header_buffer_size 1k;    
    client_max_body_size 10M;
    large_client_header_buffers 2 1k;
    keepalive_timeout 5 5;
    send_timeout 10; 
    if ($host !~ ^($server)$ ) {
        return 444;
    }
    if ( $http_referer ~* (babes|forsale|girl|jewerly|love|nude|nudit|organic|poker|porn|sex|teen|oral|anal) )
    {
        return 403;
    }
    location /media  {
        valid_referers none blocked $server;
        if ($invalid_referer) {return 444;}
        alias /var/www/$project/media;
        }       
    location /static {
        alias /var/www/$project/static;
        }
    location / {
        uwsgi_pass  unix:///run/uwsgi/$server.socket;
        uwsgi_param  QUERY_STRING       $query_string;
        uwsgi_param  REQUEST_METHOD     $request_method;
        uwsgi_param  CONTENT_TYPE       $content_type;
        uwsgi_param  CONTENT_LENGTH     $content_length;
        uwsgi_param  REQUEST_URI        $request_uri;
        uwsgi_param  PATH_INFO          $document_uri;
        uwsgi_param  DOCUMENT_ROOT      $document_root;
        uwsgi_param  SERVER_PROTOCOL    $server_protocol;
        uwsgi_param  REQUEST_SCHEME     $scheme;
        uwsgi_param  HTTPS              $https if_not_empty;
        uwsgi_param  REMOTE_ADDR        $remote_addr;
        uwsgi_param  REMOTE_PORT        $remote_port;
        uwsgi_param  SERVER_PORT        $server_port;
        uwsgi_param  SERVER_NAME        $server_name;
    }
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/$server.io/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/$server.io/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
    if ($host = $server) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
    listen          80;
    server_name     $server;
    return 404; # managed by Certbot
}

sudo nginx -t

sudo systemctl enable nginx
sudo systemctl enable uwsgi
```
#### Let`s Encrypt certificate gaining
```bash=

sudo snap install certbot --classic
#sudo apt install python-certbot-nginx
sudo ln -s /snap/bin/certbot /usr/bin/certbot

sudo certbot run --nginx

# enable auto renewal
sudo certbot renew --dry-run

# root
cd /etc/nginx/
nano acme
# ---
location /.well-known {
    root /var/www/crypt;
}

mkdir&cd /var/www/crypt/.well-known
nano example.html
curl -L http://$server/.well-known/example.html
cat /etc/letsencrypt/live/*/cert.pem | openssl x509 -text | grep -o 'DNS:[^,]*' | cut -f2 -d:

```


TLS cetificates 

```bash=
openssl req -x509 -out localhost.crt -keyout localhost.key \
  -newkey rsa:2048 -nodes -sha256 \
  -subj '/CN=localhost' -extensions EXT -config <( \
   printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth"

```