### Description

It is impossible to create a follower index with a `$` character in its name (please note, it is possible to create a regular index with `$` in its name).

This could be reproduced by rest request:
```
PUT /my-index/_ccr/follow
{
    "remote_cluster": "my-remote-cluster",
    "leader_index": "my-index$follower"
}
```

or `CcrIntegTestCase`:

```
    public void testFollowIndex() throws Exception {
        assertAcked(leaderClient().admin().indices().prepareCreate("my$index"));
        setupRemoteCluster();
        final PutFollowAction.Request followRequest = putFollow("my$index", "my$index");
        followerClient().execute(PutFollowAction.INSTANCE, followRequest).get();
    }
```

This is happening as during initial follow phase we restore the leader cluster from the remote using a snapshot restore.
Corresponding request is created with index name added to `RestoreSnapshotRequest#renamePattern` (regexp) without escaping `$`.

x-pack/plugin/ccr/src/internalClusterTest/java/org/elasticsearch/xpack/ccr/IndexFollowingIT.java
.setSource(getIndexSettings(1, 0, Map.of(DataTier.TIER_PREFERENCE, tier)), XContentType.JSON)
        );
        ensureLeaderGreen("leader");
        if (randomBoolean()) {
            String templateTier = randomValueOtherThan(tier, () -> randomFrom(DataTier.DATA_HOT, DataTier.DATA_WARM, DataTier.DATA_COLD));
            putFollowerTemplate(DataTier.TIER_PREFERENCE, templateTier);
        } else if (randomBoolean()) {
            putFollowerTemplate(IndexMetadata.INDEX_ROUTING_REQUIRE_GROUP_PREFIX + ".attr", "ignore");
        }
        final PutFollowAction.Request followRequest = putFollow("leader", "follower");
        followerClient().execute(PutFollowAction.INSTANCE, followRequest).get();
        GetSettingsResponse resp = followerClient().admin().indices().prepareGetSettings("follower").get();
        assertThat(resp.getSetting("follower", DataTier.TIER_PREFERENCE), equalTo(tier));
    }
    public void testReplicatePrivateSettingsOnly() throws Exception {
        assertAcked(leaderClient().admin().indices().prepareCreate("leader").setSource(getIndexSettings(1, 0), XContentType.JSON));
        ensureLeaderGreen("leader");
        followerClient().execute(PutFollowAction.INSTANCE, putFollow("leader", "follower")).get();
        final ClusterService clusterService = getLeaderCluster().getInstance(ClusterService.class, getLeaderCluster().getMasterName());
        final SetOnce<Long> settingVersionOnLeader = new SetOnce<>();
        final CountDownLatch latch = new CountDownLatch(1);
        clusterService.submitUnbatchedStateUpdateTask("test", new ClusterStateUpdateTask() {
            @Override
            public ClusterState execute(ClusterState currentState) {
                final IndexMetadata indexMetadata = currentState.metadata().index("leader");
                Settings.Builder settings = Settings.builder().put(indexMetadata.getSettings());
                settings.put(PrivateSettingPlugin.INDEX_PRIVATE_SETTING.getKey(), "internal-value");
                settings.put(PrivateSettingPlugin.INDEX_INTERNAL_SETTING.getKey(), "internal-value");
                final Metadata.Builder metadata = Metadata.builder(currentState.metadata())
                    .put(