Nach vielen Überlegungen und Versuchen zur Absicherung von fhem nach "aussen" bin ich zum Schuss gekommen, den Zugang mit einer Zweifaktor-Authentisierung abzusichern.
Hierzu bietet sich das Projekt apache_2fa von itemir auf GitHub an.
Nach einigen Stunden habe ich es auch für fhem unter Centos 7 zum laufen gebracht.
Hier will ich nun meine Erfahrungen mit der Gemeinde teilen ...
Benötigt wird noch onetimepass über pip installiert.
Bei mir hatte auch noch pip gefehlt ...
yum install python-pip python-devel
pip install onetimepassApache (hier httpd) benötigt hierfür folgende Module:
- proxy_html_module (shared)
- fcgid_module (shared)
- rewrite_module (shared)
- auth_digest_module (shared)
Bei mir haben nach der Grundinstallation noch proxy_html und fcgid gefehlt.
yum install mod_proxy_html mod_fcgidZur Kontrolle kann noch der Webserver neu gestartet werden
systemctl restart httpdAuflisten geladener Module:
httpd -MNun holen wir den Projektinhalt nach /var/www/a2fa
git clone https://github.com/itemir/apache_2fa /var/www/a2faDas state-Verzeichnis für die Sessions fehlt noch
mkdir /var/www/a2fa/stateNun noch die benötigten Berechtigungen vergeben
chown -R apache:apache /var/www/a2fa
chmod 750 /var/www/a2fa/state
chmod 755 /var/www/a2fa/auth
chmod 755 /var/www/a2fa/state_clean
chmod 640 /var/www/a2fa/tokens.jsonBei aktiviertem SELinux fehlen noch Freigaben für den Webserver zum ausführen des Projektes, wie auch zum schreiben im state-Verzeichnis.
semanage fcontext -a -t httpd_sys_script_exec_t '/var/www/a2fa(/.*)?'
restorecon -Rv '/var/www/a2fa/
semanage fcontext -a -t httpd_sys_rw_content_t '/var/www/a2fa/state(/.*)?'
restorecon -Rv '/var/www/a2fa/state/'Nun wird die Konfiguration zur Webseite in /etc/httpd/conf.d/ erstellt.
Empfohlen ist eine Namenskonvention, wie z.B. meine.domaene.org_2FA.conf
Hier nun meine komplette Konfiguration (sanitarisiert)
<VirtualHost *:80>
DocumentRoot /var/www/html/sweethome
ServerName meine.domaene.org
ServerAlias meine.domaene.org
Redirect permanent / https://meine.domaene.org/
<Directory />
Require all granted
Options None
AllowOverride All
</Directory>
</VirtualHost>
<VirtualHost *:443>
ServerName meine.domaene.org
ServerAlias meine.domaene.org
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/auth/
RewriteCond %{HTTP_COOKIE} !^.*2FA_Auth=([a-zA-Z0-9]+)
RewriteRule ^(.*)$ /auth/auth?/fhem%{QUERY_STRING} [L,R=302]
RewriteCond %{REQUEST_URI} !^/auth/
RewriteCond %{HTTP_COOKIE} ^.*2FA_Auth=([a-zA-Z0-9]+)
RewriteCond /var/www/a2fa/state/%1 !-f
RewriteRule ^(.*)$ /auth/auth?/fhem%{QUERY_STRING} [L,R=302]
Header always set Feature-Policy "microphone 'none'; camera 'none'; geolocation 'none';payment 'none'; sync-xhr 'self' https://meine.domaene.org"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/butzies.ddnss.org/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/butzies.ddnss.org/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/butzies.ddnss.org/chain.pem
# a2fa selbst
ScriptAlias /auth/ /var/www/a2fa/
<Directory /var/www/a2fa>
AllowOverride All
Options FollowSymLinks
AuthType Digest
AuthName "meine.domaene.org"
AuthDigestDomain /
AuthDigestProvider file
AuthUserFile /var/www/a2fa/apache_credentials
Require valid-user
</Directory>
# a2fa geschützer Pfad
<Directory /var/www/html/sweethome>
AllowOverride All
Options Indexes FollowSymLinks
AuthType Digest
AuthName "meine.domaene.org"
AuthDigestDomain /
AuthDigestProvider file
AuthUserFile /var/www/a2fa/apache_credentials
Require valid-user
</Directory>
ProxyRequests Off
ProxyVia Off
ProxyPreserveHost On
<Location /fhem>
ProxyPass http://localhost:8083/fhem
ProxyPassReverse http://localhost:8083/fhem
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /fhem(.*) ws://localhost:8083/fhem$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /fhem(.*) http://localhost:8083/fhem$1 [P,L]
</Location>
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
LogLevel warn
ErrorLog /var/log/httpd/meine.domaene.org.ERROR.log
CustomLog /var/log/httpd/meine.domaene.org.CUSTOM.log combined
</VirtualHost>Dieses Beispiel beinhaltet auch eine letsencrypt-Konfiguration.
Weitere Informationen hierzu gibt es im Wiki.
Neustart des Webservers ...
systemctl restart httpdNun müssen noch Schlüssel generiert und angezeigt werden.
Hierfür werden oathtool und qrencode benötigt
yum install oathtool qrencodeUnd los geht's ...
Hierfü habe ich mir ein Tool geschrieben und auf GitHub gestellt.
cd /var/www
git clone https://github.com/peedy2495/apache_2fa-newuser.git a2fa/newuser.sh
chmod +x a2fa/newuser.shLos geht's :-)
cd /var/www/a2fa
./newuser.shBitte achtet darauf, dass der Shell-Benutzer die notwendigen Rechte zum bearbeiten der Dateien apache_credentials und tokens.json besitzt.
Nun muss nur noch regelmäßig im Verzeichnis state die Kehrwoche gemacht werden:
crontab -emit folgend anghängten Eintrag wird stündlich aufgeräumt
0 * * * * /var/www/a2fa/state_cleanDas soll es schon gewesen sein ... viel Spaß!
PS: Musste alles offline vorbereiten, da eine Stunde Loginzeit einfach zu mager ist ... >1Std?
Ohne Worte ....