0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ラズベリーパイ+ flaskアプリ + gunicorn + docker + nginx + オレオレ証明書 + FW で本格的?なwebサーバ構築

Last updated at Posted at 2025-01-22

なぜやるか

webの構造を知りたい。

今回の構成

アプリケーション flask
アプリケーション実行環境 wsgi
仮想環境コンテナ Docker
webサーバ nginx
HTTPS オレオレ証明書
ファイアウォール ufw

ラズパイVNC設定

sudo apt-get update
sudo apt-get upgrade

ラズパイIP固定

sambaファイル共有

ラズパイに必要なものインストール

【docker】
docker.io
docker-compose
【FW】
ufw
【nginx】
nginx

sudo apt install -y docker.io docker-compose ufw nginx

ディレクトリ構成

ユーザーフォルダの下に次のようなフォルダ構造にします。

project
├─App2
└─kajiApp
| └─flaskr
| ├─static
| ├─templates
| └─__pycache__
└─docker-compose.yml

projectフォルダの中にアプリケーションファイル kajiApp とApp2
今回はkajiAppだけ動かします。今後アプリケーション増やしたときのためにApp2置いときます。スケールすることを想定しています。
docker-composeファイルいれてあります。

アプリはdockerで動かして nginxはコンテナの外で動かします。

フォルダ構造を作る。

アプリを作る or コピペ or git clone する。
今回はgit clone

cd /home/pcmainte/project
git clone https://github.com/arisaEN/kajiApp.git

こんなかんじになった。

image.png

Dockerfileの用意

git cloneしたものの中にはいっている。
書き換えます。

FROM python:3.9-slim

WORKDIR /app

# 必要なパッケージをインストール
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションコードをコピー
COPY . .

# Gunicornを使用してアプリケーションを起動
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "flaskr:app"]

Docker-Composeファイルの作成

Projectフォルダ下に作ったものに書き込みます。

version: '3.8'

services:
  kajiapp:
    build:
      context: ./kajiApp 
      dockerfile: Dockerfile
    volumes:
      - ./kajiApp/flaskr/static:/app/flaskr/static
    container_name: kajiapp
    ports:
      - "127.0.0.1:5000:5000"
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

ホストマシンの127.0.0.1:5000(ローカルホスト)へのアクセスをコンテナ内のポート5000に転送します。つまり、ホストマシンの127.0.0.1:5000に接続することで、コンテナ内のFlaskアプリケーションにアクセスできるようになります。

nginx.confファイルの作成

user pcmainte;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

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

    upstream kajiApp {
        server 127.0.0.1:5000;
    }
    server {
        listen 80;
        server_name kajiApp.example.com;
        charset UTF-8; 
        location / {
            proxy_pass http://kajiApp;
        }
    }
    server {
        listen 80;
        server_name unko.com;

        location / {
            root /home/pcmainte/project/App2;
            index index.html;
        }
    }
}


クライアントにDNS設定

windowsの場合
C:\windows\system32\drivers\etc\hosts ここに管理者として

100.64.16.104 kajiapp.example.com
100.64.16.104 unko.com

みたいな感じで追加 メモ帳で編集すればOK

image.png

【windowsの設定】
kajiapp.example.comにアクセスしたら100.64.16.104に行きなさいってこと。
【nginxの設定】
100.64.16.104(nginxサーバ)はkajiapp.example.comというリクエストは127.0.0.1:5000に飛ばしてkajiAppを表示させるという設定になっています。

ここまでできれば、dockerコンテナ立ち上げてアプリ稼働させて、
nginxも稼働させれば、クライアントはkajiapp.example.comとブラウザで入力すればnginxを通してコンテナアプリに接続できます。

テストとして、コンテナ立ち上げてみます。
コンテナ立ち上げ

cd project
sudo docker-compose up --build

nginxサーバ(ラズパイ)から接続するとつながるはずです。
ブラウザで、 127.0.0.1:5000 enter

image.png

繋がりました。クライアントからhttp://100.64.16.104:5000/ には接続できないようにdockerfileとcomposeファイルで設定してあります。
クライアントはnginxを通してdockerコンテナにアクセスさせるためです。
でお次は↓HTTP通信をHTTPS通信にします。

HTTPSの設定

今回は自己証明書を使います。通称:オレオレ証明書
nginxサーバで証明書を作って、クライアントには証明書をインストールしてもらいます
↓設定手順

nginxサーバー上で実行

mkdir -p ~/ssl-certs
cd ~/ssl-certs

/home/pcmainte/ssl-certs ここに鍵生成されます


ここからこちらの記事参照
一応本記事でもメモしていますが、こちらの見やすい記事とやっていることは同じです。

ここに
subjectnames.txt を作る
中身↓

subjectAltName = DNS:kajiapp.example.com, IP:127.0.0.1

秘密鍵の生成

openssl genrsa 2048 > server.key

証明書署名要求(CSR)の作成

openssl req -new -key server.key -subj "/C=JP/ST=Some-State/O=Some-Org/CN=kajiapp.example.com" > server.csr

パスワード 任意 覚えとく
国コード JP
Province 都道府県名 空白でOK
Locality 市区町村名 空白でOK
Organization 組織名
Organizational Unit 部署名
Common Name 証明書を使いたいFQDN 今回は kajiapp.example.com
メールアドレス
challenge password 空白でOK
optional company name 空白でOK

自己署名証明書の作成

openssl x509 -days 3650 -req -extfile subjectnames.txt -signkey server.key < server.csr > server.crt

秘密鍵(private.key)が暗号化されている場合に表示されます。秘密鍵を生成する際に設定したパスフレーズを入力する

Certificate request self-signature ok

証明書署名要求(CSR)の自己署名が正常に完了したということ。

証明書確認

openssl x509 -in server.crt -text -noout

nginxの設定

nginxの設定ファイルに HTTPS接続設定をする
↑の方で設定したnginxのファイルに追記します。

sudo nano /etc/nginx/nginx.conf
user pcmainte;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

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

    upstream kajiApp {
        server 127.0.0.1:5000;
    }

    server {
        listen 443 ssl;
        server_name kajiapp.example.com;


        ssl_certificate /home/pcmainte/ssl-certs/server.crt;
        ssl_certificate_key /home/pcmainte/ssl-certs/server.key;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';

        location / {
            proxy_pass http://kajiApp;
        }
    }


    server {
        listen 80;
        server_name kajiApp.example.com;
        charset UTF-8; 
        location / {
            proxy_pass http://kajiApp;
        }
    }
    server {
        listen 80;
        server_name unko.com;

        location / {
            root /home/pcmainte/project/App2;
            index index.html;
        }
    }
}

nginxを再起動

sudo systemctl restart nginx

ブラウザでHTTPS接続

現状だとまだ保護されていない通信となる。 これは、HTTPS通信できてるけど、証明書がブラウザに認証されていなくて疑われている状態。
疑いを晴らす作業をしていきます。
image.png

windowsならばnginxサーバに作った/home/pcmainte/ssl-certs/server.crt これをコピーしてwindowsのローカルにいれる。

crtファイルをwindowsにインストールする
image.png

windowsでクリック
image.png

image.png

ローカルコンピューター
証明書をすべて次のストア
参照
信頼されたルート証明書

インストール終わったら再度 https://kajiapp.example.com/ に接続。

image.png

完了。

UFWの設定

アクセスする必要のないポートは閉じて、脅威からデバイスを守りましょう。

ポート開放
上から順に
HTTP
HTTPS
VNC
ssh
sambaを使ったクライアントからのファイル共有・操作

sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 5900/tcp
sudo ufw allow OpenSSH
sudo ufw allow from any to any port 137,138,139,445 proto tcp
sudo ufw allow from any to any port 137,138,139,445 proto udp

ファイアウォールを有効化(未有効の場合)

sudo ufw enable

docker コンテナ自動起動設定

サーバーのコンソールで打つ。

docker update --restart=always kajiapp

参考

感想

◎クライアント側の課題
クライアントはURLを貼り付けるだけでアプリを見れる環境を作りたい。
現状クライアント側の操作は:
①サーバの自己証明書をクライアントにインストール。
②URLに対するサーバのIPアドレスをアプリごとにhostsファイルに書き込み。
③URLをブラウザに貼る。

①と②をなくすためになにか考えるのが今の課題。

◎サーバー側の課題
アプリごとに証明書を発行しなければいけないのが面倒。

自分用メモ

nginx , docker , nanoで使ったコマンドまとめです。


nginx設定ファイル
sudo nano /etc/nginx/nginx.conf

nginx起動
sudo systemctl start nginx

Nginx を有効化(自動起動設定)
sudo systemctl enable nginx

nginx再起動
sudo systemctl restart nginx

Nginx の動作確認コマンド
sudo systemctl status nginx

ポート仕様状況確認
sudo lsof -i :80

nginxダウン
sudo systemctl stop nginx

ログのパス
/var/log/nginx

nginxの設定ファイル
/etc/nginx


起動コンテナ一覧
sudo docker ps

起動・停止コンテナ一覧
sudo docker ps -a

コンテナ削除
docker rm 6c796c021e54

dockerコンテナ起動
sudo docker-compose up --build

docker の中見る
sudo docker exec -it 1b8a90a5fb4e /bin/bash

dockerのなかのフォルダ確認
ls -l /app/flaskr/static/

docker exec コマンドを実行するには、現在のユーザーが docker グループに属している必要があります。
sudo usermod -aG docker pcmainte

コンテナ内の /app/flaskr/static/ にアクセスする権限付与
sudo docker exec -it kajiapp bash
ls -ld /app/flaskr/static/

chmod -R 755 /app/flaskr/static/


nanoエディタ

1行切り取り 削除にも使える
Ctrl K

1行コピー
Alt ^


HTTPS設定

sudo nano /usr/lib/ssl/openssl.cnf


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?