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?

リバースプロキシを使用したVPSサーバの設定をする

Last updated at Posted at 2025-02-12

はじめに

仕事の関係でテストサーバが必要となり、VPSサーバをレンタルしました。その設定過程を記載します。
私が求める条件としては、Rocky Linux 8.10が使用出来る、Node.jsがインストール出来る、ドメインのネームサーバの変更が出来るというものでした。

レンタルサーバ環境

xServerさんのVPSをレンタルすることにしました。
仕事で使用しているサーバがRed Hat Enterprise Linux release 8.10 (Ootpa)ですので、それと互換性があるRocky Linux 8.10を選択します。

OS: Rocky Linux 8.10(64bit)
メモリ: 2GB
ストレージ(NVMe SSD): 50GB
node version: v16.20.2 ※nvmで管理
npm version: 8.19.4

サーバにログイン

サーバ契約時に作成した公開鍵は、サーバの
/root/.ssh/authorized_keys
にあります。

サーバ契約時に作成した秘密鍵は自身のPCの以下に保存しています。
~/.ssh/xServerKey.pem

こちらのxServerさんのマニュアルを参考にして、SSHの接続を許可します。ポート番号はデフォルトの22のままにします。

スクリーンショット 2025-02-06 11.43.52.jpg
※後述する通り、最終的にはフィルタールール設定は使用せず、ファイアウォールで対応することにしました。

以下のコマンドでログイン出来ます。

ssh -i ~/.ssh/xServerKey.pem root@(IPアドレス)

-i ~/.ssh/xServerKey.pem で使用する秘密鍵を指定しています。

ユーザの作成

以下のコマンドでユーザーを作成します。

adduser newusername

以下のコマンドでパスワードを設定します。

passwd newusername

ssh接続のための設定

作成したユーザでもssh接続を可能とするために、.ssh ディレクトリを作成します。

sudo mkdir -p /home/newusername/.ssh

ここで-pは、親ディレクトリが存在しない場合、自動で作成 するオプションです。

次に、.ssh ディレクトリとその中のファイルの所有者(ユーザー)とグループを newusername に変更します。

sudo chown -R newusername:newusername /home/newusername/.ssh

契約時にサーバー側で作成された 公開鍵 (/root/.ssh/authorized_keys) を、newusername の .ssh ディレクトリにコピーし、権限の変更などをします。

sudo cp /root/.ssh/authorized_keys /home/newusername/.ssh/authorized_keys
sudo chown newusername:newusername /home/newusername/.ssh/authorized_keys
sudo chmod 600 /home/newusername/.ssh/authorized_keys

これで以下のコマンドでログイン出来るようになりました。

ssh -i ~/.ssh/xServerKey.pem newusername@85.131.247.36

sudoコマンドを使用するための設定

デフォルトでは新しいユーザはsudoを実行する権限を持っていないので与えます。

usermod -aG wheel newusername

usermod:ユーザーの情報を変更するコマンド
-a:(append) 追加(既存のグループ設定を維持しながら追加)
-G:wheel 管理者権限(sudo)を持つユーザーが所属する特別なグループであるwheelグループに追加

これでsudoが使用出来るようになりました。

ファイアウォールの設定

firewalld をインストール

sudo dnf install -y firewalld

firewalld を有効化

sudo systemctl enable --now firewalld

FTP のポートを開放

sudo firewall-cmd --permanent --add-service=ftp
sudo firewall-cmd --permanent --add-port=40000-50000/tcp
sudo firewall-cmd --reload

上記のコマンドは以下の意味を持ちます。
• --add-service=ftp → FTPの標準ポート (21) を開放。
• --add-port=40000-50000/tcp → パッシブモードで使うポート範囲を開放。
• --reload → 設定を反映。

HTTP (80) と HTTPS (443) などのポートを許可

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https

ついでによく使用する、3000、8080、8443のポートも許可しておきます。

sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=8443/tcp

設定の反映

設定を反映させるには、firewalld をリロードします。

sudo firewall-cmd --reload

再度、開放されたポートやサービスを確認します。

sudo firewall-cmd --list-all

最初は、xServerのパケットフィルター設定をONにしていましたが、後述するFileZillaの使用で「ディレクトリリスト表示の取り出しに失敗しました」というエラーが発生したので、OFFとすることにしました。
スクリーンショット 2025-02-07 10.25.58.jpg

FTP設定

ローカルからサーバにファイルなどを転送するためにFTP設定をします。

FTP サーバーのインストール

sudo dnf install -y vsftpd

vsftpd の設定ファイルを編集

sudo vi /etc/vsftpd/vsftpd.conf

として、設定ファイルを開き編集していきます。

listen=YES(IPv4を有効化)
listen_ipv6=NO(IPv6を無効化)
pasv_enable=YES(クライアントが「PASV」コマンドを送ると、サーバーがデータ転送用のポートを開放し、クライアントにそのポート番号を通知する。)
pasv_min_port=40000
pasv_max_port=50000

を追記しました。

chroot_local_user=YES(すべてのユーザーを chroot で制限)
chroot_list_enable=YES	(chroot_list に記載されたユーザーのみ chroot 解除)
chroot_list_file=/etc/vsftpd/chroot_list   (chroot_listファイル)
allow_writeable_chroot=YES	(エラー防止用。書き込み可能なディレクトリでもログインできるように)

/etc/vsftpd/chroot_listを作成してchrootを解除したユーザ名を記載します。

sudo touch /etc/vsftpd/chroot_list
sudo chmod 600 /etc/vsftpd/chroot_list
echo "newusername" | sudo tee -a /etc/vsftpd/chroot_list

SELinux の設定

FTP サーバーがホームディレクトリにアクセスすることを許可

sudo setsebool -P ftpd_full_access on

FTP を通じたファイルアップロードを許可

sudo setsebool -P allow_ftpd_full_access on

SELinux が有効な場合の FTP パッシブモードの設定

SELinux が Enforcing になっている場合、パッシブモードの FTP を許可する必要があります。

sudo setsebool -P ftpd_use_passive_mode on

• -P オプション → 設定を永続化(リブート後も有効)
• ftpd_use_passive_mode on → FTP のパッシブモードを許可

※SELinux(Security-Enhanced Linux)
Linux システムに強固なアクセス制御を追加するセキュリティ機能です。
Red Hat Enterprise Linux(RHEL)や Rocky Linux などのディストリビューション で標準搭載されています。

vsftpd を起動 & 自動起動設定

sudo systemctl start vsftpd
sudo systemctl enable vsftpd

2つのコマンドは、FTP サーバー vsftpd (Very Secure FTP Daemon) の起動と自動起動の設定を行うものです。
vsftpd は FTP サーバーのデーモン(バックグラウンドで動作するプロセス)です。
systemctl enable は systemd の機能で、サービスを 永続的に有効化 します。
これにより、サーバーを再起動しても vsftpd が自動的に起動するようになります。

FTPコマンドのインストール

sudo dnf install -y ftp

サーバ上で以下を実行すると、つながることが確認できます。

ftp localhost

クライアントから FTP に接続

ftp (IPアドレス)

として、ユーザ名、パスワードを入力すると、クライアントからサーバにつながります。

FileZillaを使う

以下の設定でつながりました。

スクリーンショット 2025-02-07 11.18.19.jpg

ホストは、まだドメインを取得していないので、IPアドレスを記載しています。

nvmのインストール

ユーザでサーバにログインします。
こちらの記事を参考にインストールします。

node.jsのインストール

nvmを利用して、開発環境のホスティングサーバに合わせて
node version: v16.20.2
をインストールします。

nvm install v16.20.2

ちなみにnpmのバージョンは8.19.4がインストールされています。

Nginxのインストール

リバースプロキシを使用したいので、Nginxをインストールします。
問題意識としては、Node.jsのexpressを使用してサーバを立ち上げる時に、HTTPS接続だと「(failed) net::ERR_HTTP2_PROTOCOL_ERROR 」というエラーが頻発していました。これをどうにか解決したいと思い、リバースプロキシを使用する方法を試してみます。
リバースプロキシとは、クライアントとリバースプロキシ間はHTTPSを利用し、リバースプロキシとサーバ間はHTTPを利用するというものです。
こうすることで、HTTP/2プロトコル対応などはリバースプロキシに任せられるので、上記エラーが解消されると期待しています。

システムを最新の状態に更新

sudo dnf update -y

EPEL リポジトリを有効化

Rocky Linux のデフォルトリポジトリには nginx が含まれていますが、最新版を取得するために EPEL (Extra Packages for Enterprise Linux) リポジトリ を追加するのが一般的です。

sudo dnf install -y epel-release

Nginx のインストール

sudo dnf install -y nginx

インストール後、Nginx を起動し、OS 起動時に自動起動するように設定します。

# Nginx の起動
sudo systemctl start nginx

# Nginx を自動起動するように設定
sudo systemctl enable nginx

# Nginx の状態を確認
sudo systemctl status nginx
http://<サーバーのIPアドレス>

とすると確認できます。

スクリーンショット 2025-02-07 14.27.43.jpg

Let's Encryptを利用したSSL/TLS 証明書の設定

Let's Encryptとは?

無料でSSL/TLS証明書を発行する認証局(CA: Certificate Authority) です。Let’s Encryptの証明書は 90日ごとに更新する必要がありますが、Certbot(Let’s Encrypt公式ツール)を使うと、自動更新 できるので手間がかかりません。

こちらのcerbotのページで作業をします。

Cerbotとは?

Let’s Encrypt が提供する 無料のSSL/TLS証明書 を取得・管理するためのツールで、Nginxの設定を自動で変更、証明書の自動更新が可能などの特徴があります。

My HTTP website is running [Nginx] on [Linux (snap)]で作業します。
snapは、Certbotの公式推奨インストール方法です。

設定手順

SSH into the server

sudo権限を持ったユーザで、SSH接続を利用してサーバに入ります。

Install snapd

snapdは、“Snap パッケージ” を管理するデーモン(バックグラウンドサービス) です。
通常、Linux ではソフトウェアをインストールする方法として dnf(RHEL, CentOS, Rocky Linux)や apt(Ubuntu, Debian)を使います。
しかし、これらの方法ではディストリビューションごとに異なるパッケージ管理システムがあり、互換性の問題が発生することがあります。

Snap は、その問題を解決するために設計された新しいパッケージ形式 です。

# まず EPEL リポジトリを有効化
sudo dnf install epel-release -y

# `snapd` をインストール
sudo dnf install snapd -y

# `snapd` を有効化
sudo systemctl enable --now snapd

# `snapd` の状態を確認
systemctl status snapd

Remove certbot-auto and any Certbot OS packages

dnfなどのcerbotパッケージが存在すると、うまく動かないようなので、念の為削除しておきます。

certbot --version

こちらのコマンドでcerbotが見つからなかったので、OKです。

Install Certbot

多少詰まりましたが、chatGPTに聞いてインストール出来ました。

Prepare the Certbot command

sudo ln -s /snap/bin/certbot /usr/bin/certbot

このコマンドは /snap/bin/certbot へのシンボリックリンク(ソフトリンク)を /usr/bin/certbot に作成するものです。
シンボリックリンク(-s オプション)は、ファイルやディレクトリへの 参照(ショートカット)を作成する 仕組みです。
この場合、/usr/bin/certbot を実行すると、実際には /snap/bin/certbot が呼び出されます。
このコマンドを実行することで、certbot を どこからでも実行できるようにする ことができます!

Choose how you'd like to run Certbot

sudo certbot --nginx

コマンドを実行後、質問をいくつかされるのでそれに回答すると終了です。

Test automatic renewal

証明書が自動更新するかテストします。

sudo certbot renew --dry-run

成功したので、実際の更新も問題なく動作するはずです。

Confirm that Certbot worked

最後にhttpsでページが見られるか確認しました。

nginxの設定ファイル

/etc/nginx/nginx.conf
に設定ファイルがあり、証明書の保存場所やリダイレクト設定などが記載されています。
以下のように設定して、解説も記載しました。cerbotによって設定されたものから、少し修正しています。

nginx.conf
user nginx;
worker_processes auto; # サーバーの CPU コア数に応じて最適なプロセス数を自動設定
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;  #	1つのワーカープロセスが同時に処理できる最大の接続数 を設定
}

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 2048;

    include             /etc/nginx/mime.types; #適用される MIMEタイプ
    default_type        application/octet-stream; #MIME タイプが不明なファイルは application/octet-stream(バイナリデータ)として送信

    include /etc/nginx/conf.d/*.conf; # 設定の分割管理だが使用していない

    server {
        listen       80 default_server; #ポート 80(HTTP)で待ち受ける。
        listen       [::]:80 default_server; #IPv6 アドレスでも 80 を待ち受ける。#「default_server」はserver_name にも一致しないリクエストをこの server ブロックで処理
        server_name  k96mz.com;
        root         /usr/share/nginx/html; #Web サイトのルートディレクトリを指定

        include /etc/nginx/default.d/*.conf; #追加の設定を分割管理できるが使用していない。

        location / { # /(ルートディレクトリ)に対するリクエストを処理
        }

        error_page 404 /404.html; #404 エラーが発生した場合、/404.html を表示
            location = /40x.html { #/40x.html にリクエストがあったときの処理を指定
        }

        error_page 500 502 503 504 /50x.html; #500(内部エラー)、502(Bad Gateway)、503(Service Unavailable)、504(Gateway Timeout)の場合、/50x.html を表示
            location = /50x.html {
        }
    }

    server {
        listen       443 ssl http2 default_server;
        listen       [::]:443 ssl http2 default_server;
        server_name  k96mz.com;
        root         /usr/share/nginx/html;

            ssl_certificate /etc/letsencrypt/live/k96mz.com/fullchain.pem; # managed by Certbot
            ssl_certificate_key /etc/letsencrypt/live/k96mz.com/privkey.pem; # managed by Certbot

            include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
            ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

        include /etc/nginx/default.d/*.conf;
        
       #HTTP でバックエンドに転送
        location / {
            proxy_pass http://localhost:8080;
            proxy_set_header Host $host; #クライアントのホスト名を保持
            proxy_set_header X-Real-IP $remote_addr; #クライアントの IP アドレスを保持
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #プロキシを経由した元の IP アドレスを送信
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

ここで肝になるのは、リバースプロキシ設定部分です。

例えば、
https://k96mz.com/test/index.html
にきたリクエストは、
http://localhost:8080/test/index.html
に転送されます。
この時、リダイレクトとは異なり、クライアントに表示されるURLは、
https://k96mz.com/test/index.html
のままです。

設定後は以下でエラーがないか確認します。

sudo nginx -t

コードを修正した後は、以下のコマンドで修正を反映します。

sudo systemctl reload nginx

node.jsでサーバを立ち上げる

node.jsでサーバを立ち上げて、実際の挙動を確かめました。

const express = require('express');
const app = express();
const PORT = 8080;

// ルート("/")にアクセスしたときのレスポンス
app.get('/', (req, res) => {
    res.send('Hello, World!');
});

app.get('/test', (req, res) => {
  res.send('Test response');
});

// サーバーを起動
app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
});

実際に
https://k96mz.com
とすると「Hello, World!」が返り、
https://k96mz.com/test
とすると、「Test response」が返ります。

リバースプロキシを使用してベクトルタイルを表示

こちらの記事で、node.jsを用いてベクトルタイルサーバを作成しました。HTTPSでの地図表示について、非常に不安定な状態で、おそらくですがHTTP/2プロトコルでの表示がうまくいっていないようでした。そこで、今回はリバースプロキシを用いて、リバースプロキシとサーバ間はHTTP接続とすることで、不安定な状態を解決したいと思います。
使用するコードはこちらのGitHubページにあります。

コード修正

今回のサーバに合わせて以下の点を修正します。
・使用するポートは8080
・styleO-pbf.jsonのタイルURLは以下に変更
"tiles": ["https://k96mz.com/VTpractice/{z}/{x}/{y}.pbf"]
・styleO-mbtiles.jsonのタイルURLは以下に変更
"tiles": ["https://k96mz.com/VT/zxy/VTpracticegzip/{z}/{x}/{y}.pbf"]

上記の設定に修正することで、例えば、以下のURLにアクセスすると地図が表示されます。(現在はサーバを立ち上げていないので、地図は見られません。)
https://k96mz.com/map/mapO-mbtiles.html

スクリーンショット 2025-02-12 11.28.02.jpg

コードの中で、appHttps.jsなどはHTTPS接続のための鍵を読み込んでいますが、リバースプロキシを利用すれば、そのようなことは意識しなくて良いので楽だと感じました

まとめ

レンタルしたVPSサーバの設定過程を記載しました。特にNginxを使用したリバースプロキシの挙動を試したかったのですが、地図表示がうまくいって良かったです。

Reference

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?