Přeskočit obsah

Instalace reverse proxy

Reverse proxy dělá ssl offloading pro následující služby:

  • PMC-BE
  • PMC-FE
  • Keycloak

info

Konfigurace reverse proxy z velké části závisí na požadovaném koncovém stavu (chceme-li mít keycloak na jiné doméně než PMC atp.). Popis níže ukazuje konfiguraci, kdy pmc je dostupné na pmc.parkcloud.cz a keycloak na kc.parkcloud.cz. Pokud chcete mít vše dostupné na stejné doméně, je možné se inspirovat konfigurací reverseproxy z popisu instalace v dockeru.

Instalace apache2

sudo apt update && sudo apt upgrade
sudo apt install apache2

Vytvoření a povolení virtual hostů

vim /etc/apache2/sites-available/001-pmc.parkcloud.cz.conf # (1)!
vim /etc/apache2/sites-available/002-kc.parkcloud.cz.conf # (2)!

sudo a2ensite 001-pmc.parkcloud.cz.conf 002-kc.parkcloud.cz.conf
sudo systemctl restart apache2
  1. viz 001-pmc.parkcloud.cz.conf
  2. viz 002-kc.parkcloud.cz.conf

V konfiguraci si dejte pozor, aby nebyly odkazy na neexistující soubory (např. certifikáty, klíče...), jinak aplikace po restartu nenaběhne. Před instalací certifikátu přes certbot je třeba, aby nějaký certifikát existoval a konfigurace se na něj odkazovala. Je možno použít libovolný certifikát. Certbot odkaz aktualizuje, aby směroval na certifikát vygenerovaný jím.

Nastavení ssl

Máme několik možnosti jak na web serveru nakonfigurovat SSL. Níže jsou zmíněny dvě z nich - certbot a manuální vytvoření certifikátu.

Certbot

Nejjednodušší způsob, jak nastavit ssl je přes aplikaci certbot. Na stránkách vyberte požadovanou konfiguraci a postupujte podle pokynů. Pro ubuntu 22.04 jsou to kroky níže.

sudo apt update
sudo apt install snapd
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
sudo certbot --apache

Manuální

Pokud se jedná o testovací instanci, je možné si vytvořit vlastní certifikát.

vytvoření CA a certifikátu

Vytvoření CA

Pozor

Všechny příkazy je nutné spouštět z cesty /home/greenc/greenc-ca/

Příprava

mkdir /home/greenc/greenc-ca
cd /home/greenc/greenc-ca
openssl dhparam -out dh.pem -2 2048

sudo vim /usr/lib/ssl/misc/CA.pl # (1)!
sudo vim /etc/ssl/openssl.cnf # (2)!
  1. Nakonfigurujeme výchozí parametry OpenSSL, které bude nová CA používat:
    ...
    my $DAYS = "-days 730"; # expirace serverovych a klientskych certifikatu: dva roky
    my $CADAYS = "-days 3650"; # expirace certifikatu CA: deset let
    ...
    
  2. ...
    default_days = 730 # how long to certify for
    ...
    

Vytvoření

/usr/lib/ssl/misc/CA.pl -newca # (1)!
  1. vyplnit dle situace. Například:
    CA certificate filename (prázdné) vygeneruje se soubor ./demoCA/cacert.pem
    Enter PEM pass phrase HpsawCaHEbMt39UN
    Verifying - Enter PEM pass phrase
    Country Name (2 letter code) CZ
    State or Province Name (full name) Czechia
    Locality Name (eg, city) (prázdné)
    Organization Name (eg, company) Green Center s.r.o.
    Organizational Unit Name (eg, section) (prázdné)
    Common Name (e.g. server FQDN or YOUR name) Green Center Root CA
    Email Address (prázdné)
    A challenge password (prázdné)
    An optional company name (prázdné)
    Enter pass phrase for ./demoCA/private/cakey.pem HpsawCaHEbMt39UN
    

Vznikne podadresář demoCA. V něm je uložen privátní klíč a certifikát CA, dále CRL, ukazatel na sériové číslo, index certifikátů a seznam samotných certifikátů (v podadresáři demoCA/newcerts). Pokud budeme chtít vydávat více certifikátů se stejným subjectem, je nutné povolit to v konfiguračním souboru ./demoCA/index.txt.attr

./demoCA/index.txt.attr
unique_subject = no

Vytvoření a podpis certifikátu

Je nutné upravit soubor /etc/ssl/openssl.cnf

vim /etc/ssl/openssl.cnf # (1)!

openssl req -new -subj "/C=CZ/ST=Czechia/O=Green Center/CN=Green Center PMC" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1,IP:10.0.1.113" \
-newkey rsa:2048 -keyout newkey.pem -out newreq.pem
  1. Příklad vyplněných hodnot je níže. CN by mělo odpovídat názvu domény na které je PMC dostupné (může být např. pmc.local...). Do SubjectAltName je možno zadat další alternativní názvy (např IP...). Další parametry vyplnit podle příkladu.
    ...
    [ CA_default ]
    copy_extensions = copy
    ...
    [dn]
    CN=localhost
    [req]
    distinguised_name = dn
    [EXT]
    subjectAltName = DNS:localhost,IP:127.0.0.1,IP:10.0.1.113
    keyUsage = digitalSignature
    extendedKeyUsage = serverAuth
    

Následně lze běžným postupem vydat certifikát ke klíči uloženému v souboru newkey.pem na základě žádosti v souboru newreq.pem:

/usr/lib/ssl/misc/CA.pl -sign

Pokud je třeba z klíče odstranit heslo, lze to udělat následujícím způsobem:

openssl rsa -in newkey.pem -out server-no-pass.key

Info

Po dokonční celého procesu je možné porovnat nově vytvořený certifikát s privátním klíčem a tím ověřit, že ve soubory vytvořily správna. Příkazy níže musí mít stejný výstup

openssl x509 -noout -modulus -in newcert.pem | openssl md5
openssl rsa -noout -modulus -in server-no-pass.key | openssl md5
Parametry certifikátu si lze pro kontrolu vypsat příkazem
openssl x509 -in newcert.pem -noout -text

Soubor newcert.pem je certifikát pro web server a soubor server-no-pass.key je klíč k tomuto certifikátu. Nyní byste v reverse proxy nastavili parametry SSLCertificateFile a SSLCertificateKeyFile, aby směřovaly na tyto soubory.

Povolení potřebných modulů

sudo a2enmod ssl proxy proxy_http headers rewrite
sudo systemctl restart apache2

Zmíněné soubory

/etc/apache2/sites-available/001-pmc.parkcloud.cz.conf
<VirtualHost *:80>
        ServerName pmc.parkcloud.cz
        ServerAlias pmc.parkcloud.cz
        RewriteEngine On
        RewriteCond %{HTTPS} !=on
        RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
        RewriteCond %{SERVER_NAME} =pmc.parkcloud.cz
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerName pmc.parkcloud.cz
        ServerAlias pmc.parkcloud.cz
        ServerAdmin pmc@green.cz
        ErrorLog ${APACHE_LOG_DIR}/pmc.parkcloud.cz.error.log
        CustomLog ${APACHE_LOG_DIR}/pmc.parkcloud.cz.access.log combined

        DocumentRoot /var/www/html

        <Directory /var/www/html/>
                Options FollowSymLinks
                AllowOverride All
                Require all granted
        </Directory>

        SSLEngine on

        ProxyPreserveHost On
        SSLProxyEngine On
        SSLProxyVerify none
        SSLProxyCheckPeerCN Off
        SSLProxyCheckPeerName Off
        SSLProxyCHeckPeerExpire Off

        RequestHeader set X-Forwarded-Port "443"
        RequestHeader set X_FORWARDED_PROTO "https" env=HTTPS
        RequestHeader merge SSL_CLIENT_S_DN "%{SSL_CLIENT_S_DN}s"
        RequestHeader merge SSL_CLIENT_I_DN "%{SSL_CLIENT_I_DN}s"
        RequestHeader merge SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"
        RequestHeader merge SSL_CLIENT_V_START "%{SSL_CLIENT_V_START}s"
        RequestHeader merge SSL_CLIENT_V_END "%{SSL_CLIENT_V_END}s"
        RequestHeader merge SSL_CLIENT_M_VERSION "%{SSL_CLIENT_M_VERSION}s"
        RequestHeader merge SSL_CLIENT_M_SERIAL "%{SSL_CLIENT_M_SERIAL}s"
        RequestHeader merge SSL_CLIENT_VERIFY "%{SSL_CLIENT_VERIFY}s"
        RequestHeader merge X_SSL_CLIENT_M_SERIAL "%{SSL_CLIENT_M_SERIAL}s"
        RequestHeader merge SslSubject "%{SSL_CLIENT_S_DN}s"
        RequestHeader merge X-SSL-CLIENT-S-DN-O "%{SSL_CLIENT_S_DN_O}s"

        Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"

        ProxyPass /api/ http://127.0.0.1:8012/api/
        ProxyPassReverse /api/ http://127.0.0.1:8012/api/

        ProxyPass /manage/ http://127.0.0.1:8012/manage/
        ProxyPassReverse /manage/ http://127.0.0.1:8012/manage/

        ProxyPass /scep http://127.0.0.1:8012/scep
        ProxyPassReverse /scep http://127.0.0.1:8012/scep

        SSLCACertificateFile /usr/local/share/ca-certificates/extra/ca-chain.cert.pem
        SSLCARevocationPath /var/lib/pmc/scep/depot/crl/
        SSLCARevocationCheck chain no_crl_for_cert_ok
        SSLOCSPEnable Off
        SSLVerifyClient optional
        SSLVerifyDepth 10

        SSLOptions +ExportCertData +StdEnvVars

        SSLCertificateFile /etc/letsencrypt/live/kc.parkcloud.cz/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/kc.parkcloud.cz/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
/etc/apache2/sites-available/002-kc.parkcloud.cz.conf
<VirtualHost *:80>
        ServerName kc.parkcloud.cz
        ServerAlias kc.parkcloud.cz
        RewriteEngine On
        RewriteCond %{HTTPS} !=on
        RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
        RewriteCond %{SERVER_NAME} =kc.parkcloud.cz
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerName kc.parkcloud.cz
        ServerAlias kc.parkcloud.cz
        ServerAdmin pmc@green.cz
        ErrorLog ${APACHE_LOG_DIR}/kc.parkcloud.cz.error.log
        CustomLog ${APACHE_LOG_DIR}/kc.parkcloud.cz.access.log combined
        <IfModule log_forensic_module>
        ForensicLog ${APACHE_LOG_DIR}/kc.parkcloud.cz.forensic.log
        </IfModule>

        SSLProxyEngine On
        SSLProxyCheckPeerCN Off 

        RewriteCond %{QUERY_STRING} ^$
        RewriteRule ^/$ /auth

        Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
        ProxyRequests     Off
        AllowEncodedSlashes NoDecode

        RequestHeader set X-Forwarded-Proto "https"
        RequestHeader set X-Forwarded-Port "443"
        RequestHeader set X-Forwarded-Host "kc.parkcloud.cz"
        RequestHeader set X-Forwarded-Server "kc.parkcloud.cz"

        ProxyPass /auth/ https://127.0.0.1:8084/
        ProxyPassReverse /auth/ https://127.0.0.1:8084/

        ProxyPass / https://127.0.0.1:8084/
        ProxyPassReverse / https://127.0.0.1:8084/

        SSLCertificateFile /etc/letsencrypt/live/kc.parkcloud.cz/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/kc.parkcloud.cz/privkey.pem
        Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>