Connecting sms gateway to local CHT instance

services:
  medic-os:
    container_name: medic-os
    image: medicmobile/medic-os:cht-3.9.0-rc.2
    volumes:
      - medic-data:/srv
    ports:
      - "${CHT_HTTP:-80}:80"
      - "${CHT_HTTPS:-443}:443"
    working_dir: /srv
    depends_on:
      - haproxy
    networks:
      - medic-net
    environment:
      - DOCKER_NETWORK_NAME=haproxy
      - DOCKER_COUCHDB_ADMIN_PASSWORD=${DOCKER_COUCHDB_ADMIN_PASSWORD:-password}

  haproxy:
    container_name: haproxy
    image: medicmobile/haproxy:rc-1.17
    volumes:
      - medic-data:/srv
    environment:
      - COUCHDB_HOST=medic-os
      - HA_PASSWORD=${DOCKER_COUCHDB_ADMIN_PASSWORD:-password}
    networks:
      - medic-net

volumes:
  medic-data:
    name: medic-data

networks:
  medic-net:
    name: medic-net

Indeed there’s a typo in the route (/api/v1/sms/radpidpro/incoming-messages) so please continue using that!
The integration with RapidPro was added in version 3.11.0: RapidPro Messaging Gateway | Community Health Toolkit
Could you please upgrade to at least 3.11.0 (or preferably 3.13.0 which is latest)?

1 Like

Thanks @diana ,
so looks like its only the latest tag availlable , which is newer than the cht-3.9.0-rc.2.

Switched to using the latest tag , but same error

Ok , as a matter of fact , the latest tag was pushed more than a year ago , and this commit to integrate Rapid pro was pushed on Apr 9, 2021 , which is less that a year

looks like theres no public published image with RapiPro integration

I believe that you should upgrade the CHT version inside the container to get the latest. Maybe this is useful: Can't upgrade to 3.8 version

We can integrate a github action in the ci build pipeline that builds and publishes images to the Gihub container registry on every PR ,or merge

woow, thats a perfect feature.
let me try it out

Thanks @mrjones and @diana ,
i have upgraded my instance to the latest.

i can now succesfully diretly post a message via the api using Postman :innocent:

Let me try RapidPro

RapidPro also worked fine

1 Like

@mozzy

This will be the case in the next major version 4.0. coming later this year.

1 Like

@mozzy - You are correct that the medic-os image on docker hub has not been updated recently. It ships with 3.9.1 However, you can follow these steps to update your instance to 3.13. Assuming your URL is https://192-168-0-103.my.local-ip.co/:

  1. Login as admin
  2. Go to the Admin menu in the upper right hamburger. You should be on https://192-168-0-103.my.local-ip.co/admin/
  3. Click the “Upgrades” link on the left so you’re on https://192-168-0-103.my.local-ip.co/admin/#/upgrade. At the top of the page it should say Version 3.9.1
  4. Find 3.13.0 from Sep 28, 2021 listed below and click the far right button “Install”
  5. Choose “Confirm” to start the upgrade. The upgrade may take some minutes -
  6. Wait for the upgrade to proceed
  7. Click “Reload application” when prompted
  8. It should now say “Version 3.13.0” at the top.

UPDATE - oops - step 3 had the wrong side of the screen - my apologies!

1 Like

@diana ,
i set up a CHT test instance on AWS , and installed some valid certificates .
This works fine on all browsers but the CHT-gateway Andorid app still throws SSL connection failed while the cht android app throws ‘Unable to contact server’

see Chrome validates the certificate

May be you could find these Nginix logs useful

  • error-ssl.log
2022/01/14 08:44:00 [error] 460#0: *7 connect() failed (111: Connection refused) while connecting to upstream, client: 41.210.146.124, server: _, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5988/", host: "cht.openelis-global.org"
2022/01/14 08:44:00 [error] 460#0: *7 connect() failed (111: Connection refused) while connecting to upstream, client: 41.210.146.124, server: _, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5988/", host: "cht.openelis-global.org"
2022/01/14 08:44:00 [error] 460#0: *7 open() "/srv/storage/medic-core/nginx/data/html/50x.html" failed (2: No such file or directory), client: 41.210.146.124, server: _, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:5988/", host: "cht.openelis-global.org"
2022/01/14 08:44:00 [error] 460#0: *7 no live upstreams while connecting to upstream, client: 41.210.146.124, server: _, request: "GET /favicon.ico HTTP/1.1", upstream: "http://medic-api/favicon.ico", host: "cht.openelis-global.org", referrer: "https://cht.openelis-global.org/"
2022/01/14 08:44:00 [error] 460#0: *7 open() "/srv/storage/medic-core/nginx/data/html/50x.html" failed (2: No such file or directory), client: 41.210.146.124, server: _, request: "GET /favicon.ico HTTP/1.1", upstream: "http://medic-api/favicon.ico", host: "cht.openelis-global.org", referrer: "https://cht.openelis-global.org/"

The other log files are empty

Thanks for reporting, @mozzy

I tried your host on my mobile device using CHT-Android and I’m getting the same error.
I’m also getting the an error when I try to access the URL on Firefox on my Android device, Chrome works however.

Pasting the whole Java error here for reference:

2022-01-14 14:31:50.430 18284-18398/org.medicmobile.webapp.mobile D/MedicMobile: Exception caught trying to verify url: https://cht.openelis-global.org
    javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
        at com.android.org.conscrypt.SSLUtils.toSSLHandshakeException(SSLUtils.java:363)
        at com.android.org.conscrypt.ConscryptEngine.convertException(ConscryptEngine.java:1134)
        at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1089)
        at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:876)
        at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
        at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
        at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:858)
        at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.access$100(ConscryptEngineSocket.java:731)
        at com.android.org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:241)
        at com.android.org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:220)
        at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:196)
        at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:153)
        at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
        at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
        at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
        at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
        at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:542)
        at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:106)
        at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:30)
        at org.medicmobile.webapp.mobile.SimpleJsonClient2.get(SimpleJsonClient2.java:50)
        at org.medicmobile.webapp.mobile.SimpleJsonClient2.get(SimpleJsonClient2.java:38)
        at org.medicmobile.webapp.mobile.AppUrlVerifier.verify(AppUrlVerifier.java:23)
        at org.medicmobile.webapp.mobile.SettingsDialogActivity$AppUrlVerificationTask.doInBackground(SettingsDialogActivity.java:44)
        at org.medicmobile.webapp.mobile.SettingsDialogActivity$AppUrlVerificationTask.doInBackground(SettingsDialogActivity.java:37)
        at android.os.AsyncTask$3.call(AsyncTask.java:394)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:920)

Hi @mozzy. I noticed you’ve switched out the certificate on cht.openelis-global.org to be the local-ip.co one:

echo |openssl s_client -connect cht.openelis-global.org:443 | openssl x509 -noout -dates           
depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = R3
verify return:1
depth=0 CN = *.my.local-ip.co
verify return:1
DONE
notBefore=Oct 26 07:27:54 2021 GMT
notAfter=Jan 24 07:27:53 2022 GMT

If this is the case, then to remove the TLS errors, you can use https://44-228-97-26.my.local-ip.com as your URL. Note that you should consider this as effectively not having TLS enabled because the private key is intentionally shared.

Otherwise, if you want to go back to the wild card *.openelis-global.org cert issued by InCommon where you had the error - I strongly suspect an issue with your certificate chaining. The Java error that @diana gives me this page discussing the issue, and only #3 " The server configuration is missing an intermediate CA" applies to you as you’re using a valid CA and it isn’t self signed. Another relevant search result was this one, which also points to a chaining issue.

To verify your chain is correct in your container, these are the steps to try:

  1. Get a copy of your wildcard certificate in server.pem, a copy of your intermediate chain cert in chain.pem and a copy of your private key in server.key
  2. Add the server and chain .pem to the same file: cat server.pem chain.pem > default.crt
  3. Copy the newly created .crt into your medic-os container to /srv/settings/medic-core/nginx/private/default.crt
  4. Copy the private .key to /srv/settings/medic-core/nginx/private/default.key
  5. Restart nginx with: docker exec -it medic-os /boot/svc-restart medic-core nginx

Let us know if that fixes the issue!

CC @craig

1 Like

Thanks @mrjones .

Yeah. i did that as a quick work round for the mean time ,as i was trying to debug why my certs fail to validate on Android.
so temporalily we use https://44-228-97-26.my.local-ip.co/ and it works fine .

Let me try out the steps above and let you know.

1 Like

@mrjones ,
Thats true , when i install back the *. openelis-global.org cert and i try to verify it
i get

depth=0 C = US, postalCode = 98195, ST = Washington, L = Seattle, street = 4545 15th Ave NE, O = University of Washington, OU = UW-IT, CN = *.openelis-global.org
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, postalCode = 98195, ST = Washington, L = Seattle, street = 4545 15th Ave NE, O = University of Washington, OU = UW-IT, CN = *.openelis-global.org
verify error:num=21:unable to verify the first certificate
verify return:1

meaning OPenSSL was unable to verify the certificate’s issuer or the topmost certificate of a provided chain

@mozzy - Thanks for the update and the confirmation that the error is in the chain. Did you double check that you you added the intermediate cert before copying the default.crt file to the container? Is there another nginix, or any other web server, with this *.openelis-global.org cert that you can compare against?

As well, since this is a server with access to the internet and a DNS entry, you may want to set up Let’s Encrypt certificates for just cht.openelis-global.org - this would bypass any issues you have with the InCommon CA wildcard cert.

hello @diana

Am trying to integrate rapidpro with cht however am getting

{
    "code": 400,
    "error": "Message was not saved"
}

Hi @cliff

Please share API logs to see more details about what is going on.
Alternatively, please share the contents of your POST body.

thanks @diana

{
    "content":"cht","from":"+256783243994","id":"355fce73-2ce1-428d-aa9a-8123f7eac886"
}

though it keeps on hanging when sending the request

i have also upgraded my CHT instance

Hi @cliff
Could you have a look at API logs to see if there are any errors logged?

1 Like