はじめに
この記事では、Ubuntuで運用するApacheをHTTPS化するための手順を記載します。
これにより、出先のどこからでも家のサーバー機にアクセスすることができるようになります。
ただし、自前サーバーの外部ネットワークへの公開すると外部から攻撃される可能性があるため、自己責任でお願い致します。
- 家庭用ルーターでポートフォワーディング設定
- Dynamic DNSサービス「MyDNS」でドメインを取得
- Let’s Encryptでサーバー証明書を取得
- 国内からのみアクセスできるよう、IPフィルタリング設定
家庭用ルーターでポートフォワーディング設定
家庭で使用しているルーターは、セキュリティの観点からアウトバンド通信に対するレスポンスしか通さないような設定になっています。
これにより、ルーター配下の機器はネットに接続しつつ外部からのアクセスは遮断します。
ここへ、特定のインバウンド通信のみを許可する設定がポートフォワーディング設定です。
お使いのルーターによって設定は異なりますので、詳細は説明書等を確認してください。
ここでは一例を紹介します。
ルーター設定
ブラウザのアドレスバーにルーターのIPアドレスを入力することで、ルーターの設定画面にアクセスします。
ipconfig等で自分のPCに割り振られているローカルIPアドレスを確認し、その最後の数値を「1」にしたものがほとんどです。
「ルーター機能の設定」を選択し、ログインIDとパスワードを設定してください。
ログインIDとパスワードは取扱説明書などにデフォルトのものが載っていると思います。

ポート転送設定を選択します。

外部ネットワーク(WAN側)から、ルーターIPアドレスのHTTPSウェルノウンポート「443」へアクセスがあった場合に、ローカルネットワーク(LAN側)のIPアドレス(192.168.○.○)のポート「443」へ転送するよう設定します。
転送先IPアドレスにはサーバーのIPアドレスを設定してください。

設定してルーターを再起動すると設定内容が反映されます。
以上でポートフォワーディングの設定は完了です。
ルーターが再起動されると、ローカルネットワーク側の機器にIPアドレスアドレスが再度割り振られるので、サーバーのIPアドレスが変わってしまう可能性があります。
後述するDDNSを利用する場合は、都度新しいIPアドレスを通知するか、サーバーに割り振られるIPアドレスを固定するようにします。
Dynamic DNSサービス「My DNS」でドメインを取得
DDNSは、インターネット上のデバイスのIPアドレスが動的に変更される場合でも、そのデバイスに簡単にアクセスできるようにするためのシステムです。
例えば、家庭のルーターは電源を再起動するとインターネットサービスプロバイダ(ISP)がIPアドレスを動的に変更します。
ドメインに紐づけられたIPアドレスが固定だと、ルーターを再起動するだけで接続できなくなってしまいます。
DDNSを使用することで、そのIPアドレスの変更に追随してドメインに紐づくIPアドレスを簡単に更新することができます。
登録
MyDNSのページへアクセス。
https://www.mydns.jp/

「JOIN US」をクリックして会員登録ページにアクセス。

必要事項を入力して送信すると、メールアドレスにメールが届きます。

メールのリンクにアクセスしてログインし、「DOMAIN INFO」をクリックします。
ページの上部に使用可能なドメインリストがありますので、好きなものを一つ選びます。

赤枠部に、サブドメイン名+上記で選択したメインドメイン名を入力します。
その他を空欄にすることで、サブドメイン名をホスト名として使用できます。

IPアドレスの通知
「HOW TO USE」に詳しい使い方が記載されています。
今回は「HTTP(s)-BASIC」でIPアドレスを通知します。

サーバーとして使用しているPCから「curl」で上記のリクエストを送信します。
-uのオプションをつけることでBASIC認証をかけることができます。
以下のコマンドでidとpasswordをMyDNSに登録時に通知されたものへ置き換えて送信します。
IPv4の場合
curl -u master_id:password https://ipv4.mydns.jp/login.html
IPv6の場合
curl -u master_id:password https://ipv6.mydns.jp/login.html
以上で、登録したホスト名でサーバーへアクセスが可能になります。
上記のIPアドレスをMyDNSへ通知つるコマンドを定期的に自動で実行する仕組みを作ることで、停電など何等かの理由でルーターのグローバルIPアドレスが変更された場合も、IPアドレスをホスト名に紐づけなおすことが可能です。
Let’s Encryptでサーバー証明書を取得
Let’s Encryptは非営利団体「Internet Security Research Group (ISRG)」によって運営される、無料で利用できるSSL/TLS証明書を提供するオープンな認証局です。
UbuntuとApacheを使用した際の設定例をご紹介します。
- 無料で利用可能
- Certbotというツールを利用して証明書の自動更新が可能
- 証明書の有効期間は90日間と短い
- 保障するのはドメイン所有権
SSL/TLS証明書の種類
SSL/TLS証明書には以下のような種類があります。
- ドメイン検証(DV:Domain Validation)証明書
最も基本的な証明書で、ドメイン所有権の確認のみが行われます。 - 組織検証(OV:Organization Validation)証明書
ドメイン所有権に加えて、組織の実在性も確認される証明書です。 - 拡張検証(EV:Extended Validation)証明書
最も高い保証レベルの証明書で、厳格な審査手続きを経て発行されます。
Let’s Encryptの証明書は上記のDVに該当します。
ドメインの所有権は確認していますが、その所有者(組織や個人)の実在性や信用性までは保障しません。
Webサイトで個人情報等を入力するとき等は、HTTPSであることに加えて、その組織が信用できることまで確認することが重要ですね。
OVやEV証明書であることが望ましいです。
個人のWebサイトで使う分にはDVで十分です。
Apacheの設定
以下のコマンドを入力して、apache2でSSL通信機能を有効にするためのモジュールを有効化します。
sudo a2enmod ssl
「etc/apache2/sites-available」のパスに「000-default.conf」「default-ssl.conf」というファイルがあるので、編集用のコピーファイルを作成します。
sudo cp 000-default.conf test.conf
sudo cp default-ssl.conf test-ssl.conf
上記で作成したファイルの両方に以下の2行目を追加することで、ホスト名とドメイン名を紐づけます。
ServerAdmin webmaster@localhost
ServerName embedded.onshitsudo.mydns.jp
DocumentRoot /home/tbs/apache2/www/html
一旦デフォルト内容のまま、test-ssl.confのバーチャルホスト設定ファイルを有効化します。
以下のコマンドを実行することで、「/etc/apache2/sites-enabled」のパスに「test-ssl.conf」のシンボリックリンクが作成され、有効になります。
sudo a2ensite test.conf
sudo a2ensite test-ssl.conf
以下のコマンドを実行して、apache2を再起動して、設定内容を反映します。
sudo systemctl restart apache2
以上でApacheをHTTPSで動作させるための設定は完了です。
Apacheはデフォルトで独自の証明書を持っているので、「https://サーバーIPアドレス」でアクセスすると、httpsで接続することができます。
(ファイアーウォールでhttpsのポート(443)が開いている場合です。)
Apacheのデフォルト証明書は正式なものではないため、「この接続ではプライバシーが保護されません」と表示されるはずです。
certbotのインストール
以下のコマンドでcertbotをインストールします。
sudo apt-get install certbot python3-certbot-apache
インストールが完了したら、certbotを実行します。
sudo certbot --apache
規約への同意など、いくつか質問に回答する必要があります。
最後に以下のログが表示されたら、証明書のインストールは完了です。
Successfully deployed certificate for embedded.onshitsudo.mydns.jp to /etc/apache2/sites-enabled/hoge-ssl.conf
Congratulations! You have successfully enabled HTTPS on https://*******************
MyDNSで取得したドメインに外部ネットワークからhttpsでアクセスできることを確認してください。
国内からのみアクセスできるよう、IPフィルタリング設定
国内のIPアドレスのみ、サーバーにアクセスを許可するためにIPフィルタリング設定を行います。
ここではfirewalldを使用して、その他のファイアーウォールはオフになっている前提とします。
海外には自動でサーバーを徘徊して攻撃を仕掛けるようなプログラムがうごめいています。
apacheのアクセスログ「/var/log/apache2/access.log」を確認すると、攻撃を受けたログを見ることができます。
国内のIPアドレス一覧作成
rootの下に「iptables」フォルダを作成して、IPアドレス一覧を管理していきます。
cd /
mkdir iptables
そこへ、ファイル名を「make_jpip.sh」として以下のプログラムを作成、保存します。
#!/bin/bash
# 設定
COUNTRYLIST="JP"
BASE_DIR="/iptables"
DELEGATED_FILE="$BASE_DIR/delegated-apnic-latest"
OUTPUT_FILE="$BASE_DIR/jpip"
# 最新データをダウンロード
if ! curl -s -o "$DELEGATED_FILE" http://ftp.apnic.net/stats/apnic/delegated-apnic-latest; then
echo "Error: Failed to download APNIC data."
exit 1
fi
# 出力ファイルを初期化
: > "$OUTPUT_FILE"
# 国ごとの処理
for country in $COUNTRYLIST; do
# IPv4アドレスの抽出と処理
grep "apnic|$country|ipv4|" "$DELEGATED_FILE" | while IFS="|" read -r registry cc type start_ip count _; do
# サブネットのCIDR計算
mask=$((32 - $(echo "l($count)/l(2)" | bc -l | awk '{printf("%d\n", $1)}')))
echo "$start_ip/$mask" >> "$OUTPUT_FILE"
done
done
echo "JP IP list has been saved to $OUTPUT_FILE."
まず、アジア太平洋地域のインターネットレジストリであるAPNICが提供するIPアドレス割り当ての最新情報を含むファイル「delegated-apnic-latest」をダウンロードしています。
ここにいろんな国のIPアドレスが記載されています。
次に日本のIPアドレスに関する行を変数に格納して、サブネットのCIDRを計算してファイル「jpip」に書き込みます。
上記ファイルを実行します。
sudo chmod 755 make_jpip.sh
/iptables/make_jpip.sh
以上で日本のIPアドレス一覧の作成は完了です。
firewalldでゾーンの作成
新しく「domestic」というゾーンを作ってHTTPSに対して国内からのみアクセスできる設定を行います。
以下のコマンドで「domestic」というゾーンを作成します。
sudo firewall-cmd --permanent --new-zone=domestic
firewalldを再起動して、ゾーン一覧に「domestic」が表示されることを確認します。
「permanent」オプションを付けたら、都度再起動して状況を確認します。
sudo systemctl restart firewalld
sudo firewall-cmd --get-zones
次に、「domestic」というipsetを作成します。
sudo firewall-cmd --permanent --new-ipset=domestic --type=hash:net
firewalldを再起動して、ipset一覧に「domestic」が表示されることを確認します。
sudo systemctl restart firewalld
sudo firewall-cmd --get-ipsets
ipsetの「domestic」に作成した日本のIPアドレス一覧を適用します。
firewall-cmd --permanent --ipset=domestic --add-entries-from-file=/root/iptables/jpip
ipsetに国内のIPアドレスが適用されたかを確認します。
firewall-cmd --permanent --info-ipset=domestic
ipsetの「domestic」をゾーンの「domestic」に適用します。
firewall-cmd --permanent --zone=domestic --add-source=ipset:domestic
作成した「domestic」のゾーンで、httpsのポートを許可します。
他のゾーンでhttpsを許可している場合、禁止に設定します。
firewall-cmd --permanent --zone=public --remove-service=https
firewall-cmd --permanent --zone=domestic --add-service=https
以上でIPアドレスによるフィルタリングの設定は完了です。
まとめ
外から自宅のサーバーにアクセスできるのは便利ですが、やはり攻撃が怖いです。
最低限のセキュリティ対策は施してから実施したいですね。
コメント