簡易WEBサーバを作ってみた
Back
Alt+HOME
一応公開目的なので最低限のセキュリティ対策をしておこうと、HTTPS化の練習をこの前行ったので、トータルでその他注意点も含めてレシピ化しておこうと思う。
使用する機器・アプリは、Raspberry Pi に
Pi-OS trixie 64bit を入れ、WEB サーバとして Apache2 + PHP。
なお、MyApp と言う
Python アプリケーションを /opt 以下にインストールし、
Python の仮想環境で動かし、
その出力を html ファイルとして Document Root に配布するものとする。
なお、SSL/TLS認証用には
Certbot を利用、ファイアウォールには
nftables を新たにインストールして使用する。
又、URLとしてダイナミックDNSを
dynamicdns.net (仮) とする。
SSL/TSL化したWEBの入れ物を作る
詳しくはWEBサーバを HTTPS 化するを参照
- ポートを変更する前に、標準設定の 80 ポートで certbot に依る SSL/TLS環境を作る
$ sudo apt install php # phpをインストールするとapache2もインストールされDocument Rootにテスト用phpが配置される。
$ sudo apt install certbot python3-certbot-apche -y
$ sudo sertbot --apache -d dynamicdns.net
いずれポートを変更した後は、他のポート80の PC から更新された証明書を転送する仕組みを作る。(上記リンク参照)
- SSL/TLS の環境設定ファイルに、取得した証明書の有る場所を指定して Apache を再構築する
$ sudo nano /etc/apache2/sites-available/ssl-8080.conf
GNU nano 8.4 /etc/apache2/sites-available/ssl-8080.conf
<VirtualHost *:8080>
ServerName dynamicdns.net
DocumentRoot /var/www/html-8080 # 通常デフォルトは /var/www/html となるので後にフォルダ作成
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/dynamicdns.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/dynamicdns.net/privkey.pem
<Directory /var/www/html-8080>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/ssl-8080-error.log
CustomLog ${APACHE_LOG_DIR}/ssl-8080-access.log combined
</VirtualHost>
$ sudo a2ensite ssl_8080.conf
$ sudo apache2ctl configtest
AH00526: Syntax error on line 5 of /etc/apache2/sites-enabled/ssl_8090_tm-listen.conf:
Invalid command 'SSLEngine', perhaps misspelled or defined by a module not included in the server configuration
このエラーが出たら SSL が起動していない可能性が有る。その場合は・・
$ sudo a2enmod ssl
なお、apache2.confに ServerName の指定が無い場合もエラーになる。apache2.conf に指定してからテストする。
$ sudo nano /etc/apache2/apache2.conf
GNU nano 8.4 /etc/apache2/apache2.conf
: (追記)
:
ServerName dynamicdns.net
$ sudo apache2ctl configtest
Syntax OK
$ sudo systemctl restart apache2.service
- 先ず条件として、Apache2 を使用して、ポートを 443 ではなく 8080 にするという設定で開始する。
そのために前述の ssl-8080.conf のフォルダ指定にも /var/www/html-8080 と記述した。
$ sudo nano /etc/apache2/ports.conf
GNU nano 8.4 /etc/apache2/ports.conf
Listen 8080
<IfModule ssl_module>
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
- WEB サーバのドキュメント用フォルダを専用ユーザで新規作成
標準的には /var/www/html がインストール時 root 権限で作成されている。
$ sudo useradd -r -s /usr/sbin/nologin myapp # 以後 MyApp 関連にアクセスするユーザ
$ sudo mkdir /var/www/html-8080
$ sudo chown -R myapp:myapp /var/www/html-8080
$ sudo chmod -R 755 /var/www/html-8080
$ ls /var/www
html html-8090
アプリケーションの格納場所と起動方法
- 先ずは格納場所と Python の安全な起動に関する処置 (専用ユーザ:myapp)
$ sudo mkdir -p /opt/MyApp
$ sudo chown -R myapp:myapp /opt/MyApp
$ sudo chmod -R 750 /opt/MyApp
$ sudo -u myapp python3 -m venv /opt/MyApp/.venv # Python 仮想環境の作成。隠しフォルダでなくても良い
$ sudo -u myapp /opt/MyApp/.venv/bin/pip install --no-cache-dir requests
$ sudo -u myapp /opt/MyApp/.venv/bin/pip install --no-cache-dir beautifulsoup4
仮想環境にインストールされた pip を使って必要なライブラリーをインストールする。
$ sudo -u myapp /opt/MyApp/.venv/bin/python /opt/MyApp/MyApp.py
- アプリの自動起動を設定する
$ sudo nano /etc/systemd/system/MyApp.service
GNU nano 8.4 /etc/systemd/system/MyApp.service
[Unit]
Description=MyApp Python Service
After=network.target
[Service]
User=myapp
Group=myapp
WorkingDirectory=/opt/MyApp
ExecStart=/opt/MyApp/.venv/bin/python /opt/MyApp/MyApp.py
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
- Pythonアプリの html 出力と Apache2 の DocumentRoot との関係
GNU nano 8.4 /opt/MyApp/MyApp.py
"""
:
# html構成
:
"""
:
# ローカルへ保存
with open("/var/www/html-8080/MyApp.html", "w", encoding="utf-8") as f:
f.write(html)
:
ユーザ(myapp)権限で動いている MyApp の出力が ユーザ(myapp)所有の /var/www/html-8080 に書き込まれる。
このようにアプリケーションごとにフォルダやポート管理が可能となる。
SSL/TLS ポートと SSH ポートのみを通すファイアウォールを構築する
- nftablesをインストール
$ sudo apt install nftables
- nftables の設定ファイルを編集
$ sudo nano /etc/nftables.conf
GNU nano 8.4 /etc/nftables.conf
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority filter;
policy drop;
iif lo accept
ct state established,related accept
tcp dport 22 accept
tcp dport 8080 accept
}
chain forward {
type filter hook forward priority filter;
policy drop;
}
chain output {
type filter hook output priority filter;
policy accept; # ここは標準では drop になっている (SSHがいきなり切れる)
}
}
- 起動とその他関連コマンド
$ sudo systemctl enable nftables
$ sudo systemctl start nftables
$ sudo nft list ruleset # nftables.conf の内容を表示
$ sudo nft list chain inet filter input # 特定チェインの確認
$ sudo ss -tlnp # サービスの Listen ポート
Back
Alt+HOME

この 作品 は
クリエイティブ・コモンズ 表示 - 非営利 - 改変禁止 4.0 国際 ライセンス
の下に提供されています。
English
Powered by