直接urlがIPアドレス(http://***.***.***.*** 、 https://***.***.***.***)でアクセスするのを禁止する、Apache2.4



##### 環境、前提
AWS ec2、amazon linux2(cent7系)
Apache2.4

DNSで「独自ドメイン.com」と「www.独自ドメイン.com」のAレコードは設定済み。

WebサイトのSSL化は自己署名証明書（オレオレ証明書）で設定済み。
・[自己署名ルート証明書（オレオレ証明書）を使ってssl化、httpからhttps、Apache2.4](https://qiita.com/matsu_qiita/items/963867c2365f1d7a365d)

WebサイトのSSL化で正規のSSL証明書を導入するなら色々あるが、無料だとLet's Encryptが有名でよく使われている。
・[Let’s EncryptにSSL証明書の取得の申請し、ウェブサイトをSSL化する【無料で初めてのhttps】](https://it-jog.com/khow/serv/sslbyletsencrypt)
・[Let’s EncryptのSSL証明書を更新する(手動とcronによる自動更新)](https://it-jog.com/khow/serv/renewletsencrypt)


以下の設定ではすべて、Apacheのリダイレクトはテストのために302にしてある。301リダイレクトさせたいなら置き換える。


##### urlがIPアドレス（`http://***.***.***.***`）でのアクセスを禁止する、ケース１

まずは下のケース１の内容を、httpd.confファイルに追加します。
これで、`http://***.***.***.***`にアクセスした場合、403 Forbiddenを返します。
ついでに、`http://www.ドメイン.com`にアクセスした場合、`http://ドメイン.com`にリダイレクトさせています。最初の前提でも書いたがリダイレクトは302です。301リダイレクトさせたいなら置き換える。

あと、最初のVirtualHostタグは（ServerNameがany）必要ないですが、DNSで他にホスト（サブドメイン）のレコード設定がされていれば、このVirtualHostタグの設定が適用されます。今は何も設定内容を書いていませんので、設定したいことがあれば、このVirtualHostタグ内に書く。


```/etc/httpd/conf/httpd.conf-ケース1
#ファイルの最後に追加。

#このVirtualHostはあってもなくても変わらない。
<VirtualHost *:80>
  ServerName any
</VirtualHost>

<VirtualHost *:80>
  ServerName ***.***.***.***
  <Location />
    Order Deny,Allow
    Deny from all
  </Location>
</VirtualHost>

<VirtualHost *:80>
  ServerName www.ドメイン.com
  # リダイレクト設定
  RewriteEngine on
  RewriteCond %{HTTP_HOST} www.ドメイン.com$
  RewriteRule ^/(.*) http://ドメイン.com/$1 [R=302,L]
</VirtualHost>

<VirtualHost *:80>
  ServerName ドメイン.com
  DocumentRoot /var/www/html
  #httpからhttpsへリダイレクトさせたいなら、下のコメントアウトされた3行を有効にする。
#  RewriteEngine on
#  RewriteCond %{HTTPS} off
#  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
</VirtualHost>
```

##### urlがIPアドレス（`http://***.***.***.***`）でのアクセスを禁止する、ケース2

ケース1ではサーバのIPアドレス用のVirtualHostタグを追加していますが、やりたい事が下の２つで
それ以外はアクセス不可にしたいなら、まとめて`ServerName any`でアクセス不可の設定をした方がシンプルです。それがケース２です。

やりたい事
・`http://www.ドメイン.com`にアクセスした場合、`http://ドメイン.com`にリダイレクトする。
・それ以外のurlアクセス（IPアドレスも含む）は拒否する。


```/etc/httpd/conf/httpd.conf-ケース2

<VirtualHost *:80>
  ServerName any
  <Location />
    Order Deny,Allow
    Deny from all
  </Location>
</VirtualHost>

<VirtualHost *:80>
  ServerName www.ドメイン.com
  # リダイレクト設定
  RewriteEngine on
  RewriteCond %{HTTP_HOST} www.ドメイン.com$
  RewriteRule ^/(.*) http://ドメイン.com/$1 [R=302,L]
</VirtualHost>

<VirtualHost *:80>
  ServerName ドメイン.com
  DocumentRoot /var/www/html
  #httpからhttpsへリダイレクトさせたいなら、下のコメントアウトされた3行を有効にする。
#  RewriteEngine on
#  RewriteCond %{HTTPS} off
#  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
</VirtualHost>
```

##### urlがIPアドレス（`http://***.***.***.***`）でアクセスした場合、`http://ドメイン.com`へリダイレクトさせる、ケース3

今度は`http://***.***.***.***`でアクセスした場合、403拒否ではなく、`http://ドメイン.com`へリダイレクトさせています。それがケース3です。
ケース１では、ServerNameがIPアドレスのVirtualHostタグでLocationタグを使ってアクセス拒否設定をしていましたが、ケース３ではその代わりにRewriteRuleでリダイレクト設定しています。
あと、複数のVirtualHostでリダイレクト設定をしているので、`RewriteEngine On`を外に出しています。


```/etc/httpd/conf/httpd.conf-ケース3
RewriteEngine On

#今回はこのVirtualHostはあってもなくても変わらない。
<VirtualHost *:80>
  ServerName any
</VirtualHost>

<VirtualHost *:80>
  ServerName ***.***.***.***
  RewriteRule ^/(.*) http://ドメイン.com/$1 [R=302,L]
</VirtualHost>

<VirtualHost *:80>
  ServerName www.ドメイン.com
  # リダイレクト設定
#  RewriteEngine on
  RewriteCond %{HTTP_HOST} www.ドメイン.com$
  RewriteRule ^/(.*) http://ドメイン.com/$1 [R=302,L]
</VirtualHost>

<VirtualHost *:80>
  ServerName ドメイン.com
  DocumentRoot /var/www/html
  #httpからhttpsへリダイレクトさせたいなら、下のコメントアウトされた3行を有効にする。
#  RewriteEngine on
#  RewriteCond %{HTTPS} off
#  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
</VirtualHost>
```

##### urlがIPアドレス（`http://***.***.***.***`）でアクセスした場合、`http://ドメイン.com`へリダイレクトさせる、ケース4

ケース２でそれ以外のurlアクセス（IPアドレスも含む）は拒否していましたが、拒否ではなく`http://ドメイン.com`へリダイレクトさせます。それがケース４です。


```/etc/httpd/conf/httpd.conf-ケース4
RewriteEngine On

<VirtualHost *:80>
  ServerName any
  RewriteRule ^/(.*) http://ドメイン.com/$1 [R=302,L]
</VirtualHost>

<VirtualHost *:80>
  ServerName www.ドメイン.com
  # リダイレクト設定
#  RewriteEngine on
  RewriteCond %{HTTP_HOST} www.ドメイン.com$
  RewriteRule ^/(.*) http://ドメイン.com/$1 [R=302,L]
</VirtualHost>

<VirtualHost *:80>
  ServerName ドメイン.com
  DocumentRoot /var/www/html
  #httpからhttpsへリダイレクトさせたいなら、下のコメントアウトされた3行を有効にする。
#  RewriteEngine on
#  RewriteCond %{HTTPS} off
#  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
</VirtualHost>
```

##### urlがIPアドレス（`http://***.***.***.***`）でアクセスした場合、`http://ドメイン.com`へリダイレクトさせる、ケース5

今更ですが基本方針として、DNSで設定してあるレコードはすべてVirtualHostタグで設定した方がいいかなと思います。でないと忘れたり後々管理で面倒な事になったりするかも。そして、IPアドレス用のVirtualHostタグをもう１つ追加する。

ただ、DNSで設定したレコードにあわせてすべてVirtualHostタグで設定しようとしても、漏れが出そう。そのために最初に`ServerName any`のVirtualHostタグでは403で拒否する。それがケース５です。
でケース５を書いた後に見直してみると、ちょっと見にくいですね。もっとシンプルに書いて、DNSの設定の方を厳しくチェックした方がいいのかも。このへんはケースバイケースで。。。

```/etc/httpd/conf/httpd.conf-ケース5
RewriteEngine On

<VirtualHost *:80>
  ServerName any
  <Location />
    Order Deny,Allow
    Deny from all
  </Location>
</VirtualHost>

<VirtualHost *:80>
  ServerName ***.***.***.***
  RewriteRule ^/(.*) http://ドメイン.com/$1 [R=302,L]
</VirtualHost>

<VirtualHost *:80>
  ServerName www.ドメイン.com
  # リダイレクト設定
#  RewriteEngine on
  RewriteCond %{HTTP_HOST} www.ドメイン.com$
  RewriteRule ^/(.*) http://ドメイン.com/$1 [R=302,L]
</VirtualHost>

<VirtualHost *:80>
  ServerName ドメイン.com
  DocumentRoot /var/www/html
  #httpからhttpsへリダイレクトさせたいなら、下のコメントアウトされた3行を有効にする。
#  RewriteEngine on
#  RewriteCond %{HTTPS} off
#  RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
</VirtualHost>
```

##### httpアクセスはすべてhttpsへリダイレクトさせ、urlがIPアドレス（`https://***.***.***.***`）でのアクセスを禁止する、もしくはリダイレクトさせる、ケース6

ssl化しての運用が実用的だと思うので、今度はhttpアクセスはhttpsへリダイレクトして、かつ、`https://***.***.***.***`にアクセスした場合、403 Forbiddenを返すようにします。
ついでに、`https://www.ドメイン.com`にアクセスした場合、`https://ドメイン.com`にリダイレクトさせています。これがケース6です。
httpd.confだけでなく、ssl.confも編集しています。

```/etc/httpd/conf/httpd.conf-ケース6
#ファイルの最後に追加。
#httpからhttpsへリダイレクト
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=302,L]
```

```/etc/httpd/conf.d/ssl.conf-ケース6
# ホストwwwからホスト無しへリダイレクト。この4行は既存の<VirtualHost _default_:443>タグ内の最後に追加する。
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www.ドメイン.com$
RewriteRule ^(.*)$ https://ドメイン.com%{REQUEST_URI} [R=302,L]

#このVirtualHostタグはファイルの最後に追記する。直IPアドレスでのアクセスを禁止
<VirtualHost *:443>
  ServerName ***.***.***.***
  <Location />
    Require all denied
# 下の2行でも同じ結果になる
#    Order Deny,Allow
#    Deny from all
  </Location>
# https://***.***.***.***にアクセスした時に、https://ドメイン.comへリダイレクトさせる
#  RewriteRule ^(.*)$ https://ドメイン.com%{REQUEST_URI} [R=302,L]
</VirtualHost>
```

また、`https://***.***.***.***`にアクセスした場合、403を返すのではなく、`https://ドメイン.com`にリダイレクトさせたい場合、ssl.confファイルを下のように編集すればできます。
上の設定との違いは、`<Location>`タグを削除してRewriteRuleの１行を追加しているだけです。

```/etc/httpd/conf.d/ssl.conf-ケース6
# ホストwwwからホスト無しへリダイレクト。この4行は既存の<VirtualHost _default_:443>タグ内の最後に追加する。
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www.ドメイン.com$
RewriteRule ^(.*)$ https://ドメイン.com%{REQUEST_URI} [R=302,L]

#このVirtualHostタグはファイルの最後に追記する。直IPアドレスでのアクセスはリダイレクト。
<VirtualHost *:443>
  ServerName ***.***.***.***
# https://***.***.***.***にアクセスした時に、https://ドメイン.comへリダイレクトさせる
  RewriteRule ^(.*)$ https://ドメイン.com%{REQUEST_URI} [R=302,L]
</VirtualHost>
```

あと、ssl.confの最後に追加した`<VirtualHost *:443>`タグですが、既存の`<VirtualHost _default_:443>`タグより前へ追加すると、まったく動作しなくなります。。位置にも意味があるという事ですね。httpd.confと同じなら、最初に書いた`<VirtualHost *:443>`タグが優先されて適用されるというルールだと思います。
ちなみに、ssl.confの最後に追加した`<VirtualHost *:443>`タグをhttpd.confの最後に追加しても問題なく動作しました。けど、httpの設定はhttpd.conf、httpsの設定はssl.confに分けて書いた方がよさそうです。



##### その他

- Apacheの設定を色々とやりながら思ったことは、Apacheで無理にコントロールしようとしないで、サーバサイドのプログラミングでコントロールするのも１つの手かも。Apacheで大枠をコントロールして、細かい部分はサーバサイドプログラミングで対応するとかがいいかなと思った。例えば403ではなく、他の拒否を返す場合とか。けどapacheで対処してできなかったり問題があれば、サーバサイドで対処するのがいいか、、
 
<!--
- `<VirtualHost *:80>`タグの*でIPアドレスを指定してもダメかな、、
-->

##### 参考サイト
[Apacheの未定義ドメインリクエストURLの落とし穴を埋める](https://www.netmarvs.com/archives/1088)
[WEBサーバー(Apache)で直IPアドレスでのアクセスを禁止/リダイレクトする方法](https://dbit.jp/articles/apache-ip-direct-disable)
[httpアクセスをhttpsへ強制リダイレクト（Virtualhost環境下での個別設定）](https://ygg-tech.com/2019/02/redirect_http_to_https_for_virtualhost_env/)
[FQDNとは？ドメイン名・ホスト名・IPアドレスとの違い](https://www.kagoya.jp/howto/network/fqdn/)


##### 試したけどできなかった。完全に自分のメモ用。urlがIPアドレスでアクセスされた時にドメインへリダイレクトさせる

```/etc/httpd/conf/httpd.conf
RewriteEngine On
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^***.***.***.***$
RewriteRule ^(.*)$ http://ドメイン.com%{REQUEST_URI} [R=302,L]
```

ダメだった、、HTTP_HOSTをSERVER_ADDRやREMOTE_ADDRに変更してみたり、^と$を削除して試したけど、ダメだった、、

他のダメパターン、、というかonじゃなくてoffだろ、、というかそもそも今はhttpだけを考えてやっているんだから、httpsのRewriteCond行はいらないだろ、、

```
#全部だめ、特定のIPのみ禁止するという事ができない、、
RewriteCond %{SERVER_ADDR} ^***.***.***.***$ =
RewriteCond ^***.***.***.***$ =
RewriteCond %{SERVER_ADDR} "=***.***.***.***"
RewriteCond %{SERVER_ADDR} ***.***.***.***
```