はじめに

前回の記事からだいぶ時間が経ちましたが、第3回めです(・∀・)。 今回は全体的なアーキテクトについて記述していこうと思います(・∀・)。

※注意! この一連の記事で紹介するコードは動作の概念を説明するものでありセキュリティーなどは意識していません(・∀・)。

実際に運用するシステムなどに使用しないでください(・∀・)。 (そのまま使うひともいないと思いますが)

また、私も記事を書きながら開発をしていくので「後になってみたら最初の方の記事間違えてたー」なんて事は起きそうです(・∀・)。

ご了承ください(・∀・)。

目次

サーバー設定前のDNSまわり下準備

ドメインを取る

今回は お名前.com を使用します(・∀・)。 他のレジストラサービスでも良いと思います(・∀・)。

レンタルサーバーサービスの運用には独自ドメインが必要になりますので、適当に取得してみてください(・∀・)。 .xxx とか .xyz とかの適当なドメインなら初年度はけっこう安いです(・∀・)。

この記事では rentaserve.com という独自ドメインを取得したように記事を書きます(・∀・)。

ドメイン取得方法については割愛します(・∀・)。 (ちゃんと書いて欲しい人が居たらコメントください)

VPSを借りる

サーバーOSには Debian/GNU Linux 11 を採用します(・∀・)。 ホスティングサービスには (ConoHa VPS)[https://www.conoha.jp/] を使用します(・∀・)。 (このはたん可愛い)

Debian ベースの Raspberry Pi OS でもほぼ同じ手順が取れますので、自宅サーバーでレンタルサーバーサービスなどにチャレンジしてみても面白いかも知れません(・∀・)。 (※グローバルIPアドレスとポート開放が必要になります)

VPS や Linux の基本的な手順については割愛します(・∀・)。 (ちゃんと書いて欲しい人が居たらコメントください)

私は以下の感じで VPS を作成しました(・∀・)。

VPSセットアップ

必要に応じて適当な性能のVPSを借りてください(・∀・)。

独自ドメインでDNSサーバーを動かす下準備

ドメインをネームサーバーとして動作させる設定をお名前.com で行います(・∀・)。

取得したドメイン(今回の場合は rentaserve.com )をネームサーバー(権威DNSサーバー)として動作させるための設定です(・∀・)。

まず、作成した ConoHa VPS のグローバルIPアドレスが必要になります(・∀・)。 ConoHa の VPS 詳細画面から確認できます(・∀・)。

IPアドレス確認

自宅サーバーのひとは確認くんなどのページから確認できます(・∀・)。

次に、お名前.com の NAVI 画面からDNS関連の設定を行っていきます(・∀・)。

rentaserve.com を選択した状態で設定画面の「ネームサーバー名としてホスト登録を行う」を選択します(・∀・)。

ホスト登録

これは、取得した独自ドメインにアクセスした時にどのIPアドレスのDNSサーバーの情報を見に行くかの設定で、独自ドメインでDNSサーバーを立ち上げるのに必須の設定になります(・∀・)。

ここに

  • ns1.rentaserve.com
  • ns2.rentaserve.com

のふたつのDNSホストを作成します(・∀・)。

ホストには ConoHa VPS インスタンスのグローバルIPアドレスを設定してください(・∀・)。

※注意!

本来は ns1 と ns2 は別々のDNSサーバーを立ててそれぞれのIPアドレスを設定して障害耐性を高めます(・∀・)。 今回は全てを単一のDNSサーバーで実現するためにインチキをしています(・∀・)。

最後に rentaserve.com のネームサーバーを ns1.rentaserve.com / ns2.rentaserve.com に設定します(・∀・)。

ここに最低ふたつのDNSサーバーを指定しないと行けないので、ns1 と ns2 を作成しました(・∀・)。

これでDNS関連の下準備が完了です(・∀・)。

サーバーの設定をしていく

下準備

まずはパッケージを更新します(・∀・)。 私は基本 root で作業してるので、気になるひとは sudo でも使ってください(・∀・)。

$ apt update
$ apt upgrade

ファイヤーウォールとポート転送

とりあえず、必要そうなネットワーク関連のパッケージをインストールします(・∀・)。

apt install dnsutils whois iptables-persistent nmap

手順では使わないものもありますが、とりあえず入れちゃう感じ(・∀・)。 (最低限必要なのは iptables-persistent です)

今回作るレンタルサーバーでは

  • HTTP/HTTPS
  • SMTP/SMTPS
  • IMAP/IMAPS
  • SSH
  • FTP
  • DNS を動かします(・∀・)。

それらがインターネットからアクセスできるようにするためにポートを開け、それ以外は閉じておくように設定します(・∀・)。

では、実際に設定していきます(・∀・)。

まずは基本

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -i eth1 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -j ACCEPT

意味は

  • 自分のサーバーからのアクセスは無条件に許可
  • 外部からの接続は確立されていれば許可
  • 内部から外部へのアクセスは無条件で許可

のような感じです(・∀・)。

次に、アクセスできるポートを指定します(・∀・)。

iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 25 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 465 -j ACCEPT
iptables -A INPUT -p tcp --dport 587 -j ACCEPT
iptables -A INPUT -p tcp --dport 993 -j ACCEPT
iptables -A INPUT -p tcp --dport 30100:30500 -j ACCEPT

設定を確認する場合は

iptables -L

で確認できます(・∀・)。

また、設定をリセットしたい場合は

iptables -F

とすると全部消えて無くなってくれます(・∀・)。

最後に、上記の設定を保存して反映します(・∀・)。

netfilter-persistent save
netfilter-persistent reload
systemctl enable netfilter-persistent

mariadb

インストール

ざっくり mariadb をインストールします(・∀・)。 mariadb は、この記事執筆段階での最新である 10.6 をインストールします(・∀・)。

面倒なひとは Debian/GNU Linux 11 標準の mariadb 10.3 でも問題ないと思います(・∀・)w

apt install software-properties-common dirmngr
apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'
add-apt-repository 'deb [arch=amd64,arm64,ppc64el]

https://mirrors.ukfast.co.uk/sites/mariadb/repo/10.6/debian bullseye main'

apt update
apt upgrade

apt install mariadb-server

systemctl restart mariadb
systemctl enable mariadb

mysql_secure_installation

rentaserve.com 用のデータベースを作成

mysql -u root -p

以下のSQLを実行します(・∀・)。

CREATE USER 'rentaserve'@'localhost' IDENTIFIED BY 'ここにパスワードを入れる';
CREATE DATABASE IF NOT EXISTS `rentaserve`;
GRANT ALL PRIVILEGES ON `rentaserve`.* TO 'rentaserve'@'localhost';
QUIT;

DNSサーバーを構築する

インストール他

まずは PowerDNS をインストール(・∀・)。

apt install pdns-server pdns-backend-mysql

systemctl stop pdns

DNSサーバーの設定を行う(・∀・)。

vi /etc/powerdns/pdns.conf

以下の追記(270行目付近)

launch=gmysql
gmysql-host=127.0.0.1
gmysql-user=rentaserve
gmysql-password=データベースに設定したパスワード
gmysql-dbname=rentaserve

意味は

  • バックエンドに MySQL(mariadb)を使用およびそのアクセス情報の設定

になります(・∀・)。

設定を反映(・∀・)。

systemctl restart pdns
systemctl enable pdns

これで、こちらで用意したDNSサーバーを参照すると独自ドメインのIPアドレスを mariadb 内に格納したレコードによって制御できます(・∀・)。

バックエンド mariadb にテーブルを作成(・∀・)。

PowerDNS バックエンドの mariadb には以下のテーブルが必要です(・∀・)。 ここは 良く分からんけどそういうもの と思って、以下のテーブルを作成しましょう(・∀・)。

私は以下の SQL を Laravel のシーダーで実装しました(・∀・)。

CREATE TABLE `comments`(
    `id` INT(11) NOT NULL,
    `domain_id` INT(11) NOT NULL,
    `name` VARCHAR(255) NOT NULL,
    `type` VARCHAR(10) NOT NULL,
    `modified_at` INT(11) NOT NULL,
    `account` VARCHAR(40) NOT NULL,
    `comment` TEXT NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
;
CREATE TABLE `cryptokeys`(
    `id` INT(11) NOT NULL,
    `domain_id` INT(11) NOT NULL,
    `flags` INT(11) NOT NULL,
    `active` TINYINT(1) DEFAULT NULL,
    `content` TEXT DEFAULT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
;
CREATE TABLE `domainmetadata`(
    `id` INT(11) NOT NULL,
    `domain_id` INT(11) NOT NULL,
    `kind` VARCHAR(32) DEFAULT NULL,
    `content` TEXT DEFAULT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
;
CREATE TABLE `domains`(
    `id` INT(11) NOT NULL,
    `name` VARCHAR(255) NOT NULL,
    `master` VARCHAR(128) DEFAULT NULL,
    `last_check` INT(11) DEFAULT NULL,
    `type` VARCHAR(6) NOT NULL,
    `notified_serial` INT(11) DEFAULT NULL,
    `account` VARCHAR(40) DEFAULT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
;
CREATE TABLE `records`(
    `id` INT(11) NOT NULL,
    `domain_id` INT(11) DEFAULT NULL,
    `name` VARCHAR(255) DEFAULT NULL,
    `type` VARCHAR(10) DEFAULT NULL,
    `content` TEXT DEFAULT NULL,
    `ttl` INT(11) DEFAULT NULL,
    `prio` INT(11) DEFAULT NULL,
    `change_date` INT(11) DEFAULT NULL,
    `disabled` TINYINT(1) DEFAULT 0,
    `ordername` VARCHAR(255) CHARACTER
SET
    utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
    `auth` TINYINT(1) DEFAULT 1
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
;
CREATE TABLE `supermasters`(
    `ip` VARCHAR(64) NOT NULL,
    `nameserver` VARCHAR(255) NOT NULL,
    `account` VARCHAR(40) NOT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
;
CREATE TABLE `tsigkeys`(
    `id` INT(11) NOT NULL,
    `name` VARCHAR(255) DEFAULT NULL,
    `algorithm` VARCHAR(50) DEFAULT NULL,
    `secret` VARCHAR(255) DEFAULT NULL
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4
;

ALTER TABLE `comments` ADD PRIMARY KEY(
    `id`
),
ADD KEY `comments_domain_id_idx`(
    `domain_id`
),
ADD KEY `comments_name_type_idx`(
    `name`,
    `type`
),
ADD KEY `comments_order_idx`(
    `domain_id`,
    `modified_at`
)
;
ALTER TABLE `cryptokeys` ADD PRIMARY KEY(
    `id`
),
ADD KEY `domainidindex`(
    `domain_id`
)
;
ALTER TABLE `domainmetadata` ADD PRIMARY KEY(
    `id`
),
ADD KEY `domainmetadata_idx`(
    `domain_id`,
    `kind`
)
;
ALTER TABLE `domains` ADD PRIMARY KEY(
    `id`
),
ADD UNIQUE KEY `name_index`(
    `name`
)
;
ALTER TABLE `records` ADD PRIMARY KEY(
    `id`
),
ADD KEY `nametype_index`(
    `name`,
    `type`
),
ADD KEY `domain_id`(
    `domain_id`
),
ADD KEY `recordorder`(
    `domain_id`,
    `ordername`
)
;
ALTER TABLE `supermasters` ADD PRIMARY KEY(
    `ip`,
    `nameserver`
)
;
ALTER TABLE `tsigkeys` ADD PRIMARY KEY(
    `id`
),
ADD UNIQUE KEY `namealgoindex`(
    `name`,
    `algorithm`
)
;
ALTER TABLE `comments` MODIFY `id` INT(
    11
) NOT NULL AUTO_INCREMENT
;
ALTER TABLE `cryptokeys` MODIFY `id` INT(
    11
) NOT NULL AUTO_INCREMENT
;
ALTER TABLE `domainmetadata` MODIFY `id` INT(
    11
) NOT NULL AUTO_INCREMENT
;
ALTER TABLE `domains` MODIFY `id` INT(
    11
) NOT NULL AUTO_INCREMENT
;
ALTER TABLE `records` MODIFY `id` INT(
    11
) NOT NULL AUTO_INCREMENT
;
ALTER TABLE `tsigkeys` MODIFY `id` INT(
    11
) NOT NULL AUTO_INCREMENT
;
ALTER TABLE `records` ADD CONSTRAINT `records_ibfk_1` FOREIGN KEY(
    `domain_id`
) REFERENCES `domains`(
    `id`
)
ON  DELETE CASCADE
;

ドメインとレコードを登録

ドメインテーブル

ドメインとレコードを登録していきます(・∀・)。

まずはドメイン、コレはかんたんです(・∀・)。 ドメイン名と type に NATIVE を入れるだけです(・∀・)。

INSERT INTO `domains`(
    `name`,
    `type`
)
VALUES(
    'rentaserve.com',
    'NATIVE'
)
;

レコードテーブル

続いて rentaserve.com のDNSレコード(・∀・)。

  • レコードが所属するドメインIDを指定(domains の id)
  • レコード名
  • レコード形式(SOA / NS / A / AAAA / MX / TXT など)
  • レコードの内容

などを入れていきます(・∀・)。 まずは SOA と NS レコード、これが無いと nslookup などでエラーになります(・∀・)。

SOA のメールアドレスは連絡の取れる自分のメールアドレスを設定してください(・∀・)。

まずは SOA レコード、これがないとドメインとして機能しません(・∀・)。 コンテキストカラムに半角スペース刻みでいろいろな情報を入れていきます(・∀・)。

INSERT INTO `records`(
    `domain_id`,
    `name`,
    `type`,
    `content`,
    `ttl`
)
VALUES(
    1,
    'rentaserve.com',
    'SOA',
    'rentaserve.com mao.lembryo@gmail.com 1 86400 21600 604800 1200',
    '86400'
)

次に NS レコード、DNSに問い合わせがあった際にどのDNSサーバーを参照するかの設定を行います(・∀・)。

INSERT INTO `records`(
    1,
    `domain_id`,
    `name`,
    `type`,
    `content`
)
VALUES(
    '1',
    'rentaserve.com',
    'NS',
    'ns1.rentaserve.com',
    '86400'
)
;
INSERT INTO `records`(
    `domain_id`,
    `name`,
    `type`,
    `content`,
    `ttl`
)
VALUES(
    '1',
    'rentaserve.com',
    'NS',
    'ns2.rentaserve.com',
    '86400'
)
;

最後にAレコード、逆引きIPアドレスの情報を入れていきます(・∀・)。 レンタルサーバーにする(ConoHa または自宅サーバーの)グローバルIPをコンテキストカラムに指定します(・∀・)。

INSERT INTO `records`(
    `domain_id`,
    `name`,
    `type`,
    `content`,
    `ttl`
)
VALUES(
    '1',
    'rentaserve.com',
    'A',
    '160.251.99.234',
    '600'
)
;
INSERT INTO `records`(
    `domain_id`,
    `name`,
    `type`,
    `content`,
    `ttl`
)
VALUES(
    '1',
    'ns1.rentaserve.com',
    'A',
    '160.251.99.234',
    '600'
)
;
INSERT INTO `records`(
    `domain_id`,
    `name`,
    `type`,
    `content`,
    `ttl`
)
VALUES(
    '1',
    'ns2.rentaserve.com',
    'A',
    '160.251.99.234',
    '600'
)
;

これで、rentaserve.com / ns1.rentaserve.com / ns2.rentaserve.com にアクセスした時にIPアドレス 160.251.99.234 を返すようになります(・∀・)。

疎通するとテンション上がりますよ(・∀・)w

records に「mao.rentaserve.com」を入れればサブドメインにも出来ます(・∀・)。 (設定した AレコードのコンテキストカラムのIPアドレスを返すようになる)

レンタルサーバー利用者の独自ドメインを使用する場合も、同期の domains と records に相応のデータを INSERT するだけです(・∀・)。

最後に

必要なサーバー設定はある程度終わりましたので、次回以降はレンタルサーバーのシステム開発に入れたら良いなーと思っています(・∀・)。