6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

オレオレCD(N)を作る

Last updated at Posted at 2023-12-19

この記事は エンジニア学生団体IDEA Advent Calendar 2023 の12/19分になります

cloudflared経由でm3u8など大量のデータを流すとキャッシュの上限を突破して同一ドメインを使用しているサイトすべてが死んでしまうので代替としてCD(N)を自作しました

材料

  • VPS(必要に応じてn個)
  • インターネットにアクセスできるオリジンサーバー
  • ドメイン

手順

1. VPSをセットアップする

a. OSのインストール

linux系なら何でも良いです(多分)
この記事では ubuntu-server を想定しています

b. NGINXのインストール

apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
apt update
apt install nginx
systemctl enable --now nginx

2. オリジンサーバーをセットアップする

a. sshの公開鍵認証を設定する

適宜やってください
オリジン、VPS共に専用ユーザーを作成することをおすすめします

b. systemdのサービスを作成する

各VPSへ向けてsshを用いたトンネルを作成する

[Unit]
Description=Setup a secure tunnel to remote server
After=network.target

[Service]
ExecStart=/usr/bin/ssh -NT -o ServerAliveInterval=60 -o ExitOnForwardFailure=yes -R <remote-port>:localhost:<local-port> <remote-server>

RestartSec=5
Restart=always

User=<username>

[Install]
WantedBy=multi-user.target

作成後適宜起動・有効化してください

3. キャッシュ&リバプロを設定する

a. ssl証明書の取得

適宜letsencryptなどを用いて取得してください
この記事ではcertbotで証明書を取得した場合を想定しています

b. キャッシュ場所の設定

/etc/nginx/nginx.confのhttpブロック内に以下の内容を追記します

proxy_cache_path /var/cache/nginx keys_zone=zone1:1024m max_size=30g inactive=24h;
proxy_temp_path  /var/cache/nginx_tmp;

c. コンフィグファイルの作成

/etc/nginx/conf.d/に以下のファイルを作成します

server {
    listen       443 ssl;
    listen  [::]:443 ssl;
    server_name  <hostname>;

    ssl_certificate /etc/letsencrypt/live/<hostname>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<hostname>/privkey.pem;

    location / { #キャッシュしてほしいディレクトリ
        proxy_pass http://localhost:<remote-port>/;
        proxy_set_header    Host <hostname>;
        proxy_set_header    X-Real-IP    $remote_addr;   
        proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

        proxy_buffering on;
        proxy_cache_valid 200 302 1y;
        proxy_cache_valid 404 10m;
        proxy_cache zone1;
        add_header X-Nginx-Cache $upstream_cache_status;
    }
    
    location /hoge { #キャッシュしてほしくないディレクトリ、認証エンドポイントとか
        proxy_pass http://localhost:<remote-port>;
        proxy_set_header    Host <hostname>;
        proxy_set_header    X-Real-IP    $remote_addr;
        proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

        proxy_buffering on;
        proxy_no_cache 1;
        proxy_cache_bypass 1;
    }

    location /huga { #別途認証をかけたいディレクトリ
        auth_request /<path-to-auth>; #認証エンドポイントにリクエストが飛び、200を返すと表示される 
        proxy_pass http://localhost:<remote-port>;
        proxy_set_header    Host <hostname>;
        proxy_set_header    X-Real-IP    $remote_addr;
        proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

        proxy_hide_header Cookie;
        proxy_set_header  Cookie "";

        proxy_buffering on;
        proxy_cache_valid 200 302 1y;
        proxy_cache_valid 404 10m;
        proxy_cache zone1;
        add_header X-Nginx-Cache $upstream_cache_status;
        add_header Cache-Control "no-cache";
    }
}

d. コンフィグの確認・反映

nginx -t

でコンフィグの確認を行います
問題なさそうであればnginxを再起動してコンフィグを反映します

systemctl restart nginx

4. ドメインの設定

セットアップした各VPSのIP宛にAレコードを貼れば完了です

おまけ

実際に運用しているドメインを掲載しておくので煮るなり焼くなりご自由にどうぞ
※パブリックなリソースは一切ないので403しか返ってこないと思いますが

https://cdn.xpa.dev/

以前公開した nginx-vod-moduleでon-the-flyなhls配信環境を作る の前段に置いてあります

余談

実際のCDNではロケーションに応じて適切なサーバーが選択されるようになっていますが、やってられないので正直1台あれば十分だと思います
(そもそもオリジンへのリクエストによる負荷を減らしたいだけなので)

6
2
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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?