Add HealthPlix fetch callback endpoint and Apache proxy rollout templates

This commit is contained in:
DevSoftTech Server 2026-04-28 06:29:29 +05:30
parent d230d8960d
commit cc5018568b
14 changed files with 631 additions and 0 deletions

View File

@ -553,6 +553,7 @@ $healthplixPermFilter = 'permission:admin.access,admin.settings';
$routes->post('HealthplixGateway/generate_token', 'HealthplixGateway::generateToken', ['filter' => $healthplixPermFilter]);
$routes->post('HealthplixGateway/register_patient', 'HealthplixGateway::registerPatient', ['filter' => $healthplixPermFilter]);
$routes->post('HealthplixGateway/book_appointment', 'HealthplixGateway::bookAppointment', ['filter' => $healthplixPermFilter]);
$routes->post('healthplix/fetch', 'HealthplixCallback::fetch');
$routes->get('Opd_prescription/fhir_bundle/(:num)', 'Opd_prescription::fhir_bundle/$1');
$routes->get('Opd_prescription/fhir_bundle/(:num)/(:num)', 'Opd_prescription::fhir_bundle/$1/$2');
$routes->get('Opd_prescription/fhir_bundle_history/(:num)', 'Opd_prescription::fhir_bundle_history/$1');

View File

@ -0,0 +1,81 @@
<?php
namespace App\Controllers;
class HealthplixCallback extends BaseController
{
public function fetch()
{
$rawBody = (string) $this->request->getBody();
$decoded = $this->request->getJSON(true);
$payload = is_array($decoded) ? $decoded : [];
$expectedSecret = $this->resolveExpectedSecret();
$providedSecret = trim((string) $this->request->getHeaderLine('X-Healthplix-Secret'));
if ($expectedSecret !== '' && ! hash_equals($expectedSecret, $providedSecret)) {
$this->logFetchEvent('error', 401, [
'message' => 'Invalid callback secret',
'payload_bytes' => strlen($rawBody),
'payload_keys' => array_keys($payload),
], 'Unauthorized callback request');
return $this->response->setStatusCode(401)->setJSON([
'ok' => 0,
'error_text' => 'Unauthorized callback request',
]);
}
$this->logFetchEvent('success', 200, [
'message' => 'Callback payload received',
'payload_bytes' => strlen($rawBody),
'payload_keys' => array_keys($payload),
]);
return $this->response->setJSON([
'ok' => 1,
'message' => 'HealthPlix fetch callback received',
]);
}
private function resolveExpectedSecret(): string
{
$secret = trim((string) hospital_setting_value('HEALTHPLIX_FETCH_SECRET', ''));
if ($secret !== '') {
return $secret;
}
return trim((string) env('HEALTHPLIX_FETCH_SECRET', ''));
}
/**
* @param array<string, mixed> $response
*/
private function logFetchEvent(string $status, int $responseCode, array $response, string $errorMessage = ''): void
{
try {
if (! $this->db || ! method_exists($this->db, 'tableExists') || ! $this->db->tableExists('abdm_api_logs')) {
return;
}
$this->db->table('abdm_api_logs')->insert([
'channel' => 'healthplix',
'event_type' => 'healthplix.fetch.callback',
'endpoint' => (string) $this->request->getUri()->getPath(),
'http_method' => strtoupper($this->request->getMethod()),
'entity_type' => 'callback',
'entity_id' => trim((string) ($this->request->getHeaderLine('X-Request-Id') ?: 'n/a')),
'request_json' => json_encode([
'ip' => $this->request->getIPAddress(),
'content_type' => (string) $this->request->getHeaderLine('Content-Type'),
], JSON_UNESCAPED_SLASHES),
'response_code' => $responseCode,
'response_json' => json_encode($response, JSON_UNESCAPED_SLASHES),
'status' => $status,
'error_message' => $errorMessage,
'created_at' => date('Y-m-d H:i:s'),
]);
} catch (\Throwable $e) {
}
}
}

View File

@ -16,6 +16,8 @@ class HealthplixSettings extends BaseController
return view('Setting/Admin/healthplix_settings', [
'healthplix_enabled' => $this->readSettingValue('HEALTHPLIX_ENABLED') === '1' ? '1' : '0',
'healthplix_base_url' => $this->readSettingValue('HEALTHPLIX_BASE_URL') ?: 'https://consultation-edge-dev.healthplix.com',
'healthplix_fetch_secret_masked' => $this->maskKey($this->readSettingValue('HEALTHPLIX_FETCH_SECRET')),
'healthplix_fetch_secret_exists' => $this->readSettingValue('HEALTHPLIX_FETCH_SECRET') !== '',
'healthplix_tenant_id' => $this->readSettingValue('HEALTHPLIX_TENANT_ID'),
'healthplix_tenant_key_masked' => $this->maskKey($this->readSettingValue('HEALTHPLIX_TENANT_KEY')),
'healthplix_tenant_key_exists' => $this->readSettingValue('HEALTHPLIX_TENANT_KEY') !== '',
@ -47,6 +49,7 @@ class HealthplixSettings extends BaseController
$fields = [
'HEALTHPLIX_ENABLED' => $this->request->getPost('healthplix_enabled') === '1' ? '1' : '0',
'HEALTHPLIX_BASE_URL' => trim((string) $this->request->getPost('healthplix_base_url')),
'HEALTHPLIX_FETCH_SECRET' => trim((string) $this->request->getPost('healthplix_fetch_secret')),
'HEALTHPLIX_TENANT_ID' => trim((string) $this->request->getPost('healthplix_tenant_id')),
'HEALTHPLIX_TENANT_KEY' => trim((string) $this->request->getPost('healthplix_tenant_key')),
'HEALTHPLIX_DOCTOR_IDENTIFIER' => trim((string) $this->request->getPost('healthplix_doctor_identifier')),

View File

@ -30,6 +30,20 @@
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label">Fetch Callback Secret</label>
<input type="password" class="form-control" id="healthplix_fetch_secret" placeholder="Enter to set/update callback secret">
<div class="form-text" id="healthplix_fetch_secret_hint">
<?php if (!empty($healthplix_fetch_secret_exists)) : ?>
<span class="text-success">&#10003; Secret saved (<?= esc($healthplix_fetch_secret_masked ?? '') ?>). Leave blank to keep existing.</span>
<?php else : ?>
No callback secret configured yet.
<?php endif; ?>
</div>
</div>
</div>
<hr class="my-2">
<h6 class="mb-2">API Endpoints <span class="badge bg-secondary">V1</span></h6>
<div class="form-text mb-2">Paths are relative to the Base URL above. Pre-filled from HealthPlix API Specification Doc v1.7.</div>
@ -140,6 +154,7 @@
return {
healthplix_enabled: $('#healthplix_enabled').is(':checked') ? '1' : '0',
healthplix_base_url: ($('#healthplix_base_url').val() || '').trim(),
healthplix_fetch_secret: ($('#healthplix_fetch_secret').val() || '').trim(),
healthplix_tenant_header_name: ($('#healthplix_tenant_header_name').val() || '').trim(),
healthplix_tenant_id: ($('#healthplix_tenant_id').val() || '').trim(),
healthplix_tenant_key: ($('#healthplix_tenant_key').val() || '').trim(),
@ -163,6 +178,15 @@
}
});
$('#healthplix_fetch_secret').on('input', function() {
var val = $(this).val().trim();
if (val.length > 0) {
$('#healthplix_fetch_secret_hint').html('<span class="text-warning">&#9998; New secret will be saved on Save Settings.</span>');
} else {
$('#healthplix_fetch_secret_hint').html('<span class="text-muted">Leave blank to keep existing callback secret.</span>');
}
});
$('#btn_save_healthplix').on('click', function() {
postJson('<?= base_url('setting/admin/healthplix-settings/save') ?>', payload(), function(data) {
if ((data.update || 0) !== 1) {
@ -178,7 +202,17 @@
} else {
$('#healthplix_tenant_key_hint').html('<span class="text-muted">Leave blank to keep existing key.</span>');
}
var savedSecret = ($('#healthplix_fetch_secret').val() || '').trim();
if (savedSecret.length > 0) {
var maskedSecret = savedSecret.length <= 8 ? '********' : (savedSecret.substring(0, 4) + '****' + savedSecret.slice(-4));
$('#healthplix_fetch_secret_hint').html('<span class="text-success">&#10003; Secret saved (' + maskedSecret + '). Leave blank to keep existing.</span>');
} else {
$('#healthplix_fetch_secret_hint').html('<span class="text-muted">Leave blank to keep existing callback secret.</span>');
}
$('#healthplix_tenant_key').val('');
$('#healthplix_fetch_secret').val('');
});
});

View File

@ -0,0 +1,156 @@
# HealthPlix Reverse Proxy Setup (CentOS 7 + Apache)
This guide is for a central public Apache server that forwards each hospital domain to its own local HMS over VPN.
Example topology:
- Public Apache server: 139.59.13.39
- Hospital A domain: 100001.dhms.in -> A record -> 139.59.13.39
- Hospital A HMS private VPN IP: 10.7.0.32
- Hospital B domain: 100002.dhms.in -> A record -> 139.59.13.39
- Hospital B HMS private VPN IP: 10.8.0.45
Recommended exposure model:
- Expose only callback/fetch path to internet.
- Do not expose full HMS unless required.
## 1) Install and enable required Apache modules
Run on CentOS 7 Apache host:
sudo yum install -y mod_ssl
sudo httpd -M | egrep "proxy|ssl|headers|rewrite"
If any are missing, enable in Apache config and restart httpd.
## 2) Reusable virtual-host template (callback-only)
Create one file per hospital in /etc/httpd/conf.d/
Template file name:
- /etc/httpd/conf.d/DOMAIN.conf
Template content:
<VirtualHost *:80>
ServerName DOMAIN
RewriteEngine On
RewriteRule ^/(.*)$ https://DOMAIN/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName DOMAIN
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/DOMAIN/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/DOMAIN/privkey.pem
ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s
ProxyTimeout 60
Timeout 60
# Callback/fetch endpoint only
ProxyPass /healthplix/fetch http://VPN_HMS_IP/healthplix/fetch
ProxyPassReverse /healthplix/fetch http://VPN_HMS_IP/healthplix/fetch
ErrorLog /var/log/httpd/DOMAIN-healthplix-error.log
CustomLog /var/log/httpd/DOMAIN-healthplix-access.log combined
</VirtualHost>
Replace:
- DOMAIN with hospital DNS name (example 100001.dhms.in)
- VPN_HMS_IP with local HMS VPN IP (example 10.7.0.32)
## 3) Hardened variant (recommended)
Use this inside the :443 VirtualHost when HealthPlix source IPs and secret are available.
# 3.1 Limit endpoint to known HealthPlix source IPs
<Location /healthplix/fetch>
Require all denied
Require ip 203.0.113.10
Require ip 203.0.113.11
</Location>
# 3.2 Shared-secret header validation at edge
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/healthplix/fetch$
RewriteCond %{HTTP:X-Healthplix-Secret} !^REPLACE_WITH_STRONG_SECRET$
RewriteRule ^ - [F,L]
# 3.3 Restrict methods
<Location /healthplix/fetch>
<LimitExcept POST>
Require all denied
</LimitExcept>
</Location>
# 3.4 Body size limits (adjust to payload)
LimitRequestBody 1048576
Notes:
- Replace placeholder IPs with official HealthPlix outbound IPs.
- Replace secret with a long random value.
- Validate same secret again in HMS controller before processing.
## 4) Multi-hospital mapping examples
Hospital A:
- Domain: 100001.dhms.in
- Target: 10.7.0.32
Hospital B:
- Domain: 100002.dhms.in
- Target: 10.8.0.45
Hospital C:
- Domain: 100003.dhms.in
- Target: 10.9.0.20
All domains can point to same public IP 139.59.13.39.
Apache routes by ServerName.
## 5) Enable and reload Apache
sudo apachectl configtest
sudo systemctl reload httpd
If using firewalld:
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload
## 6) HMS application-side settings
For outbound sync from HMS to HealthPlix:
- Keep HEALTHPLIX_BASE_URL as official HealthPlix API base URL.
- Keep token/patient/appointment paths as currently configured.
For inbound fetch/callback from HealthPlix:
- Give HealthPlix callback URL as:
https://DOMAIN/healthplix/fetch
## 7) Validation checklist
1. DNS resolves correctly:
nslookup DOMAIN
2. TLS certificate is valid:
curl -Iv https://DOMAIN/healthplix/fetch
3. Reverse proxy reaches HMS private node:
curl -i -X POST https://DOMAIN/healthplix/fetch -H "X-Healthplix-Secret: REPLACE_WITH_STRONG_SECRET" -d '{}'
4. Apache logs show routed request in domain-specific log file.
5. HMS receives request and returns expected response.
## 8) Operations notes
- Keep one vhost file per hospital for isolation.
- Keep one log file pair per hospital for easier troubleshooting.
- Rotate logs and monitor 4xx/5xx rates.
- Keep VPN routes and ACLs documented and version-controlled.
- Do not log bearer tokens or patient-sensitive payloads in plaintext.

View File

@ -0,0 +1,51 @@
<VirtualHost *:80>
ServerName 100001.dhms.in
RewriteEngine On
RewriteRule ^/(.*)$ https://100001.dhms.in/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName 100001.dhms.in
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/100001.dhms.in/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/100001.dhms.in/privkey.pem
ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine On
SSLProxyVerify require
SSLProxyCheckPeerName on
SSLProxyCheckPeerExpire on
RequestHeader set X-Forwarded-Proto "https"
RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s
ProxyTimeout 60
Timeout 60
# Replace with official HealthPlix source IPs
<Location /healthplix/fetch>
Require all denied
Require ip 203.0.113.10
Require ip 203.0.113.11
<LimitExcept POST>
Require all denied
</LimitExcept>
</Location>
# Replace with your strong shared secret
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/healthplix/fetch$
RewriteCond %{HTTP:X-Healthplix-Secret} !^CHANGE_ME_TO_STRONG_SECRET$
RewriteRule ^ - [F,L]
LimitRequestBody 1048576
# Use internal DNS name reachable via VPN so backend TLS/certificate can be used.
ProxyPass /healthplix/fetch https://khrc.dhms.in/healthplix/fetch
ProxyPassReverse /healthplix/fetch https://khrc.dhms.in/healthplix/fetch
ErrorLog /var/log/httpd/100001-healthplix-error.log
CustomLog /var/log/httpd/100001-healthplix-access.log combined
</VirtualHost>

View File

@ -0,0 +1,47 @@
<VirtualHost *:80>
ServerName 100002.dhms.in
RewriteEngine On
RewriteRule ^/(.*)$ https://100002.dhms.in/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName 100002.dhms.in
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/100002.dhms.in/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/100002.dhms.in/privkey.pem
ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s
ProxyTimeout 60
Timeout 60
# Replace with official HealthPlix source IPs
<Location /healthplix/fetch>
Require all denied
Require ip 203.0.113.10
Require ip 203.0.113.11
<LimitExcept POST>
Require all denied
</LimitExcept>
</Location>
# Replace with your strong shared secret
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/healthplix/fetch$
RewriteCond %{HTTP:X-Healthplix-Secret} !^CHANGE_ME_TO_STRONG_SECRET$
RewriteRule ^ - [F,L]
LimitRequestBody 1048576
ProxyPass /healthplix/fetch http://10.8.0.45/healthplix/fetch
ProxyPassReverse /healthplix/fetch http://10.8.0.45/healthplix/fetch
ErrorLog /var/log/httpd/100002-healthplix-error.log
CustomLog /var/log/httpd/100002-healthplix-access.log combined
</VirtualHost>

View File

@ -0,0 +1,47 @@
<VirtualHost *:80>
ServerName 100003.dhms.in
RewriteEngine On
RewriteRule ^/(.*)$ https://100003.dhms.in/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName 100003.dhms.in
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/100003.dhms.in/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/100003.dhms.in/privkey.pem
ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s
ProxyTimeout 60
Timeout 60
# Replace with official HealthPlix source IPs
<Location /healthplix/fetch>
Require all denied
Require ip 203.0.113.10
Require ip 203.0.113.11
<LimitExcept POST>
Require all denied
</LimitExcept>
</Location>
# Replace with your strong shared secret
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/healthplix/fetch$
RewriteCond %{HTTP:X-Healthplix-Secret} !^CHANGE_ME_TO_STRONG_SECRET$
RewriteRule ^ - [F,L]
LimitRequestBody 1048576
ProxyPass /healthplix/fetch http://10.9.0.20/healthplix/fetch
ProxyPassReverse /healthplix/fetch http://10.9.0.20/healthplix/fetch
ErrorLog /var/log/httpd/100003-healthplix-error.log
CustomLog /var/log/httpd/100003-healthplix-access.log combined
</VirtualHost>

View File

@ -0,0 +1,47 @@
# Local-First Validation Checklist (My Host + VPN Server)
## A) My Host local test (10.7.0.31 machine)
1. Start CI4 locally:
php spark serve --host localhost --port 8080
2. Add hosts entry from my-host/hosts.example:
127.0.0.1 100001.localtest
3. Enable local Apache vhost:
my-host/100001.localtest.conf
4. Reload local Apache.
5. Test through local domain (same callback path):
curl -i -X POST http://100001.localtest/healthplix/fetch -H "X-Healthplix-Secret: CHANGE_ME_TO_STRONG_SECRET" -d '{}'
Expected:
- Request reaches CI4 route at localhost:8080/healthplix/fetch.
## B) VPN server test (10.7.0.1)
1. Install config:
vpn-server/100001.dhms.in.conf -> /etc/httpd/conf.d/100001.dhms.in.conf
2. Validate and reload Apache:
apachectl configtest
systemctl reload httpd
3. From your VPN client machine (10.7.0.31), verify DNS and TLS:
nslookup 100001.dhms.in
curl -Iv https://100001.dhms.in/healthplix/fetch
4. Verify callback path through edge proxy:
curl -i -X POST https://100001.dhms.in/healthplix/fetch -H "X-Healthplix-Secret: CHANGE_ME_TO_STRONG_SECRET" -d '{}'
Expected:
- Edge server accepts request.
- Request is forwarded to khrc.dhms.in over VPN.
- HMS responds with your fetch endpoint response.
## Notes
- Replace placeholder source IPs and secret before production.
- If backend HMS certificate is private/self-signed, import internal CA cert to proxy trust store.
- Keep healthplix/fetch endpoint method-restricted to POST.

View File

@ -0,0 +1,23 @@
# Local machine Apache config for pre-production testing
# Purpose: test callback flow locally by forwarding to CI4 dev server (php spark serve)
# Place on local Apache host and adapt paths/ports for your OS.
<VirtualHost *:80>
ServerName 100001.localtest
ProxyRequests Off
ProxyPreserveHost On
RequestHeader set X-Forwarded-Proto "http"
RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s
ProxyTimeout 60
Timeout 60
# Keep same route shape as production, but target local spark server.
ProxyPass /healthplix/fetch http://localhost:8080/healthplix/fetch
ProxyPassReverse /healthplix/fetch http://localhost:8080/healthplix/fetch
ErrorLog logs/100001-localtest-error.log
CustomLog logs/100001-localtest-access.log combined
</VirtualHost>

View File

@ -0,0 +1,8 @@
# Add to your local hosts file for local-domain testing
# Windows path: C:\Windows\System32\drivers\etc\hosts
# Linux path: /etc/hosts
127.0.0.1 100001.localtest
# Optional for testing real VPN domain from your machine over VPN
# 10.7.0.1 100001.dhms.in

View File

@ -0,0 +1,51 @@
# CentOS 7 VPN/public proxy server config
# Place on VPN server: /etc/httpd/conf.d/100001.dhms.in.conf
<VirtualHost *:80>
ServerName 100001.dhms.in
RewriteEngine On
RewriteRule ^/(.*)$ https://100001.dhms.in/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName 100001.dhms.in
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/100001.dhms.in/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/100001.dhms.in/privkey.pem
ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s
ProxyTimeout 60
Timeout 60
# Replace with official HealthPlix source IPs
<Location /healthplix/fetch>
Require all denied
Require ip 203.0.113.10
Require ip 203.0.113.11
<LimitExcept POST>
Require all denied
</LimitExcept>
</Location>
# Replace with your strong shared secret
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/healthplix/fetch$
RewriteCond %{HTTP:X-Healthplix-Secret} !^CHANGE_ME_TO_STRONG_SECRET$
RewriteRule ^ - [F,L]
LimitRequestBody 1048576
# Production target: HMS server over VPN
ProxyPass /healthplix/fetch https://khrc.dhms.in/healthplix/fetch
ProxyPassReverse /healthplix/fetch https://khrc.dhms.in/healthplix/fetch
ErrorLog /var/log/httpd/100001-healthplix-error.log
CustomLog /var/log/httpd/100001-healthplix-access.log combined
</VirtualHost>

View File

@ -0,0 +1,51 @@
# Copy to /etc/httpd/conf.d/DOMAIN.conf and replace placeholders.
# This variant includes source IP allowlist and shared-secret header check.
<VirtualHost *:80>
ServerName __DOMAIN__
RewriteEngine On
RewriteRule ^/(.*)$ https://__DOMAIN__/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName __DOMAIN__
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/__DOMAIN__/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/__DOMAIN__/privkey.pem
ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s
ProxyTimeout 60
Timeout 60
# Allow only known HealthPlix source IPs (replace with official list)
<Location /healthplix/fetch>
Require all denied
Require ip __HEALTHPLIX_IP_1__
Require ip __HEALTHPLIX_IP_2__
<LimitExcept POST>
Require all denied
</LimitExcept>
</Location>
# Block requests without valid shared secret header
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/healthplix/fetch$
RewriteCond %{HTTP:X-Healthplix-Secret} !^__STRONG_SHARED_SECRET__$
RewriteRule ^ - [F,L]
# Limit payload size to 1 MB (adjust as needed)
LimitRequestBody 1048576
ProxyPass /healthplix/fetch http://__VPN_HMS_IP__/healthplix/fetch
ProxyPassReverse /healthplix/fetch http://__VPN_HMS_IP__/healthplix/fetch
ErrorLog /var/log/httpd/__DOMAIN__-healthplix-error.log
CustomLog /var/log/httpd/__DOMAIN__-healthplix-access.log combined
</VirtualHost>

View File

@ -0,0 +1,31 @@
# Copy to /etc/httpd/conf.d/DOMAIN.conf and replace placeholders.
<VirtualHost *:80>
ServerName __DOMAIN__
RewriteEngine On
RewriteRule ^/(.*)$ https://__DOMAIN__/$1 [R=301,L]
</VirtualHost>
<VirtualHost *:443>
ServerName __DOMAIN__
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/__DOMAIN__/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/__DOMAIN__/privkey.pem
ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine On
RequestHeader set X-Forwarded-Proto "https"
RequestHeader append X-Forwarded-For %{REMOTE_ADDR}s
ProxyTimeout 60
Timeout 60
ProxyPass /healthplix/fetch http://__VPN_HMS_IP__/healthplix/fetch
ProxyPassReverse /healthplix/fetch http://__VPN_HMS_IP__/healthplix/fetch
ErrorLog /var/log/httpd/__DOMAIN__-healthplix-error.log
CustomLog /var/log/httpd/__DOMAIN__-healthplix-access.log combined
</VirtualHost>