本番環境のHyperforceの移行


準備していたのですが、月曜(2025/01/20)の朝から大変でした...


# Yoom

Salesforceとの連携でエラーです

:::note alert
エラーメッセージ
実行中にエラーが発生しました。
再度時間をおいて実行するか、オペレーションを差し戻してアウトプットの修正をお願いします。

オブジェクトの取得に失敗しました。 マイドメインURLまたはオブジェクトのAPI参照名に誤りがあるか、マイアプリ登録時のセッションが無効になっている可能性があります。 セッションが無効な場合は、マイアプリの再登録をお願いいたします。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5250fe58-64b4-6992-4f2f-f3c36a7caaf1.png)


インスタンスが変わったのでマイアプリの再登録が必要でした。

+ [マイアプリ登録方法およびアプリの再連携を行う場合と方法について](https://intercom.help/yoom/ja/articles/9819109-%E3%83%9E%E3%82%A4%E3%82%A2%E3%83%97%E3%83%AA%E7%99%BB%E9%8C%B2%E6%96%B9%E6%B3%95%E3%81%8A%E3%82%88%E3%81%B3%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E5%86%8D%E9%80%A3%E6%90%BA%E3%82%92%E8%A1%8C%E3%81%86%E5%A0%B4%E5%90%88%E3%81%A8%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)

# 外部サーバーとの連携エラー

オチとしてはApacheは準備していたけど、ufwの設定変更を忘れていましたね。

+ [AP0 インスタンスリフレッシュの影響【2023年11月20】](https://qiita.com/Keiji_otsubo/items/eb9f6b2faaa02c6446b3)

上記の時には単純にApecheの設定だけで済んでいたので盲点でしたね。

-----------------------

IPアドレスが変わるのでApache2.4側では準備をしていました。

141.163.208.0/23と18.181.43.11/32が今回のHyperforceのIPアドレス

```
ScriptAlias /cgi-bin/ "/var/www/CGI/"
<Directory /var/www/CGI/>
AllowOverride None
Options ExecCGI
AllowOverride None
AddHandler cgi-script .CGI .cgi
Require all denied
Require ip 141.163.208.0/23
Require ip 18.181.43.11/32
</Directory>
```

+ [Apache2.4 のRequireディレクティブでアクセス制御を行う](https://www.magata.net/memo/index.php?Apache2.4%20%A4%CERequire%A5%C7%A5%A3%A5%EC%A5%AF%A5%C6%A5%A3%A5%D6%A4%C7%A5%A2%A5%AF%A5%BB%A5%B9%C0%A9%B8%E6%A4%F2%B9%D4%A4%A6)

書き方が違った？

```
    <RequireAny>
        Require all denied
        Require ip 141.163.208.0/23
        Require ip 18.181.43.11/32
    </RequireAny>
```


Apexのログを見ると503エラー何ですが、おそらくHTMLのタグがエラーメッセージに含まれるからだろう。
エラーの詳細は以下の通りです。Apacheのエラーログがないのに、接続できないのはファイアウォールを疑った方がよさそうです。

:::note alert
Check with destination team if they have implemented some allow-listing mechanism. Note: If  destination endpoint  is hosted on ingress gateway ( #managed-mesh-support ) can guide if they are blocking requests.
宛先チームが許可リスト メカニズムを実装しているかどうかを確認します。注: 宛先エンドポイントが Ingress ゲートウェイでホストされている場合 ( #managed-mesh-support )、リクエストがブロックされているかどうかを確認できます。

In case of no issues at destination team, check the destination firewall/security groups for access. Reach out to #soter-support for assistance 
宛先チームに問題がない場合は、宛先のファイアウォール/セキュリティ グループにアクセスがあるかどうかを確認してください。サポートについては #soter-support にお問い合わせください。

Reach out to the slack channel #outbound_access if the issue persists
問題が解決しない場合は、Slack チャネル #outbound_access に問い合わせてください。


The remote host or network may be down or blocking requests from publicproxy.  Please verify acls at the origin  os3-388-27074.vs.sakura.ne.jp(xxx.xxx.xxx.xxx) 

リモート ホストまたはネットワークがダウンしているか、publicproxy からのリクエストをブロックしている可能性があります。オリジン os3-388-27074.vs.sakura.ne.jp(xxx.xxx.xxx.xxx) の ACL を確認してください。

heck with destination team if they have implemented some allow-listing mechanism. Note: If  destination endpoint  is hosted on ingress gateway ( #managed-mesh-support ) can guide if they are blocking requests.

宛先チームが何らかの許可リストメカニズムを実装しているかどうかを確認してください。注: 宛先エンドポイントが Ingress ゲートウェイでホストされている場合 ( #managed-mesh-support )、リクエストがブロックされているかどうかを確認できます。

In case of no issues at destination team, check the destination firewall/security groups for access. Reach out to #soter-support for assistance

Reach out to the slack channel #outbound_access if the issue persists
:::

syslogを見たら... あれぇUFW BLOCKがブロックしている感じですね。と気づいた...

:::note alert
Jan 20 07:31:16 os3-388-27074 kernel: [36879824.017619] [UFW BLOCK] IN=ens3 OUT= MAC=9c:a3:ba:43:42:b2:18:80:90:b7:72:ff:08:00 SRC=141.163.209.254 DST=xxx.xxx.xxx.xxx LEN=60 TOS=0x00 PREC=0x00 TTL=57 ID=16865 DF PROTO=TCP SPT=51208 DPT=80 WINDOW=26883 RES=0x00 SYN URGP=0
:::

# IPアドレスの確認方法

1.組織情報からインスタンスを確認
（例：JPN138

2.下記ページにてインスタンスを入力することでデータセンターの場所を確認
https://availability.salesforce.com/find-my-instance/

3.下記ページにてインスタンスとデータセンターの場所からデータセンター名を特定
https://help.salesforce.com/s/articleView?id=000396845&type=1
[JPNx] - 日本
apnortheast1 - アジア太平洋 (東京)
apnortheast3 - アジア太平洋 (大阪)

４．JSONを確認
https://ip-ranges.salesforce.com/ip-ranges.json


# apacheのコマンド

```
vi /etc/apache2/apache2.conf
apache2ctl configtest
systemctl stop apache2
systemctl start apache2
```

# ufwのコマンド

```
ufw status
ufw disable
ufw allow from 141.163.208.0/23 to any port 80
ufw allow from 18.181.43.11/32 to any port 80
ufw enable
```

# 今回はホワイトリスト化で逃げましたが、本来は以下の対応がいいとのこと

+ [【Hyperforce の IP 許可リスト登録の望ましい代替案】](https://help.salesforce.com/s/articleView?id=000394078&type=1)


次のベストプラクティスの採用をお勧めします。
### 許可リストドメイン

apache にSetEnvIf ディレクティブの中にRemote_Host - リクエストを行なっているクライアントのホスト名があるけど使い方が分からないですね。

https://httpd.apache.org/docs/2.4/ja/mod/mod_setenvif.html#SetEnvIf

またufwもドメインを使った制御はデフォルトではないみたい

### Service Name Indicator (SNI) を使用する

上記がダメな場合は次のこの方法みたいですが、今一つ設定方法が見えてきませんね

Hyperforce から顧客の内部ネットワークに安全な接続を確立するには、IP 許可リストを使用するのではなく、顧客のネットワークインフラストラクチャが SNI ヘッダー検査をサポートしているかどうかを調べることをお勧めします。SNI ヘッダーを検査することで、Salesforce から送信されるトラフィックが顧客の Salesforce 環境に誘導されることを確認できます。

+ [Apache SNIで、1IP上の複数サイトでSSL証明書を利用する](https://rms.ne.jp/sslserver/description/apache_sni/)

>かつては、IPアドレスとSSLサーバ証明書は1対1である必要があり、1IPアドレス上の複数のサイトでは、ドメイン（Webサイト）ごとに独自の証明書を利用することはできないとされていました。
しかし、Apache v2.2.12、OpenSSL v0.9.8j以降で利用可能な「SNI (Server Name Indication)」と呼ばれる技術を使うことで、1IP上で複数のサーバー証明書を利用することができるようになりました。

しかし、IPアドレスで許可したIPしか通さないようにするファイアウォールは設定しておきたい。Salesforceとの接続ではこの方法でもいいけど、関係ない他のアドレスからの接続は拒否したい。ということはファイアウォールでやっぱりSalesforceからのIPもOKにする必要があるんでは？

ファイアウォールでドメイン名が使えないと根本的には解決しないような気がします。


### Mutual TLS (mTLS) を実装する

これは今回のケースでなくて、Salesforceにアクセスする時の方法みたい

### 認証プロバイダを使用する (任意)

これは今回のケースでなくて、Salesforceにアクセスする時の方法みたい

### 接続アプリケーションを使用する

これは今回のケースでなくて、Salesforceにアクセスする時の方法みたい

# 関連しそうな資料

+ [クライアント認証を使用したApexコールアウト](https://esp-labo.com/clientcertificate/#google_vignette)
+ [Salesforce がサポートする SSL 証明書](https://help.salesforce.com/s/articleView?id=000385468&type=1)

+ [HTTP リクエストでの証明書の使用](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_client_certs_http.htm)

```Java
HttpRequest req = new HttpRequest();
req.setClientCertificateName('DocSampleCert');
```

+ [Apacheをプライベート認証局やオレオレ証明書でHTTPS化](https://pvision.jp/tech/2023/05/apache-how-to-enable-https/)
+ [コールアウトの目的で自己署名証明書を Salesforce にアップロードすることは可能ですか?](https://salesforce.stackexchange.com/questions/275721/is-it-possible-to-upload-a-self-signed-certificate-into-salesforce-for-callout-p)
+ [System.CalloutException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007T4Rv7SAF)
+ [クライアント証明書を使用した Apex コールアウト](https://salesforce.stackexchange.com/questions/275514/apex-callout-with-a-client-certificate)
+ [Hyperforce における SNI による HTTPS/SSL 接続エラーの解決](https://help.salesforce.com/s/articleView?id=000392990&type=1)
+ [Using Certificates](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_client_certs.htm)

--------------

+ [Making authenticated web service callouts from Salesforce to IBM Cast Iron using SSL/certificates–Part I](https://krishhari.wordpress.com/2012/02/04/making-authenticated-web-service-callouts-from-salesforce-to-ibm-cast-iron-using-sslcertificatespart-i/)
+ [Making authenticated web service callouts from Salesforce to IBM Cast Iron using SSL/certificates–Part II](https://krishhari.wordpress.com/2012/02/06/making-authenticated-web-service-callouts-from-salesforce-to-ibm-cast-iron-using-sslcertificatespart-ii/)

リモートサイトの設定

+ [Making authenticated web service callouts from Salesforce to IBM Cast Iron using SSL/certificates–Part III](https://krishhari.wordpress.com/2012/02/08/making-authenticated-web-service-callouts-from-salesforce-to-ibm-cast-iron-part-iii/)

一方向SSL/証明書セキュリティの理解
パブリック CA によって署名された証明書を取得します。

+ [Making authenticated web service callouts from Salesforce to IBM Cast Iron using SSL/certificates–Part V](https://krishhari.wordpress.com/2012/03/01/making-authenticated-web-service-callouts-from-salesforce-to-ibm-cast-iron-using-sslcertificatespart-v/)

双方向 SSL 認証を使用するには、Salesforce で生成された証明書、または認証局 (CA) によって署名された証明書をコールアウトとともに送信します。証明書を送信すると、コールアウトのターゲットが証明書を受信し、その証明書を使用してキーストアに対して要求を認証できるため、セキュリティが強化されます。