jdjwzx233

jdjwzx233

如期待奇迹发生,那唯有不停伸手去抓紧,去把握才行
bilibili
github
email

Netlifyを使用してリバースプロキシを構築する

1. 免責事項

この記事は、技術愛好者に Netlify を使用してリバースプロキシを構築する方法に関する技術的なガイダンスと例を提供することを目的としています。この記事の情報と提案は参考用であり、具体的な実施は実際の状況によって異なる場合があります。この記事で提供される方法と手順を使用する際は、地元の法律や規制を遵守し、ネットワークセキュリティとデータ保護の要件を十分に考慮してください。

この記事の著者および発表プラットフォームは、この記事の内容を使用することによって生じる直接的または間接的な損失、損害、または法的責任について一切の責任を負いません。技術的なソリューションを実施する前に、十分なテストとリスク評価を行い、適用される法律および業界基準に準拠することを確認するために専門的な意見を求めることをお勧めします。

2. 合法的な使用声明

関連する法律および規制を遵守してください。これには、中華人民共和国のネットワークセキュリティ法およびインターネット情報サービス管理方法が含まれます。Netlify や他のサービスを使用する際は、以下を確実に行ってください:

  1. 合法性の確保:構築したリバースプロキシが法律や規制に違反する活動に使用されないようにしてください。これには、検閲の回避、違法なデータ転送、またはその他の違法な目的が含まれます。
  2. 著作権とプライバシーの尊重:著作権法を遵守し、代理するコンテンツが第三者の知的財産権を侵害しないことを確認してください。また、ユーザーのプライバシーを保護し、データ保護に関する要件を遵守してください。
  3. ネットワークセキュリティ:リバースプロキシサービスが悪意のある目的に使用されないように必要なセキュリティ対策を講じ、システムとユーザーデータの安全を確保してください。
  4. 情報の透明性:提供するサービスの情報が明確で透明であることを確認し、ユーザーがリバースプロキシの目的と潜在的なリスクを明確に理解できるようにしてください。

前書き / 要約#

今日のインターネット環境では、特に一部の国外および国内のウェブサイトが DNS 汚染やその他の理由により正常にアクセスできないことが多く、これが多くのユーザーにとって大きな悩みの種となっています。また、IP アドレスを介してのみアクセスできるウェブサイトもあり、カスタムドメイン名をバインドできないため、柔軟性と可用性が制限されています。これらの問題を解決するために、リバースプロキシサーバーを構築することが効果的な解決策となります。リバースプロキシは、ユーザーが DNS 汚染の問題を回避するのを助けるだけでなく、IP アドレスを介してのみアクセスできるウェブサイトにカスタムドメイン名でアクセスできるようにします。

この記事では、Netlify という強力で使いやすいツールを使用してリバースプロキシを構築します。Netlify の強みは、そのシンプルな設定プロセスと強力な機能にあり、技術に不慣れなユーザーでも簡単に始められます。このタスクを完了するには、Netlify アカウントと GitHub アカウントの 2 つの基本条件が必要です。次に、これらの 2 つのアカウントを使用してリバースプロキシを設定する方法を詳しく説明します。

本文#

お知らせ
タイトルの後に (選) とあるものはバックエンド関連の内容であり、必要ない場合はスキップできます。

第 1 ステップ リバースプロキシ構築のための環境を準備する#

1. リポジトリを作成する#

Netlify の設定ファイルを保存するための GitHub リポジトリを作成します。

以下のように:

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/1726582387299_23298110f4e294999cce8e5ddb9919ed.png

2. 設定ファイルを作成する#

netlify.tomlという名前の設定ファイルを新規作成します。

以下のように:

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_b32990708afc79c8ac57533641e18942.png

ファイルの内容は次の通りです:

[[redirects]]
  from = "/*"
  to = "https://github.com/:splat"
  status = 200

選択的内容#

管理バックエンドを構築するための別のリポジトリを新規作成します (選)。

以下のように:

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/1726582387299_23298110f4e294999cce8e5ddb9919ed.png

リポジトリに含まれるファイル (選):#
│  index.html
│  package.json
│  README.md

└─netlify
  └─functions
    auth-callback.js
    check-auth.js
    update-redirect.js
  1. index.html:アプリケーションの主要なフロントエンドページで、ユーザーのログインとリバースプロキシの設定フォームを含みます。(選)

お知らせ
コード内の【ここにあなたの GitHub clientid を入力】の部分にあなたの GitHub clientid を入力してください。取得方法は下記を参照してください。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>リバプロ設定</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background: linear-gradient(to bottom, #87CEFA, #FFFFFF);
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            overflow-x: hidden;
        }

        .container {
            text-align: center;
            width: 90%;
            max-width: 500px;
        }

        h1 {
            color: #333;
            margin-bottom: 20px;
            font-size: 1.8em;
        }

        form {
            background: #f9f9f9;
            border-radius: 15px;
            padding: 20px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            transition: transform 0.3s ease-in-out;
        }

        form:hover {
            transform: scale(1.02);
        }

        label {
            font-size: 1.2em;
            display: block;
            margin-bottom: 10px;
            color: #555;
        }

        input[type="url"] {
            width: calc(100% - 22px);
            padding: 10px;
            border-radius: 8px;
            border: 1px solid #ddd;
            margin-bottom: 20px;
            font-size: 1em;
            box-sizing: border-box;
        }

        button {
            background-color: #87CEFA;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 1.1em;
            transition: background-color 0.3s ease-in-out;
        }

        button:hover {
            background-color: #00BFFF;
        }

        #message {
            font-size: 1.2em;
            color: #333;
            margin-top: 20px;
        }

        .error-container,
        .success-container {
            display: none;
            background: #f0f8ff;
            border: 1px solid #d4edda;
            border-radius: 8px;
            padding: 20px;
            margin-top: 20px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            text-align: center;
        }

        .error-container {
            border-color: #f5c6cb;
            background: #f8d7da;
            color: #721c24;
        }

        .success-container {
            border-color: #c3e6cb;
            background: #d4edda;
            color: #155724;
        }

        .error-container p,
        .success-container p {
            margin: 0;
        }

        .success-container button {
            margin-top: 10px;
            background-color: #4CAF50;
            border: none;
        }

        .success-container button:hover {
            background-color: #45a049;
        }

        .tooltip {
            position: relative;
            display: inline-block;
            cursor: pointer;
        }

        .tooltip .tooltiptext {
            visibility: hidden;
            width: 200px;
            background-color: #333;
            color: #fff;
            text-align: center;
            border-radius: 6px;
            padding: 5px 10px;
            position: absolute;
            z-index: 1;
            bottom: 125%;
            left: 50%;
            margin-left: -100px;
            opacity: 0;
            transition: opacity 0.3s;
        }

        .tooltip:hover .tooltiptext {
            visibility: visible;
            opacity: 1;
        }

        #loginContainer {
            display: none;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>リバプロ設定ツール</h1>
        <div id="loginContainer">
            <p>このページにアクセスするにはログインしてください。</p>
            <button id="loginButton">GitHubでログイン</button>
        </div>
        <form id="redirectForm" style="display: none;">
            <div class="tooltip">
                <label for="website">リバースプロキシ先のURLを入力してください:</label>
                <span class="tooltiptext">完全なURLを入力してください。例: https://example.com</span>
            </div>
            <input type="url" id="website" name="website" required>
            <button type="submit">送信</button>
        </form>
        <div id="errorMessage" class="error-container">
            <p id="errorStatusMessage"></p>
        </div>
        <div id="successMessage" class="success-container">
            <p id="successStatusMessage"></p>
            <button id="redirectButton" style="display: none;">リバースプロキシサイトに移動</button>
        </div>
    </div>

    <script>
        async function checkAuthentication() {
            const response = await fetch('/.netlify/functions/check-auth');
            const result = await response.json();

            if (result.authenticated) {
                document.getElementById('loginContainer').style.display = 'none';
                document.getElementById('redirectForm').style.display = 'block';
            } else {
                document.getElementById('loginContainer').style.display = 'block';
                document.getElementById('redirectForm').style.display = 'none';
            }
        }

        document.getElementById('loginButton').addEventListener('click', () => {
            window.location.href = `https://github.com/login/oauth/authorize?client_id=【ここにあなたのGitHub clientidを入力】&redirect_uri=${encodeURIComponent(window.location.origin + '/.netlify/functions/auth-callback')}`;
        });

        document.getElementById('redirectForm').addEventListener('submit', async (event) => {
            event.preventDefault();
            const website = document.getElementById('website').value;

            const urlPattern = /^https:\/\/[^\/]+$/;
            const errorMessageElement = document.getElementById('errorStatusMessage');
            const successMessageElement = document.getElementById('successStatusMessage');
            const errorContainer = document.getElementById('errorMessage');
            const successContainer = document.getElementById('successMessage');
            const redirectButton = document.getElementById('redirectButton');

            if (!urlPattern.test(website)) {
                const suggestion = website.replace(/\/+$/, '');
                errorMessageElement.innerText = `入力されたURL形式が正しくありません。URLは 'https://example.com' の形式で入力してください。あなたの正しい入力例は:${suggestion}`;
                errorContainer.style.display = 'block';
                successContainer.style.display = 'none';
                return;
            }

            const response = await fetch('/.netlify/functions/update-redirect', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({ website })
            });

            const result = await response.json();
            if (result.message === 'リダイレクトが正常に更新されました!') {
                successMessageElement.innerText = 'リバースプロキシの設定が成功しました!サーバーの更新をお待ちください。予想時間は1分です。';
                successContainer.style.display = 'block';
                errorContainer.style.display = 'none';
                redirectButton.style.display = 'inline-block';
                redirectButton.addEventListener('click', () => {
                    window.location.href = 'https://g.j23.one/';
                });
            } else {
                errorMessageElement.innerText = `設定に失敗しました:${result.message}`;
                errorContainer.style.display = 'block';
                successContainer.style.display = 'none';
            }
        });

        // 認証チェックを初期化
        checkAuthentication();
    </script>
</body>
</html>
  1. /netlify/functions/auth-callback.js:GitHub OAuth コールバックを処理する関数で、ユーザーのログイン状態を設定します。(選)
exports.handler = async function(event, context) {
    const clientId = process.env.GITHUB_CLIENT_ID;
    const clientSecret = process.env.GITHUB_CLIENT_SECRET;
    const allowedUsers = process.env.ALLOWED_USERS.split(',');
    const jwtSecret = process.env.JWT_SECRET;

    const code = event.queryStringParameters.code;

    if (!code) {
        return {
            statusCode: 400,
            body: JSON.stringify({ message: 'コードパラメータが欠落しています' })
        };
    }

    try {
        const fetch = (await import('node-fetch')).default;
        const jwt = (await import('jsonwebtoken')).default;

        const response = await fetch(`https://github.com/login/oauth/access_token`, {
            method: 'POST',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                client_id: clientId,
                client_secret: clientSecret,
                code: code
            })
        });

        const data = await response.json();

        if (data.error) {
            throw new Error(data.error_description);
        }

        const userResponse = await fetch('https://api.github.com/user', {
            headers: {
                Authorization: `token ${data.access_token}`
            }
        });

        const userInfo = await userResponse.json();

        if (allowedUsers.includes(userInfo.login)) {
            const token = jwt.sign({ username: userInfo.login }, jwtSecret, { expiresIn: '1h' });

            return {
                statusCode: 302,
                headers: {
                    'Set-Cookie': `token=${token}; Path=/; HttpOnly`,
                    'Location': '/'
                },
                body: ''
            };
        } else {
            return {
                statusCode: 403,
                body: JSON.stringify({ message: '未承認' })
            };
        }
    } catch (error) {
        return {
            statusCode: 500,
            body: `エラー: ${error.message}`
        };
    }
};
  1. /netlify/functions/check-auth.js:ユーザーがログインしているかどうかを確認する関数。(選)
exports.handler = async function(event, context) {
    const jwtSecret = process.env.JWT_SECRET;

    const cookieHeader = event.headers.cookie || '';
    const cookies = Object.fromEntries(cookieHeader.split('; ').map(cookie => cookie.split('=')));
    const token = cookies.token;

    try {
        const jwt = (await import('jsonwebtoken')).default;
        jwt.verify(token, jwtSecret);
        return {
            statusCode: 200,
            body: JSON.stringify({ authenticated: true })
        };
    } catch (err) {
        return {
            statusCode: 403,
            body: JSON.stringify({ authenticated: false })
        };
    }
};
  1. /netlify/functions/update-redirect.js:リバースプロキシ設定を処理する関数。(選)

お知らせ
コード内の【ここにあなたの GitHub ユーザー名】【Netlify 設定ファイルを保存するための GitHub リポジトリ名】の部分にそれぞれあなたの GitHub ユーザー名と Netlify 設定ファイルを保存するための GitHub リポジトリ名を入力してください。取得方法は下記を参照してください。

exports.handler
const jwtSecret = process.env.JWT_SECRET;
    const allowedUsers = process.env.ALLOWED_USERS.split(',');

    const cookieHeader = event.headers.cookie || '';
    const cookies = Object.fromEntries(cookieHeader.split('; ').map(cookie => cookie.split('=')));
    const token = cookies.token;

    let decodedToken;

    try {
        const jwt = (await import('jsonwebtoken')).default;
        decodedToken = jwt.verify(token, jwtSecret);
    } catch (err) {
        return {
            statusCode: 403,
            body: JSON.stringify({ message: '未承認' })
        };
    }

    if (!allowedUsers.includes(decodedToken.username)) {
        return {
            statusCode: 403,
            body: JSON.stringify({ message: '未承認' })
        };
    }

    const { Octokit } = await import('@octokit/rest');
    const octokit = new Octokit({
        auth: process.env.GITHUB_TOKEN
    });

    const { website } = JSON.parse(event.body);

    if (!website) {
        return {
            statusCode: 400,
            body: JSON.stringify({ message: 'ウェブサイトが提供されていません' })
        };
    }

    try {
        const fetch = (await import('node-fetch')).default;

        const { data: fileData } = await octokit.repos.getContent({
            owner: '【ここにあなたのGitHubユーザー名を入力】',
            repo: '【Netlify設定ファイルを保存するためのGitHubリポジトリ名】',
            path: 'netlify.toml'
        });

        const content = Buffer.from(fileData.content, 'base64').toString();
  
        const newContent = content.replace(/to\s*=\s*"[^"]+"/, `to = "${website}/:splat"`);

        await octokit.repos.createOrUpdateFileContents({
            owner: '【ここにあなたのGitHubユーザー名を入力】',
            repo: '【Netlify設定ファイルを保存するためのGitHubリポジトリ名】',
            path: 'netlify.toml',
            message: 'リダイレクトURLを更新',
            content: Buffer.from(newContent).toString('base64'),
            sha: fileData.sha
        });

        return {
            statusCode: 200,
            body: JSON.stringify({ message: 'リダイレクトが正常に更新されました!' })
        };
    } catch (error) {
        console.error(error);
        return {
            statusCode: 500,
            body: JSON.stringify({ message: 'リダイレクトの更新に失敗しました' })
        };
    }
};
  1. package.json:依存関係を保存するファイル。(選)
    {
      "name": "Rcs,
      "version": "1.0.0",
      "description": "NetlifyにデプロイされたGitHub認証を使用したリバースプロキシ設定ツール。",
      "main": "index.js",
      "scripts": {
        "start": "netlify dev",
        "build": "netlify build"
      },
      "dependencies": {
        "@octokit/rest": "^19.0.7",
        "jsonwebtoken": "^9.0.2",
        "node-fetch": "^3.3.2"
      },
      "devDependencies": {
        "netlify-cli": "^15.0.0"
      },
      "engines": {
        "node": ">=16.x"
      },
      "author": "j23",
      "license": "MIT"
    }
    

第 2 ステップ Netlify を設定する#

1. サイトを作成する#

以下のように:

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_24ce560b9f2dc57d0d6f51bfebae6b71.png

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_d0c9459ade47c217db7d74d4c0dc815f.png

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_ee9fc4b5245b51661e8a91a2c509c959.png

  1. Netlify 設定ファイルを保存するための GitHub リポジトリを選択します。

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_1f40a4eb848a567c69eee524172ba04a.png

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17 / スクリーンショット_17-9-2024_23297_app.netlify.com_9d63c0ed9504f5a945c156f026d8fc1f.jpeg

2. カスタムドメインを設定する#

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_03b28a83de8ee0c91accd703fdca989d.png

これで基本的な操作はすべて完了しました。バックエンドの設定が不要な場合は、Netlify 設定ファイル内のリンクを変更するだけで、プロキシしたいウェブサイトを変更できます。

変更内容は以下の通りです(注意!URL 形式は必ずhttps://example.com/ で、https:// を削除したり最後の / を削除したりしないでください):

[[redirects]]
  from = "/*"
  to = "【ここを変更】:splat"
  status = 200

選択的内容#

一.GitHub ログイン#

GitHub を使用して OAuth ログインを行い、承認されたユーザーのみが設定機能にアクセスできるようにします。

第 1 ステップ:#

以下の URL を開き、設定を入力しますhttps://github.com/settings/applications/new

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_08ba52609ba4bfe62f2563933cbba566.png

第 2 ステップ:#

Client ID を取得し、Client secrets を生成します。後で使用します。

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_038e6d1208bd8e0990b3b595a40f256e.png
2.
https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_0572103207489f7a3ae48fd3a3e2a2b6.png

警告!
Client secrets を適切に保管してください!

二。リポジトリを変更するためのキーを設定する#

  1. 以下の URL を開きますhttps://github.com/settings/tokens

    https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_29ac6da4b073ffc18764a3748bcc885a.png

  2. 関連情報を入力し、期限なしを選択し、リポジトリをチェックします。

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_bdfead6a17b8cdf05219e9ae7e9bd799.png

  1. キーを取得します。

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_56563b4d40ebd00c25c2ddbc0aea9565.png

警告!
キーを適切に保管してください。

三.Netlify を設定する#

第 1 ステップ:サイトを作成する#

以下のように:

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_24ce560b9f2dc57d0d6f51bfebae6b71.png

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_d0c9459ade47c217db7d74d4c0dc815f.png

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_ee9fc4b5245b51661e8a91a2c509c959.png

  1. バックエンドリポジトリを選択します。

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_1f40a4eb848a567c69eee524172ba04a.png

  1. 環境変数を入力します。
    ALLOWED_USERS:バックエンドを使用するために承認されたGitHubユーザー名を半角カンマで区切って入力します。1人だけの場合はカンマは不要です。例:ユーザー名1,ユーザー名2
    GITHUB_CLIENT_ID:あなたのCLIENT_ID
    GITHUB_CLIENT_SECRET:あなたのCLIENT_SECRET
    GITHUB_TOKEN:あなたのGitHubアカウントのキー
    JWT_SECRET:ランダムな任意の長さの文字列。例:wfhehfihwjdwefnabwaieu72dub3uigfvqty2UGQWADIWGADIY3UGF378
    

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_5bb90ceb6dd257c5c3e51cd20423f929.png
このステップを漏らした場合は、以下のページで見つけて補充できます。

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/18/image_1184a04b95f68e809a5360a9e5925ecc.png

第 2 ステップ。カスタムドメインを設定する#

https://upcdn.jdjwzx233.cn/upload/Qexo/24/9/17/image_03b28a83de8ee0c91accd703fdca989d.png

結論#

ここまで読んでいただきありがとうございます。何か問題があればコメント欄でお知らせください!可能であれば、私のウェブサイトを購読してください:https://jdjwzx233.cn/Subscribe

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。